86 #include <linux/kernel.h>
87 #include <linux/errno.h>
92 #include <linux/version.h>
93 #if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) )
95 #include <linux/slab.h>
96 #include <linux/module.h>
104 #define USB_CED_VENDOR_ID 0x0525
105 #define USB_CED_PRODUCT_ID 0xa0f0
116 #define USB_CED_MINOR_BASE 192
119 #define MAX_TRANSFER (PAGE_SIZE - 512)
123 #define WRITES_IN_FLIGHT 8
133 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) )
134 #define usb_alloc_coherent usb_buffer_alloc
135 #define usb_free_coherent usb_buffer_free
136 #define noop_llseek NULL
139 static struct usb_driver ced_driver;
141 static void ced_delete(
struct kref *
kref)
170 int subminor = iminor(inode);
174 pr_err(
"%s - error, can't find device for minor %d", __func__,
189 kref_get(&pdx->
kref);
196 retval = usb_autopm_get_interface(
interface);
200 kref_put(&pdx->
kref, ced_delete);
208 kref_put(&pdx->
kref, ced_delete);
221 static int ced_release(
struct inode *inode,
struct file *file)
230 usb_autopm_put_interface(pdx->
interface);
233 kref_put(&pdx->
kref, ced_delete);
237 static int ced_flush(
struct file *file,
fl_owner_t id)
280 static void ced_writechar_callback(
struct urb *pUrb)
283 int nGot = pUrb->actual_length;
290 "%s - nonzero write bulk status received: %d",
291 __func__, pUrb->status);
295 pdx->
errors = pUrb->status;
307 "%s - char out done, 0 chars sent", __func__);
310 "%s - char out done, %d chars sent", __func__, nGot);
328 usb_sndbulkpipe(pdx->
udev,
331 ced_writechar_callback, pdx);
333 URB_NO_TRANSFER_DMA_MAP;
344 "%s usb_submit_urb() returned %d",
366 (CanAcceptIoRequests(pdx)))
372 "Send %d chars to 1401, EP0 flag %d\n", dwCount,
378 unsigned int count = dwCount;
379 unsigned int index = 0;
385 int n = count > 64 ? 64 :
count;
387 usb_sndctrlpipe(pdx->
udev, 0),
397 "Send %d chars by EP0 failed: %d",
401 "Sent %d chars by EP0", n);
421 usb_sndbulkpipe(pdx->
udev,
424 ced_writechar_callback, pdx);
426 URB_NO_TRANSFER_DMA_MAP;
438 "SendChars bSendCharsPending:true");
464 unsigned int dwOffset =
475 if (nPage < pArea->nPages) {
479 unsigned int uiPageOff = dwOffset & (
PAGE_SIZE - 1);
484 memcpy(pvAddress + uiPageOff,
488 pvAddress + uiPageOff,
496 "%s did not map page %d",
503 "%s exceeded pages %d", __func__,
520 static void staged_callback(
struct urb *pUrb)
523 unsigned int nGot = pUrb->actual_length;
524 bool bCancel =
false;
525 bool bRestartCharInput;
535 "%s - nonzero write bulk status received: %d",
536 __func__, pUrb->status);
539 "%s - staged xfer cancelled", __func__);
542 pdx->
errors = pUrb->status;
550 CopyUserSpace(pdx, nGot);
566 "%s transfer done, bytes %d, cancel %d", __func__,
584 "RWM_Complete, circ block 1 now %d bytes at %d",
594 "%s ERROR, circ block 1 re-started %d bytes at %d",
608 "RWM_Complete, circ block 0 now %d bytes at %d",
620 "RWM_Complete, circ block 1 started %d bytes at %d",
633 "RWM_Complete, circ block 0 started %d bytes at %d",
643 "RWM_Complete, bCircular %d, bToHost %d, eStart %d, eSize %d",
655 unsigned int dwTotal =
660 unsigned int transEnd =
663 unsigned int eventEnd =
671 "About to set event to notify app");
687 "*** RWM_Complete *** pending transfer will now be set up!!!");
696 "RWM_Complete rw setup failed %d",
715 if (bRestartCharInput)
731 unsigned int ChunkSize;
738 if (!CanAcceptIoRequests(pdx))
750 CopyUserSpace(pdx, ChunkSize);
756 usb_sndbulkpipe(pdx->
udev, pdx->
epAddr[nPipe]),
758 pdx->
pStagedUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
792 unsigned int dwOffs,
unsigned int dwLen)
796 if (!CanAcceptIoRequests(pdx))
804 "%s xfer %d bytes to %s, offset %d, area %d", __func__, dwLen,
805 Read ?
"host" :
"1401", dwOffs, wIdent);
812 "%s xfer is waiting, as previous staged pending",
820 "%s OK; zero-len read/write request", __func__);
830 "Circular buffers are %d at %d and %d at %d",
837 bWait |= (dwOffs + dwLen) > pArea->
dwLength;
845 if ((dwOffs + dwLen) > pArea->
dwLength)
850 bWait |= (dwOffs + dwLen) > pArea->
dwLength;
858 "%s xfer waiting for circular buffer space",
864 "%s circular xfer, %d bytes starting at %d", __func__,
890 static bool ReadChar(
unsigned char *pChar,
char *
pBuf,
unsigned int *pdDone,
894 unsigned int dDone = *pdDone;
898 *pChar = (
unsigned char)pBuf[dDone];
915 static bool ReadWord(
unsigned short *pWord,
char *pBuf,
unsigned int *pdDone,
918 if (ReadChar((
unsigned char *)pWord, pBuf, pdDone, dGot))
919 return ReadChar(((
unsigned char *)pWord) + 1, pBuf, pdDone,
936 static bool ReadHuff(
volatile unsigned int *pDWord,
char *pBuf,
937 unsigned int *pdDone,
unsigned int dGot)
939 unsigned char ucData;
941 unsigned int dwData = 0;
943 if (ReadChar(&ucData, pBuf, pdDone, dGot)) {
945 if ((dwData & 0x00000080) != 0) {
946 dwData &= 0x0000007F;
947 if (ReadChar(&ucData, pBuf, pdDone, dGot)) {
948 dwData = (dwData << 8) | ucData;
949 if ((dwData & 0x00004000) != 0) {
950 dwData &= 0x00003FFF;
952 (&ucData, pBuf, pdDone, dGot))
953 dwData = (dwData << 8) | ucData;
982 char *pBuf,
unsigned int dwCount)
984 bool bResult =
false;
985 unsigned char ucData;
986 unsigned int dDone = 0;
990 if (ReadChar(&ucData, pBuf, &dDone, dwCount)) {
991 unsigned char ucTransCode = (ucData & 0x0F);
992 unsigned short wIdent = ((ucData >> 4) & 0x07);
996 pDmaDesc->
wIdent = wIdent;
1005 switch (ucTransCode) {
1010 ReadHuff(&(pDmaDesc->
dwOffset), pBuf,
1012 && ReadHuff(&(pDmaDesc->
dwSize), pBuf,
1016 "%s xfer offset & size %d %d",
1029 "%s bad param - id %d, bUsed %d, offset %d, size %d, area length %d",
1069 unsigned int dwCount)
1081 if (ReadDMAInfo(&pdx->
rDMAInfo, pdx, pCh, dwCount))
1086 "%s xfer to %s, offset %d, length %d", __func__,
1093 "ERROR: DMA setup while transfer still waiting");
1107 "%s ReadWriteMem() failed %d",
1111 "%s Unknown block xfer type %d",
1112 __func__, wTransType);
1129 static void ced_readchar_callback(
struct urb *pUrb)
1132 int nGot = pUrb->actual_length;
1136 int nPipe = pdx->
nPipes == 4 ? 1 : 0;
1142 "%s - nonzero write bulk status received: %d",
1143 __func__, pUrb->status);
1146 "%s - 0 chars pUrb->status=%d (shutdown?)",
1147 __func__, pUrb->status);
1150 pdx->
errors = pUrb->status;
1157 if ((nGot > 1) && ((pdx->
pCoherCharIn[0] & 0x7f) == 0x1b))
1168 "%s got %d chars >%s<",
1173 for (i = 0; i < nGot; i++) {
1204 unsigned long flags;
1216 (CanAcceptIoRequests(pdx)))
1219 int nPipe = pdx->
nPipes == 4 ? 1 : 0;
1225 usb_rcvintpipe(pdx->
udev, pdx->
epAddr[nPipe]),
1228 pdx->
pUrbCharIn->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1237 "%s submit urb failed: %d", __func__, iReturn);
1242 spin_unlock_irqrestore(&pdx->
charInLock, flags);
1255 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
1256 static long ced_ioctl(
struct file *file,
unsigned int cmd,
unsigned long ulArg)
1258 static int ced_ioctl(
struct inode *
node,
struct file *file,
unsigned int cmd,
1259 unsigned long ulArg)
1264 if (!CanAcceptIoRequests(pdx))
1361 pdx->bForceReset =
true;
1388 .release = ced_release,
1391 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
1392 .unlocked_ioctl = ced_ioctl,
1402 static struct usb_class_driver ced_class = {
1414 struct usb_host_interface *iface_desc;
1422 dev_err(&interface->dev,
"Out of memory\n");
1438 kref_init(&pdx->
kref);
1447 bcdDevice = pdx->
udev->descriptor.bcdDevice;
1448 i = (bcdDevice >> 8);
1451 else if ((i >= 1) && (i <= 23))
1454 dev_err(&interface->dev,
"%s Unknown device. bcdDevice = %d",
1455 __func__, bcdDevice);
1460 iface_desc = interface->cur_altsetting;
1461 pdx->
nPipes = iface_desc->desc.bNumEndpoints;
1462 dev_info(&interface->dev,
"1401Type=%d with %d End Points",
1472 dev_err(&interface->dev,
"%s URB alloc failed", __func__);
1486 dev_err(&interface->dev,
"%s Coherent buffer alloc failed",
1491 for (i = 0; i < pdx->
nPipes; ++
i) {
1492 endpoint = &iface_desc->endpoint[
i].desc;
1494 dev_info(&interface->dev,
"Pipe %d, ep address %02x", i,
1496 if (((pdx->
nPipes == 3) && (i == 0)) ||
1497 ((pdx->
nPipes == 4) && (i == 1))) {
1499 dev_info(&interface->dev,
"Pipe %d, bInterval = %d", i,
1503 if (i == pdx->
nPipes - 1)
1513 usb_set_intfdata(interface, pdx);
1520 "Not able to get a minor for this device.\n");
1521 usb_set_intfdata(interface,
NULL);
1527 "USB CEDUSB device now attached to cedusb #%d",
1533 kref_put(&pdx->
kref, ced_delete);
1540 int minor = interface->minor;
1543 usb_set_intfdata(interface,
NULL);
1559 kref_put(&pdx->
kref, ced_delete);
1561 dev_info(&interface->dev,
"USB cedusb #%d now disconnected", minor);
1624 static struct usb_driver ced_driver = {
1627 .disconnect = ced_disconnect,
1628 .suspend = ced_suspend,
1629 .resume = ced_resume,
1630 .pre_reset = ced_pre_reset,
1631 .post_reset = ced_post_reset,
1632 .id_table = ced_table,
1633 .supports_autosuspend = 1,