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

if (!dev->processed_urb) {
        /*
         * the URB hasn't been processed
         * do it now
         */
        wait_for_completion(&dev->bulk_in_completion);
        dev->bulk_in_copied = 0;
        dev->processed_urb = 1;
    }

/* errors must be reported */
    rv = dev->errors;
    if (rv < 0) {
        /* any error is reported once */
        dev->errors = 0;
        /* to preserve notifications about reset */
        rv = (rv == -EPIPE) ? rv : -EIO;
        /* no data to deliver */
        dev->bulk_in_filled = 0;
        /* report it */
        goto exit;
    }

/*
     * if the buffer is filled we may satisfy the read
     * else we need to start IO
     */

if (dev->bulk_in_filled) {
        /* we had read data */
        size_t available = dev->bulk_in_filled - dev->bulk_in_copied;
        size_t chunk = min(available, count);

if (!available) {
            /*
             * all data has been used
             * actual IO needs to be done
             */
            rv = skel_do_read_io(dev, count);
            if (rv < 0)
                goto exit;
            else
                goto retry;
        }
        /*
         * data is available
         * chunk tells us how much shall be copied
         */

if (copy_to_user(buffer,
                 dev->bulk_in_buffer + dev->bulk_in_copied,
                 chunk))
            rv = -EFAULT;
        else
            rv = chunk;

dev->bulk_in_copied += chunk;

/*
         * if we are asked for more than we have,
         * we start IO but don't wait
         */
        if (available < count)
            skel_do_read_io(dev, count - chunk);
    } else {
        /* no data in the buffer */
        rv = skel_do_read_io(dev, count);
        if (rv < 0)
            goto exit;
        else if (!(file->f_flags & O_NONBLOCK))
            goto retry;
        rv = -EAGAIN;
    }
exit:
    mutex_unlock(&dev->io_mutex);
    return rv;
}

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

dev = 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",
                __func__, urb->status);

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

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