aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/zd1211rw/zd_usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/zd1211rw/zd_usb.c')
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c177
1 files changed, 145 insertions, 32 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index f6df3665fdb6..81e80489a052 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -1156,6 +1156,7 @@ void zd_usb_init(struct zd_usb *usb, struct ieee80211_hw *hw,
1156 memset(usb, 0, sizeof(*usb)); 1156 memset(usb, 0, sizeof(*usb));
1157 usb->intf = usb_get_intf(intf); 1157 usb->intf = usb_get_intf(intf);
1158 usb_set_intfdata(usb->intf, hw); 1158 usb_set_intfdata(usb->intf, hw);
1159 init_usb_anchor(&usb->submitted_cmds);
1159 init_usb_interrupt(usb); 1160 init_usb_interrupt(usb);
1160 init_usb_tx(usb); 1161 init_usb_tx(usb);
1161 init_usb_rx(usb); 1162 init_usb_rx(usb);
@@ -1634,15 +1635,15 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values,
1634 1635
1635 udev = zd_usb_to_usbdev(usb); 1636 udev = zd_usb_to_usbdev(usb);
1636 prepare_read_regs_int(usb); 1637 prepare_read_regs_int(usb);
1637 r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT), 1638 r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT),
1638 req, req_len, &actual_req_len, 50 /* ms */); 1639 req, req_len, &actual_req_len, 50 /* ms */);
1639 if (r) { 1640 if (r) {
1640 dev_dbg_f(zd_usb_dev(usb), 1641 dev_dbg_f(zd_usb_dev(usb),
1641 "error in usb_bulk_msg(). Error number %d\n", r); 1642 "error in usb_interrupt_msg(). Error number %d\n", r);
1642 goto error; 1643 goto error;
1643 } 1644 }
1644 if (req_len != actual_req_len) { 1645 if (req_len != actual_req_len) {
1645 dev_dbg_f(zd_usb_dev(usb), "error in usb_bulk_msg()\n" 1646 dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()\n"
1646 " req_len %d != actual_req_len %d\n", 1647 " req_len %d != actual_req_len %d\n",
1647 req_len, actual_req_len); 1648 req_len, actual_req_len);
1648 r = -EIO; 1649 r = -EIO;
@@ -1663,13 +1664,103 @@ error:
1663 return r; 1664 return r;
1664} 1665}
1665 1666
1666int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, 1667static void iowrite16v_urb_complete(struct urb *urb)
1667 unsigned int count) 1668{
1669 struct zd_usb *usb = urb->context;
1670
1671 if (urb->status && !usb->cmd_error)
1672 usb->cmd_error = urb->status;
1673}
1674
1675static int zd_submit_waiting_urb(struct zd_usb *usb, bool last)
1676{
1677 int r = 0;
1678 struct urb *urb = usb->urb_async_waiting;
1679
1680 if (!urb)
1681 return 0;
1682
1683 usb->urb_async_waiting = NULL;
1684
1685 if (!last)
1686 urb->transfer_flags |= URB_NO_INTERRUPT;
1687
1688 usb_anchor_urb(urb, &usb->submitted_cmds);
1689 r = usb_submit_urb(urb, GFP_KERNEL);
1690 if (r) {
1691 usb_unanchor_urb(urb);
1692 dev_dbg_f(zd_usb_dev(usb),
1693 "error in usb_submit_urb(). Error number %d\n", r);
1694 goto error;
1695 }
1696
1697 /* fall-through with r == 0 */
1698error:
1699 usb_free_urb(urb);
1700 return r;
1701}
1702
1703void zd_usb_iowrite16v_async_start(struct zd_usb *usb)
1704{
1705 ZD_ASSERT(usb_anchor_empty(&usb->submitted_cmds));
1706 ZD_ASSERT(usb->urb_async_waiting == NULL);
1707 ZD_ASSERT(!usb->in_async);
1708
1709 ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex));
1710
1711 usb->in_async = 1;
1712 usb->cmd_error = 0;
1713 usb->urb_async_waiting = NULL;
1714}
1715
1716int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout)
1717{
1718 int r;
1719
1720 ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex));
1721 ZD_ASSERT(usb->in_async);
1722
1723 /* Submit last iowrite16v URB */
1724 r = zd_submit_waiting_urb(usb, true);
1725 if (r) {
1726 dev_dbg_f(zd_usb_dev(usb),
1727 "error in zd_submit_waiting_usb(). "
1728 "Error number %d\n", r);
1729
1730 usb_kill_anchored_urbs(&usb->submitted_cmds);
1731 goto error;
1732 }
1733
1734 if (timeout)
1735 timeout = usb_wait_anchor_empty_timeout(&usb->submitted_cmds,
1736 timeout);
1737 if (!timeout) {
1738 usb_kill_anchored_urbs(&usb->submitted_cmds);
1739 if (usb->cmd_error == -ENOENT) {
1740 dev_dbg_f(zd_usb_dev(usb), "timed out");
1741 r = -ETIMEDOUT;
1742 goto error;
1743 }
1744 }
1745
1746 r = usb->cmd_error;
1747error:
1748 usb->in_async = 0;
1749 return r;
1750}
1751
1752int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
1753 unsigned int count)
1668{ 1754{
1669 int r; 1755 int r;
1670 struct usb_device *udev; 1756 struct usb_device *udev;
1671 struct usb_req_write_regs *req = NULL; 1757 struct usb_req_write_regs *req = NULL;
1672 int i, req_len, actual_req_len; 1758 int i, req_len;
1759 struct urb *urb;
1760 struct usb_host_endpoint *ep;
1761
1762 ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex));
1763 ZD_ASSERT(usb->in_async);
1673 1764
1674 if (count == 0) 1765 if (count == 0)
1675 return 0; 1766 return 0;
@@ -1685,17 +1776,23 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
1685 return -EWOULDBLOCK; 1776 return -EWOULDBLOCK;
1686 } 1777 }
1687 1778
1688 ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); 1779 udev = zd_usb_to_usbdev(usb);
1689 BUILD_BUG_ON(sizeof(struct usb_req_write_regs) + 1780
1690 USB_MAX_IOWRITE16_COUNT * sizeof(struct reg_data) > 1781 ep = usb_pipe_endpoint(udev, usb_sndintpipe(udev, EP_REGS_OUT));
1691 sizeof(usb->req_buf)); 1782 if (!ep)
1692 BUG_ON(sizeof(struct usb_req_write_regs) + 1783 return -ENOENT;
1693 count * sizeof(struct reg_data) > 1784
1694 sizeof(usb->req_buf)); 1785 urb = usb_alloc_urb(0, GFP_KERNEL);
1786 if (!urb)
1787 return -ENOMEM;
1695 1788
1696 req_len = sizeof(struct usb_req_write_regs) + 1789 req_len = sizeof(struct usb_req_write_regs) +
1697 count * sizeof(struct reg_data); 1790 count * sizeof(struct reg_data);
1698 req = (void *)usb->req_buf; 1791 req = kmalloc(req_len, GFP_KERNEL);
1792 if (!req) {
1793 r = -ENOMEM;
1794 goto error;
1795 }
1699 1796
1700 req->id = cpu_to_le16(USB_REQ_WRITE_REGS); 1797 req->id = cpu_to_le16(USB_REQ_WRITE_REGS);
1701 for (i = 0; i < count; i++) { 1798 for (i = 0; i < count; i++) {
@@ -1704,28 +1801,44 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
1704 rw->value = cpu_to_le16(ioreqs[i].value); 1801 rw->value = cpu_to_le16(ioreqs[i].value);
1705 } 1802 }
1706 1803
1707 udev = zd_usb_to_usbdev(usb); 1804 usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT),
1708 r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT), 1805 req, req_len, iowrite16v_urb_complete, usb,
1709 req, req_len, &actual_req_len, 50 /* ms */); 1806 ep->desc.bInterval);
1807 urb->transfer_flags |= URB_FREE_BUFFER | URB_SHORT_NOT_OK;
1808
1809 /* Submit previous URB */
1810 r = zd_submit_waiting_urb(usb, false);
1710 if (r) { 1811 if (r) {
1711 dev_dbg_f(zd_usb_dev(usb), 1812 dev_dbg_f(zd_usb_dev(usb),
1712 "error in usb_bulk_msg(). Error number %d\n", r); 1813 "error in zd_submit_waiting_usb(). "
1713 goto error; 1814 "Error number %d\n", r);
1714 }
1715 if (req_len != actual_req_len) {
1716 dev_dbg_f(zd_usb_dev(usb),
1717 "error in usb_bulk_msg()"
1718 " req_len %d != actual_req_len %d\n",
1719 req_len, actual_req_len);
1720 r = -EIO;
1721 goto error; 1815 goto error;
1722 } 1816 }
1723 1817
1724 /* FALL-THROUGH with r == 0 */ 1818 /* Delay submit so that URB_NO_INTERRUPT flag can be set for all URBs
1819 * of currect batch except for very last.
1820 */
1821 usb->urb_async_waiting = urb;
1822 return 0;
1725error: 1823error:
1824 usb_free_urb(urb);
1726 return r; 1825 return r;
1727} 1826}
1728 1827
1828int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
1829 unsigned int count)
1830{
1831 int r;
1832
1833 zd_usb_iowrite16v_async_start(usb);
1834 r = zd_usb_iowrite16v_async(usb, ioreqs, count);
1835 if (r) {
1836 zd_usb_iowrite16v_async_end(usb, 0);
1837 return r;
1838 }
1839 return zd_usb_iowrite16v_async_end(usb, 50 /* ms */);
1840}
1841
1729int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) 1842int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits)
1730{ 1843{
1731 int r; 1844 int r;
@@ -1794,15 +1907,15 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits)
1794 } 1907 }
1795 1908
1796 udev = zd_usb_to_usbdev(usb); 1909 udev = zd_usb_to_usbdev(usb);
1797 r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT), 1910 r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT),
1798 req, req_len, &actual_req_len, 50 /* ms */); 1911 req, req_len, &actual_req_len, 50 /* ms */);
1799 if (r) { 1912 if (r) {
1800 dev_dbg_f(zd_usb_dev(usb), 1913 dev_dbg_f(zd_usb_dev(usb),
1801 "error in usb_bulk_msg(). Error number %d\n", r); 1914 "error in usb_interrupt_msg(). Error number %d\n", r);
1802 goto out; 1915 goto out;
1803 } 1916 }
1804 if (req_len != actual_req_len) { 1917 if (req_len != actual_req_len) {
1805 dev_dbg_f(zd_usb_dev(usb), "error in usb_bulk_msg()" 1918 dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()"
1806 " req_len %d != actual_req_len %d\n", 1919 " req_len %d != actual_req_len %d\n",
1807 req_len, actual_req_len); 1920 req_len, actual_req_len);
1808 r = -EIO; 1921 r = -EIO;