USB fixes for 2.6.22-rc4
Subsystems (9)
PATCH 1/1 USB fixes for 2.6.22-rc4
Here are some USB fixes against your 2.6.22-rc4 tree.
They fix a number of minor things and update some documentation and add some usb-storage quirks, and make the config option a default that has been tripping up some usbfs users with older udev configurations.
All of these have been in the -mm releases for a while.
Please pull from:
master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6.git/
The full patches will be sent to the linux-usb-devel mailing list, if anyone wants to see them.
thanks,
greg k-h
Documentation/networking/00-INDEX | 2 + Documentation/networking/cxacru.txt | 84 +++++++++++++++++++++++++++++++++++ drivers/usb/atm/cxacru.c | 52 +++++++++++----------- drivers/usb/class/usblp.c | 5 +- drivers/usb/core/Kconfig | 22 +++++---- drivers/usb/core/config.c | 42 +++++++++++++++++- drivers/usb/gadget/epautoconf.c | 2 +- drivers/usb/gadget/inode.c | 8 ++-- drivers/usb/gadget/net2280.c | 6 +- drivers/usb/gadget/omap_udc.c | 6 +- drivers/usb/gadget/rndis.c | 35 +++++++++----- drivers/usb/host/ohci-hub.c | 2 + drivers/usb/storage/unusual_devs.h | 21 ++++++++- 13 files changed, 222 insertions(+), 65 deletions(-) create mode 100644 Documentation/networking/cxacru.txt
---------------
Alan Stern (2):
USB: Fix up bogus bInterval values in endpoint descriptors
OHCI: Fix machine check in ohci_hub_status_data
Ben Collins (1):
USB: UNUSUAL_DEV: Sync up some reported devices from Ubuntu
David Brownell (1):
USB: usb gadgets avoid le{16,32}_to_cpup()Kay Sievers (1):
USB: set default y for CONFIG_USB_DEVICE_CLASS
Pete Zaitcev (1):
usblp: Don't let suspend to kill ->used
Simon Arlott (3):
USB: cxacru: add Documentation file
USB: cxacru: create sysfs attributes in atm_start instead of bind
USB: cxacru: ignore error trying to start ADSL in atm_start
PATCH 1/9 USB: set default y for CONFIG_USB_DEVICE_CLASS
From: Kay Sievers <[email protected]>
--- drivers/usb/core/Kconfig | 22 +++++++++++++--------- 1 files changed, 13 insertions(+), 9 deletions(-)
drivers/usb/core/Kconfig +13 -9
@@ -40,21 +40,25 @@ config USB_DEVICEFS config USB_DEVICE_CLASS bool "USB device class-devices (DEPRECATED)" depends on USB - default n + default y ---help--- Userspace access to USB devices is granted by device-nodes exported directly from the usbdev in sysfs. Old versions of the driver core and udev needed additional class devices to export device nodes. These additional devices are difficult to handle in userspace, if - information about USB interfaces must be available. One device contains - the device node, the other device contains the interface data. Both - devices are at the same level in sysfs (siblings) and one can't access - the other. The device node created directly by the usbdev is the parent - device of the interface and therefore easily accessible from the interface - event. - - This option provides backward compatibility if needed. + information about USB interfaces must be available. One device + contains the device node, the other device contains the interface + data. Both devices are at the same level in sysfs (siblings) and one + can't access the other. The device node created directly by the + usb device is the parent device of the interface and therefore + easily accessible from the interface event. + + This option provides backward compatibility for libusb device + nodes (lsusb) when usbfs is not used, and the following udev rule + doesn't exist: + SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", \ + NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0644" config USB_DYNAMIC_MINORS bool "Dynamic USB minor allocation (EXPERIMENTAL)"
Signature · 1 line
1.5.2.1
PATCH 2/9 usblp: Don't let suspend to kill ->used
From: Pete Zaitcev <[email protected]>
Suspend destroys refcounting for open/release.
--- drivers/usb/class/usblp.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-)
drivers/usb/class/usblp.c +2 -3
@@ -347,10 +347,8 @@ static int handle_bidir (struct usblp *usblp)if (usblp->bidir && usblp->used && !usblp->sleeping) { usblp->readcount =0 ; usblp->readurb->dev = usblp->dev; -if (usb_submit_urb (usblp->readurb,GFP_KERNEL ) <0 ) { - usblp->used =0 ; +if (usb_submit_urb (usblp->readurb,GFP_KERNEL ) <0 )return -EIO ; - } }return 0 ;
@@ -412,6 +410,7 @@ static int usblp_open(struct inode *inode, struct file *file) usblp->readurb->status =0 ;if (handle_bidir (usblp) <0 ) { + usblp->used =0 ; file->private_data =NULL ; retval = -EIO ; }
Signature · 1 line
1.5.2.1
PATCH 3/9 USB: usb gadgets avoid le{16,32}_to_cpup()
From: David Brownell <[email protected]>
It turns out that le16_to_cpup() and le32_to_cpup() aren't always safe to call with pointers into packed structures, since those are inlined functions and GCC may lose the "packed" attribute. So those references can become unaligned kernel accesses, which are evil on some hardware.
This patch updates uses of those routines in the gadget stack. The references into packed structures can just use leXX_to_cpu(*x), which in most cases is more natural. Some other uses in RNDIS, mostly in debug code, were wrong in the first place; those use get_unaligned().
--- drivers/usb/gadget/epautoconf.c | 2 +- drivers/usb/gadget/inode.c | 8 ++++---- drivers/usb/gadget/net2280.c | 6 +++--- drivers/usb/gadget/omap_udc.c | 6 +++--- drivers/usb/gadget/rndis.c | 35 ++++++++++++++++++++++------------- 5 files changed, 33 insertions(+), 24 deletions(-)
drivers/usb/gadget/epautoconf.c +1 -1
@@ -132,7 +132,7 @@ ep_matches (* where it's an output parameter representing the full speed limit. * the usb spec fixes high speed bulk maxpacket at 512 bytes. */ - max =0x7ff &le16_to_cpup (&desc->wMaxPacketSize); + max =0x7ff &le16_to_cpu (desc->wMaxPacketSize);switch (type) {case USB_ENDPOINT_XFER_INT :/* INT: limit 64 bytes full speed, 1024 high speed */
drivers/usb/gadget/inode.c +4 -4
@@ -1369,12 +1369,12 @@ config_buf (struct dev_data *dev, u8 type, unsigned index) hs = !hs;if (hs) { dev->req->buf = dev->hs_config; - len =le16_to_cpup (&dev->hs_config->wTotalLength); + len =le16_to_cpu (dev->hs_config->wTotalLength); } else#endif { dev->req->buf = dev->config; - len =le16_to_cpup (&dev->config->wTotalLength); + len =le16_to_cpu (dev->config->wTotalLength); } ((u8 *)dev->req->buf) [1 ] = type;return len;
@@ -1885,7 +1885,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)/* full or low speed config */ dev->config = (void *) kbuf; - total =le16_to_cpup (&dev->config->wTotalLength); + total =le16_to_cpu (dev->config->wTotalLength);if (!is_valid_config (dev->config) || total >= length) goto fail; kbuf += total;
@@ -1894,7 +1894,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)/* optional high speed config */ if (kbuf [1 ] ==USB_DT_CONFIG ) { dev->hs_config = (void *) kbuf; - total =le16_to_cpup (&dev->hs_config->wTotalLength); + total =le16_to_cpu (dev->hs_config->wTotalLength);if (!is_valid_config (dev->hs_config) || total >= length) goto fail; kbuf += total;
drivers/usb/gadget/net2280.c +3 -3
@@ -2440,9 +2440,9 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) tmp =0 ; -#define w_value le16_to_cpup (&u.r.wValue) -#define w_index le16_to_cpup (&u.r.wIndex) -#define w_length le16_to_cpup (&u.r.wLength) +#define w_value le16_to_cpu(u.r.wValue) +#define w_index le16_to_cpu(u.r.wIndex) +#define w_length le16_to_cpu(u.r.wLength)/* ack the irq */ writel (1 <<SETUP_PACKET_INTERRUPT , &dev->regs->irqstat0);
drivers/usb/gadget/omap_udc.c +3 -3
@@ -1651,9 +1651,9 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)UDC_EP_NUM_REG =0 ; }while (UDC_IRQ_SRC_REG &UDC_SETUP ); -#define w_value le16_to_cpup (&u.r.wValue) -#define w_index le16_to_cpup (&u.r.wIndex) -#define w_length le16_to_cpup (&u.r.wLength) +#define w_value le16_to_cpu(u.r.wValue) +#define w_index le16_to_cpu(u.r.wIndex) +#define w_length le16_to_cpu(u.r.wLength)/* Delegate almost all control requests to the gadget driver, * except for a handful of ch9 status/feature requests that
drivers/usb/gadget/rndis.c +22 -13
@@ -186,10 +186,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,DEBUG ("query OID %08x value, len %d:\n" ,OID , buf_len);for (i =0 ; i < buf_len; i +=16 ) {DEBUG ("%03d: %08x %08x %08x %08x\n" , i, -le32_to_cpup ((__le32 *)&buf[i]), -le32_to_cpup ((__le32 *)&buf[i +4 ]), -le32_to_cpup ((__le32 *)&buf[i +8 ]), -le32_to_cpup ((__le32 *)&buf[i +12 ])); +le32_to_cpu (get_unaligned ((__le32 *) + &buf[i])), +le32_to_cpu (get_unaligned ((__le32 *) + &buf[i +4 ])), +le32_to_cpu (get_unaligned ((__le32 *) + &buf[i +8 ])), +le32_to_cpu (get_unaligned ((__le32 *) + &buf[i +12 ]))); } }
@@ -665,7 +669,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,break ;case OID_PNP_QUERY_POWER :DEBUG ("%s: OID_PNP_QUERY_POWER D%d\n" , __FUNCTION__, -le32_to_cpup ((__le32 *) buf) -1 ); +le32_to_cpu (get_unaligned ((__le32 *)buf)) -1 );/* only suspend is a real power state, and * it can't be entered by OID_PNP_SET_POWER... */
@@ -704,10 +708,14 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,DEBUG ("set OID %08x value, len %d:\n" ,OID , buf_len);for (i =0 ; i < buf_len; i +=16 ) {DEBUG ("%03d: %08x %08x %08x %08x\n" , i, -le32_to_cpup ((__le32 *)&buf[i]), -le32_to_cpup ((__le32 *)&buf[i +4 ]), -le32_to_cpup ((__le32 *)&buf[i +8 ]), -le32_to_cpup ((__le32 *)&buf[i +12 ])); +le32_to_cpu (get_unaligned ((__le32 *) + &buf[i])), +le32_to_cpu (get_unaligned ((__le32 *) + &buf[i +4 ])), +le32_to_cpu (get_unaligned ((__le32 *) + &buf[i +8 ])), +le32_to_cpu (get_unaligned ((__le32 *) + &buf[i +12 ]))); } }
@@ -721,7 +729,8 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,* PROMISCUOUS, DIRECTED, * MULTICAST, ALL_MULTICAST, BROADCAST */ - *params->filter = (u16 )le32_to_cpup ((__le32 *)buf); + *params->filter = (u16 )le32_to_cpu (get_unaligned ( + (__le32 *)buf));DEBUG ("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n" , __FUNCTION__, *params->filter);
@@ -771,7 +780,7 @@ update_linkstate:* resuming, Windows forces a reset, and then SET_POWER D0. * FIXME ... then things go batty; Windows wedges itself. */ - i =le32_to_cpup ((__force __le32 *)buf); + i =le32_to_cpu (get_unaligned ((__le32 *)buf));DEBUG ("%s: OID_PNP_SET_POWER D%d\n" , __FUNCTION__, i -1 );switch (i) {case NdisDeviceStateD0:
@@ -1058,8 +1067,8 @@ int rndis_msg_parser (u8 configNr, u8 *buf)return -ENOMEM ; tmp = (__le32 *) buf; - MsgType =le32_to_cpup (tmp++); - MsgLength =le32_to_cpup (tmp++); + MsgType =le32_to_cpu (get_unaligned (tmp++)); + MsgLength =le32_to_cpu (get_unaligned (tmp++));if (configNr >=RNDIS_MAX_CONFIGS )return -ENOTSUPP ;
Signature · 1 line
1.5.2.1
PATCH 4/9 USB: UNUSUAL_DEV: Sync up some reported devices from Ubuntu
From: Ben Collins <[email protected]>
UNUSUAL_DEV: Sync up some reported devices from Ubuntu
Various unusual dev entries accumulated from Ubuntu bug reports.
--- drivers/usb/storage/unusual_devs.h | 21 +++++++++++++++++++-- 1 files changed, 19 insertions(+), 2 deletions(-)
drivers/usb/storage/unusual_devs.h +19 -2
@@ -1179,8 +1179,8 @@ UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), -/* These are virtual windows driver CDs, which the zd1211rw driver automatically -* converts into a WLAN devices. */ +/* These are virtual windows driver CDs, which the zd1211rw driver +* automatically converts into WLAN devices. */ UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101, "ZyXEL", "G-220F USB-WLAN Install",
@@ -1193,6 +1193,14 @@ UNUSUAL_DEV( 0x0ace, 0x20ff, 0x0101, 0x0101, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_DEVICE ), +/* SanDisk that has a second LUN for a driver ISO, reported by +* Ben Collins <[email protected]> */ +UNUSUAL_DEV( 0x0781, 0x5406, 0x0000, 0xffff, + "SanDisk", + "U3 Cruzer Micro driver ISO", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_SINGLE_LUN ), +#ifdef CONFIG_USB_STORAGE_ISD200 UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, "ATI",
@@ -1271,6 +1279,15 @@ UNUSUAL_DEV( 0x0dd8, 0x1060, 0x0000, 0xffff, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), +/* Reported by Edward Chapman (taken from linux-usb mailing list) +Netac OnlyDisk Mini U2CV2 512MB USB 2.0 Flash Drive */ +UNUSUAL_DEV (0x0dd8 ,0xd202 ,0x0000 ,0x9999 , +"Netac" , +"USB Flash Disk" , +US_SC_DEVICE ,US_PR_DEVICE ,NULL , +US_FL_IGNORE_RESIDUE ), + +/* Patch by Stephan Walter <[email protected]> * I don't know why, but it works... */ UNUSUAL_DEV( 0x0dda, 0x0001, 0x0012, 0x0012,
Signature · 1 line
1.5.2.1
PATCH 5/9 USB: cxacru: add Documentation file
From: Simon Arlott <[email protected]>
The sysfs attributes for exposing cxacru statistics/status information with possible values is now explained in Documentation/networking/cxacru.txt including information on the writable adsl_state attribute's commands and a sample of the kernel log format.
--- Documentation/networking/00-INDEX | 2 + Documentation/networking/cxacru.txt | 84 +++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 0 deletions(-) create mode 100644 Documentation/networking/cxacru.txt
Documentation/networking/00-INDEX +2 -0
@@ -32,6 +32,8 @@ cops.txt - info on the COPS LocalTalk Linux driver cs89x0.txt - the Crystal LAN (CS8900/20-based) Ethernet ISA adapter driver +cxacru.txt + - Conexant AccessRunner USB ADSL Modem de4x5.txt - the Digital EtherWORKS DE4?? and DE5?? PCI Ethernet driver decnet.txt
Documentation/networking/cxacru.txt new file +84 -0
84 lines not on this page · raw message
Signature · 1 line
1.5.2.1
PATCH 6/9 USB: cxacru: create sysfs attributes in atm_start instead of bind
From: Simon Arlott <[email protected]>
Since usbatm doesn't set the usb_interface driver data until after calling bind and heavy_init, it would be NULL when the sysfs attributes are read. Reading the MAC address from atm_dev before atm_dev exists would have been be possible too.
Calling create_device_file in atm_start will avoid this problem, and the data is useless until the first status poll runs. However, it must be ready before a status poll does a printk on line status change otherwise userspace could react before the files exist.
For completeness I've moved remove_device_file to atm_stop so it's not called in unbind when it's not needed. There's no point starting ADSL if atm_start could still fail either.
--- drivers/usb/atm/cxacru.c | 45 +++++++++++++++++++++++++-------------------- 1 files changed, 25 insertions(+), 20 deletions(-)
drivers/usb/atm/cxacru.c +25 -20
@@ -629,10 +629,22 @@ static int cxacru_card_status(struct cxacru_data *instance)return 0 ; } +static void cxacru_remove_device_files (struct usbatm_data *usbatm_instance, +struct atm_dev *atm_dev) +{ +struct usb_interface *intf = usbatm_instance->usb_intf; + +#define CXACRU_DEVICE_REMOVE_FILE (_name) \ + device_remove_file(&intf->dev, &dev_attr_##_name); +CXACRU_ALL_FILES (REMOVE ); +#undef CXACRU_DEVICE_REMOVE_FILE +} +static int cxacru_atm_start (struct usbatm_data *usbatm_instance,struct atm_dev *atm_dev) {struct cxacru_data *instance = usbatm_instance->driver_data; +struct usb_interface *intf = usbatm_instance->usb_intf;/* struct atm_dev *atm_dev = usbatm_instance->atm_dev; */
@@ -649,6 +661,13 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance,return ret; } +#define CXACRU_DEVICE_CREATE_FILE (_name) \ + ret = device_create_file(&intf->dev, &dev_attr_##_name); \ + if (unlikely(ret)) \ + goto fail_sysfs; +CXACRU_ALL_FILES (CREATE ); +#undef CXACRU_DEVICE_CREATE_FILE +/* start ADSL */ mutex_lock (&instance->adsl_state_serialize); ret =cxacru_cm (instance,CM_REQUEST_CHIP_ADSL_LINE_START ,NULL ,0 ,NULL ,0 );
@@ -680,6 +699,11 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance,if (start_polling)cxacru_poll_status (&instance->poll_work.work);return 0 ; + +fail_sysfs: +usb_err (usbatm_instance,"cxacru_atm_start: device_create_file failed (%d)\n" , ret); +cxacru_remove_device_files (usbatm_instance, atm_dev); +return ret; }static void cxacru_poll_status (struct work_struct *work)
@@ -1065,13 +1089,6 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, goto fail; } -#define CXACRU_DEVICE_CREATE_FILE (_name) \ - ret = device_create_file(&intf->dev, &dev_attr_##_name); \ - if (unlikely(ret)) \ - goto fail_sysfs; -CXACRU_ALL_FILES (CREATE ); -#undef CXACRU_DEVICE_CREATE_FILE - usb_fill_int_urb(instance->rcv_urb, usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD), instance->rcv_buf, PAGE_SIZE,
@@ -1092,14 +1109,6 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,return 0 ; - fail_sysfs: -dbg ("cxacru_bind: device_create_file failed (%d)\n" , ret); - -#define CXACRU_DEVICE_REMOVE_FILE (_name) \ - device_remove_file(&intf->dev, &dev_attr_##_name); -CXACRU_ALL_FILES (REMOVE ); -#undef CXACRU_DEVICE_REVOVE_FILE - fail:free_page ((unsigned long ) instance->snd_buf);free_page ((unsigned long ) instance->rcv_buf);
@@ -1146,11 +1155,6 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance,free_page ((unsigned long ) instance->snd_buf);free_page ((unsigned long ) instance->rcv_buf); -#define CXACRU_DEVICE_REMOVE_FILE (_name) \ - device_remove_file(&intf->dev, &dev_attr_##_name); -CXACRU_ALL_FILES (REMOVE ); -#undef CXACRU_DEVICE_REVOVE_FILE -kfree (instance); usbatm_instance->driver_data =NULL ;
@@ -1231,6 +1235,7 @@ static struct usbatm_driver cxacru_driver = { .heavy_init = cxacru_heavy_init, .unbind = cxacru_unbind, .atm_start = cxacru_atm_start, + .atm_stop = cxacru_remove_device_files, .bulk_in = CXACRU_EP_DATA, .bulk_out = CXACRU_EP_DATA, .rx_padding = 3,
Signature · 1 line
1.5.2.1
PATCH 7/9 USB: cxacru: ignore error trying to start ADSL in atm_start
From: Simon Arlott <[email protected]>
The sysfs adsl_status attribute ignores (aside from returning -EIO to the user) any error sending a START/STOP command to the device and there is at least one firmware which never sends a response but appears to work regardless. Therefore atm_start should also continue if an error is received so that such firmware is usable.
The official Conexant driver doesn't expect a reply either but this is for another device (E2 router) and a commonly used firmware does respond.
Also, there is no point in changing -ECONNRESET to -ETIMEDOUT since nothing ever checks for either of these values.
--- drivers/usb/atm/cxacru.c | 7 +------ 1 files changed, 1 insertions(+), 6 deletions(-)
drivers/usb/atm/cxacru.c +1 -6
@@ -476,8 +476,6 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done,add_timer (&timer);wait_for_completion (done); status = urb->status; -if (status == -ECONNRESET ) - status = -ETIMEDOUT ;del_timer_sync (&timer);if (actual_length)
@@ -671,11 +669,8 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance,/* start ADSL */ mutex_lock (&instance->adsl_state_serialize); ret =cxacru_cm (instance,CM_REQUEST_CHIP_ADSL_LINE_START ,NULL ,0 ,NULL ,0 ); -if (ret <0 ) { +if (ret <0 )atm_err (usbatm_instance,"cxacru_atm_start: CHIP_ADSL_LINE_START returned %d\n" , ret); -mutex_unlock (&instance->adsl_state_serialize); -return ret; - }/* Start status polling */ mutex_lock (&instance->poll_state_serialize);
Signature · 1 line
1.5.2.1
PATCH 8/9 USB: Fix up bogus bInterval values in endpoint descriptors
From: Alan Stern <[email protected]>
This patch (as904) adds code to check for endpoint descriptor bInterval values outside the legal limits. Illegal values are set to 32 ms, which seems like a reasonable default.
This fixes Bugzilla #8432.
--- drivers/usb/core/config.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 files changed, 41 insertions(+), 1 deletions(-)
drivers/usb/core/config.c +41 -1
@@ -1,4 +1,5 @@#include <linux/usb.h> +#include <linux/usb/ch9.h> #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h>
@@ -49,7 +50,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,unsigned char *buffer0 = buffer;struct usb_endpoint_descriptor *d;struct usb_host_endpoint *endpoint; -int n, i; +int n, i, j; d = (struct usb_endpoint_descriptor *) buffer; buffer += d->bLength;
@@ -84,6 +85,45 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,memcpy (&endpoint->desc, d, n);INIT_LIST_HEAD (&endpoint->urb_list); +/* If the bInterval value is outside the legal range, +* set it to a default value: 32 ms */ + i =0 ;/* i = min, j = max, n = default */ + j =255 ; +if (usb_endpoint_xfer_int (d)) { + i =1 ; +switch (to_usb_device (ddev)->speed) { +case USB_SPEED_HIGH : + n =9 ;/* 32 ms = 2^(9-1) uframes */ + j =16 ; +break ; +default :/* USB_SPEED_FULL or _LOW */ +/* For low-speed, 10 ms is the official minimum. +* But some "overclocked" devices might want faster +* polling so we'll allow it. */ + n =32 ; +break ; + } + }else if (usb_endpoint_xfer_isoc (d)) { + i =1 ; + j =16 ; +switch (to_usb_device (ddev)->speed) { +case USB_SPEED_HIGH : + n =9 ;/* 32 ms = 2^(9-1) uframes */ +break ; +default :/* USB_SPEED_FULL */ + n =6 ;/* 32 ms = 2^(6-1) frames */ +break ; + } + } +if (d->bInterval < i || d->bInterval > j) { +dev_warn (ddev,"config %d interface %d altsetting %d " +"endpoint 0x%X has an invalid bInterval %d, " +"changing to %d\n" , + cfgno, inum, asnum, + d->bEndpointAddress, d->bInterval, n); + endpoint->desc.bInterval = n; + } +/* Skip over any Class Specific or Vendor Specific descriptors; * find the next endpoint or interface descriptor */ endpoint->extra = buffer;
Signature · 1 line
1.5.2.1
PATCH 9/9 OHCI: Fix machine check in ohci_hub_status_data
From: Alan Stern <[email protected]>
This patch (as901) fixes an oversight in ohci-hcd. The hub_status_data routine must not try to access the controller's memory-mapped registers if the controller is in a low-power state; such attempts will cause a crash on some architectures (such as PPC).
--- drivers/usb/host/ohci-hub.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/usb/host/ohci-hub.c +2 -0
@@ -417,6 +417,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)unsigned long flags;spin_lock_irqsave (&ohci->lock, flags); +if (!test_bit (HCD_FLAG_HW_ACCESSIBLE , &hcd->flags)) + goto done;/* undocumented erratum seen on at least rev D */ if ((ohci->flags & OHCI_QUIRK_AMD756)
Signature · 1 line
1.5.2.1