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

static int skel_open(struct inode *inode, struct file *file)
{
    struct usb_skel *dev;
    struct usb_interface *interface;
    int subminor;
    int retval = 0;

subminor = iminor(inode);

interface = usb_find_interface(&skel_driver, subminor);
    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);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwxzgx.html