/* static void ss801u_write_bulk_callback(struct urb *urb) { usb_ss801u *dev; dev = (usb_ss801u *)urb->context; // sync/async unlink faults aren't errors // if (urb->status) { if(!(urb->status == -ENOENT || urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) err("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); Egis_Reset_device(dev); spin_lock(&dev->err_lock); dev->errors = urb->status; spin_unlock(&dev->err_lock); } // free up our allocated buffer // usb_buffer_free(urb->dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma); up(&dev->limit_sem); } */ static ssize_t ss801u_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) { printk(KERN_INFO "Patrick-> ss801u_write start\n"); printk(KERN_INFO "Patrick-> ss801u_write finish\n"); //*/ //--------------- CASE1 : return only -----------------------// //-----------------------------------------------------------// return -ENOSYS; // function not implement #if 0 /*---------------- CASE2 : bulk write -----------------------*/ /*-----------------------------------------------------------*/ usb_ss801u *dev; int retval = 0; struct urb *urb = NULL; char *buf = NULL; size_t writesize = min(count, (size_t)MAX_TRANSFER); dev = (usb_ss801u *)file->private_data; if (count == 0) goto exit; if (down_interruptible(&dev->limit_sem)) { retval = -ERESTARTSYS; goto exit; } spin_lock_irq(&dev->err_lock); retval = dev->errors; if (retval < 0) { dev->errors = 0; retval = (retval == -EPIPE) ? retval : -EIO; } spin_unlock_irq(&dev->err_lock); if (retval < 0) goto error; /*----- create a urb, and a buffer for it, and copy the data to the urb -----*/ urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { retval = -ENOMEM; goto error; } buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma); if (!buf) { retval = -ENOMEM; goto error; } if (copy_from_user(buf, user_buffer, writesize)) { retval = -EFAULT; goto error; } /*----- this lock makes sure we don't submit URBs to gone devices -----*/ /*---------------------------------------------------------------------*/ mutex_lock(&dev->io_mutex); if (!dev->interface) { /* disconnect() was called */ mutex_unlock(&dev->io_mutex); retval = -ENODEV; goto error; } /*----- To NOT go to suspend -----*/ usb_autopm_get_interface(dev->interface); /*----- initialize the urb properly -----*/ usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), buf, writesize, ss801u_write_bulk_callback, dev); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /*usb_anchor_urb(urb, &dev->submitted);*/ /*----- send the data out the bulk port -----*/ retval = usb_submit_urb(urb, GFP_KERNEL); /*----- Auto suspend -----*/ usb_autopm_put_interface(dev->interface); mutex_unlock(&dev->io_mutex); /*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/ if (retval) { Egis_Reset_device(dev); err("%s - failed submitting write urb, error %d", retval, retval); goto error_unanchor; } /*----- release our reference to this urb, the USB core will eventually free it entirely -----*/ usb_free_urb(urb); return writesize; error_unanchor: usb_unanchor_urb(urb); error: if (urb) { usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma); usb_free_urb(urb); } up(&dev->limit_sem); exit: return retval; #endif }
int Egis_BulkXfer( usb_ss801u *dev, trans_dir dir, void* Data, int DataSize, int* pActualSize, int Timeout ) { int retval = -1; int iActualRWSize; bool bRestore=false; //Wayne for test // dev->bPrintDbgMsg = true; // pr_debug("%s:%d bulk In endpoint = %d Out endpoint = %d\n", __FUNCTION__, __LINE__, dev->bulk_in_endpointAddr, dev->bulk_out_endpointAddr); if (!dev->udev) { pr_debug("dev->udev = NULL\n"); } else { pr_debug("dev->udev->state = %d dev->udev->speed = %d\n", dev->udev->state, dev->udev->speed); } // for (i = 0; i < DataSize; i++) // { // pr_debug("%2x ", (u8)Data[i]); // } // pr_debug("\n"); mutex_lock(&dev->Bulk_Mutex); //----- if EPROTO happens, we will call clear feature and re-send again do{ EgisMsg(dev->bPrintDbgMsg, KERN_ERR,"Do usb_bulk_msg\n"); retval = usb_bulk_msg( dev->udev, (dir_in == dir) ? usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr) : usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), Data, DataSize, &iActualRWSize, Timeout ); // show data // EgisMsg(dev->bPrintDbgMsg, KERN_ERR,"following are data block of bulk transfer:\r\n"); // int iLoopIndex = 0; // unsigned char *pData = Data; // for(iLoopIndex = 0; iLoopIndex<DataSize; iLoopIndex++) // { // EgisMsg(dev->bPrintDbgMsg, KERN_ERR,"%2x", pData[iLoopIndex]); // } // EgisMsg(dev->bPrintDbgMsg, KERN_ERR,"\r\ndata block finish\r\n"); if(EGIS_FAIL(retval)){ //----- if error == EPROTO && not be restored --> clear halt if(EOVERFLOW == retval) { EgisMsg(dev->bPrintDbgMsg, KERN_ERR,"=Egis_BulkXfer= bulk transfer error, EOVERFLOW, data size = %d" , DataSize); } if(EPROTO == retval && !bRestore){ EgisMsg(dev->bPrintDbgMsg, KERN_ERR, "=Egis_BulkXfer= bulk xfer fail clear feature\r\n"); retval = usb_clear_halt(dev->udev, (dir_in == dir) ? usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr) : usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr) ); bRestore = true; } //----- this if include "else" above and check clear halt fail if(EGIS_FAIL(retval)){ EgisMsg(dev->bPrintDbgMsg, KERN_ERR, "=Egis_BulkXfer= bulk xfer fail %d\r\n", retval); break; } } else{ //----- if xfer is success, set bRestore=false to leave while loop bRestore = false; } }while(EGIS_SUCCESS(retval) && bRestore); memcpy(pActualSize, &iActualRWSize, sizeof(int)); EgisMsg(dev->bPrintDbgMsg, KERN_ERR, "=Egis_BulkXfer= bulk xfer actual data size: %d\r\n", iActualRWSize); mutex_unlock(&dev->Bulk_Mutex); //----- If xfer fails, reset device. if(EGIS_FAIL(retval)){ Egis_Reset_device(dev); } //Wayne for test dev->bPrintDbgMsg = false; return retval; }