1 2#include <linux/init.h> 3#include <asm/atomic.h> 4#include <linux/bitmap.h> 5#include <linux/slab.h> 6 7#include "wusbhc.h" 8#include "wa-hc.h" 9 10static int __rpipe_get_descr(struct wahc *wa, 11 struct usb_rpipe_descriptor *descr, u16 index) 12{ 13 ssize_t result; 14 struct device *dev = &wa->usb_iface->dev; 15 16 /* Get the RPIPE descriptor -- we cannot use the usb_get_descriptor() 17 * function because the arguments are different. 18 */ 19 result = usb_control_msg( 20 wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0), 21 USB_REQ_GET_DESCRIPTOR, 22 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_RPIPE, 23 USB_DT_RPIPE<<8, index, descr, sizeof(*descr), 24 1000); 25 if (result < 0) { 26 dev_err(dev, "rpipe %u: get descriptor failed: %d\n", 27 index, (int)result); 28 goto error; 29 } 30 if (result < sizeof(*descr)) { 31 dev_err(dev, "rpipe %u: got short descriptor " 32 "(%zd vs %zd bytes needed)\n", 33 index, result, sizeof(*descr)); 34 result = -EINVAL; 35 goto error; 36 } 37 result = 0; 38 39error: 40 return result; 41} 42 43/* 44 * 45 * The descriptor is assumed to be properly initialized (ie: you got 46 * it through __rpipe_get_descr()). 47 */ 48static int __rpipe_set_descr(struct wahc *wa, 49 struct usb_rpipe_descriptor *descr, u16 index) 50{ 51 ssize_t result; 52 struct device *dev = &wa->usb_iface->dev; 53 54 /* we cannot use the usb_get_descriptor() function because the 55 * arguments are different. 56 */ 57 result = usb_control_msg( 58 wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0), 59 USB_REQ_SET_DESCRIPTOR, 60 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE, 61 USB_DT_RPIPE<<8, index, descr, sizeof(*descr), 62 HZ / 10); 63 if (result < 0) { 64 dev_err(dev, "rpipe %u: set descriptor failed: %d\n", 65 index, (int)result); 66 goto error; 67 } 68 if (result < sizeof(*descr)) { 69 dev_err(dev, "rpipe %u: sent short descriptor " 70 "(%zd vs %zd bytes required)\n", 71 index, result, sizeof(*descr)); 72 result = -EINVAL; 73 goto error; 74 } 75 result = 0; 76 77error: 78 return result; 79 80} 81 82static void rpipe_init(struct wa_rpipe *rpipe) 83{ 84 kref_init(&rpipe->refcnt); 85 spin_lock_init(&rpipe->seg_lock); 86 INIT_LIST_HEAD(&rpipe->seg_list); 87} 88 89static unsigned rpipe_get_idx(struct wahc *wa, unsigned rpipe_idx) 90{ 91 unsigned long flags; 92 93 spin_lock_irqsave(&wa->rpipe_bm_lock, flags); 94 rpipe_idx = find_next_zero_bit(wa->rpipe_bm, wa->rpipes, rpipe_idx); 95 if (rpipe_idx < wa->rpipes) 96 set_bit(rpipe_idx, wa->rpipe_bm); 97 spin_unlock_irqrestore(&wa->rpipe_bm_lock, flags); 98 99 return rpipe_idx; 100} 101 102static void rpipe_put_idx(struct wahc *wa, unsigned rpipe_idx) 103{ 104 unsigned long flags; 105 106 spin_lock_irqsave(&wa->rpipe_bm_lock, flags); 107 clear_bit(rpipe_idx, wa->rpipe_bm); 108 spin_unlock_irqrestore(&wa->rpipe_bm_lock, flags); 109} 110 111void rpipe_destroy(struct kref *_rpipe) 112{ 113 struct wa_rpipe *rpipe = container_of(_rpipe, struct wa_rpipe, refcnt); 114 u8 index = le16_to_cpu(rpipe->descr.wRPipeIndex); 115 116 if (rpipe->ep) 117 rpipe->ep->hcpriv = NULL; 118 rpipe_put_idx(rpipe->wa, index); 119 wa_put(rpipe->wa); 120 kfree(rpipe); 121} 122EXPORT_SYMBOL_GPL(rpipe_destroy); 123 124/* 125 * Locate an idle rpipe, create an structure for it and return it 126 * 127 * @wa is referenced and unlocked 128 * @crs enum rpipe_attr, required endpoint characteristics 129 * 130 * The rpipe can be used only sequentially (not in parallel). 131 * 132 * The rpipe is moved into the "ready" state. 133 */ 134static int rpipe_get_idle(struct wa_rpipe **prpipe, struct wahc *wa, u8 crs, 135 gfp_t gfp) 136{ 137 int result; 138 unsigned rpipe_idx; 139 struct wa_rpipe *rpipe; 140 struct device *dev = &wa->usb_iface->dev; 141 142 rpipe = kzalloc(sizeof(*rpipe), gfp); 143 if (rpipe == NULL) 144 return -ENOMEM; 145 rpipe_init(rpipe); 146 147 /* Look for an idle pipe */ 148 for (rpipe_idx = 0; rpipe_idx < wa->rpipes; rpipe_idx++) { 149 rpipe_idx = rpipe_get_idx(wa, rpipe_idx); 150 if (rpipe_idx >= wa->rpipes) /* no more pipes :( */ 151 break; 152 result = __rpipe_get_descr(wa, &rpipe->descr, rpipe_idx); 153 if (result < 0) 154 dev_err(dev, "Can't get descriptor for rpipe %u: %d\n", 155 rpipe_idx, result); 156 else if ((rpipe->descr.bmCharacteristics & crs) != 0) 157 goto found; 158 rpipe_put_idx(wa, rpipe_idx); 159 } 160 *prpipe = NULL; 161 kfree(rpipe); 162 return -ENXIO; 163 164found: 165 set_bit(rpipe_idx, wa->rpipe_bm); 166 rpipe->wa = wa_get(wa); 167 *prpipe = rpipe; 168 return 0; 169} 170 171static int __rpipe_reset(struct wahc *wa, unsigned index) 172{ 173 int result; 174 struct device *dev = &wa->usb_iface->dev; 175 176 result = usb_control_msg( 177 wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0), 178 USB_REQ_RPIPE_RESET, 179 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE, 180 0, index, NULL, 0, 1000); 181 if (result < 0) 182 dev_err(dev, "rpipe %u: reset failed: %d\n", 183 index, result); 184 return result; 185} 186 187/* 188 * Fake companion descriptor for ep0 189 * 190 * See WUSB1.0[7.4.4], most of this is zero for bulk/int/ctl 191 */ 192static struct usb_wireless_ep_comp_descriptor epc0 = { 193 .bLength = sizeof(epc0), 194 .bDescriptorType = USB_DT_WIRELESS_ENDPOINT_COMP, 195/* .bMaxBurst = 1, */ 196 .bMaxSequence = 31, 197}; 198 199/* 200 * Look for EP companion descriptor 201 * 202 * Get there, look for Inara in the endpoint's extra descriptors 203 */ 204static struct usb_wireless_ep_comp_descriptor *rpipe_epc_find( 205 struct device *dev, struct usb_host_endpoint *ep) 206{ 207 void *itr; 208 size_t itr_size; 209 struct usb_descriptor_header *hdr; 210 struct usb_wireless_ep_comp_descriptor *epcd; 211 212 if (ep->desc.bEndpointAddress == 0) { 213 epcd = &epc0; 214 goto out; 215 } 216 itr = ep->extra; 217 itr_size = ep->extralen; 218 epcd = NULL; 219 while (itr_size > 0) { 220 if (itr_size < sizeof(*hdr)) { 221 dev_err(dev, "HW Bug? ep 0x%02x: extra descriptors " 222 "at offset %zu: only %zu bytes left\n", 223 ep->desc.bEndpointAddress, 224 itr - (void *) ep->extra, itr_size); 225 break; 226 } 227 hdr = itr; 228 if (hdr->bDescriptorType == USB_DT_WIRELESS_ENDPOINT_COMP) { 229 epcd = itr; 230 break; 231 } 232 if (hdr->bLength > itr_size) { 233 dev_err(dev, "HW Bug? ep 0x%02x: extra descriptor " 234 "at offset %zu (type 0x%02x) " 235 "length %d but only %zu bytes left\n", 236 ep->desc.bEndpointAddress, 237 itr - (void *) ep->extra, hdr->bDescriptorType, 238 hdr->bLength, itr_size); 239 break; 240 } 241 itr += hdr->bLength; 242 itr_size -= hdr->bDescriptorType; 243 } 244out: 245 return epcd; 246} 247 248/* 249 * Aim an rpipe to its device & endpoint destination 250 * 251 * Make sure we change the address to unauthenticathed if the device 252 * is WUSB and it is not authenticated. 253 */ 254static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa, 255 struct usb_host_endpoint *ep, struct urb *urb, gfp_t gfp) 256{ 257 int result = -ENOMSG; /* better code for lack of companion? */ 258 struct device *dev = &wa->usb_iface->dev; 259 struct usb_device *usb_dev = urb->dev; 260 struct usb_wireless_ep_comp_descriptor *epcd; 261 u8 unauth; 262 263 epcd = rpipe_epc_find(dev, ep); 264 if (epcd == NULL) { 265 dev_err(dev, "ep 0x%02x: can't find companion descriptor\n", 266 ep->desc.bEndpointAddress); 267 goto error; 268 } 269 unauth = usb_dev->wusb && !usb_dev->authenticated ? 0x80 : 0; 270 __rpipe_reset(wa, le16_to_cpu(rpipe->descr.wRPipeIndex)); 271 atomic_set(&rpipe->segs_available, le16_to_cpu(rpipe->descr.wRequests)); 272 rpipe->descr.wBlocks = cpu_to_le16(16); /* given */ 273 /* ep0 maxpktsize is 0x200 (WUSB1.0[4.8.1]) */ 274 rpipe->descr.wMaxPacketSize = cpu_to_le16(ep->desc.wMaxPacketSize); 275 rpipe->descr.bHSHubAddress = 0; /* reserved: zero */ 276 rpipe->descr.bHSHubPort = wusb_port_no_to_idx(urb->dev->portnum); 277 rpipe->descr.bSpeed = usb_pipeendpoint(urb->pipe) == 0 ? 278 UWB_PHY_RATE_53 : UWB_PHY_RATE_200; 279 280 dev_dbg(dev, "addr %u (0x%02x) rpipe #%u ep# %u speed %d\n", 281 urb->dev->devnum, urb->dev->devnum | unauth, 282 le16_to_cpu(rpipe->descr.wRPipeIndex), 283 usb_pipeendpoint(urb->pipe), rpipe->descr.bSpeed); 284 285 /* see security.c:wusb_update_address() */ 286 if (unlikely(urb->dev->devnum == 0x80)) 287 rpipe->descr.bDeviceAddress = 0; 288 else 289 rpipe->descr.bDeviceAddress = urb->dev->devnum | unauth; 290 rpipe->descr.bEndpointAddress = ep->desc.bEndpointAddress; 291 rpipe->descr.bDataSequence = 0; 292 rpipe->descr.dwCurrentWindow = cpu_to_le32(1); 293 rpipe->descr.bMaxDataSequence = epcd->bMaxSequence - 1; 294 rpipe->descr.bInterval = ep->desc.bInterval; 295 rpipe->descr.bOverTheAirInterval = 0; /* 0 if not isoc */ 296 rpipe->descr.bmAttribute = ep->desc.bmAttributes & 0x03; 297 /* rpipe->descr.bmCharacteristics RO */ 298 rpipe->descr.bmRetryOptions = 15; 299 rpipe->descr.wNumTransactionErrors = 0; 300 result = __rpipe_set_descr(wa, &rpipe->descr, 301 le16_to_cpu(rpipe->descr.wRPipeIndex)); 302 if (result < 0) { 303 dev_err(dev, "Cannot aim rpipe: %d\n", result); 304 goto error; 305 } 306 result = 0; 307error: 308 return result; 309} 310 311/* 312 * Check an aimed rpipe to make sure it points to where we want 313 * 314 * We use bit 19 of the Linux USB pipe bitmap for unauth vs auth 315 * space; when it is like that, we or 0x80 to make an unauth address. 316 */ 317static int rpipe_check_aim(const struct wa_rpipe *rpipe, const struct wahc *wa, 318 const struct usb_host_endpoint *ep, 319 const struct urb *urb, gfp_t gfp) 320{ 321 int result = 0; /* better code for lack of companion? */ 322 struct device *dev = &wa->usb_iface->dev; 323 struct usb_device *usb_dev = urb->dev; 324 u8 unauth = (usb_dev->wusb && !usb_dev->authenticated) ? 0x80 : 0; 325 u8 portnum = wusb_port_no_to_idx(urb->dev->portnum); 326 327#define AIM_CHECK(rdf, val, text) \ 328 do { \ 329 if (rpipe->descr.rdf != (val)) { \ 330 dev_err(dev, \ 331 "rpipe aim discrepancy: " #rdf " " text "\n", \ 332 rpipe->descr.rdf, (val)); \ 333 result = -EINVAL; \ 334 WARN_ON(1); \ 335 } \ 336 } while (0) 337 AIM_CHECK(wMaxPacketSize, cpu_to_le16(ep->desc.wMaxPacketSize), 338 "(%u vs %u)"); 339 AIM_CHECK(bHSHubPort, portnum, "(%u vs %u)"); 340 AIM_CHECK(bSpeed, usb_pipeendpoint(urb->pipe) == 0 ? 341 UWB_PHY_RATE_53 : UWB_PHY_RATE_200, 342 "(%u vs %u)"); 343 AIM_CHECK(bDeviceAddress, urb->dev->devnum | unauth, "(%u vs %u)"); 344 AIM_CHECK(bEndpointAddress, ep->desc.bEndpointAddress, "(%u vs %u)"); 345 AIM_CHECK(bInterval, ep->desc.bInterval, "(%u vs %u)"); 346 AIM_CHECK(bmAttribute, ep->desc.bmAttributes & 0x03, "(%u vs %u)"); 347#undef AIM_CHECK 348 return result; 349} 350 351#ifndef CONFIG_BUG 352#define CONFIG_BUG 0 353#endif 354 355/* 356 * Make sure there is an rpipe allocated for an endpoint 357 * 358 * If already allocated, we just refcount it; if not, we get an 359 * idle one, aim it to the right location and take it. 360 * 361 * Attaches to ep->hcpriv and rpipe->ep to ep. 362 */ 363int rpipe_get_by_ep(struct wahc *wa, struct usb_host_endpoint *ep, 364 struct urb *urb, gfp_t gfp) 365{ 366 int result = 0; 367 struct device *dev = &wa->usb_iface->dev; 368 struct wa_rpipe *rpipe; 369 u8 eptype; 370 371 mutex_lock(&wa->rpipe_mutex); 372 rpipe = ep->hcpriv; 373 if (rpipe != NULL) { 374 if (CONFIG_BUG == 1) { 375 result = rpipe_check_aim(rpipe, wa, ep, urb, gfp); 376 if (result < 0) 377 goto error; 378 } 379 __rpipe_get(rpipe); 380 dev_dbg(dev, "ep 0x%02x: reusing rpipe %u\n", 381 ep->desc.bEndpointAddress, 382 le16_to_cpu(rpipe->descr.wRPipeIndex)); 383 } else { 384 /* hmm, assign idle rpipe, aim it */ 385 result = -ENOBUFS; 386 eptype = ep->desc.bmAttributes & 0x03; 387 result = rpipe_get_idle(&rpipe, wa, 1 << eptype, gfp); 388 if (result < 0) 389 goto error; 390 result = rpipe_aim(rpipe, wa, ep, urb, gfp); 391 if (result < 0) { 392 rpipe_put(rpipe); 393 goto error; 394 } 395 ep->hcpriv = rpipe; 396 rpipe->ep = ep; 397 __rpipe_get(rpipe); /* for caching into ep->hcpriv */ 398 dev_dbg(dev, "ep 0x%02x: using rpipe %u\n", 399 ep->desc.bEndpointAddress, 400 le16_to_cpu(rpipe->descr.wRPipeIndex)); 401 } 402error: 403 mutex_unlock(&wa->rpipe_mutex); 404 return result; 405} 406 407/* 408 * Allocate the bitmap for each rpipe. 409 */ 410int wa_rpipes_create(struct wahc *wa) 411{ 412 wa->rpipes = wa->wa_descr->wNumRPipes; 413 wa->rpipe_bm = kzalloc(BITS_TO_LONGS(wa->rpipes)*sizeof(unsigned long), 414 GFP_KERNEL); 415 if (wa->rpipe_bm == NULL) 416 return -ENOMEM; 417 return 0; 418} 419 420void wa_rpipes_destroy(struct wahc *wa) 421{ 422 struct device *dev = &wa->usb_iface->dev; 423 424 if (!bitmap_empty(wa->rpipe_bm, wa->rpipes)) { 425 char buf[256]; 426 WARN_ON(1); 427 bitmap_scnprintf(buf, sizeof(buf), wa->rpipe_bm, wa->rpipes); 428 dev_err(dev, "BUG: pipes not released on exit: %s\n", buf); 429 } 430 kfree(wa->rpipe_bm); 431} 432 433/* 434 * Release resources allocated for an endpoint 435 * 436 * If there is an associated rpipe to this endpoint, Abort any pending 437 * transfers and put it. If the rpipe ends up being destroyed, 438 * __rpipe_destroy() will cleanup ep->hcpriv. 439 * 440 * This is called before calling hcd->stop(), so you don't need to do 441 * anything else in there. 442 */ 443void rpipe_ep_disable(struct wahc *wa, struct usb_host_endpoint *ep) 444{ 445 struct wa_rpipe *rpipe; 446 447 mutex_lock(&wa->rpipe_mutex); 448 rpipe = ep->hcpriv; 449 if (rpipe != NULL) { 450 u16 index = le16_to_cpu(rpipe->descr.wRPipeIndex); 451 452 usb_control_msg( 453 wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0), 454 USB_REQ_RPIPE_ABORT, 455 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE, 456 0, index, NULL, 0, 1000); 457 rpipe_put(rpipe); 458 } 459 mutex_unlock(&wa->rpipe_mutex); 460} 461EXPORT_SYMBOL_GPL(rpipe_ep_disable); 462