aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/rndis_host.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/net/usb/rndis_host.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/net/usb/rndis_host.c')
-rw-r--r--drivers/net/usb/rndis_host.c41
1 files changed, 33 insertions, 8 deletions
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index dd8a4adf48ca..255d6a424a6b 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -104,8 +104,10 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,
104int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) 104int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
105{ 105{
106 struct cdc_state *info = (void *) &dev->data; 106 struct cdc_state *info = (void *) &dev->data;
107 struct usb_cdc_notification notification;
107 int master_ifnum; 108 int master_ifnum;
108 int retval; 109 int retval;
110 int partial;
109 unsigned count; 111 unsigned count;
110 __le32 rsp; 112 __le32 rsp;
111 u32 xid = 0, msg_len, request_id; 113 u32 xid = 0, msg_len, request_id;
@@ -133,13 +135,20 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
133 if (unlikely(retval < 0 || xid == 0)) 135 if (unlikely(retval < 0 || xid == 0))
134 return retval; 136 return retval;
135 137
136 // FIXME Seems like some devices discard responses when 138 /* Some devices don't respond on the control channel until
137 // we time out and cancel our "get response" requests... 139 * polled on the status channel, so do that first. */
138 // so, this is fragile. Probably need to poll for status. 140 if (dev->driver_info->data & RNDIS_DRIVER_DATA_POLL_STATUS) {
141 retval = usb_interrupt_msg(
142 dev->udev,
143 usb_rcvintpipe(dev->udev,
144 dev->status->desc.bEndpointAddress),
145 &notification, sizeof(notification), &partial,
146 RNDIS_CONTROL_TIMEOUT_MS);
147 if (unlikely(retval < 0))
148 return retval;
149 }
139 150
140 /* ignore status endpoint, just poll the control channel; 151 /* Poll the control channel; the request probably completed immediately */
141 * the request probably completed immediately
142 */
143 rsp = buf->msg_type | RNDIS_MSG_COMPLETION; 152 rsp = buf->msg_type | RNDIS_MSG_COMPLETION;
144 for (count = 0; count < 10; count++) { 153 for (count = 0; count < 10; count++) {
145 memset(buf, 0, CONTROL_BUFFER_SIZE); 154 memset(buf, 0, CONTROL_BUFFER_SIZE);
@@ -573,7 +582,18 @@ EXPORT_SYMBOL_GPL(rndis_tx_fixup);
573 582
574static const struct driver_info rndis_info = { 583static const struct driver_info rndis_info = {
575 .description = "RNDIS device", 584 .description = "RNDIS device",
576 .flags = FLAG_ETHER | FLAG_FRAMING_RN | FLAG_NO_SETINT, 585 .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
586 .bind = rndis_bind,
587 .unbind = rndis_unbind,
588 .status = rndis_status,
589 .rx_fixup = rndis_rx_fixup,
590 .tx_fixup = rndis_tx_fixup,
591};
592
593static const struct driver_info rndis_poll_status_info = {
594 .description = "RNDIS device (poll status before control)",
595 .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
596 .data = RNDIS_DRIVER_DATA_POLL_STATUS,
577 .bind = rndis_bind, 597 .bind = rndis_bind,
578 .unbind = rndis_unbind, 598 .unbind = rndis_unbind,
579 .status = rndis_status, 599 .status = rndis_status,
@@ -585,13 +605,18 @@ static const struct driver_info rndis_info = {
585 605
586static const struct usb_device_id products [] = { 606static const struct usb_device_id products [] = {
587{ 607{
608 /* 2Wire HomePortal 1000SW */
609 USB_DEVICE_AND_INTERFACE_INFO(0x1630, 0x0042,
610 USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
611 .driver_info = (unsigned long) &rndis_poll_status_info,
612}, {
588 /* RNDIS is MSFT's un-official variant of CDC ACM */ 613 /* RNDIS is MSFT's un-official variant of CDC ACM */
589 USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), 614 USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
590 .driver_info = (unsigned long) &rndis_info, 615 .driver_info = (unsigned long) &rndis_info,
591}, { 616}, {
592 /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */ 617 /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
593 USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1), 618 USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
594 .driver_info = (unsigned long) &rndis_info, 619 .driver_info = (unsigned long) &rndis_poll_status_info,
595}, { 620}, {
596 /* RNDIS for tethering */ 621 /* RNDIS for tethering */
597 USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3), 622 USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),