aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@mbnet.fi>2011-05-30 03:15:47 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-05-31 14:47:26 -0400
commit59342f6a6bc35df623fb44784daa5e1077063b8f (patch)
tree612d3ec8c09d18fb0a97f841a535de8b25e46ada /drivers/net
parent66870b1ccd5c1460e437c18b0026e2dcaab1ece9 (diff)
zd1211rw: fix to work on OHCI
zd1211 devices register 'EP 4 OUT' endpoint as Interrupt type on USB 2.0: Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x04 EP 4 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 1 However on USB 1.1 endpoint becomes Bulk: Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x04 EP 4 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Commit 37939810b937aba830dd751291fcdc51cae1a6cb assumed that endpoint is always interrupt type and changed usb_bulk_msg() calls to usb_interrupt_msg(). Problem here is that usb_bulk_msg() on interrupt endpoint selfcorrects the call and changes requested pipe to interrupt type (see usb_bulk_msg). However with usb_interrupt_msg() on bulk endpoint does not correct the pipe type to bulk, but instead URB is submitted with interrupt type pipe. So pre-2.6.39 used usb_bulk_msg() and therefore worked with both endpoint types, however in 2.6.39 usb_interrupt_msg() with bulk endpoint causes ohci_hcd to fail submitted URB instantly with -ENOSPC and preventing zd1211rw from working with OHCI. Fix this by detecting endpoint type and using correct endpoint/pipe types for URB. Also fix asynchronous zd_usb_iowrite16v_async() to use right URB type on 'EP 4 OUT'. Cc: stable@kernel.org Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 0e819943b9e4..631194d49828 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -1533,6 +1533,31 @@ static void __exit usb_exit(void)
1533module_init(usb_init); 1533module_init(usb_init);
1534module_exit(usb_exit); 1534module_exit(usb_exit);
1535 1535
1536static int zd_ep_regs_out_msg(struct usb_device *udev, void *data, int len,
1537 int *actual_length, int timeout)
1538{
1539 /* In USB 2.0 mode EP_REGS_OUT endpoint is interrupt type. However in
1540 * USB 1.1 mode endpoint is bulk. Select correct type URB by endpoint
1541 * descriptor.
1542 */
1543 struct usb_host_endpoint *ep;
1544 unsigned int pipe;
1545
1546 pipe = usb_sndintpipe(udev, EP_REGS_OUT);
1547 ep = usb_pipe_endpoint(udev, pipe);
1548 if (!ep)
1549 return -EINVAL;
1550
1551 if (usb_endpoint_xfer_int(&ep->desc)) {
1552 return usb_interrupt_msg(udev, pipe, data, len,
1553 actual_length, timeout);
1554 } else {
1555 pipe = usb_sndbulkpipe(udev, EP_REGS_OUT);
1556 return usb_bulk_msg(udev, pipe, data, len, actual_length,
1557 timeout);
1558 }
1559}
1560
1536static int usb_int_regs_length(unsigned int count) 1561static int usb_int_regs_length(unsigned int count)
1537{ 1562{
1538 return sizeof(struct usb_int_regs) + count * sizeof(struct reg_data); 1563 return sizeof(struct usb_int_regs) + count * sizeof(struct reg_data);
@@ -1648,15 +1673,14 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values,
1648 1673
1649 udev = zd_usb_to_usbdev(usb); 1674 udev = zd_usb_to_usbdev(usb);
1650 prepare_read_regs_int(usb); 1675 prepare_read_regs_int(usb);
1651 r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT), 1676 r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/);
1652 req, req_len, &actual_req_len, 50 /* ms */);
1653 if (r) { 1677 if (r) {
1654 dev_dbg_f(zd_usb_dev(usb), 1678 dev_dbg_f(zd_usb_dev(usb),
1655 "error in usb_interrupt_msg(). Error number %d\n", r); 1679 "error in zd_ep_regs_out_msg(). Error number %d\n", r);
1656 goto error; 1680 goto error;
1657 } 1681 }
1658 if (req_len != actual_req_len) { 1682 if (req_len != actual_req_len) {
1659 dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()\n" 1683 dev_dbg_f(zd_usb_dev(usb), "error in zd_ep_regs_out_msg()\n"
1660 " req_len %d != actual_req_len %d\n", 1684 " req_len %d != actual_req_len %d\n",
1661 req_len, actual_req_len); 1685 req_len, actual_req_len);
1662 r = -EIO; 1686 r = -EIO;
@@ -1818,9 +1842,17 @@ int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
1818 rw->value = cpu_to_le16(ioreqs[i].value); 1842 rw->value = cpu_to_le16(ioreqs[i].value);
1819 } 1843 }
1820 1844
1821 usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT), 1845 /* In USB 2.0 mode endpoint is interrupt type. However in USB 1.1 mode
1822 req, req_len, iowrite16v_urb_complete, usb, 1846 * endpoint is bulk. Select correct type URB by endpoint descriptor.
1823 ep->desc.bInterval); 1847 */
1848 if (usb_endpoint_xfer_int(&ep->desc))
1849 usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT),
1850 req, req_len, iowrite16v_urb_complete, usb,
1851 ep->desc.bInterval);
1852 else
1853 usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_REGS_OUT),
1854 req, req_len, iowrite16v_urb_complete, usb);
1855
1824 urb->transfer_flags |= URB_FREE_BUFFER; 1856 urb->transfer_flags |= URB_FREE_BUFFER;
1825 1857
1826 /* Submit previous URB */ 1858 /* Submit previous URB */
@@ -1924,15 +1956,14 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits)
1924 } 1956 }
1925 1957
1926 udev = zd_usb_to_usbdev(usb); 1958 udev = zd_usb_to_usbdev(usb);
1927 r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT), 1959 r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/);
1928 req, req_len, &actual_req_len, 50 /* ms */);
1929 if (r) { 1960 if (r) {
1930 dev_dbg_f(zd_usb_dev(usb), 1961 dev_dbg_f(zd_usb_dev(usb),
1931 "error in usb_interrupt_msg(). Error number %d\n", r); 1962 "error in zd_ep_regs_out_msg(). Error number %d\n", r);
1932 goto out; 1963 goto out;
1933 } 1964 }
1934 if (req_len != actual_req_len) { 1965 if (req_len != actual_req_len) {
1935 dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()" 1966 dev_dbg_f(zd_usb_dev(usb), "error in zd_ep_regs_out_msg()"
1936 " req_len %d != actual_req_len %d\n", 1967 " req_len %d != actual_req_len %d\n",
1937 req_len, actual_req_len); 1968 req_len, actual_req_len);
1938 r = -EIO; 1969 r = -EIO;