diff options
Diffstat (limited to 'drivers/usb/gadget/function')
-rw-r--r-- | drivers/usb/gadget/function/f_fs.c | 22 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_hid.c | 8 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_ncm.c | 30 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_printer.c | 8 | ||||
-rw-r--r-- | drivers/usb/gadget/function/u_serial.c | 192 | ||||
-rw-r--r-- | drivers/usb/gadget/function/uvc_queue.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/function/uvc_queue.h | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/function/uvc_v4l2.c | 2 |
8 files changed, 55 insertions, 211 deletions
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index b6cf5ab5a0a1..8f2cf3baa19c 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -266,6 +266,7 @@ static void ffs_ep0_complete(struct usb_ep *ep, struct usb_request *req) } static int __ffs_ep0_queue_wait(struct ffs_data *ffs, char *data, size_t len) + __releases(&ffs->ev.waitq.lock) { struct usb_request *req = ffs->ep0req; int ret; @@ -458,6 +459,7 @@ done_spin: /* Called with ffs->ev.waitq.lock and ffs->mutex held, both released on exit. */ static ssize_t __ffs_ep0_read_events(struct ffs_data *ffs, char __user *buf, size_t n) + __releases(&ffs->ev.waitq.lock) { /* * n cannot be bigger than ffs->ev.count, which cannot be bigger than @@ -543,6 +545,7 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf, break; } + /* unlocks spinlock */ return __ffs_ep0_read_events(ffs, buf, min(n, (size_t)ffs->ev.count)); @@ -638,10 +641,10 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value) return ret; } -static unsigned int ffs_ep0_poll(struct file *file, poll_table *wait) +static __poll_t ffs_ep0_poll(struct file *file, poll_table *wait) { struct ffs_data *ffs = file->private_data; - unsigned int mask = POLLWRNORM; + __poll_t mask = EPOLLWRNORM; int ret; poll_wait(file, &ffs->ev.waitq, wait); @@ -653,19 +656,19 @@ static unsigned int ffs_ep0_poll(struct file *file, poll_table *wait) switch (ffs->state) { case FFS_READ_DESCRIPTORS: case FFS_READ_STRINGS: - mask |= POLLOUT; + mask |= EPOLLOUT; break; case FFS_ACTIVE: switch (ffs->setup_state) { case FFS_NO_SETUP: if (ffs->ev.count) - mask |= POLLIN; + mask |= EPOLLIN; break; case FFS_SETUP_PENDING: case FFS_SETUP_CANCELLED: - mask |= (POLLIN | POLLOUT); + mask |= (EPOLLIN | EPOLLOUT); break; } case FFS_CLOSING: @@ -1246,7 +1249,7 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code, desc = epfile->ep->descs[desc_idx]; spin_unlock_irq(&epfile->ffs->eps_lock); - ret = copy_to_user((void *)value, desc, desc->bLength); + ret = copy_to_user((void __user *)value, desc, desc->bLength); if (ret) ret = -EFAULT; return ret; @@ -2324,7 +2327,7 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type, length, pnl, type); return -EINVAL; } - pdl = le32_to_cpu(*(u32 *)((u8 *)data + 10 + pnl)); + pdl = le32_to_cpu(*(__le32 *)((u8 *)data + 10 + pnl)); if (length != 14 + pnl + pdl) { pr_vdebug("invalid os descriptor length: %d pnl:%d pdl:%d (descriptor %d)\n", length, pnl, pdl, type); @@ -2878,7 +2881,7 @@ static int __ffs_func_bind_do_os_desc(enum ffs_os_desc_type type, ext_prop->type = le32_to_cpu(desc->dwPropertyDataType); ext_prop->name_len = le16_to_cpu(desc->wPropertyNameLength); - ext_prop->data_len = le32_to_cpu(*(u32 *) + ext_prop->data_len = le32_to_cpu(*(__le32 *) usb_ext_prop_data_len_ptr(data, ext_prop->name_len)); length = ext_prop->name_len + ext_prop->data_len + 14; @@ -3700,7 +3703,8 @@ static void ffs_closed(struct ffs_data *ffs) ci = opts->func_inst.group.cg_item.ci_parent->ci_parent; ffs_dev_unlock(); - unregister_gadget_item(ci); + if (test_bit(FFS_FL_BOUND, &ffs->flags)) + unregister_gadget_item(ci); return; done: ffs_dev_unlock(); diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index daae35318a3a..54e859dcb25c 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -413,19 +413,19 @@ release_write_pending_unlocked: return status; } -static unsigned int f_hidg_poll(struct file *file, poll_table *wait) +static __poll_t f_hidg_poll(struct file *file, poll_table *wait) { struct f_hidg *hidg = file->private_data; - unsigned int ret = 0; + __poll_t ret = 0; poll_wait(file, &hidg->read_queue, wait); poll_wait(file, &hidg->write_queue, wait); if (WRITE_COND) - ret |= POLLOUT | POLLWRNORM; + ret |= EPOLLOUT | EPOLLWRNORM; if (READ_COND) - ret |= POLLIN | POLLRDNORM; + ret |= EPOLLIN | EPOLLRDNORM; return ret; } diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index c5bce8e22983..5780fba620ab 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -73,9 +73,7 @@ struct f_ncm { struct sk_buff *skb_tx_ndp; u16 ndp_dgram_count; bool timer_force_tx; - struct tasklet_struct tx_tasklet; struct hrtimer task_timer; - bool timer_stopping; }; @@ -1104,7 +1102,7 @@ static struct sk_buff *ncm_wrap_ntb(struct gether *port, /* Delay the timer. */ hrtimer_start(&ncm->task_timer, TX_TIMEOUT_NSECS, - HRTIMER_MODE_REL); + HRTIMER_MODE_REL_SOFT); /* Add the datagram position entries */ ntb_ndp = skb_put_zero(ncm->skb_tx_ndp, dgram_idx_len); @@ -1148,17 +1146,15 @@ err: } /* - * This transmits the NTB if there are frames waiting. + * The transmit should only be run if no skb data has been sent + * for a certain duration. */ -static void ncm_tx_tasklet(unsigned long data) +static enum hrtimer_restart ncm_tx_timeout(struct hrtimer *data) { - struct f_ncm *ncm = (void *)data; - - if (ncm->timer_stopping) - return; + struct f_ncm *ncm = container_of(data, struct f_ncm, task_timer); /* Only send if data is available. */ - if (ncm->skb_tx_data) { + if (!ncm->timer_stopping && ncm->skb_tx_data) { ncm->timer_force_tx = true; /* XXX This allowance of a NULL skb argument to ndo_start_xmit @@ -1171,16 +1167,6 @@ static void ncm_tx_tasklet(unsigned long data) ncm->timer_force_tx = false; } -} - -/* - * The transmit should only be run if no skb data has been sent - * for a certain duration. - */ -static enum hrtimer_restart ncm_tx_timeout(struct hrtimer *data) -{ - struct f_ncm *ncm = container_of(data, struct f_ncm, task_timer); - tasklet_schedule(&ncm->tx_tasklet); return HRTIMER_NORESTART; } @@ -1513,8 +1499,7 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) ncm->port.open = ncm_open; ncm->port.close = ncm_close; - tasklet_init(&ncm->tx_tasklet, ncm_tx_tasklet, (unsigned long) ncm); - hrtimer_init(&ncm->task_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_init(&ncm->task_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT); ncm->task_timer.function = ncm_tx_timeout; DBG(cdev, "CDC Network: %s speed IN/%s OUT/%s NOTIFY/%s\n", @@ -1623,7 +1608,6 @@ static void ncm_unbind(struct usb_configuration *c, struct usb_function *f) DBG(c->cdev, "ncm unbind\n"); hrtimer_cancel(&ncm->task_timer); - tasklet_kill(&ncm->tx_tasklet); ncm_string_defs[0].id = 0; usb_free_all_descriptors(f); diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index dd607b99eb1d..d359efe06c76 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -680,12 +680,12 @@ printer_fsync(struct file *fd, loff_t start, loff_t end, int datasync) return 0; } -static unsigned int +static __poll_t printer_poll(struct file *fd, poll_table *wait) { struct printer_dev *dev = fd->private_data; unsigned long flags; - int status = 0; + __poll_t status = 0; mutex_lock(&dev->lock_printer_io); spin_lock_irqsave(&dev->lock, flags); @@ -698,11 +698,11 @@ printer_poll(struct file *fd, poll_table *wait) spin_lock_irqsave(&dev->lock, flags); if (likely(!list_empty(&dev->tx_reqs))) - status |= POLLOUT | POLLWRNORM; + status |= EPOLLOUT | EPOLLWRNORM; if (likely(dev->current_rx_bytes) || likely(!list_empty(&dev->rx_buffers))) - status |= POLLIN | POLLRDNORM; + status |= EPOLLIN | EPOLLRDNORM; spin_unlock_irqrestore(&dev->lock, flags); diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 4d653d2960d4..29436f75bbe0 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -26,6 +26,7 @@ #include <linux/module.h> #include <linux/console.h> #include <linux/kthread.h> +#include <linux/kfifo.h> #include "u_serial.h" @@ -80,19 +81,11 @@ #define WRITE_BUF_SIZE 8192 /* TX only */ #define GS_CONSOLE_BUF_SIZE 8192 -/* circular buffer */ -struct gs_buf { - unsigned buf_size; - char *buf_buf; - char *buf_get; - char *buf_put; -}; - /* console info */ struct gscons_info { struct gs_port *port; struct task_struct *console_thread; - struct gs_buf con_buf; + struct kfifo con_buf; /* protect the buf and busy flag */ spinlock_t con_lock; int req_busy; @@ -122,7 +115,7 @@ struct gs_port { struct list_head write_pool; int write_started; int write_allocated; - struct gs_buf port_write_buf; + struct kfifo port_write_buf; wait_queue_head_t drain_wait; /* wait while writes drain */ bool write_busy; wait_queue_head_t close_wait; @@ -154,144 +147,6 @@ static struct portmaster { /*-------------------------------------------------------------------------*/ -/* Circular Buffer */ - -/* - * gs_buf_alloc - * - * Allocate a circular buffer and all associated memory. - */ -static int gs_buf_alloc(struct gs_buf *gb, unsigned size) -{ - gb->buf_buf = kmalloc(size, GFP_KERNEL); - if (gb->buf_buf == NULL) - return -ENOMEM; - - gb->buf_size = size; - gb->buf_put = gb->buf_buf; - gb->buf_get = gb->buf_buf; - - return 0; -} - -/* - * gs_buf_free - * - * Free the buffer and all associated memory. - */ -static void gs_buf_free(struct gs_buf *gb) -{ - kfree(gb->buf_buf); - gb->buf_buf = NULL; -} - -/* - * gs_buf_clear - * - * Clear out all data in the circular buffer. - */ -static void gs_buf_clear(struct gs_buf *gb) -{ - gb->buf_get = gb->buf_put; - /* equivalent to a get of all data available */ -} - -/* - * gs_buf_data_avail - * - * Return the number of bytes of data written into the circular - * buffer. - */ -static unsigned gs_buf_data_avail(struct gs_buf *gb) -{ - return (gb->buf_size + gb->buf_put - gb->buf_get) % gb->buf_size; -} - -/* - * gs_buf_space_avail - * - * Return the number of bytes of space available in the circular - * buffer. - */ -static unsigned gs_buf_space_avail(struct gs_buf *gb) -{ - return (gb->buf_size + gb->buf_get - gb->buf_put - 1) % gb->buf_size; -} - -/* - * gs_buf_put - * - * Copy data data from a user buffer and put it into the circular buffer. - * Restrict to the amount of space available. - * - * Return the number of bytes copied. - */ -static unsigned -gs_buf_put(struct gs_buf *gb, const char *buf, unsigned count) -{ - unsigned len; - - len = gs_buf_space_avail(gb); - if (count > len) - count = len; - - if (count == 0) - return 0; - - len = gb->buf_buf + gb->buf_size - gb->buf_put; - if (count > len) { - memcpy(gb->buf_put, buf, len); - memcpy(gb->buf_buf, buf+len, count - len); - gb->buf_put = gb->buf_buf + count - len; - } else { - memcpy(gb->buf_put, buf, count); - if (count < len) - gb->buf_put += count; - else /* count == len */ - gb->buf_put = gb->buf_buf; - } - - return count; -} - -/* - * gs_buf_get - * - * Get data from the circular buffer and copy to the given buffer. - * Restrict to the amount of data available. - * - * Return the number of bytes copied. - */ -static unsigned -gs_buf_get(struct gs_buf *gb, char *buf, unsigned count) -{ - unsigned len; - - len = gs_buf_data_avail(gb); - if (count > len) - count = len; - - if (count == 0) - return 0; - - len = gb->buf_buf + gb->buf_size - gb->buf_get; - if (count > len) { - memcpy(buf, gb->buf_get, len); - memcpy(buf+len, gb->buf_buf, count - len); - gb->buf_get = gb->buf_buf + count - len; - } else { - memcpy(buf, gb->buf_get, count); - if (count < len) - gb->buf_get += count; - else /* count == len */ - gb->buf_get = gb->buf_buf; - } - - return count; -} - -/*-------------------------------------------------------------------------*/ - /* I/O glue between TTY (upper) and USB function (lower) driver layers */ /* @@ -346,11 +201,11 @@ gs_send_packet(struct gs_port *port, char *packet, unsigned size) { unsigned len; - len = gs_buf_data_avail(&port->port_write_buf); + len = kfifo_len(&port->port_write_buf); if (len < size) size = len; if (size != 0) - size = gs_buf_get(&port->port_write_buf, packet, size); + size = kfifo_out(&port->port_write_buf, packet, size); return size; } @@ -398,7 +253,7 @@ __acquires(&port->port_lock) req->length = len; list_del(&req->list); - req->zero = (gs_buf_data_avail(&port->port_write_buf) == 0); + req->zero = kfifo_is_empty(&port->port_write_buf); pr_vdebug("ttyGS%d: tx len=%d, 0x%02x 0x%02x 0x%02x ...\n", port->port_num, len, *((u8 *)req->buf), @@ -787,10 +642,11 @@ static int gs_open(struct tty_struct *tty, struct file *file) spin_lock_irq(&port->port_lock); /* allocate circular buffer on first open */ - if (port->port_write_buf.buf_buf == NULL) { + if (!kfifo_initialized(&port->port_write_buf)) { spin_unlock_irq(&port->port_lock); - status = gs_buf_alloc(&port->port_write_buf, WRITE_BUF_SIZE); + status = kfifo_alloc(&port->port_write_buf, + WRITE_BUF_SIZE, GFP_KERNEL); spin_lock_irq(&port->port_lock); if (status) { @@ -839,7 +695,7 @@ static int gs_writes_finished(struct gs_port *p) /* return true on disconnect or empty buffer */ spin_lock_irq(&p->port_lock); - cond = (p->port_usb == NULL) || !gs_buf_data_avail(&p->port_write_buf); + cond = (p->port_usb == NULL) || !kfifo_len(&p->port_write_buf); spin_unlock_irq(&p->port_lock); return cond; @@ -875,7 +731,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) /* wait for circular write buffer to drain, disconnect, or at * most GS_CLOSE_TIMEOUT seconds; then discard the rest */ - if (gs_buf_data_avail(&port->port_write_buf) > 0 && gser) { + if (kfifo_len(&port->port_write_buf) > 0 && gser) { spin_unlock_irq(&port->port_lock); wait_event_interruptible_timeout(port->drain_wait, gs_writes_finished(port), @@ -889,9 +745,9 @@ static void gs_close(struct tty_struct *tty, struct file *file) * let the push tasklet fire again until we're re-opened. */ if (gser == NULL) - gs_buf_free(&port->port_write_buf); + kfifo_free(&port->port_write_buf); else - gs_buf_clear(&port->port_write_buf); + kfifo_reset(&port->port_write_buf); port->port.tty = NULL; @@ -915,7 +771,7 @@ static int gs_write(struct tty_struct *tty, const unsigned char *buf, int count) spin_lock_irqsave(&port->port_lock, flags); if (count) - count = gs_buf_put(&port->port_write_buf, buf, count); + count = kfifo_in(&port->port_write_buf, buf, count); /* treat count == 0 as flush_chars() */ if (port->port_usb) gs_start_tx(port); @@ -934,7 +790,7 @@ static int gs_put_char(struct tty_struct *tty, unsigned char ch) port->port_num, tty, ch, __builtin_return_address(0)); spin_lock_irqsave(&port->port_lock, flags); - status = gs_buf_put(&port->port_write_buf, &ch, 1); + status = kfifo_put(&port->port_write_buf, ch); spin_unlock_irqrestore(&port->port_lock, flags); return status; @@ -961,7 +817,7 @@ static int gs_write_room(struct tty_struct *tty) spin_lock_irqsave(&port->port_lock, flags); if (port->port_usb) - room = gs_buf_space_avail(&port->port_write_buf); + room = kfifo_avail(&port->port_write_buf); spin_unlock_irqrestore(&port->port_lock, flags); pr_vdebug("gs_write_room: (%d,%p) room=%d\n", @@ -977,7 +833,7 @@ static int gs_chars_in_buffer(struct tty_struct *tty) int chars = 0; spin_lock_irqsave(&port->port_lock, flags); - chars = gs_buf_data_avail(&port->port_write_buf); + chars = kfifo_len(&port->port_write_buf); spin_unlock_irqrestore(&port->port_lock, flags); pr_vdebug("gs_chars_in_buffer: (%d,%p) chars=%d\n", @@ -1148,7 +1004,7 @@ static int gs_console_thread(void *data) ep = port->port_usb->in; spin_lock_irq(&info->con_lock); - count = gs_buf_data_avail(&info->con_buf); + count = kfifo_len(&info->con_buf); size = ep->maxpacket; if (count > 0 && !info->req_busy) { @@ -1156,7 +1012,7 @@ static int gs_console_thread(void *data) if (count < size) size = count; - xfer = gs_buf_get(&info->con_buf, req->buf, size); + xfer = kfifo_out(&info->con_buf, req->buf, size); req->length = xfer; spin_unlock(&info->con_lock); @@ -1192,7 +1048,7 @@ static int gs_console_setup(struct console *co, char *options) info->req_busy = 0; spin_lock_init(&info->con_lock); - status = gs_buf_alloc(&info->con_buf, GS_CONSOLE_BUF_SIZE); + status = kfifo_alloc(&info->con_buf, GS_CONSOLE_BUF_SIZE, GFP_KERNEL); if (status) { pr_err("%s: allocate console buffer failed\n", __func__); return status; @@ -1202,7 +1058,7 @@ static int gs_console_setup(struct console *co, char *options) co, "gs_console"); if (IS_ERR(info->console_thread)) { pr_err("%s: cannot create console thread\n", __func__); - gs_buf_free(&info->con_buf); + kfifo_free(&info->con_buf); return PTR_ERR(info->console_thread); } wake_up_process(info->console_thread); @@ -1217,7 +1073,7 @@ static void gs_console_write(struct console *co, unsigned long flags; spin_lock_irqsave(&info->con_lock, flags); - gs_buf_put(&info->con_buf, buf, count); + kfifo_in(&info->con_buf, buf, count); spin_unlock_irqrestore(&info->con_lock, flags); wake_up_process(info->console_thread); @@ -1256,7 +1112,7 @@ static void gserial_console_exit(void) unregister_console(&gserial_cons); if (!IS_ERR_OR_NULL(info->console_thread)) kthread_stop(info->console_thread); - gs_buf_free(&info->con_buf); + kfifo_free(&info->con_buf); } #else @@ -1529,7 +1385,7 @@ void gserial_disconnect(struct gserial *gser) /* finally, free any unused/unusable I/O buffers */ spin_lock_irqsave(&port->port_lock, flags); if (port->port.count == 0 && !port->openclose) - gs_buf_free(&port->port_write_buf); + kfifo_free(&port->port_write_buf); gs_free_requests(gser->out, &port->read_pool, NULL); gs_free_requests(gser->out, &port->read_queue, NULL); gs_free_requests(gser->in, &port->write_pool, NULL); diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index 278d50ff1eea..9e33d5206d54 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -193,7 +193,7 @@ int uvcg_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf, * This function implements video queue polling and is intended to be used by * the device poll handler. */ -unsigned int uvcg_queue_poll(struct uvc_video_queue *queue, struct file *file, +__poll_t uvcg_queue_poll(struct uvc_video_queue *queue, struct file *file, poll_table *wait) { return vb2_poll(&queue->queue, file, wait); diff --git a/drivers/usb/gadget/function/uvc_queue.h b/drivers/usb/gadget/function/uvc_queue.h index 51ee94e5cf2b..f9f65b5c1062 100644 --- a/drivers/usb/gadget/function/uvc_queue.h +++ b/drivers/usb/gadget/function/uvc_queue.h @@ -72,7 +72,7 @@ int uvcg_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf); int uvcg_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf, int nonblocking); -unsigned int uvcg_queue_poll(struct uvc_video_queue *queue, +__poll_t uvcg_queue_poll(struct uvc_video_queue *queue, struct file *file, poll_table *wait); int uvcg_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma); diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index f3069db6f08e..9a9019625496 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -329,7 +329,7 @@ uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) return uvcg_queue_mmap(&uvc->video.queue, vma); } -static unsigned int +static __poll_t uvc_v4l2_poll(struct file *file, poll_table *wait) { struct video_device *vdev = video_devdata(file); |