From e454cea20bdcff10ee698d11b8882662a0153a47 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 18 Sep 2009 23:01:12 +0200 Subject: Driver-Core: extend devnode callbacks to provide permissions This allows subsytems to provide devtmpfs with non-default permissions for the device node. Instead of the default mode of 0600, null, zero, random, urandom, full, tty, ptmx now have a mode of 0666, which allows non-privileged processes to access standard device nodes in case no other userspace process applies the expected permissions. This also fixes a wrong assignment in pktcdvd and a checkpatch.pl complain. Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usblp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/usb/class') diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 26c09f0257d..9bc112ee780 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -1057,14 +1057,14 @@ static const struct file_operations usblp_fops = { .release = usblp_release, }; -static char *usblp_nodename(struct device *dev) +static char *usblp_devnode(struct device *dev, mode_t *mode) { return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); } static struct usb_class_driver usblp_class = { .name = "lp%d", - .nodename = usblp_nodename, + .devnode = usblp_devnode, .fops = &usblp_fops, .minor_base = USBLP_MINOR_BASE, }; -- cgit v1.2.3 From 9b80fee149a875a6292b2556ab2c64dc7ab7d6f5 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 19 Sep 2009 13:13:23 -0700 Subject: cdc_acm: Fix to use modern speed interfaces This changed in 2006 so its about time the ACM driver caught up Signed-off-by: Alan Cox Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/usb/class') diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 2bfc41ece0e..85a1a55815c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -858,10 +858,7 @@ static void acm_tty_set_termios(struct tty_struct *tty, if (!ACM_READY(acm)) return; - /* FIXME: Needs to support the tty_baud interface */ - /* FIXME: Broken on sparc */ - newline.dwDTERate = cpu_to_le32p(acm_tty_speed + - (termios->c_cflag & CBAUD & ~CBAUDEX) + (termios->c_cflag & CBAUDEX ? 15 : 0)); + newline.dwDTERate = cpu_to_le32(tty_get_baud_rate(tty)); newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0; newline.bParityType = termios->c_cflag & PARENB ? (termios->c_cflag & PARODD ? 1 : 2) + -- cgit v1.2.3 From a419aef8b858a2bdb98df60336063d28df4b272f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 18 Aug 2009 11:18:35 -0700 Subject: trivial: remove unnecessary semicolons Signed-off-by: Joe Perches Signed-off-by: Jiri Kosina --- drivers/usb/class/cdc-wdm.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/usb/class') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index ba589d4ca8b..8c64c018b67 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -506,8 +506,6 @@ static int wdm_open(struct inode *inode, struct file *file) desc = usb_get_intfdata(intf); if (test_bit(WDM_DISCONNECTING, &desc->flags)) goto out; - - ; file->private_data = desc; rv = usb_autopm_get_interface(desc->intf); -- cgit v1.2.3 From 7f1dc313d01f5f0f84c06051343a3b8623932d3c Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 9 Sep 2009 10:12:48 +0200 Subject: USB: CDC WDM driver doesn't support non-blocking reads support for O_NONBLOCK in read and write path by simply not waiting for data in read or availability of the write urb in write but returning -EAGAIN Signed-off-by: Oliver Neukum Tested-by: Marcel Holtmann Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'drivers/usb/class') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 8c64c018b67..3e564bfe17d 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -313,8 +313,13 @@ static ssize_t wdm_write r = usb_autopm_get_interface(desc->intf); if (r < 0) goto outnp; - r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, - &desc->flags)); + + if (!file->f_flags && O_NONBLOCK) + r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, + &desc->flags)); + else + if (test_bit(WDM_IN_USE, &desc->flags)) + r = -EAGAIN; if (r < 0) goto out; @@ -377,7 +382,7 @@ outnl: static ssize_t wdm_read (struct file *file, char __user *buffer, size_t count, loff_t *ppos) { - int rv, cntr; + int rv, cntr = 0; int i = 0; struct wdm_device *desc = file->private_data; @@ -389,10 +394,23 @@ static ssize_t wdm_read if (desc->length == 0) { desc->read = 0; retry: + if (test_bit(WDM_DISCONNECTING, &desc->flags)) { + rv = -ENODEV; + goto err; + } i++; - rv = wait_event_interruptible(desc->wait, - test_bit(WDM_READ, &desc->flags)); + if (file->f_flags & O_NONBLOCK) { + if (!test_bit(WDM_READ, &desc->flags)) { + rv = cntr ? cntr : -EAGAIN; + goto err; + } + rv = 0; + } else { + rv = wait_event_interruptible(desc->wait, + test_bit(WDM_READ, &desc->flags)); + } + /* may have happened while we slept */ if (test_bit(WDM_DISCONNECTING, &desc->flags)) { rv = -ENODEV; goto err; @@ -448,7 +466,7 @@ retry: err: mutex_unlock(&desc->rlock); - if (rv < 0) + if (rv < 0 && rv != -EAGAIN) dev_err(&desc->intf->dev, "wdm_read: exit error\n"); return rv; } -- cgit v1.2.3 From 7af25b4b34a2439020d78da765a3bed0ff73f25c Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 8 Sep 2009 23:51:28 +0200 Subject: USB: fix cdc-acm regression in open cdc-acm needs to set a flag during open to tell the tty layer that the device is initialized Signed-off-by: Oliver Neukum Cc: Marcel Holtmann Cc: Paul Martin Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/usb/class') diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 85a1a55815c..e3861b21e77 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -609,6 +610,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) acm->throttle = 0; tasklet_schedule(&acm->urb_task); + set_bit(ASYNCB_INITIALIZED, &acm->port.flags); rv = tty_port_block_til_ready(&acm->port, tty, filp); done: mutex_unlock(&acm->mutex); -- cgit v1.2.3 From 86286883fc8218c81cc1deb04cd1b4a8464bba6f Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 2 Jul 2009 11:36:30 +0200 Subject: USB: usbtmc can do IO to device after disconnect usbtmc will happily complete read/write requests even after disconnect has returned. The fix is to introduce a flag. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usbtmc.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers/usb/class') diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index b09a527f734..0c9df97f677 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -86,6 +86,8 @@ struct usbtmc_device_data { bool TermCharEnabled; bool auto_abort; + bool zombie; /* fd of disconnected device */ + struct usbtmc_dev_capabilities capabilities; struct kref kref; struct mutex io_mutex; /* only one i/o function running at a time */ @@ -384,6 +386,10 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, return -ENOMEM; mutex_lock(&data->io_mutex); + if (data->zombie) { + retval = -ENODEV; + goto exit; + } remaining = count; done = 0; @@ -496,6 +502,10 @@ static ssize_t usbtmc_write(struct file *filp, const char __user *buf, return -ENOMEM; mutex_lock(&data->io_mutex); + if (data->zombie) { + retval = -ENODEV; + goto exit; + } remaining = count; done = 0; @@ -925,6 +935,10 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) data = file->private_data; mutex_lock(&data->io_mutex); + if (data->zombie) { + retval = -ENODEV; + goto skip_io_on_zombie; + } switch (cmd) { case USBTMC_IOCTL_CLEAR_OUT_HALT: @@ -952,6 +966,7 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } +skip_io_on_zombie: mutex_unlock(&data->io_mutex); return retval; } @@ -995,6 +1010,7 @@ static int usbtmc_probe(struct usb_interface *intf, usb_set_intfdata(intf, data); kref_init(&data->kref); mutex_init(&data->io_mutex); + data->zombie = 0; /* Initialize USBTMC bTag and other fields */ data->bTag = 1; @@ -1065,6 +1081,9 @@ static void usbtmc_disconnect(struct usb_interface *intf) usb_deregister_dev(intf, &usbtmc_class); sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp); sysfs_remove_group(&intf->dev.kobj, &data_attr_grp); + mutex_lock(&data->io_mutex); + data->zombie = 1; + mutex_unlock(&data->io_mutex); kref_put(&data->kref, usbtmc_delete); } -- cgit v1.2.3 From a4708103adeaf5731c329b37b0a2b397f814c55c Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 2 Jul 2009 11:44:33 +0200 Subject: USB: suspend/resume support for usbtmc a class driver should have suspend/resume. This makes sure we don't see a virtual disconnect unnecessarily. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usbtmc.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers/usb/class') diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 0c9df97f677..4f0858fbf98 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -1087,11 +1087,24 @@ static void usbtmc_disconnect(struct usb_interface *intf) kref_put(&data->kref, usbtmc_delete); } +static int usbtmc_suspend (struct usb_interface *intf, pm_message_t message) +{ + /* this driver does not have pending URBs */ + return 0; +} + +static int usbtmc_resume (struct usb_interface *intf) +{ + return 0; +} + static struct usb_driver usbtmc_driver = { .name = "usbtmc", .id_table = usbtmc_devices, .probe = usbtmc_probe, - .disconnect = usbtmc_disconnect + .disconnect = usbtmc_disconnect, + .suspend = usbtmc_suspend, + .resume = usbtmc_resume, }; static int __init usbtmc_init(void) -- cgit v1.2.3 From 665d7662d15441b4b3e54131a9418a1a198d0d31 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Wed, 22 Jul 2009 17:39:42 +0200 Subject: USB: usbtmc: sanity checks for DEV_DEP_MSG_IN urbs According to the specifications, an instrument should not return more data in a DEV_DEP_MSG_IN urb than requested. However, some instruments can send more than requested. This could cause the kernel to write the extra data past the end of the buffer provided by read(). Fix this by checking that the value of the TranserSize field is not larger than the urb itself and not larger than the size of the userspace buffer. Also correctly decrement the remaining size of the buffer when userspace read()s more than USBTMC_SIZE_IOBUFFER. Signed-off-by: Guus Sliepen Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usbtmc.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'drivers/usb/class') diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 4f0858fbf98..5bab8e596c8 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -369,13 +369,13 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, { struct usbtmc_device_data *data; struct device *dev; - unsigned long int n_characters; + u32 n_characters; u8 *buffer; int actual; - int done; - int remaining; + size_t done; + size_t remaining; int retval; - int this_part; + size_t this_part; /* Get pointer to private data structure */ data = filp->private_data; @@ -461,6 +461,18 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, (buffer[6] << 16) + (buffer[7] << 24); + /* Ensure the instrument doesn't lie about it */ + if(n_characters > actual - 12) { + dev_err(dev, "Device lies about message size: %zu > %zu\n", n_characters, actual - 12); + n_characters = actual - 12; + } + + /* Ensure the instrument doesn't send more back than requested */ + if(n_characters > this_part) { + dev_err(dev, "Device returns more than requested: %zu > %zu\n", done + n_characters, done + this_part); + n_characters = this_part; + } + /* Copy buffer to user space */ if (copy_to_user(buf + done, &buffer[12], n_characters)) { /* There must have been an addressing problem */ @@ -471,6 +483,8 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, done += n_characters; if (n_characters < USBTMC_SIZE_IOBUFFER) remaining = 0; + else + remaining -= n_characters; } /* Update file position value */ -- cgit v1.2.3 From a2fbf10eba3a38407e3984bc9503342de2b5e399 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 28 Jul 2009 11:22:41 -0700 Subject: USB: usbtmc: fix printk format warnings Fix printk format warnings: drivers/usb/class/usbtmc.c:466: warning: format '%zu' expects type 'size_t', but argument 4 has type 'u32' drivers/usb/class/usbtmc.c:466: warning: format '%zu' expects type 'size_t', but argument 5 has type 'int' Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usbtmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/class') diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 5bab8e596c8..40ef4da786d 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -463,7 +463,7 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, /* Ensure the instrument doesn't lie about it */ if(n_characters > actual - 12) { - dev_err(dev, "Device lies about message size: %zu > %zu\n", n_characters, actual - 12); + dev_err(dev, "Device lies about message size: %u > %d\n", n_characters, actual - 12); n_characters = actual - 12; } -- cgit v1.2.3 From c2cd26e15b84b964c489f2aff278cdaf03840c93 Mon Sep 17 00:00:00 2001 From: Steve Holland Date: Thu, 18 Jun 2009 17:37:49 -0500 Subject: USB: usbtmc: Fix short reads in usbtmc_read() The header size should not be included in the number of bytes requested of the instrument Signed-off-by: Steve Holland Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usbtmc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/usb/class') diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 40ef4da786d..f2fde7cd610 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -407,10 +407,10 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, buffer[1] = data->bTag; buffer[2] = ~(data->bTag); buffer[3] = 0; /* Reserved */ - buffer[4] = (this_part - 12 - 3) & 255; - buffer[5] = ((this_part - 12 - 3) >> 8) & 255; - buffer[6] = ((this_part - 12 - 3) >> 16) & 255; - buffer[7] = ((this_part - 12 - 3) >> 24) & 255; + buffer[4] = (this_part) & 255; + buffer[5] = ((this_part) >> 8) & 255; + buffer[6] = ((this_part) >> 16) & 255; + buffer[7] = ((this_part) >> 24) & 255; buffer[8] = data->TermCharEnabled * 2; /* Use term character? */ buffer[9] = data->TermChar; -- cgit v1.2.3 From 92d07e422df3cc5370d0d9b95a671abb69d50ef1 Mon Sep 17 00:00:00 2001 From: Steve Holland Date: Thu, 18 Jun 2009 17:37:49 -0500 Subject: USB: usbtmc: inhibit corruption Limit data copied to userspace to amount requested. Prevents a faulty instrument from overwriting user memory. Signed-off-by: Steve Holland Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usbtmc.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/usb/class') diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index f2fde7cd610..91d3a94eeaa 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -473,6 +473,10 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, n_characters = this_part; } + /* Bound amount of data received by amount of data requested */ + if (n_characters > this_part) + n_characters = this_part; + /* Copy buffer to user space */ if (copy_to_user(buf + done, &buffer[12], n_characters)) { /* There must have been an addressing problem */ -- cgit v1.2.3 From 4143d178e7b39c00d5277040c69a1522c4d98871 Mon Sep 17 00:00:00 2001 From: Steve Holland Date: Thu, 18 Jun 2009 17:37:49 -0500 Subject: USB: usbtmc: correct termination condition for reads. Follow T&M convention of obeying EOM flag. Avoid exception cases where instrument response size matches a buffer size. Signed-off-by: Steve Holland Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usbtmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/usb/class') diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 91d3a94eeaa..6395f22a58e 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -485,7 +485,8 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, } done += n_characters; - if (n_characters < USBTMC_SIZE_IOBUFFER) + /* Terminate if end-of-message bit recieved from device */ + if ((buffer[8] & 0x01) && (actual >= n_characters + 12)) remaining = 0; else remaining -= n_characters; -- cgit v1.2.3 From d0a38365d9585bf3fb71f7c57fd532441a14f3e8 Mon Sep 17 00:00:00 2001 From: Gergely Imreh Date: Mon, 7 Sep 2009 10:47:01 +0800 Subject: USB: fix USBTMC get_capabilities success handling In order: Add reference to relevant section of USBTMC usb488 subclass specs. Print debug output of capabilities only when it was retrieved successfully. Clear return value on success, otherwise driver always reports failure. Signed-off-by: Gergely Imreh Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usbtmc.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/usb/class') diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 6395f22a58e..333ee02e7b2 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -57,7 +57,9 @@ MODULE_DEVICE_TABLE(usb, usbtmc_devices); /* * This structure is the capabilities for the device - * See section 4.2.1.8 of the USBTMC specification for details. + * See section 4.2.1.8 of the USBTMC specification, + * and section 4.2.2 of the USBTMC usb488 subclass + * specification for details. */ struct usbtmc_dev_capabilities { __u8 interface_capabilities; @@ -796,20 +798,21 @@ static int get_capabilities(struct usbtmc_device_data *data) } dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); - dev_dbg(dev, "Interface capabilities are %x\n", buffer[4]); - dev_dbg(dev, "Device capabilities are %x\n", buffer[5]); - dev_dbg(dev, "USB488 interface capabilities are %x\n", buffer[14]); - dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]); if (buffer[0] != USBTMC_STATUS_SUCCESS) { dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); rv = -EPERM; goto err_out; } + dev_dbg(dev, "Interface capabilities are %x\n", buffer[4]); + dev_dbg(dev, "Device capabilities are %x\n", buffer[5]); + dev_dbg(dev, "USB488 interface capabilities are %x\n", buffer[14]); + dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]); data->capabilities.interface_capabilities = buffer[4]; data->capabilities.device_capabilities = buffer[5]; data->capabilities.usb488_interface_capabilities = buffer[14]; data->capabilities.usb488_device_capabilities = buffer[15]; + rv = 0; err_out: kfree(buffer); -- cgit v1.2.3