Linux 2.6.35 下usb框架程序源码(二)

2014-11-24 08:39:33 ? 作者: ? 浏览: 8
bminor);
if (!interface) {
err("%s - error, can't find device for minor %d",
__func__, subminor);
retval = -ENODEV;
goto exit;
}


dev = usb_get_intfdata(interface);
if (!dev) {
retval = -ENODEV;
goto exit;
}


/* increment our usage count for the device */
kref_get(&dev->kref);


/* lock the device to allow correctly handling errors
* in resumption */
mutex_lock(&dev->io_mutex);


if (!dev->open_count++) {
retval = usb_autopm_get_interface(interface);
if (retval) {
dev->open_count--;
mutex_unlock(&dev->io_mutex);
kref_put(&dev->kref, skel_delete);
goto exit;
}
} /* else { //uncomment this block if you want exclusive open
retval = -EBUSY;
dev->open_count--;
mutex_unlock(&dev->io_mutex);
kref_put(&dev->kref, skel_delete);
goto exit;
} */
/* prevent the device from being autosuspended */


/* save our object in the file's private structure */
file->private_data = dev;
mutex_unlock(&dev->io_mutex);


exit:
return retval;
}


static int skel_release(struct inode *inode, struct file *file)
{
struct usb_skel *dev;


dev = (struct usb_skel *)file->private_data;
if (dev == NULL)
return -ENODEV;


/* allow the device to be autosuspended */
mutex_lock(&dev->io_mutex);
if (!--dev->open_count && dev->interface)
usb_autopm_put_interface(dev->interface);
mutex_unlock(&dev->io_mutex);


/* decrement the count on our device */
kref_put(&dev->kref, skel_delete);
return 0;
}


static int skel_flush(struct file *file, fl_owner_t id)
{
struct usb_skel *dev;
int res;


dev = (struct usb_skel *)file->private_data;
if (dev == NULL)
return -ENODEV;


/* wait for io to stop */
mutex_lock(&dev->io_mutex);
skel_draw_down(dev);


/* read out errors, leave subsequent opens a clean slate */
spin_lock_irq(&dev->err_lock);
res = dev->errors (dev->errors == -EPIPE -EPIPE : -EIO) : 0;
dev->errors = 0;
spin_unlock_irq(&dev->err_lock);


mutex_unlock(&dev->io_mutex);


return res;
}


static void skel_read_bulk_callback(struct urb *urb)
{
struct usb_skel *dev;


dev = urb->context;


spin_lock(&dev->err_lock);
/* 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",
__func__, urb->status);


dev->errors = urb->status;
} else {
dev->bulk_in_filled = urb->actual_length;
}
dev->ongoing_read = 0;
spin_unlock(&dev->err_lock);


complete(&dev->bulk_in_completion);
}


static int skel_do_read_io(struct usb_skel *dev, size_t count)
{
int rv;


/* prepare a read */
usb_fill_bulk_urb(dev->bulk_in_urb,
dev->udev,
usb_rcvbulkpipe(dev->udev,
dev->bulk_in_endpointAddr),
dev->bulk_in_buffer,
min(dev->bulk_in_size, count),
skel_read_bulk_callback,
dev);
/* tell everybody to leave the URB alone */
spin_lock_irq(&dev->err_lock);
dev->ongoing_read = 1;
spin_unlock_irq(&dev->err_lock);


/* do it */
rv = usb_submit_urb(d

-->

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: