linux 2.6下编译usb驱动和arm板进行数据通信(4)
- UID
- 1029342
- 性别
- 男
|
linux 2.6下编译usb驱动和arm板进行数据通信(4)
static ssize_t lcd_write(struct file *file, const char __user * user_buffer, size_t count, loff_t *ppos)
{
struct usb_lcd *dev;
int retval = 0, r;
struct urb *urb = NULL;
char *buf = NULL;
dev = (struct usb_lcd *)file->private_data;
/* verify that we actually have some data to write */
if (count == 0)
goto exit;
r = down_interruptible(&dev->limit_sem);
if (r < 0)
return -EINTR;
/* 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 err_no_buf;
}
buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
if (!buf) {
retval = -ENOMEM;
goto error;
}
if (copy_from_user(buf, user_buffer, count)) {
retval = -EFAULT;
goto error;
}
/* initialize the urb properly */
usb_fill_bulk_urb(urb, dev->udev,
usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
buf, count, lcd_write_bulk_callback, dev);
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
/* send the data out the bulk port */
retval = usb_submit_urb(urb, GFP_KERNEL);
if (retval) {
err("USBLCD: %s - failed submitting write urb, error %d", __FUNCTION__, retval);
goto error;
}
/* release our reference to this urb, the USB core will eventually free it entirely */
usb_free_urb(urb);
r = down_interruptible(&dev->limit_sem);//等待,直到数据完全发送完毕
up(&dev->limit_sem);
// mdelay(10);
exit:
return count;
error:
usb_buffer_free(dev->udev, count, buf, urb->transfer_dma);
usb_free_urb(urb);
err_no_buf:
up(&dev->limit_sem);
return retval;
}
static const struct file_operations lcd_fops = {
.owner = THIS_MODULE,
.read = lcd_read,
.write = lcd_write,
.open = lcd_open,
.ioctl = lcd_ioctl,
.release = lcd_release,
}; |
|
|
|
|
|