1 /* 2 * USB device driver framework. 3 * 4 * This is in charge of providing access to actual HCIs 5 * and providing I/O to the various endpoints of devices. 6 * A separate user program (usbd) is in charge of 7 * enumerating the bus, setting up endpoints and 8 * starting devices (also user programs). 9 * 10 * The interface provided is a violation of the standard: 11 * you're welcome. 12 * 13 * The interface consists of a root directory with several files 14 * plus a directory (epN.M) with two files per endpoint. 15 * A device is represented by its first endpoint, which 16 * is a control endpoint automatically allocated for each device. 17 * Device control endpoints may be used to create new endpoints. 18 * Devices corresponding to hubs may also allocate new devices, 19 * perhaps also hubs. Initially, a hub device is allocated for 20 * each controller present, to represent its root hub. Those can 21 * never be removed. 22 * 23 * All endpoints refer to the first endpoint (epN.0) of the device, 24 * which keeps per-device information, and also to the HCI used 25 * to reach them. Although all endpoints cache that information. 26 * 27 * epN.M/data files permit I/O and are considered DMEXCL. 28 * epN.M/ctl files provide status info and accept control requests. 29 * 30 * Endpoints may be given file names to be listed also at #u, 31 * for those drivers that have nothing to do after configuring the 32 * device and its endpoints. 33 * 34 * Drivers for different controllers are kept at usb[oue]hci.c 35 * It's likely we could factor out much from controllers into 36 * a generic controller driver, the problem is that details 37 * regarding how to handle toggles, tokens, Tds, etc. will 38 * get in the way. Thus, code is probably easier the way it is. 39 */ 40 41 #include "u.h" 42 #include "../port/lib.h" 43 #include "mem.h" 44 #include "dat.h" 45 #include "fns.h" 46 #include "io.h" 47 #include "../port/error.h" 48 #include "../port/usb.h" 49 50 typedef struct Hcitype Hcitype; 51 52 enum 53 { 54 /* Qid numbers */ 55 Qdir = 0, /* #u */ 56 Qusbdir, /* #u/usb */ 57 Qctl, /* #u/usb/ctl - control requests */ 58 59 Qep0dir, /* #u/usb/ep0.0 - endpoint 0 dir */ 60 Qep0io, /* #u/usb/ep0.0/data - endpoint 0 I/O */ 61 Qep0ctl, /* #u/usb/ep0.0/ctl - endpoint 0 ctl. */ 62 Qep0dummy, /* give 4 qids to each endpoint */ 63 64 Qepdir = 0, /* (qid-qep0dir)&3 is one of these */ 65 Qepio, /* to identify which file for the endpoint */ 66 Qepctl, 67 68 /* ... */ 69 70 /* Usb ctls. */ 71 CMdebug = 0, /* debug on|off */ 72 CMdump, /* dump (data structures for debug) */ 73 74 /* Ep. ctls */ 75 CMnew = 0, /* new nb ctl|bulk|intr|iso r|w|rw (endpoint) */ 76 CMnewdev, /* newdev full|low|high portnb (allocate new devices) */ 77 CMhub, /* hub (set the device as a hub) */ 78 CMspeed, /* speed full|low|high|no */ 79 CMmaxpkt, /* maxpkt size */ 80 CMntds, /* ntds nb (max nb. of tds per µframe) */ 81 CMclrhalt, /* clrhalt (halt was cleared on endpoint) */ 82 CMpollival, /* pollival interval (interrupt/iso) */ 83 CMhz, /* hz n (samples/sec; iso) */ 84 CMsamplesz, /* samplesz n (sample size; iso) */ 85 CMinfo, /* info infostr (ke.ep info for humans) */ 86 CMdetach, /* detach (abort I/O forever on this ep). */ 87 CMaddress, /* address (address is assigned) */ 88 CMdebugep, /* debug n (set/clear debug for this ep) */ 89 CMname, /* name str (show up as #u/name as well) */ 90 CMtmout, /* timeout n (activate timeouts for ep) */ 91 CMpreset, /* reset the port */ 92 93 /* Hub feature selectors */ 94 Rportenable = 1, 95 Rportreset = 4, 96 97 }; 98 99 struct Hcitype 100 { 101 char* type; 102 int (*reset)(Hci*); 103 }; 104 105 #define QID(q) ((int)(q).path) 106 107 static Cmdtab usbctls[] = 108 { 109 {CMdebug, "debug", 2}, 110 {CMdump, "dump", 1}, 111 }; 112 113 static Cmdtab epctls[] = 114 { 115 {CMnew, "new", 4}, 116 {CMnewdev, "newdev", 3}, 117 {CMhub, "hub", 1}, 118 {CMspeed, "speed", 2}, 119 {CMmaxpkt, "maxpkt", 2}, 120 {CMntds, "ntds", 2}, 121 {CMpollival, "pollival", 2}, 122 {CMsamplesz, "samplesz", 2}, 123 {CMhz, "hz", 2}, 124 {CMinfo, "info", 0}, 125 {CMdetach, "detach", 1}, 126 {CMaddress, "address", 1}, 127 {CMdebugep, "debug", 2}, 128 {CMclrhalt, "clrhalt", 1}, 129 {CMname, "name", 2}, 130 {CMtmout, "timeout", 2}, 131 {CMpreset, "reset", 1}, 132 }; 133 134 static Dirtab usbdir[] = 135 { 136 "ctl", {Qctl}, 0, 0666, 137 }; 138 139 char *usbmodename[] = 140 { 141 [OREAD] "r", 142 [OWRITE] "w", 143 [ORDWR] "rw", 144 }; 145 146 static char *ttname[] = 147 { 148 [Tnone] "none", 149 [Tctl] "control", 150 [Tiso] "iso", 151 [Tintr] "interrupt", 152 [Tbulk] "bulk", 153 }; 154 155 static char *spname[] = 156 { 157 [Fullspeed] "full", 158 [Lowspeed] "low", 159 [Highspeed] "high", 160 [Nospeed] "no", 161 }; 162 163 static int debug; 164 static Hcitype hcitypes[Nhcis]; 165 static Hci* hcis[Nhcis]; 166 static QLock epslck; /* add, del, lookup endpoints */ 167 static Ep* eps[Neps]; /* all endpoints known */ 168 static int epmax; /* 1 + last endpoint index used */ 169 static int usbidgen; /* device address generator */ 170 171 /* 172 * Is there something like this in a library? should it be? 173 */ 174 char* 175 seprintdata(char *s, char *se, uchar *d, int n) 176 { 177 int i, l; 178 179 s = seprint(s, se, " %#p[%d]: ", d, n); 180 l = n; 181 if(l > 10) 182 l = 10; 183 for(i=0; i<l; i++) 184 s = seprint(s, se, " %2.2ux", d[i]); 185 if(l < n) 186 s = seprint(s, se, "..."); 187 return s; 188 } 189 190 static int 191 name2speed(char *name) 192 { 193 int i; 194 195 for(i = 0; i < nelem(spname); i++) 196 if(strcmp(name, spname[i]) == 0) 197 return i; 198 return Nospeed; 199 } 200 201 static int 202 name2ttype(char *name) 203 { 204 int i; 205 206 for(i = 0; i < nelem(ttname); i++) 207 if(strcmp(name, ttname[i]) == 0) 208 return i; 209 /* may be a std. USB ep. type */ 210 i = strtol(name, nil, 0); 211 switch(i+1){ 212 case Tctl: 213 case Tiso: 214 case Tbulk: 215 case Tintr: 216 return i+1; 217 default: 218 return Tnone; 219 } 220 } 221 222 static int 223 name2mode(char *mode) 224 { 225 int i; 226 227 for(i = 0; i < nelem(usbmodename); i++) 228 if(strcmp(mode, usbmodename[i]) == 0) 229 return i; 230 return -1; 231 } 232 233 static int 234 qid2epidx(int q) 235 { 236 q = (q-Qep0dir)/4; 237 if(q < 0 || q >= epmax || eps[q] == nil) 238 return -1; 239 return q; 240 } 241 242 static int 243 isqtype(int q, int type) 244 { 245 if(q < Qep0dir) 246 return 0; 247 q -= Qep0dir; 248 return (q & 3) == type; 249 } 250 251 void 252 addhcitype(char* t, int (*r)(Hci*)) 253 { 254 static int ntype; 255 256 if(ntype == Nhcis) 257 panic("too many USB host interface types"); 258 hcitypes[ntype].type = t; 259 hcitypes[ntype].reset = r; 260 ntype++; 261 } 262 263 static char* 264 seprintep(char *s, char *se, Ep *ep, int all) 265 { 266 static char* dsnames[] = { "config", "enabled", "detached", "reset" }; 267 Udev *d; 268 int i; 269 int di; 270 271 d = ep->dev; 272 273 qlock(ep); 274 if(waserror()){ 275 qunlock(ep); 276 nexterror(); 277 } 278 di = ep->dev->nb; 279 if(all) 280 s = seprint(s, se, "dev %d ep %d ", di, ep->nb); 281 s = seprint(s, se, "%s", dsnames[ep->dev->state]); 282 s = seprint(s, se, " %s", ttname[ep->ttype]); 283 assert(ep->mode == OREAD || ep->mode == OWRITE || ep->mode == ORDWR); 284 s = seprint(s, se, " %s", usbmodename[ep->mode]); 285 s = seprint(s, se, " speed %s", spname[d->speed]); 286 s = seprint(s, se, " maxpkt %ld", ep->maxpkt); 287 s = seprint(s, se, " pollival %ld", ep->pollival); 288 s = seprint(s, se, " samplesz %ld", ep->samplesz); 289 s = seprint(s, se, " hz %ld", ep->hz); 290 s = seprint(s, se, " hub %d", ep->dev->hub); 291 s = seprint(s, se, " port %d", ep->dev->port); 292 if(ep->inuse) 293 s = seprint(s, se, " busy"); 294 else 295 s = seprint(s, se, " idle"); 296 if(all){ 297 s = seprint(s, se, " load %uld", ep->load); 298 s = seprint(s, se, " ref %ld addr %#p", ep->ref, ep); 299 s = seprint(s, se, " idx %d", ep->idx); 300 if(ep->name != nil) 301 s = seprint(s, se, " name '%s'", ep->name); 302 if(ep->tmout != 0) 303 s = seprint(s, se, " tmout"); 304 if(ep == ep->ep0){ 305 s = seprint(s, se, " ctlrno %#x", ep->hp->ctlrno); 306 s = seprint(s, se, " eps:"); 307 for(i = 0; i < nelem(d->eps); i++) 308 if(d->eps[i] != nil) 309 s = seprint(s, se, " ep%d.%d", di, i); 310 } 311 } 312 if(ep->info != nil) 313 s = seprint(s, se, "\n%s %s\n", ep->info, ep->hp->type); 314 else 315 s = seprint(s, se, "\n"); 316 qunlock(ep); 317 poperror(); 318 return s; 319 } 320 321 static Ep* 322 epalloc(Hci *hp) 323 { 324 Ep *ep; 325 int i; 326 327 ep = smalloc(sizeof(Ep)); 328 ep->ref = 1; 329 qlock(&epslck); 330 for(i = 0; i < Neps; i++) 331 if(eps[i] == nil) 332 break; 333 if(i == Neps){ 334 qunlock(&epslck); 335 free(ep); 336 print("usb: bug: too few endpoints.\n"); 337 return nil; 338 } 339 ep->idx = i; 340 if(epmax <= i) 341 epmax = i+1; 342 eps[i] = ep; 343 ep->hp = hp; 344 ep->maxpkt = 8; 345 ep->ntds = 1; 346 ep->samplesz = ep->pollival = ep->hz = 0; /* make them void */ 347 qunlock(&epslck); 348 return ep; 349 } 350 351 static Ep* 352 getep(int i) 353 { 354 Ep *ep; 355 356 if(i < 0 || i >= epmax || eps[i] == nil) 357 return nil; 358 qlock(&epslck); 359 ep = eps[i]; 360 if(ep != nil) 361 incref(ep); 362 qunlock(&epslck); 363 return ep; 364 } 365 366 static void 367 putep(Ep *ep) 368 { 369 Udev *d; 370 371 if(ep != nil && decref(ep) == 0){ 372 d = ep->dev; 373 deprint("usb: ep%d.%d %#p released\n", d->nb, ep->nb, ep); 374 qlock(&epslck); 375 eps[ep->idx] = nil; 376 if(ep->idx == epmax-1) 377 epmax--; 378 if(ep == ep->ep0 && ep->dev != nil && ep->dev->nb == usbidgen) 379 usbidgen--; 380 qunlock(&epslck); 381 if(d != nil){ 382 qlock(ep->ep0); 383 d->eps[ep->nb] = nil; 384 qunlock(ep->ep0); 385 } 386 if(ep->ep0 != ep){ 387 putep(ep->ep0); 388 ep->ep0 = nil; 389 } 390 free(ep->info); 391 free(ep->name); 392 free(ep); 393 } 394 } 395 396 static void 397 dumpeps(void) 398 { 399 int i; 400 static char buf[512]; 401 char *s; 402 char *e; 403 Ep *ep; 404 405 print("usb dump eps: epmax %d Neps %d (ref=1+ for dump):\n", epmax, Neps); 406 for(i = 0; i < epmax; i++){ 407 s = buf; 408 e = buf+sizeof(buf); 409 ep = getep(i); 410 if(ep != nil){ 411 if(waserror()){ 412 putep(ep); 413 nexterror(); 414 } 415 s = seprint(s, e, "ep%d.%d ", ep->dev->nb, ep->nb); 416 seprintep(s, e, ep, 1); 417 print("%s", buf); 418 ep->hp->seprintep(buf, e, ep); 419 print("%s", buf); 420 poperror(); 421 putep(ep); 422 } 423 } 424 print("usb dump hcis:\n"); 425 for(i = 0; i < Nhcis; i++) 426 if(hcis[i] != nil) 427 hcis[i]->dump(hcis[i]); 428 } 429 430 static int 431 newusbid(Hci *) 432 { 433 int id; 434 435 qlock(&epslck); 436 id = ++usbidgen; 437 if(id >= 0x7F) 438 print("#u: too many device addresses; reuse them more\n"); 439 qunlock(&epslck); 440 return id; 441 } 442 443 /* 444 * Create endpoint 0 for a new device 445 */ 446 static Ep* 447 newdev(Hci *hp, int ishub, int isroot) 448 { 449 Ep *ep; 450 Udev *d; 451 452 ep = epalloc(hp); 453 d = ep->dev = smalloc(sizeof(Udev)); 454 d->nb = newusbid(hp); 455 d->eps[0] = ep; 456 ep->nb = 0; 457 ep->toggle[0] = ep->toggle[1] = 0; 458 d->ishub = ishub; 459 d->isroot = isroot; 460 if(hp->highspeed != 0) 461 d->speed = Highspeed; 462 else 463 d->speed = Fullspeed; 464 d->state = Dconfig; /* address not yet set */ 465 ep->dev = d; 466 ep->ep0 = ep; /* no ref counted here */ 467 ep->ttype = Tctl; 468 ep->tmout = Xfertmout; 469 ep->mode = ORDWR; 470 dprint("newdev %#p ep%d.%d %#p\n", d, d->nb, ep->nb, ep); 471 return ep; 472 } 473 474 /* 475 * Create a new endpoint for the device 476 * accessed via the given endpoint 0. 477 */ 478 static Ep* 479 newdevep(Ep *ep, int i, int tt, int mode) 480 { 481 Ep *nep; 482 Udev *d; 483 484 d = ep->dev; 485 if(d->eps[i] != nil) 486 error("endpoint already in use"); 487 nep = epalloc(ep->hp); 488 incref(ep); 489 d->eps[i] = nep; 490 nep->nb = i; 491 nep->toggle[0] = nep->toggle[1] = 0; 492 nep->ep0 = ep; 493 nep->dev = ep->dev; 494 nep->mode = mode; 495 nep->ttype = tt; 496 nep->debug = ep->debug; 497 /* set defaults */ 498 switch(tt){ 499 case Tctl: 500 nep->tmout = Xfertmout; 501 break; 502 case Tintr: 503 nep->pollival = 10; 504 break; 505 case Tiso: 506 nep->tmout = Xfertmout; 507 nep->pollival = 10; 508 nep->samplesz = 4; 509 nep->hz = 44100; 510 break; 511 } 512 deprint("newdevep ep%d.%d %#p\n", d->nb, nep->nb, nep); 513 return ep; 514 } 515 516 static int 517 epdataperm(int mode) 518 { 519 520 switch(mode){ 521 case OREAD: 522 return 0440|DMEXCL; 523 break; 524 case OWRITE: 525 return 0220|DMEXCL; 526 break; 527 default: 528 return 0660|DMEXCL; 529 } 530 } 531 532 static int 533 usbgen(Chan *c, char *, Dirtab*, int, int s, Dir *dp) 534 { 535 Qid q; 536 Dirtab *dir; 537 int perm; 538 char *se; 539 Ep *ep; 540 int nb; 541 int mode; 542 543 if(0)ddprint("usbgen q %#x s %d...", QID(c->qid), s); 544 if(s == DEVDOTDOT){ 545 if(QID(c->qid) <= Qusbdir){ 546 mkqid(&q, Qdir, 0, QTDIR); 547 devdir(c, q, "#u", 0, eve, 0555, dp); 548 }else{ 549 mkqid(&q, Qusbdir, 0, QTDIR); 550 devdir(c, q, "usb", 0, eve, 0555, dp); 551 } 552 if(0)ddprint("ok\n"); 553 return 1; 554 } 555 556 switch(QID(c->qid)){ 557 case Qdir: /* list #u */ 558 if(s == 0){ 559 mkqid(&q, Qusbdir, 0, QTDIR); 560 devdir(c, q, "usb", 0, eve, 0555, dp); 561 if(0)ddprint("ok\n"); 562 return 1; 563 } 564 s--; 565 if(s < 0 || s >= epmax) 566 goto Fail; 567 ep = getep(s); 568 if(ep == nil || ep->name == nil){ 569 if(ep != nil) 570 putep(ep); 571 if(0)ddprint("skip\n"); 572 return 0; 573 } 574 if(waserror()){ 575 putep(ep); 576 nexterror(); 577 } 578 mkqid(&q, Qep0io+s*4, 0, QTFILE); 579 devdir(c, q, ep->name, 0, eve, epdataperm(ep->mode), dp); 580 putep(ep); 581 poperror(); 582 if(0)ddprint("ok\n"); 583 return 1; 584 585 case Qusbdir: /* list #u/usb */ 586 Usbdir: 587 if(s < nelem(usbdir)){ 588 dir = &usbdir[s]; 589 mkqid(&q, dir->qid.path, 0, QTFILE); 590 devdir(c, q, dir->name, dir->length, eve, dir->perm, dp); 591 if(0)ddprint("ok\n"); 592 return 1; 593 } 594 s -= nelem(usbdir); 595 if(s < 0 || s >= epmax) 596 goto Fail; 597 ep = getep(s); 598 if(ep == nil){ 599 if(0)ddprint("skip\n"); 600 return 0; 601 } 602 if(waserror()){ 603 putep(ep); 604 nexterror(); 605 } 606 se = up->genbuf+sizeof(up->genbuf); 607 seprint(up->genbuf, se, "ep%d.%d", ep->dev->nb, ep->nb); 608 mkqid(&q, Qep0dir+4*s, 0, QTDIR); 609 putep(ep); 610 poperror(); 611 devdir(c, q, up->genbuf, 0, eve, 0755, dp); 612 if(0)ddprint("ok\n"); 613 return 1; 614 615 case Qctl: 616 s = 0; 617 goto Usbdir; 618 619 default: /* list #u/usb/epN.M */ 620 nb = qid2epidx(QID(c->qid)); 621 ep = getep(nb); 622 if(ep == nil) 623 goto Fail; 624 mode = ep->mode; 625 putep(ep); 626 if(isqtype(QID(c->qid), Qepdir)){ 627 Epdir: 628 switch(s){ 629 case 0: 630 mkqid(&q, Qep0io+nb*4, 0, QTFILE); 631 perm = epdataperm(mode); 632 devdir(c, q, "data", 0, eve, perm, dp); 633 break; 634 case 1: 635 mkqid(&q, Qep0ctl+nb*4, 0, QTFILE); 636 devdir(c, q, "ctl", 0, eve, 0664, dp); 637 break; 638 default: 639 goto Fail; 640 } 641 }else if(isqtype(QID(c->qid), Qepctl)){ 642 s = 1; 643 goto Epdir; 644 }else{ 645 s = 0; 646 goto Epdir; 647 } 648 if(0)ddprint("ok\n"); 649 return 1; 650 } 651 Fail: 652 if(0)ddprint("fail\n"); 653 return -1; 654 } 655 656 static Hci* 657 hciprobe(int cardno, int ctlrno) 658 { 659 Hci *hp; 660 char *type; 661 char name[64]; 662 static int epnb = 1; /* guess the endpoint nb. for the controller */ 663 664 ddprint("hciprobe %d %d\n", cardno, ctlrno); 665 hp = smalloc(sizeof(Hci)); 666 hp->ctlrno = ctlrno; 667 668 if(cardno < 0) 669 for(cardno = 0; cardno < Nhcis; cardno++){ 670 if(hcitypes[cardno].type == nil) 671 break; 672 type = hp->type; 673 if(type==nil || *type==0) 674 type = "uhci"; 675 if(cistrcmp(hcitypes[cardno].type, type) == 0) 676 break; 677 } 678 679 if(cardno >= Nhcis || hcitypes[cardno].type == nil){ 680 free(hp); 681 return nil; 682 } 683 dprint("%s...", hcitypes[cardno].type); 684 if(hcitypes[cardno].reset(hp) < 0){ 685 free(hp); 686 return nil; 687 } 688 689 snprint(name, sizeof(name), "usb%s", hcitypes[cardno].type); 690 intrenable(hp->irq, hp->interrupt, hp, UNKNOWN, name); 691 692 print("#u/usb/ep%d.0: %s: port %#luX irq %d\n", 693 epnb, hcitypes[cardno].type, hp->port, hp->irq); 694 epnb++; 695 696 return hp; 697 } 698 699 static void 700 usbreset(void) 701 { 702 int cardno, ctlrno; 703 Hci *hp; 704 705 dprint("usbreset\n"); 706 707 for(ctlrno = 0; ctlrno < Nhcis; ctlrno++) 708 if((hp = hciprobe(-1, ctlrno)) != nil) 709 hcis[ctlrno] = hp; 710 cardno = ctlrno = 0; 711 while(cardno < Nhcis && ctlrno < Nhcis && hcitypes[cardno].type != nil) 712 if(hcis[ctlrno] != nil) 713 ctlrno++; 714 else{ 715 hp = hciprobe(cardno, ctlrno); 716 if(hp == nil) 717 cardno++; 718 hcis[ctlrno++] = hp; 719 } 720 if(hcis[Nhcis-1] != nil) 721 print("usbreset: bug: Nhcis too small\n"); 722 } 723 724 static void 725 usbinit(void) 726 { 727 Hci *hp; 728 int ctlrno; 729 Ep *d; 730 char info[40]; 731 732 dprint("usbinit\n"); 733 for(ctlrno = 0; ctlrno < Nhcis; ctlrno++){ 734 hp = hcis[ctlrno]; 735 if(hp != nil){ 736 if(hp->init != nil) 737 hp->init(hp); 738 d = newdev(hp, 1, 1); /* new root hub */ 739 d->dev->state = Denabled; /* although addr == 0 */ 740 d->maxpkt = 64; 741 snprint(info, sizeof(info), "ports %d", hp->nports); 742 kstrdup(&d->info, info); 743 } 744 } 745 } 746 747 static Chan* 748 usbattach(char *spec) 749 { 750 return devattach(L'u', spec); 751 } 752 753 static Walkqid* 754 usbwalk(Chan *c, Chan *nc, char **name, int nname) 755 { 756 return devwalk(c, nc, name, nname, nil, 0, usbgen); 757 } 758 759 static int 760 usbstat(Chan *c, uchar *db, int n) 761 { 762 return devstat(c, db, n, nil, 0, usbgen); 763 } 764 765 /* 766 * µs for the given transfer, for bandwidth allocation. 767 * This is a very rough worst case for what 5.11.3 768 * of the usb 2.0 spec says. 769 * Also, we are using maxpkt and not actual transfer sizes. 770 * Only when we are sure we 771 * are not exceeding b/w might we consider adjusting it. 772 */ 773 static ulong 774 usbload(int speed, int maxpkt) 775 { 776 enum{ Hostns = 1000, Hubns = 333 }; 777 ulong l; 778 ulong bs; 779 780 l = 0; 781 bs = 10UL * maxpkt; 782 switch(speed){ 783 case Highspeed: 784 l = 55*8*2 + 2 * (3 + bs) + Hostns; 785 break; 786 case Fullspeed: 787 l = 9107 + 84 * (4 + bs) + Hostns; 788 break; 789 case Lowspeed: 790 l = 64107 + 2 * Hubns + 667 * (3 + bs) + Hostns; 791 break; 792 default: 793 print("usbload: bad speed %d\n", speed); 794 /* let it run */ 795 } 796 return l / 1000UL; /* in µs */ 797 } 798 799 static Chan* 800 usbopen(Chan *c, int omode) 801 { 802 int q; 803 Ep *ep; 804 int mode; 805 806 mode = openmode(omode); 807 q = QID(c->qid); 808 809 if(q >= Qep0dir && qid2epidx(q) < 0) 810 error(Eio); 811 if(q < Qep0dir || isqtype(q, Qepctl) || isqtype(q, Qepdir)) 812 return devopen(c, omode, nil, 0, usbgen); 813 814 ep = getep(qid2epidx(q)); 815 if(ep == nil) 816 error(Eio); 817 deprint("usbopen q %#x fid %d omode %d\n", q, c->fid, mode); 818 if(waserror()){ 819 putep(ep); 820 nexterror(); 821 } 822 qlock(ep); 823 if(ep->inuse){ 824 qunlock(ep); 825 error(Einuse); 826 } 827 ep->inuse = 1; 828 qunlock(ep); 829 if(waserror()){ 830 ep->inuse = 0; 831 nexterror(); 832 } 833 if(mode != OREAD && ep->mode == OREAD) 834 error(Eperm); 835 if(mode != OWRITE && ep->mode == OWRITE) 836 error(Eperm); 837 if(ep->ttype == Tnone) 838 error(Enotconf); 839 ep->clrhalt = 0; 840 ep->rhrepl = -1; 841 if(ep->load == 0) 842 ep->load = usbload(ep->dev->speed, ep->maxpkt); 843 ep->hp->epopen(ep); 844 845 poperror(); /* ep->inuse */ 846 poperror(); /* don't putep(): ref kept for fid using the ep. */ 847 848 c->mode = mode; 849 c->flag |= COPEN; 850 c->offset = 0; 851 c->aux = nil; /* paranoia */ 852 return c; 853 } 854 855 static void 856 epclose(Ep *ep) 857 { 858 qlock(ep); 859 if(waserror()){ 860 qunlock(ep); 861 nexterror(); 862 } 863 if(ep->inuse){ 864 ep->hp->epclose(ep); 865 ep->inuse = 0; 866 } 867 qunlock(ep); 868 poperror(); 869 } 870 871 static void 872 usbclose(Chan *c) 873 { 874 int q; 875 Ep *ep; 876 877 q = QID(c->qid); 878 if(q < Qep0dir || isqtype(q, Qepctl) || isqtype(q, Qepdir)) 879 return; 880 881 ep = getep(qid2epidx(q)); 882 if(ep == nil) 883 return; 884 deprint("usbclose q %#x fid %d ref %ld\n", q, c->fid, ep->ref); 885 if(waserror()){ 886 putep(ep); 887 nexterror(); 888 } 889 if(c->flag & COPEN){ 890 free(c->aux); 891 c->aux = nil; 892 epclose(ep); 893 putep(ep); /* release ref kept since usbopen */ 894 c->flag &= ~COPEN; 895 } 896 poperror(); 897 putep(ep); 898 } 899 900 static long 901 ctlread(Chan *c, void *a, long n, vlong offset) 902 { 903 int q; 904 char *s; 905 char *us; 906 char *se; 907 Ep *ep; 908 int i; 909 910 q = QID(c->qid); 911 us = s = smalloc(READSTR); 912 se = s + READSTR; 913 if(waserror()){ 914 free(us); 915 nexterror(); 916 } 917 if(q == Qctl) 918 for(i = 0; i < epmax; i++){ 919 ep = getep(i); 920 if(ep != nil){ 921 if(waserror()){ 922 putep(ep); 923 nexterror(); 924 } 925 s = seprint(s, se, "ep%d.%d ", ep->dev->nb, ep->nb); 926 s = seprintep(s, se, ep, 0); 927 poperror(); 928 } 929 putep(ep); 930 } 931 else{ 932 ep = getep(qid2epidx(q)); 933 if(ep == nil) 934 error(Eio); 935 if(waserror()){ 936 putep(ep); 937 nexterror(); 938 } 939 if(c->aux != nil){ 940 /* After a new endpoint request we read 941 * the new endpoint name back. 942 */ 943 strecpy(s, se, c->aux); 944 free(c->aux); 945 c->aux = nil; 946 }else 947 seprintep(s, se, ep, 0); 948 poperror(); 949 putep(ep); 950 } 951 n = readstr(offset, a, n, us); 952 poperror(); 953 free(us); 954 return n; 955 } 956 957 /* 958 * Fake root hub emulation. 959 */ 960 static long 961 rhubread(Ep *ep, void *a, long n) 962 { 963 char *b; 964 965 if(ep->dev->isroot == 0 || ep->nb != 0 || n < 2) 966 return -1; 967 if(ep->rhrepl < 0) 968 return -1; 969 970 b = a; 971 memset(b, 0, n); 972 PUT2(b, ep->rhrepl); 973 ep->rhrepl = -1; 974 return n; 975 } 976 977 static long 978 rhubwrite(Ep *ep, void *a, long n) 979 { 980 uchar *s; 981 int cmd; 982 int feature; 983 int port; 984 Hci *hp; 985 986 if(ep->dev == nil || ep->dev->isroot == 0 || ep->nb != 0) 987 return -1; 988 if(n != Rsetuplen) 989 error("root hub is a toy hub"); 990 ep->rhrepl = -1; 991 s = a; 992 if(s[Rtype] != (Rh2d|Rclass|Rother) && s[Rtype] != (Rd2h|Rclass|Rother)) 993 error("root hub is a toy hub"); 994 hp = ep->hp; 995 cmd = s[Rreq]; 996 feature = GET2(s+Rvalue); 997 port = GET2(s+Rindex); 998 if(port < 1 || port > hp->nports) 999 error("bad hub port number"); 1000 switch(feature){ 1001 case Rportenable: 1002 ep->rhrepl = hp->portenable(hp, port, cmd == Rsetfeature); 1003 break; 1004 case Rportreset: 1005 ep->rhrepl = hp->portreset(hp, port, cmd == Rsetfeature); 1006 break; 1007 case Rgetstatus: 1008 ep->rhrepl = hp->portstatus(hp, port); 1009 break; 1010 default: 1011 ep->rhrepl = 0; 1012 } 1013 return n; 1014 } 1015 1016 static long 1017 usbread(Chan *c, void *a, long n, vlong offset) 1018 { 1019 int q; 1020 Ep *ep; 1021 int nr; 1022 1023 q = QID(c->qid); 1024 1025 if(c->qid.type == QTDIR) 1026 return devdirread(c, a, n, nil, 0, usbgen); 1027 1028 if(q == Qctl || isqtype(q, Qepctl)) 1029 return ctlread(c, a, n, offset); 1030 1031 ep = getep(qid2epidx(q)); 1032 if(ep == nil) 1033 error(Eio); 1034 if(waserror()){ 1035 putep(ep); 1036 nexterror(); 1037 } 1038 if(ep->dev->state == Ddetach) 1039 error(Edetach); 1040 if(ep->mode == OWRITE || ep->inuse == 0) 1041 error(Ebadusefd); 1042 switch(ep->ttype){ 1043 case Tnone: 1044 error("endpoint not configured"); 1045 case Tctl: 1046 nr = rhubread(ep, a, n); 1047 if(nr >= 0){ 1048 n = nr; 1049 break; 1050 } 1051 /* else fall */ 1052 default: 1053 ddeprint("\nusbread q %#x fid %d cnt %ld off %lld\n",q,c->fid,n,offset); 1054 n = ep->hp->epread(ep, a, n); 1055 break; 1056 } 1057 poperror(); 1058 putep(ep); 1059 return n; 1060 } 1061 1062 static long 1063 pow2(int n) 1064 { 1065 return 1 << n; 1066 } 1067 1068 static void 1069 setmaxpkt(Ep *ep, char* s) 1070 { 1071 long spp; /* samples per packet */ 1072 1073 if(ep->dev->speed == Highspeed) 1074 spp = (ep->hz * ep->pollival * ep->ntds + 7999) / 8000; 1075 else 1076 spp = (ep->hz * ep->pollival + 999) / 1000; 1077 ep->maxpkt = spp * ep->samplesz; 1078 deprint("usb: %s: setmaxpkt: hz %ld poll %ld" 1079 " ntds %d %s speed -> spp %ld maxpkt %ld\n", s, 1080 ep->hz, ep->pollival, ep->ntds, spname[ep->dev->speed], 1081 spp, ep->maxpkt); 1082 if(ep->maxpkt > 1024){ 1083 print("usb: %s: maxpkt %ld > 1024. truncating\n", s, ep->maxpkt); 1084 ep->maxpkt = 1024; 1085 } 1086 } 1087 1088 /* 1089 * Many endpoint ctls. simply update the portable representation 1090 * of the endpoint. The actual controller driver will look 1091 * at them to setup the endpoints as dictated. 1092 */ 1093 static long 1094 epctl(Ep *ep, Chan *c, void *a, long n) 1095 { 1096 int i, l, mode, nb, tt; 1097 char *b, *s; 1098 Cmdbuf *cb; 1099 Cmdtab *ct; 1100 Ep *nep; 1101 Udev *d; 1102 static char *Info = "info "; 1103 1104 d = ep->dev; 1105 1106 cb = parsecmd(a, n); 1107 if(waserror()){ 1108 free(cb); 1109 nexterror(); 1110 } 1111 ct = lookupcmd(cb, epctls, nelem(epctls)); 1112 if(ct == nil) 1113 error(Ebadctl); 1114 i = ct->index; 1115 if(i == CMnew || i == CMspeed || i == CMhub || i == CMpreset) 1116 if(ep != ep->ep0) 1117 error("allowed only on a setup endpoint"); 1118 if(i != CMclrhalt && i != CMdetach && i != CMdebugep && i != CMname) 1119 if(ep != ep->ep0 && ep->inuse != 0) 1120 error("must configure before using"); 1121 switch(i){ 1122 case CMnew: 1123 deprint("usb epctl %s\n", cb->f[0]); 1124 nb = strtol(cb->f[1], nil, 0); 1125 if(nb < 0 || nb >= Ndeveps) 1126 error("bad endpoint number"); 1127 tt = name2ttype(cb->f[2]); 1128 if(tt == Tnone) 1129 error("unknown endpoint type"); 1130 mode = name2mode(cb->f[3]); 1131 if(mode < 0) 1132 error("unknown i/o mode"); 1133 newdevep(ep, nb, tt, mode); 1134 break; 1135 case CMnewdev: 1136 deprint("usb epctl %s\n", cb->f[0]); 1137 if(ep != ep->ep0 || d->ishub == 0) 1138 error("not a hub setup endpoint"); 1139 l = name2speed(cb->f[1]); 1140 if(l == Nospeed) 1141 error("speed must be full|low|high"); 1142 nep = newdev(ep->hp, 0, 0); 1143 nep->dev->speed = l; 1144 if(nep->dev->speed != Lowspeed) 1145 nep->maxpkt = 64; /* assume full speed */ 1146 nep->dev->hub = d->nb; 1147 nep->dev->port = atoi(cb->f[2]); 1148 /* next read request will read 1149 * the name for the new endpoint 1150 */ 1151 l = sizeof(up->genbuf); 1152 snprint(up->genbuf, l, "ep%d.%d", nep->dev->nb, nep->nb); 1153 kstrdup(&c->aux, up->genbuf); 1154 break; 1155 case CMhub: 1156 deprint("usb epctl %s\n", cb->f[0]); 1157 d->ishub = 1; 1158 break; 1159 case CMspeed: 1160 l = name2speed(cb->f[1]); 1161 deprint("usb epctl %s %d\n", cb->f[0], l); 1162 if(l == Nospeed) 1163 error("speed must be full|low|high"); 1164 qlock(ep->ep0); 1165 d->speed = l; 1166 qunlock(ep->ep0); 1167 break; 1168 case CMmaxpkt: 1169 l = strtoul(cb->f[1], nil, 0); 1170 deprint("usb epctl %s %d\n", cb->f[0], l); 1171 if(l < 1 || l > 1024) 1172 error("maxpkt not in [1:1024]"); 1173 qlock(ep); 1174 ep->maxpkt = l; 1175 qunlock(ep); 1176 break; 1177 case CMntds: 1178 l = strtoul(cb->f[1], nil, 0); 1179 deprint("usb epctl %s %d\n", cb->f[0], l); 1180 if(l < 1 || l > 3) 1181 error("ntds not in [1:3]"); 1182 qlock(ep); 1183 ep->ntds = l; 1184 qunlock(ep); 1185 break; 1186 case CMpollival: 1187 if(ep->ttype != Tintr && ep->ttype != Tiso) 1188 error("not an intr or iso endpoint"); 1189 l = strtoul(cb->f[1], nil, 0); 1190 deprint("usb epctl %s %d\n", cb->f[0], l); 1191 if(ep->ttype == Tiso || 1192 (ep->ttype == Tintr && ep->dev->speed == Highspeed)){ 1193 if(l < 1 || l > 16) 1194 error("pollival power not in [1:16]"); 1195 l = pow2(l-1); 1196 }else 1197 if(l < 1 || l > 255) 1198 error("pollival not in [1:255]"); 1199 qlock(ep); 1200 ep->pollival = l; 1201 if(ep->ttype == Tiso) 1202 setmaxpkt(ep, "pollival"); 1203 qunlock(ep); 1204 break; 1205 case CMsamplesz: 1206 if(ep->ttype != Tiso) 1207 error("not an iso endpoint"); 1208 l = strtoul(cb->f[1], nil, 0); 1209 deprint("usb epctl %s %d\n", cb->f[0], l); 1210 if(l <= 0 || l > 8) 1211 error("samplesz not in [1:8]"); 1212 qlock(ep); 1213 ep->samplesz = l; 1214 setmaxpkt(ep, "samplesz"); 1215 qunlock(ep); 1216 break; 1217 case CMhz: 1218 if(ep->ttype != Tiso) 1219 error("not an iso endpoint"); 1220 l = strtoul(cb->f[1], nil, 0); 1221 deprint("usb epctl %s %d\n", cb->f[0], l); 1222 if(l <= 0 || l > 100000) 1223 error("hz not in [1:100000]"); 1224 qlock(ep); 1225 ep->hz = l; 1226 setmaxpkt(ep, "hz"); 1227 qunlock(ep); 1228 break; 1229 case CMclrhalt: 1230 qlock(ep); 1231 deprint("usb epctl %s\n", cb->f[0]); 1232 ep->clrhalt = 1; 1233 qunlock(ep); 1234 break; 1235 case CMinfo: 1236 deprint("usb epctl %s\n", cb->f[0]); 1237 l = strlen(Info); 1238 s = a; 1239 if(n < l+2 || strncmp(Info, s, l) != 0) 1240 error(Ebadctl); 1241 if(n > 1024) 1242 n = 1024; 1243 b = smalloc(n); 1244 memmove(b, s+l, n-l); 1245 b[n-l] = 0; 1246 if(b[n-l-1] == '\n') 1247 b[n-l-1] = 0; 1248 qlock(ep); 1249 free(ep->info); 1250 ep->info = b; 1251 qunlock(ep); 1252 break; 1253 case CMaddress: 1254 deprint("usb epctl %s\n", cb->f[0]); 1255 ep->dev->state = Denabled; 1256 break; 1257 case CMdetach: 1258 if(ep->dev->isroot != 0) 1259 error("can't detach a root hub"); 1260 deprint("usb epctl %s ep%d.%d\n", 1261 cb->f[0], ep->dev->nb, ep->nb); 1262 ep->dev->state = Ddetach; 1263 /* Release file system ref. for its endpoints */ 1264 for(i = 0; i < nelem(ep->dev->eps); i++) 1265 putep(ep->dev->eps[i]); 1266 break; 1267 case CMdebugep: 1268 if(strcmp(cb->f[1], "on") == 0) 1269 ep->debug = 1; 1270 else if(strcmp(cb->f[1], "off") == 0) 1271 ep->debug = 0; 1272 else 1273 ep->debug = strtoul(cb->f[1], nil, 0); 1274 print("usb: ep%d.%d debug %d\n", 1275 ep->dev->nb, ep->nb, ep->debug); 1276 break; 1277 case CMname: 1278 deprint("usb epctl %s %s\n", cb->f[0], cb->f[1]); 1279 validname(cb->f[1], 0); 1280 kstrdup(&ep->name, cb->f[1]); 1281 break; 1282 case CMtmout: 1283 deprint("usb epctl %s\n", cb->f[0]); 1284 if(ep->ttype == Tiso || ep->ttype == Tctl) 1285 error("ctl ignored for this endpoint type"); 1286 ep->tmout = strtoul(cb->f[1], nil, 0); 1287 if(ep->tmout != 0 && ep->tmout < Xfertmout) 1288 ep->tmout = Xfertmout; 1289 break; 1290 case CMpreset: 1291 deprint("usb epctl %s\n", cb->f[0]); 1292 if(ep->ttype != Tctl) 1293 error("not a control endpoint"); 1294 if(ep->dev->state != Denabled) 1295 error("forbidden on devices not enabled"); 1296 ep->dev->state = Dreset; 1297 break; 1298 default: 1299 panic("usb: unknown epctl %d", ct->index); 1300 } 1301 free(cb); 1302 poperror(); 1303 return n; 1304 } 1305 1306 static long 1307 usbctl(void *a, long n) 1308 { 1309 Cmdtab *ct; 1310 Cmdbuf *cb; 1311 Ep *ep; 1312 int i; 1313 1314 cb = parsecmd(a, n); 1315 if(waserror()){ 1316 free(cb); 1317 nexterror(); 1318 } 1319 ct = lookupcmd(cb, usbctls, nelem(usbctls)); 1320 dprint("usb ctl %s\n", cb->f[0]); 1321 switch(ct->index){ 1322 case CMdebug: 1323 if(strcmp(cb->f[1], "on") == 0) 1324 debug = 1; 1325 else if(strcmp(cb->f[1], "off") == 0) 1326 debug = 0; 1327 else 1328 debug = strtol(cb->f[1], nil, 0); 1329 print("usb: debug %d\n", debug); 1330 for(i = 0; i < epmax; i++) 1331 if((ep = getep(i)) != nil){ 1332 ep->hp->debug(ep->hp, debug); 1333 putep(ep); 1334 } 1335 break; 1336 case CMdump: 1337 dumpeps(); 1338 break; 1339 } 1340 free(cb); 1341 poperror(); 1342 return n; 1343 } 1344 1345 static long 1346 ctlwrite(Chan *c, void *a, long n) 1347 { 1348 int q; 1349 Ep *ep; 1350 1351 q = QID(c->qid); 1352 if(q == Qctl) 1353 return usbctl(a, n); 1354 1355 ep = getep(qid2epidx(q)); 1356 if(ep == nil) 1357 error(Eio); 1358 if(waserror()){ 1359 putep(ep); 1360 nexterror(); 1361 } 1362 if(ep->dev->state == Ddetach) 1363 error(Edetach); 1364 if(isqtype(q, Qepctl) && c->aux != nil){ 1365 /* Be sure we don't keep a cloned ep name */ 1366 free(c->aux); 1367 c->aux = nil; 1368 error("read, not write, expected"); 1369 } 1370 n = epctl(ep, c, a, n); 1371 putep(ep); 1372 poperror(); 1373 return n; 1374 } 1375 1376 static long 1377 usbwrite(Chan *c, void *a, long n, vlong off) 1378 { 1379 int nr, q; 1380 Ep *ep; 1381 1382 if(c->qid.type == QTDIR) 1383 error(Eisdir); 1384 1385 q = QID(c->qid); 1386 1387 if(q == Qctl || isqtype(q, Qepctl)) 1388 return ctlwrite(c, a, n); 1389 1390 ep = getep(qid2epidx(q)); 1391 if(ep == nil) 1392 error(Eio); 1393 if(waserror()){ 1394 putep(ep); 1395 nexterror(); 1396 } 1397 if(ep->dev->state == Ddetach) 1398 error(Edetach); 1399 if(ep->mode == OREAD || ep->inuse == 0) 1400 error(Ebadusefd); 1401 1402 switch(ep->ttype){ 1403 case Tnone: 1404 error("endpoint not configured"); 1405 case Tctl: 1406 nr = rhubwrite(ep, a, n); 1407 if(nr >= 0){ 1408 n = nr; 1409 break; 1410 } 1411 /* else fall */ 1412 default: 1413 ddeprint("\nusbwrite q %#x fid %d cnt %ld off %lld\n",q, c->fid, n, off); 1414 ep->hp->epwrite(ep, a, n); 1415 } 1416 putep(ep); 1417 poperror(); 1418 return n; 1419 } 1420 1421 Block* 1422 usbbread(Chan *c, long n, ulong offset) 1423 { 1424 Block *bp; 1425 1426 bp = allocb(n); 1427 if(bp == 0) 1428 error(Enomem); 1429 if(waserror()) { 1430 freeb(bp); 1431 nexterror(); 1432 } 1433 bp->wp += usbread(c, bp->wp, n, offset); 1434 poperror(); 1435 return bp; 1436 } 1437 1438 long 1439 usbbwrite(Chan *c, Block *bp, ulong offset) 1440 { 1441 long n; 1442 1443 if(waserror()) { 1444 freeb(bp); 1445 nexterror(); 1446 } 1447 n = usbwrite(c, bp->rp, BLEN(bp), offset); 1448 poperror(); 1449 freeb(bp); 1450 1451 return n; 1452 } 1453 1454 void 1455 usbshutdown(void) 1456 { 1457 Hci *hp; 1458 int i; 1459 1460 for(i = 0; i < Nhcis; i++){ 1461 hp = hcis[i]; 1462 if(hp == nil) 1463 continue; 1464 if(hp->shutdown == nil) 1465 print("#u: no shutdown function for %s\n", hp->type); 1466 else 1467 hp->shutdown(hp); 1468 } 1469 } 1470 1471 Dev usbdevtab = { 1472 L'u', 1473 "usb", 1474 1475 usbreset, 1476 usbinit, 1477 usbshutdown, 1478 usbattach, 1479 usbwalk, 1480 usbstat, 1481 usbopen, 1482 devcreate, 1483 usbclose, 1484 usbread, 1485 usbbread, 1486 usbwrite, 1487 usbbwrite, 1488 devremove, 1489 devwstat, 1490 }; 1491