devusb.c 20 KB

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