devusb.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "io.h"
  7. #include "../port/error.h"
  8. #include "usb.h"
  9. static int debug = 0;
  10. #define Chatty 1
  11. #define DPRINT if(Chatty)print
  12. #define XPRINT if(debug)iprint
  13. Usbhost* usbhost[MaxUsb];
  14. static char *devstates[] = {
  15. [Disabled] "Disabled",
  16. [Attached] "Attached",
  17. [Enabled] "Enabled",
  18. [Assigned] "Assigned",
  19. [Configured] "Configured",
  20. };
  21. static char Ebadusbmsg[] = "invalid parameters to USB ctl message";
  22. enum
  23. {
  24. Qtopdir = 0,
  25. Q2nd,
  26. Qnew,
  27. Qport,
  28. Q3rd,
  29. Qctl,
  30. Qstatus,
  31. Qep0,
  32. /* other endpoint files */
  33. };
  34. /*
  35. * Qid path is:
  36. * 8 bits of file type (qids above)
  37. * 8 bits of slot number; default address 0 used for per-controller files
  38. * 4 bits of controller number
  39. */
  40. enum {
  41. TYPEBITS = 8,
  42. SLOTBITS = 8,
  43. CTLRBITS = 4,
  44. SLOTSHIFT = TYPEBITS,
  45. CTLRSHIFT = SLOTSHIFT+SLOTBITS,
  46. TYPEMASK = (1<<TYPEBITS)-1,
  47. SLOTMASK = (1<<SLOTBITS)-1,
  48. CTLRMASK = (1<<CTLRBITS)-1,
  49. };
  50. #define TYPE(q) (((ulong)(q).path)&TYPEMASK)
  51. #define SLOT(q) ((((ulong)(q).path)>>SLOTSHIFT)&SLOTMASK)
  52. #define CTLR(q) ((((ulong)(q).path)>>CTLRSHIFT)&CTLRMASK)
  53. #define PATH(t, s, c) ((t)|((s)<<SLOTSHIFT)|((c)<<CTLRSHIFT))
  54. static Dirtab usbdir2[] = {
  55. "new", {Qnew}, 0, 0666,
  56. "port", {Qport}, 0, 0666,
  57. };
  58. static Dirtab usbdir3[]={
  59. "ctl", {Qctl}, 0, 0666,
  60. "status", {Qstatus}, 0, 0444,
  61. "setup", {Qep0}, 0, 0666,
  62. /* epNdata names are generated on demand */
  63. };
  64. enum
  65. {
  66. PMdisable,
  67. PMenable,
  68. PMreset,
  69. };
  70. enum
  71. {
  72. CMclass,
  73. CMdata,
  74. CMdebug,
  75. CMep,
  76. CMmaxpkt,
  77. CMadjust,
  78. CMspeed,
  79. CMunstall,
  80. };
  81. static Cmdtab usbportmsg[] =
  82. {
  83. PMdisable, "disable", 2,
  84. PMenable, "enable", 2,
  85. PMreset, "reset", 2,
  86. };
  87. static Cmdtab usbctlmsg[] =
  88. {
  89. CMclass, "class", 0,
  90. CMdata, "data", 3,
  91. CMdebug, "debug", 3,
  92. CMep, "ep", 6,
  93. CMmaxpkt, "maxpkt", 3,
  94. CMadjust, "adjust", 3,
  95. CMspeed, "speed", 2,
  96. CMunstall, "unstall", 2,
  97. };
  98. static struct
  99. {
  100. char* type;
  101. int (*reset)(Usbhost*);
  102. } usbtypes[MaxUsb+1];
  103. void
  104. addusbtype(char* t, int (*r)(Usbhost*))
  105. {
  106. static int ntype;
  107. if(ntype == MaxUsb)
  108. panic("too many USB host interface types");
  109. usbtypes[ntype].type = t;
  110. usbtypes[ntype].reset = r;
  111. ntype++;
  112. }
  113. static Udev*
  114. usbdeviceofslot(Usbhost *uh, int s)
  115. {
  116. if(s < 0 || s > nelem(uh->dev))
  117. return nil;
  118. return uh->dev[s];
  119. }
  120. static Udev*
  121. usbdevice(Chan *c)
  122. {
  123. int bus;
  124. Udev *d;
  125. Usbhost *uh;
  126. bus = CTLR(c->qid);
  127. if(bus > nelem(usbhost) || (uh = usbhost[bus]) == nil) {
  128. error(Egreg);
  129. return nil; /* for compiler */
  130. }
  131. d = usbdeviceofslot(uh, SLOT(c->qid));
  132. if(d == nil || d->id != c->qid.vers || d->state == Disabled)
  133. error(Ehungup);
  134. return d;
  135. }
  136. static Endpt *
  137. devendpt(Udev *d, int id, int add)
  138. {
  139. Usbhost *uh;
  140. Endpt *e, **p;
  141. p = &d->ep[id&0xF];
  142. lock(d);
  143. e = *p;
  144. if(e != nil){
  145. incref(e);
  146. XPRINT("incref(0x%p) in devendpt, new value %ld\n", e, e->ref);
  147. unlock(d);
  148. return e;
  149. }
  150. unlock(d);
  151. if(!add)
  152. return nil;
  153. e = mallocz(sizeof(*e), 1);
  154. e->ref = 1;
  155. e->x = id&0xF;
  156. e->id = id;
  157. e->sched = -1;
  158. e->maxpkt = 8;
  159. e->nbuf = 1;
  160. e->dev = d;
  161. e->active = 0;
  162. uh = d->uh;
  163. uh->epalloc(uh, e);
  164. lock(d);
  165. if(*p != nil){
  166. incref(*p);
  167. XPRINT("incref(0x%p) in devendpt, new value %ld\n", *p, (*p)->ref);
  168. unlock(d);
  169. uh->epfree(uh, e);
  170. free(e);
  171. return *p;
  172. }
  173. *p = e;
  174. unlock(d);
  175. e->rq = qopen(8*1024, 0, nil, e);
  176. e->wq = qopen(8*1024, 0, nil, e);
  177. return e;
  178. }
  179. static void
  180. freept(Endpt *e)
  181. {
  182. Usbhost *uh;
  183. if(e != nil && decref(e) == 0){
  184. XPRINT("freept(%d,%d)\n", e->dev->x, e->x);
  185. uh = e->dev->uh;
  186. uh->epclose(uh, e);
  187. e->dev->ep[e->x] = nil;
  188. uh->epfree(uh, e);
  189. free(e);
  190. }
  191. }
  192. static Udev*
  193. usbnewdevice(Usbhost *uh)
  194. {
  195. int i;
  196. Udev *d;
  197. Endpt *e;
  198. d = nil;
  199. qlock(uh);
  200. if(waserror()){
  201. qunlock(uh);
  202. nexterror();
  203. }
  204. for(i=0; i<nelem(uh->dev); i++)
  205. if(uh->dev[i] == nil){
  206. uh->idgen++;
  207. d = mallocz(sizeof(*d), 1);
  208. d->uh = uh;
  209. d->ref = 1;
  210. d->x = i;
  211. d->id = (uh->idgen << 8) | i;
  212. d->state = Enabled;
  213. XPRINT("calling devendpt in usbnewdevice\n");
  214. e = devendpt(d, 0, 1); /* always provide control endpoint 0 */
  215. e->mode = ORDWR;
  216. e->iso = 0;
  217. e->sched = -1;
  218. uh->dev[i] = d;
  219. break;
  220. }
  221. poperror();
  222. qunlock(uh);
  223. return d;
  224. }
  225. static void
  226. freedev(Udev *d, int ept)
  227. {
  228. int i;
  229. Endpt *e;
  230. Usbhost *uh;
  231. uh = d->uh;
  232. if(decref(d) == 0){
  233. XPRINT("freedev 0x%p, 0\n", d);
  234. for(i=0; i<nelem(d->ep); i++)
  235. freept(d->ep[i]);
  236. if(d->x >= 0)
  237. uh->dev[d->x] = nil;
  238. free(d);
  239. } else {
  240. if(ept >= 0 && ept < nelem(d->ep)){
  241. e = d->ep[ept];
  242. XPRINT("freedev, freept 0x%p\n", e);
  243. if(e != nil)
  244. uh->epclose(uh, e);
  245. }
  246. }
  247. }
  248. static int
  249. usbgen(Chan *c, char *, Dirtab*, int, int s, Dir *dp)
  250. {
  251. Qid q;
  252. Udev *d;
  253. Endpt *e;
  254. Dirtab *tab;
  255. Usbhost *uh;
  256. int t, bus, slot, perm;
  257. /*
  258. * Top level directory contains the controller names.
  259. */
  260. if(c->qid.path == Qtopdir){
  261. if(s == DEVDOTDOT){
  262. mkqid(&q, Qtopdir, 0, QTDIR);
  263. devdir(c, q, "#U", 0, eve, 0555, dp);
  264. return 1;
  265. }
  266. if(s >= nelem(usbhost) || usbhost[s] == nil)
  267. return -1;
  268. mkqid(&q, PATH(Q2nd, 0, s), 0, QTDIR);
  269. snprint(up->genbuf, sizeof up->genbuf, "usb%d", s);
  270. devdir(c, q, up->genbuf, 0, eve, 0555, dp);
  271. return 1;
  272. }
  273. bus = CTLR(c->qid);
  274. if(bus >= nelem(usbhost) || (uh = usbhost[bus]) == nil)
  275. return -1;
  276. /*
  277. * Second level contains "new", "port", and a numbered
  278. * directory for each enumerated device on the bus.
  279. */
  280. t = TYPE(c->qid);
  281. if(t < Q3rd){
  282. if(s == DEVDOTDOT){
  283. mkqid(&q, Qtopdir, 0, QTDIR);
  284. devdir(c, q, "#U", 0, eve, 0555, dp);
  285. return 1;
  286. }
  287. if(s < nelem(usbdir2)){
  288. d = uh->dev[0];
  289. if(d == nil)
  290. return -1;
  291. tab = &usbdir2[s];
  292. mkqid(&q, PATH(tab->qid.path, 0, bus), d->id, QTFILE);
  293. devdir(c, q, tab->name, tab->length, eve, tab->perm, dp);
  294. return 1;
  295. }
  296. s -= nelem(usbdir2);
  297. if(s >= 0 && s < nelem(uh->dev)) {
  298. d = uh->dev[s];
  299. if(d == nil)
  300. return 0;
  301. sprint(up->genbuf, "%d", s);
  302. mkqid(&q, PATH(Q3rd, s, bus), d->id, QTDIR);
  303. devdir(c, q, up->genbuf, 0, eve, 0555, dp);
  304. return 1;
  305. }
  306. return -1;
  307. }
  308. /*
  309. * Third level.
  310. */
  311. slot = SLOT(c->qid);
  312. if(s == DEVDOTDOT) {
  313. mkqid(&q, PATH(Q2nd, 0, bus), c->qid.vers, QTDIR);
  314. snprint(up->genbuf, sizeof up->genbuf, "usb%d", bus);
  315. devdir(c, q, up->genbuf, 0, eve, 0555, dp);
  316. return 1;
  317. }
  318. if(s < nelem(usbdir3)) {
  319. tab = &usbdir3[s];
  320. mkqid(&q, PATH(tab->qid.path, slot, bus), c->qid.vers, QTFILE);
  321. devdir(c, q, tab->name, tab->length, eve, tab->perm, dp);
  322. return 1;
  323. }
  324. s -= nelem(usbdir3);
  325. /* active endpoints */
  326. d = usbdeviceofslot(uh, slot);
  327. if(d == nil || s >= nelem(d->ep))
  328. return -1;
  329. if(s == 0 || (e = d->ep[s]) == nil) /* ep0data is called "setup" */
  330. return 0;
  331. sprint(up->genbuf, "ep%ddata", s);
  332. mkqid(&q, PATH(Qep0+s, slot, bus), c->qid.vers, QTFILE);
  333. switch(e->mode) {
  334. case OREAD:
  335. perm = 0444;
  336. break;
  337. case OWRITE:
  338. perm = 0222;
  339. break;
  340. default:
  341. perm = 0666;
  342. break;
  343. }
  344. devdir(c, q, up->genbuf, e->buffered, eve, perm, dp);
  345. return 1;
  346. }
  347. static Usbhost*
  348. usbprobe(int cardno, int ctlrno)
  349. {
  350. Usbhost *uh;
  351. char buf[128], *ebuf, name[64], *p, *type;
  352. uh = malloc(sizeof(Usbhost));
  353. memset(uh, 0, sizeof(Usbhost));
  354. uh->tbdf = BUSUNKNOWN;
  355. if(cardno < 0){
  356. if(isaconfig("usb", ctlrno, uh) == 0){
  357. free(uh);
  358. return nil;
  359. }
  360. for(cardno = 0; usbtypes[cardno].type; cardno++){
  361. type = uh->type;
  362. if(type==nil || *type==0)
  363. type = "uhci";
  364. if(cistrcmp(usbtypes[cardno].type, type))
  365. continue;
  366. break;
  367. }
  368. }
  369. if(cardno >= MaxUsb || usbtypes[cardno].type == nil){
  370. free(uh);
  371. return nil;
  372. }
  373. if(usbtypes[cardno].reset(uh) < 0){
  374. free(uh);
  375. return nil;
  376. }
  377. /*
  378. * IRQ2 doesn't really exist, it's used to gang the interrupt
  379. * controllers together. A device set to IRQ2 will appear on
  380. * the second interrupt controller as IRQ9.
  381. */
  382. if(uh->irq == 2)
  383. uh->irq = 9;
  384. snprint(name, sizeof(name), "usb%d", ctlrno);
  385. intrenable(uh->irq, uh->interrupt, uh, uh->tbdf, name);
  386. ebuf = buf + sizeof buf;
  387. p = seprint(buf, ebuf, "#U/usb%d: %s: port 0x%luX irq %d", ctlrno, usbtypes[cardno].type, uh->port, uh->irq);
  388. if(uh->mem)
  389. p = seprint(p, ebuf, " addr 0x%luX", PADDR(uh->mem));
  390. if(uh->size)
  391. seprint(p, ebuf, " size 0x%luX", uh->size);
  392. print("%s\n", buf);
  393. return uh;
  394. }
  395. static void
  396. usbreset(void)
  397. {
  398. int cardno, ctlrno;
  399. Usbhost *uh;
  400. for(ctlrno = 0; ctlrno < MaxUsb; ctlrno++){
  401. if((uh = usbprobe(-1, ctlrno)) == nil)
  402. continue;
  403. usbhost[ctlrno] = uh;
  404. }
  405. if(getconf("*nousbprobe"))
  406. return;
  407. cardno = ctlrno = 0;
  408. while(usbtypes[cardno].type != nil && ctlrno < MaxUsb){
  409. if(usbhost[ctlrno] != nil){
  410. ctlrno++;
  411. continue;
  412. }
  413. if((uh = usbprobe(cardno, ctlrno)) == nil){
  414. cardno++;
  415. continue;
  416. }
  417. usbhost[ctlrno] = uh;
  418. ctlrno++;
  419. }
  420. }
  421. void
  422. usbinit(void)
  423. {
  424. Udev *d;
  425. int ctlrno;
  426. Usbhost *uh;
  427. for(ctlrno = 0; ctlrno < MaxUsb; ctlrno++){
  428. uh = usbhost[ctlrno];
  429. if(uh == nil)
  430. continue;
  431. if(uh->init != 0)
  432. uh->init(uh);
  433. /* reserve device for configuration */
  434. d = usbnewdevice(uh);
  435. incref(d);
  436. d->state = Attached;
  437. }
  438. }
  439. Chan *
  440. usbattach(char *spec)
  441. {
  442. return devattach('U', spec);
  443. }
  444. static Walkqid*
  445. usbwalk(Chan *c, Chan *nc, char **name, int nname)
  446. {
  447. return devwalk(c, nc, name, nname, nil, 0, usbgen);
  448. }
  449. static int
  450. usbstat(Chan *c, uchar *db, int n)
  451. {
  452. return devstat(c, db, n, nil, 0, usbgen);
  453. }
  454. Chan*
  455. usbopen(Chan *c, int omode)
  456. {
  457. Udev *d;
  458. Endpt *e;
  459. int f, s, type;
  460. Usbhost *uh;
  461. if(c->qid.type == QTDIR)
  462. return devopen(c, omode, nil, 0, usbgen);
  463. f = 0;
  464. type = TYPE(c->qid);
  465. if(type == Qnew){
  466. d = usbdevice(c);
  467. d = usbnewdevice(d->uh);
  468. XPRINT("usbopen, new dev 0x%p\n", d);
  469. if(d == nil) {
  470. XPRINT("usbopen failed (usbnewdevice)\n");
  471. error(Enodev);
  472. }
  473. type = Qctl;
  474. mkqid(&c->qid, PATH(type, d->x, CTLR(c->qid)), d->id, QTFILE);
  475. f = 1;
  476. }
  477. if(type < Q3rd){
  478. XPRINT("usbopen, devopen < Q3rd\n");
  479. return devopen(c, omode, nil, 0, usbgen);
  480. }
  481. d = usbdevice(c);
  482. uh = d->uh;
  483. qlock(uh);
  484. if(waserror()){
  485. qunlock(uh);
  486. nexterror();
  487. }
  488. switch(type){
  489. case Qctl:
  490. if(0&&d->busy)
  491. error(Einuse);
  492. d->busy = 1;
  493. if(!f)
  494. incref(d);
  495. XPRINT("usbopen, Qctl 0x%p\n", d);
  496. break;
  497. default:
  498. s = type - Qep0;
  499. XPRINT("usbopen, default 0x%p, %d\n", d, s);
  500. if(s >= 0 && s < nelem(d->ep)){
  501. if((e = d->ep[s]) == nil) {
  502. XPRINT("usbopen failed (endpoint)\n");
  503. error(Enodev);
  504. }
  505. XPRINT("usbopen: dev 0x%p, ept 0x%p\n", d, e);
  506. uh->epopen(uh, e);
  507. e->foffset = 0;
  508. e->toffset = 0;
  509. e->poffset = 0;
  510. e->buffered = 0;
  511. }
  512. incref(d);
  513. break;
  514. }
  515. poperror();
  516. qunlock(uh);
  517. c->mode = openmode(omode);
  518. c->flag |= COPEN;
  519. c->offset = 0;
  520. return c;
  521. }
  522. void
  523. usbclose(Chan *c)
  524. {
  525. Udev *d;
  526. int ept, type;
  527. Usbhost *uh;
  528. type = TYPE(c->qid);
  529. if(c->qid.type == QTDIR || type < Q3rd)
  530. return;
  531. d = usbdevice(c);
  532. uh = d->uh;
  533. qlock(uh);
  534. if(waserror()){
  535. qunlock(uh);
  536. nexterror();
  537. }
  538. if(type == Qctl)
  539. d->busy = 0;
  540. XPRINT("usbclose: dev 0x%p\n", d);
  541. if(c->flag & COPEN){
  542. ept = (type != Qctl) ? type - Qep0 : -1;
  543. XPRINT("usbclose: freedev 0x%p\n", d);
  544. freedev(d, ept);
  545. }
  546. poperror();
  547. qunlock(uh);
  548. }
  549. static char *
  550. epstatus(char *s, char *se, Endpt *e, int i)
  551. {
  552. char *p;
  553. p = seprint(s, se, "%2d %#6.6lux %10lud bytes %10lud blocks\n", i, e->csp, e->nbytes, e->nblocks);
  554. if(e->iso){
  555. p = seprint(p, se, "bufsize %6d buffered %6d", e->maxpkt, e->buffered);
  556. if(e->toffset)
  557. p = seprint(p, se, " offset %10lud time %19lld\n", e->toffset, e->time);
  558. p = seprint(p, se, "\n");
  559. }
  560. return p;
  561. }
  562. long
  563. usbread(Chan *c, void *a, long n, vlong offset)
  564. {
  565. int t, i;
  566. Udev *d;
  567. Endpt *e;
  568. Usbhost *uh;
  569. char *s, *se, *p;
  570. if(c->qid.type == QTDIR)
  571. return devdirread(c, a, n, nil, 0, usbgen);
  572. d = usbdevice(c);
  573. uh = d->uh;
  574. t = TYPE(c->qid);
  575. if(t >= Qep0) {
  576. t -= Qep0;
  577. if(t >= nelem(d->ep))
  578. error(Eio);
  579. e = d->ep[t];
  580. if(e == nil || e->mode == OWRITE)
  581. error(Egreg);
  582. if(t == 0) {
  583. if(e->iso)
  584. error(Egreg);
  585. e->rdata01 = 1;
  586. n = uh->read(uh, e, a, n, 0LL);
  587. if(e->setin){
  588. e->setin = 0;
  589. e->wdata01 = 1;
  590. uh->write(uh, e, "", 0, 0LL, TokOUT);
  591. }
  592. return n;
  593. }
  594. return uh->read(uh, e, a, n, offset);
  595. }
  596. s = smalloc(READSTR);
  597. se = s+READSTR;
  598. if(waserror()){
  599. free(s);
  600. nexterror();
  601. }
  602. switch(t){
  603. case Qport:
  604. uh->portinfo(uh, s, se);
  605. break;
  606. case Qctl:
  607. seprint(s, se, "%11d %11d\n", d->x, d->id);
  608. break;
  609. case Qstatus:
  610. if (d->did || d->vid)
  611. p = seprint(s, se, "%s %#6.6lux %#4.4ux %#4.4ux\n", devstates[d->state], d->csp, d->vid, d->did);
  612. else
  613. p = seprint(s, se, "%s %#6.6lux\n", devstates[d->state], d->csp);
  614. for(i=0; i<nelem(d->ep); i++) {
  615. e = d->ep[i];
  616. if(e == nil)
  617. continue;
  618. /* TO DO: freeze e */
  619. p = epstatus(p, se, e, i);
  620. }
  621. }
  622. n = readstr(offset, a, n, s);
  623. poperror();
  624. free(s);
  625. return n;
  626. }
  627. long
  628. usbwrite(Chan *c, void *a, long n, vlong offset)
  629. {
  630. Udev *d;
  631. Endpt *e;
  632. Cmdtab *ct;
  633. Cmdbuf *cb;
  634. Usbhost *uh;
  635. int id, nw, t, i;
  636. char cmd[50];
  637. if(c->qid.type == QTDIR)
  638. error(Egreg);
  639. d = usbdevice(c);
  640. uh = d->uh;
  641. t = TYPE(c->qid);
  642. switch(t){
  643. case Qport:
  644. cb = parsecmd(a, n);
  645. if(waserror()){
  646. free(cb);
  647. nexterror();
  648. }
  649. ct = lookupcmd(cb, usbportmsg, nelem(usbportmsg));
  650. id = strtol(cb->f[1], nil, 0);
  651. switch(ct->index){
  652. case PMdisable:
  653. uh->portenable(uh, id, 0);
  654. break;
  655. case PMenable:
  656. uh->portenable(uh, id, 1);
  657. break;
  658. case PMreset:
  659. uh->portreset(uh, id);
  660. break;
  661. }
  662. poperror();
  663. free(cb);
  664. return n;
  665. case Qctl:
  666. cb = parsecmd(a, n);
  667. if(waserror()){
  668. free(cb);
  669. nexterror();
  670. }
  671. ct = lookupcmd(cb, usbctlmsg, nelem(usbctlmsg));
  672. switch(ct->index){
  673. case CMspeed:
  674. d->ls = strtoul(cb->f[1], nil, 0) == 0;
  675. break;
  676. case CMclass:
  677. if (cb->nf != 4 && cb->nf != 6)
  678. cmderror(cb, Ebadusbmsg);
  679. /* class #ifc ept csp ( == class subclass proto) [vendor product] */
  680. d->npt = strtoul(cb->f[1], nil, 0); /* # of interfaces */
  681. i = strtoul(cb->f[2], nil, 0); /* endpoint */
  682. if (i < 0 || i >= nelem(d->ep)
  683. || d->npt > nelem(d->ep) || i >= d->npt)
  684. cmderror(cb, Ebadusbmsg);
  685. if (cb->nf == 6) {
  686. d->vid = strtoul(cb->f[4], nil, 0);
  687. d->did = strtoul(cb->f[5], nil, 0);
  688. }
  689. if (i == 0)
  690. d->csp = strtoul(cb->f[3], nil, 0);
  691. if(d->ep[i] == nil){
  692. XPRINT("calling devendpt in usbwrite (CMclass)\n");
  693. d->ep[i] = devendpt(d, i, 1);
  694. }
  695. d->ep[i]->csp = strtoul(cb->f[3], nil, 0);
  696. break;
  697. case CMdata:
  698. i = strtoul(cb->f[1], nil, 0);
  699. if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil)
  700. error(Ebadusbmsg);
  701. e = d->ep[i];
  702. e->wdata01 = e->rdata01 = strtoul(cb->f[2], nil, 0) != 0;
  703. break;
  704. case CMmaxpkt:
  705. i = strtoul(cb->f[1], nil, 0);
  706. if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil)
  707. error(Ebadusbmsg);
  708. e = d->ep[i];
  709. e->maxpkt = strtoul(cb->f[2], nil, 0);
  710. if(e->maxpkt > 1500)
  711. e->maxpkt = 1500;
  712. break;
  713. case CMadjust:
  714. i = strtoul(cb->f[1], nil, 0);
  715. if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil)
  716. error(Ebadusbmsg);
  717. e = d->ep[i];
  718. if (e->iso == 0)
  719. error(Eperm);
  720. i = strtoul(cb->f[2], nil, 0);
  721. /* speed may not result in change of maxpkt */
  722. if (i < (e->maxpkt-1)/e->samplesz * 1000/e->pollms
  723. || i > e->maxpkt/e->samplesz * 1000/e->pollms){
  724. snprint(cmd, sizeof(cmd), "%d < %d < %d?",
  725. (e->maxpkt-1)/e->samplesz * 1000/e->pollms,
  726. i,
  727. e->maxpkt/e->samplesz * 1000/e->pollms);
  728. error(cmd);
  729. }
  730. e->hz = i;
  731. break;
  732. case CMdebug:
  733. i = strtoul(cb->f[1], nil, 0);
  734. if(i < -1 || i >= nelem(d->ep) || d->ep[i] == nil)
  735. error(Ebadusbmsg);
  736. if (i == -1)
  737. debug = 0;
  738. else {
  739. debug = 1;
  740. e = d->ep[i];
  741. e->debug = strtoul(cb->f[2], nil, 0);
  742. }
  743. break;
  744. case CMunstall:
  745. i = strtoul(cb->f[1], nil, 0);
  746. if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil)
  747. error(Ebadusbmsg);
  748. e = d->ep[i];
  749. e->err = nil;
  750. break;
  751. case CMep:
  752. /* ep n `bulk' mode maxpkt nbuf OR
  753. * ep n period mode samplesize Hz
  754. */
  755. i = strtoul(cb->f[1], nil, 0);
  756. if(i < 0 || i >= nelem(d->ep)) {
  757. XPRINT("field 1: 0 <= %d < %d\n", i, nelem(d->ep));
  758. error(Ebadarg);
  759. }
  760. if((e = d->ep[i]) == nil){
  761. XPRINT("calling devendpt in usbwrite (CMep)\n");
  762. e = devendpt(d, i, 1);
  763. }
  764. qlock(uh);
  765. if(waserror()){
  766. freept(e);
  767. qunlock(uh);
  768. nexterror();
  769. }
  770. if(e->active)
  771. error(Eperm);
  772. if(strcmp(cb->f[2], "bulk") == 0){
  773. /* ep n `bulk' mode maxpkt nbuf */
  774. e->iso = 0;
  775. i = strtoul(cb->f[4], nil, 0);
  776. if(i < 8 || i > 1023)
  777. i = 8;
  778. e->maxpkt = i;
  779. i = strtoul(cb->f[5], nil, 0);
  780. if(i >= 1 && i <= 32)
  781. e->nbuf = i;
  782. } else {
  783. /* ep n period mode samplesize Hz */
  784. i = strtoul(cb->f[2], nil, 0);
  785. if(i > 0 && i <= 1000){
  786. e->pollms = i;
  787. }else {
  788. XPRINT("field 4: 0 <= %d <= 1000\n", i);
  789. error(Ebadarg);
  790. }
  791. i = strtoul(cb->f[4], nil, 0);
  792. if(i >= 1 && i <= 8){
  793. e->samplesz = i;
  794. }else {
  795. XPRINT("field 4: 0 < %d <= 8\n", i);
  796. error(Ebadarg);
  797. }
  798. i = strtoul(cb->f[5], nil, 0);
  799. if(i >= 1 && i*e->samplesz <= 12*1000*1000){
  800. /* Hz */
  801. e->hz = i;
  802. e->remain = 0;
  803. }else {
  804. XPRINT("field 5: 1 < %d <= 100000 Hz\n", i);
  805. error(Ebadarg);
  806. }
  807. e->maxpkt = (e->hz * e->pollms + 999)/1000 * e->samplesz;
  808. e->iso = 1;
  809. }
  810. e->mode = strcmp(cb->f[3],"r") == 0? OREAD :
  811. strcmp(cb->f[3],"w") == 0? OWRITE : ORDWR;
  812. uh->epmode(uh, e);
  813. poperror();
  814. qunlock(uh);
  815. }
  816. poperror();
  817. free(cb);
  818. return n;
  819. case Qep0: /* SETUP endpoint 0 */
  820. /* should canqlock etc */
  821. e = d->ep[0];
  822. if(e == nil || e->iso)
  823. error(Egreg);
  824. if(n < 8)
  825. error(Eio);
  826. nw = *(uchar*)a & RD2H;
  827. e->wdata01 = 0;
  828. n = uh->write(uh, e, a, n, 0LL, TokSETUP);
  829. if(nw == 0) { /* host to device: use IN[DATA1] to ack */
  830. e->rdata01 = 1;
  831. nw = uh->read(uh, e, cmd, 0LL, 8);
  832. if(nw != 0)
  833. error(Eio); /* could provide more status */
  834. }else
  835. e->setin = 1; /* two-phase */
  836. break;
  837. default: /* sends DATA[01] */
  838. t -= Qep0;
  839. if(t < 0 || t >= nelem(d->ep))
  840. error(Egreg);
  841. e = d->ep[t];
  842. if(e == nil || e->mode == OREAD)
  843. error(Egreg);
  844. n = uh->write(uh, e, a, n, offset, TokOUT);
  845. break;
  846. }
  847. return n;
  848. }
  849. Dev usbdevtab = {
  850. 'U',
  851. "usb",
  852. usbreset,
  853. usbinit,
  854. devshutdown,
  855. usbattach,
  856. usbwalk,
  857. usbstat,
  858. usbopen,
  859. devcreate,
  860. usbclose,
  861. usbread,
  862. devbread,
  863. usbwrite,
  864. devbwrite,
  865. devremove,
  866. devwstat,
  867. };