예제 #1
0
/*
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
}
예제 #2
0
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;
}