diff options
author | Thomas Pugliese <thomas.pugliese@gmail.com> | 2013-06-06 15:06:01 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-06-06 15:14:39 -0400 |
commit | ee0218fa43d8d7b113f60299d4f66191e0e2d76b (patch) | |
tree | b8f4cc455397a1364471fd1bfcc4ca4d5dc3f014 | |
parent | edc40a4bbe4d8bb0f6ee69d562a38e8783d7a4f9 (diff) |
USB: wusbcore: add HWA-specific fields to usb_rpipe_descriptor
This patch adds the HWA specific members to struct usb_rpipe_descriptor
and sets them correctly based on the wireless endpoint compananion
descriptor.
Signed-off-by: Thomas Pugliese <thomas.pugliese@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/wusbcore/wa-rpipe.c | 42 | ||||
-rw-r--r-- | include/linux/usb/wusb-wa.h | 17 |
2 files changed, 34 insertions, 25 deletions
diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/usb/wusbcore/wa-rpipe.c index f0d546c5a089..9429c12e4bfd 100644 --- a/drivers/usb/wusbcore/wa-rpipe.c +++ b/drivers/usb/wusbcore/wa-rpipe.c | |||
@@ -251,8 +251,8 @@ static int __rpipe_reset(struct wahc *wa, unsigned index) | |||
251 | static struct usb_wireless_ep_comp_descriptor epc0 = { | 251 | static struct usb_wireless_ep_comp_descriptor epc0 = { |
252 | .bLength = sizeof(epc0), | 252 | .bLength = sizeof(epc0), |
253 | .bDescriptorType = USB_DT_WIRELESS_ENDPOINT_COMP, | 253 | .bDescriptorType = USB_DT_WIRELESS_ENDPOINT_COMP, |
254 | /* .bMaxBurst = 1, */ | 254 | .bMaxBurst = 1, |
255 | .bMaxSequence = 31, | 255 | .bMaxSequence = 2, |
256 | }; | 256 | }; |
257 | 257 | ||
258 | /* | 258 | /* |
@@ -317,6 +317,7 @@ static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa, | |||
317 | struct device *dev = &wa->usb_iface->dev; | 317 | struct device *dev = &wa->usb_iface->dev; |
318 | struct usb_device *usb_dev = urb->dev; | 318 | struct usb_device *usb_dev = urb->dev; |
319 | struct usb_wireless_ep_comp_descriptor *epcd; | 319 | struct usb_wireless_ep_comp_descriptor *epcd; |
320 | u32 ack_window, epcd_max_sequence; | ||
320 | u8 unauth; | 321 | u8 unauth; |
321 | 322 | ||
322 | epcd = rpipe_epc_find(dev, ep); | 323 | epcd = rpipe_epc_find(dev, ep); |
@@ -333,8 +334,11 @@ static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa, | |||
333 | rpipe->descr.wBlocks = cpu_to_le16(16); /* given */ | 334 | rpipe->descr.wBlocks = cpu_to_le16(16); /* given */ |
334 | /* ep0 maxpktsize is 0x200 (WUSB1.0[4.8.1]) */ | 335 | /* ep0 maxpktsize is 0x200 (WUSB1.0[4.8.1]) */ |
335 | rpipe->descr.wMaxPacketSize = cpu_to_le16(ep->desc.wMaxPacketSize); | 336 | rpipe->descr.wMaxPacketSize = cpu_to_le16(ep->desc.wMaxPacketSize); |
336 | rpipe->descr.bHSHubAddress = 0; /* reserved: zero */ | 337 | |
337 | rpipe->descr.bHSHubPort = wusb_port_no_to_idx(urb->dev->portnum); | 338 | rpipe->descr.hwa_bMaxBurst = max(min_t(unsigned int, |
339 | epcd->bMaxBurst, 16U), 1U); | ||
340 | rpipe->descr.hwa_bDeviceInfoIndex = | ||
341 | wusb_port_no_to_idx(urb->dev->portnum); | ||
338 | /* FIXME: use maximum speed as supported or recommended by device */ | 342 | /* FIXME: use maximum speed as supported or recommended by device */ |
339 | rpipe->descr.bSpeed = usb_pipeendpoint(urb->pipe) == 0 ? | 343 | rpipe->descr.bSpeed = usb_pipeendpoint(urb->pipe) == 0 ? |
340 | UWB_PHY_RATE_53 : UWB_PHY_RATE_200; | 344 | UWB_PHY_RATE_53 : UWB_PHY_RATE_200; |
@@ -344,23 +348,24 @@ static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa, | |||
344 | le16_to_cpu(rpipe->descr.wRPipeIndex), | 348 | le16_to_cpu(rpipe->descr.wRPipeIndex), |
345 | usb_pipeendpoint(urb->pipe), rpipe->descr.bSpeed); | 349 | usb_pipeendpoint(urb->pipe), rpipe->descr.bSpeed); |
346 | 350 | ||
347 | /* see security.c:wusb_update_address() */ | 351 | rpipe->descr.hwa_reserved = 0; |
348 | if (unlikely(urb->dev->devnum == 0x80)) | 352 | |
349 | rpipe->descr.bDeviceAddress = 0; | ||
350 | else | ||
351 | rpipe->descr.bDeviceAddress = urb->dev->devnum | unauth; | ||
352 | rpipe->descr.bEndpointAddress = ep->desc.bEndpointAddress; | 353 | rpipe->descr.bEndpointAddress = ep->desc.bEndpointAddress; |
353 | /* FIXME: bDataSequence */ | 354 | /* FIXME: bDataSequence */ |
354 | rpipe->descr.bDataSequence = 0; | 355 | rpipe->descr.bDataSequence = 0; |
355 | /* FIXME: dwCurrentWindow */ | 356 | |
356 | rpipe->descr.dwCurrentWindow = cpu_to_le32(1); | 357 | /* start with base window of hwa_bMaxBurst bits starting at 0. */ |
357 | /* FIXME: bMaxDataSequence */ | 358 | ack_window = 0xFFFFFFFF >> (32 - rpipe->descr.hwa_bMaxBurst); |
358 | rpipe->descr.bMaxDataSequence = epcd->bMaxSequence - 1; | 359 | rpipe->descr.dwCurrentWindow = cpu_to_le32(ack_window); |
360 | epcd_max_sequence = max(min_t(unsigned int, | ||
361 | epcd->bMaxSequence, 32U), 2U); | ||
362 | rpipe->descr.bMaxDataSequence = epcd_max_sequence - 1; | ||
359 | rpipe->descr.bInterval = ep->desc.bInterval; | 363 | rpipe->descr.bInterval = ep->desc.bInterval; |
360 | /* FIXME: bOverTheAirInterval */ | 364 | /* FIXME: bOverTheAirInterval */ |
361 | rpipe->descr.bOverTheAirInterval = 0; /* 0 if not isoc */ | 365 | rpipe->descr.bOverTheAirInterval = 0; /* 0 if not isoc */ |
362 | /* FIXME: xmit power & preamble blah blah */ | 366 | /* FIXME: xmit power & preamble blah blah */ |
363 | rpipe->descr.bmAttribute = ep->desc.bmAttributes & 0x03; | 367 | rpipe->descr.bmAttribute = (ep->desc.bmAttributes & |
368 | USB_ENDPOINT_XFERTYPE_MASK); | ||
364 | /* rpipe->descr.bmCharacteristics RO */ | 369 | /* rpipe->descr.bmCharacteristics RO */ |
365 | /* FIXME: bmRetryOptions */ | 370 | /* FIXME: bmRetryOptions */ |
366 | rpipe->descr.bmRetryOptions = 15; | 371 | rpipe->descr.bmRetryOptions = 15; |
@@ -387,10 +392,8 @@ static int rpipe_check_aim(const struct wa_rpipe *rpipe, const struct wahc *wa, | |||
387 | const struct usb_host_endpoint *ep, | 392 | const struct usb_host_endpoint *ep, |
388 | const struct urb *urb, gfp_t gfp) | 393 | const struct urb *urb, gfp_t gfp) |
389 | { | 394 | { |
390 | int result = 0; /* better code for lack of companion? */ | 395 | int result = 0; |
391 | struct device *dev = &wa->usb_iface->dev; | 396 | struct device *dev = &wa->usb_iface->dev; |
392 | struct usb_device *usb_dev = urb->dev; | ||
393 | u8 unauth = (usb_dev->wusb && !usb_dev->authenticated) ? 0x80 : 0; | ||
394 | u8 portnum = wusb_port_no_to_idx(urb->dev->portnum); | 397 | u8 portnum = wusb_port_no_to_idx(urb->dev->portnum); |
395 | 398 | ||
396 | #define AIM_CHECK(rdf, val, text) \ | 399 | #define AIM_CHECK(rdf, val, text) \ |
@@ -403,13 +406,10 @@ static int rpipe_check_aim(const struct wa_rpipe *rpipe, const struct wahc *wa, | |||
403 | WARN_ON(1); \ | 406 | WARN_ON(1); \ |
404 | } \ | 407 | } \ |
405 | } while (0) | 408 | } while (0) |
406 | AIM_CHECK(wMaxPacketSize, cpu_to_le16(ep->desc.wMaxPacketSize), | 409 | AIM_CHECK(hwa_bDeviceInfoIndex, portnum, "(%u vs %u)"); |
407 | "(%u vs %u)"); | ||
408 | AIM_CHECK(bHSHubPort, portnum, "(%u vs %u)"); | ||
409 | AIM_CHECK(bSpeed, usb_pipeendpoint(urb->pipe) == 0 ? | 410 | AIM_CHECK(bSpeed, usb_pipeendpoint(urb->pipe) == 0 ? |
410 | UWB_PHY_RATE_53 : UWB_PHY_RATE_200, | 411 | UWB_PHY_RATE_53 : UWB_PHY_RATE_200, |
411 | "(%u vs %u)"); | 412 | "(%u vs %u)"); |
412 | AIM_CHECK(bDeviceAddress, urb->dev->devnum | unauth, "(%u vs %u)"); | ||
413 | AIM_CHECK(bEndpointAddress, ep->desc.bEndpointAddress, "(%u vs %u)"); | 413 | AIM_CHECK(bEndpointAddress, ep->desc.bEndpointAddress, "(%u vs %u)"); |
414 | AIM_CHECK(bInterval, ep->desc.bInterval, "(%u vs %u)"); | 414 | AIM_CHECK(bInterval, ep->desc.bInterval, "(%u vs %u)"); |
415 | AIM_CHECK(bmAttribute, ep->desc.bmAttributes & 0x03, "(%u vs %u)"); | 415 | AIM_CHECK(bmAttribute, ep->desc.bmAttributes & 0x03, "(%u vs %u)"); |
diff --git a/include/linux/usb/wusb-wa.h b/include/linux/usb/wusb-wa.h index f9dec37f617b..6be985b2a434 100644 --- a/include/linux/usb/wusb-wa.h +++ b/include/linux/usb/wusb-wa.h | |||
@@ -92,11 +92,20 @@ struct usb_rpipe_descriptor { | |||
92 | __le16 wRPipeIndex; | 92 | __le16 wRPipeIndex; |
93 | __le16 wRequests; | 93 | __le16 wRequests; |
94 | __le16 wBlocks; /* rw if 0 */ | 94 | __le16 wBlocks; /* rw if 0 */ |
95 | __le16 wMaxPacketSize; /* rw? */ | 95 | __le16 wMaxPacketSize; /* rw */ |
96 | u8 bHSHubAddress; /* reserved: 0 */ | 96 | union { |
97 | u8 bHSHubPort; /* ??? FIXME ??? */ | 97 | u8 dwa_bHSHubAddress; /* rw: DWA. */ |
98 | u8 hwa_bMaxBurst; /* rw: HWA. */ | ||
99 | }; | ||
100 | union { | ||
101 | u8 dwa_bHSHubPort; /* rw: DWA. */ | ||
102 | u8 hwa_bDeviceInfoIndex; /* rw: HWA. */ | ||
103 | }; | ||
98 | u8 bSpeed; /* rw: xfer rate 'enum uwb_phy_rate' */ | 104 | u8 bSpeed; /* rw: xfer rate 'enum uwb_phy_rate' */ |
99 | u8 bDeviceAddress; /* rw: Target device address */ | 105 | union { |
106 | u8 dwa_bDeviceAddress; /* rw: DWA Target device address. */ | ||
107 | u8 hwa_reserved; /* rw: HWA. */ | ||
108 | }; | ||
100 | u8 bEndpointAddress; /* rw: Target EP address */ | 109 | u8 bEndpointAddress; /* rw: Target EP address */ |
101 | u8 bDataSequence; /* ro: Current Data sequence */ | 110 | u8 bDataSequence; /* ro: Current Data sequence */ |
102 | __le32 dwCurrentWindow; /* ro */ | 111 | __le32 dwCurrentWindow; /* ro */ |