serial.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  1. /*
  2. * This part takes care of locking except for initialization and
  3. * other threads created by the hw dep. drivers.
  4. */
  5. #include <u.h>
  6. #include <libc.h>
  7. #include <ctype.h>
  8. #include <thread.h>
  9. #include "usb.h"
  10. #include "usbfs.h"
  11. #include "serial.h"
  12. #include "prolific.h"
  13. #include "ucons.h"
  14. #include "ftdi.h"
  15. int serialdebug;
  16. enum {
  17. /* Qids. Maintain order (relative to dirtabs structs) */
  18. Qroot = 0,
  19. Qctl,
  20. Qdata,
  21. Qmax,
  22. };
  23. typedef struct Dirtab Dirtab;
  24. struct Dirtab {
  25. char *name;
  26. int mode;
  27. };
  28. static Dirtab dirtab[] = {
  29. [Qroot] "/", DMDIR|0555,
  30. [Qdata] "%s", 0660,
  31. [Qctl] "%sctl", 0664,
  32. };
  33. static int sdebug;
  34. static void
  35. serialfatal(Serial *ser)
  36. {
  37. Serialport *p;
  38. int i;
  39. dsprint(2, "serial: fatal error, detaching\n");
  40. devctl(ser->dev, "detach");
  41. for(i = 0; i < ser->nifcs; i++){
  42. p = &ser->p[i];
  43. usbfsdel(&p->fs);
  44. if(p->w4data != nil)
  45. chanclose(p->w4data);
  46. if(p->gotdata != nil)
  47. chanclose(p->gotdata);
  48. if(p->readc)
  49. chanclose(p->readc);
  50. }
  51. }
  52. /* I sleep with the lock... only way to drain in general */
  53. static void
  54. serialdrain(Serialport *p)
  55. {
  56. Serial *ser;
  57. uint baud, pipesize;
  58. ser = p->s;
  59. baud = p->baud;
  60. if(p->baud == ~0)
  61. return;
  62. if(ser->maxwtrans < 256)
  63. pipesize = 256;
  64. else
  65. pipesize = ser->maxwtrans;
  66. /* wait for the at least 256-byte pipe to clear */
  67. sleep(10 + pipesize/((1 + baud)*1000));
  68. if(ser->clearpipes != nil)
  69. ser->clearpipes(p);
  70. }
  71. /* BUG: separate reset per port */
  72. int
  73. serialreset(Serial *ser)
  74. {
  75. Serialport *p;
  76. int i;
  77. /* cmd for reset */
  78. for(i = 0; i < ser->nifcs; i++){
  79. p = &ser->p[i];
  80. serialdrain(p);
  81. }
  82. if(ser->reset != nil)
  83. ser->reset(ser);
  84. return 0;
  85. }
  86. /* call this if something goes wrong */
  87. int
  88. serialrecover(Serial *ser, char *err)
  89. {
  90. if(strstr(err, "detached") != nil)
  91. return -1;
  92. if(ser->recover > 1)
  93. serialfatal(ser);
  94. ser->recover++;
  95. if(serialreset(ser) < 0)
  96. return -1;
  97. ser->recover = 0;
  98. return 0;
  99. }
  100. static int
  101. serialctl(Serialport *p, char *cmd)
  102. {
  103. Serial *ser;
  104. int c, i, n, nf, nop, nw, par, drain, set, lines;
  105. char *f[16];
  106. uchar x;
  107. ser = p->s;
  108. drain = set = lines = 0;
  109. nf = tokenize(cmd, f, nelem(f));
  110. for(i = 0; i < nf; i++){
  111. if(strncmp(f[i], "break", 5) == 0){
  112. if(ser->setbreak != nil)
  113. ser->setbreak(p, 1);
  114. continue;
  115. }
  116. nop = 0;
  117. n = atoi(f[i]+1);
  118. c = *f[i];
  119. if (isascii(c) && isupper(c))
  120. c = tolower(c);
  121. switch(c){
  122. case 'b':
  123. drain++;
  124. p->baud = n;
  125. set++;
  126. break;
  127. case 'c':
  128. p->dcd = n;
  129. // lines++;
  130. ++nop;
  131. break;
  132. case 'd':
  133. p->dtr = n;
  134. lines++;
  135. break;
  136. case 'e':
  137. p->dsr = n;
  138. // lines++;
  139. ++nop;
  140. break;
  141. case 'f': /* flush the pipes */
  142. drain++;
  143. break;
  144. case 'h': /* hangup?? */
  145. p->rts = p->dtr = 0;
  146. lines++;
  147. fprint(2, "serial: %c, unsure ctl\n", c);
  148. break;
  149. case 'i':
  150. ++nop;
  151. break;
  152. case 'k':
  153. drain++;
  154. ser->setbreak(p, 1);
  155. sleep(n);
  156. ser->setbreak(p, 0);
  157. break;
  158. case 'l':
  159. drain++;
  160. p->bits = n;
  161. set++;
  162. break;
  163. case 'm':
  164. drain++;
  165. if(ser->modemctl != nil)
  166. ser->modemctl(p, n);
  167. if(n == 0)
  168. p->cts = 0;
  169. break;
  170. case 'n':
  171. p->blocked = n;
  172. ++nop;
  173. break;
  174. case 'p': /* extended... */
  175. if(strlen(f[i]) != 2)
  176. return -1;
  177. drain++;
  178. par = f[i][1];
  179. if(par == 'n')
  180. p->parity = 0;
  181. else if(par == 'o')
  182. p->parity = 1;
  183. else if(par == 'e')
  184. p->parity = 2;
  185. else if(par == 'm') /* mark parity */
  186. p->parity = 3;
  187. else if(par == 's') /* space parity */
  188. p->parity = 4;
  189. else
  190. return -1;
  191. set++;
  192. break;
  193. case 'q':
  194. // drain++;
  195. p->limit = n;
  196. ++nop;
  197. break;
  198. case 'r':
  199. drain++;
  200. p->rts = n;
  201. lines++;
  202. break;
  203. case 's':
  204. drain++;
  205. p->stop = n;
  206. set++;
  207. break;
  208. case 'w':
  209. /* ?? how do I put this */
  210. p->timer = n * 100000LL;
  211. ++nop;
  212. break;
  213. case 'x':
  214. if(n == 0)
  215. x = CTLS;
  216. else
  217. x = CTLQ;
  218. if(ser->wait4write != nil)
  219. nw = ser->wait4write(p, &x, 1);
  220. else
  221. nw = write(p->epout->dfd, &x, 1);
  222. if(nw != 1){
  223. serialrecover(ser, "");
  224. return -1;
  225. }
  226. break;
  227. }
  228. /*
  229. * don't print. the condition is harmless and the print
  230. * splatters all over the display.
  231. */
  232. USED(nop);
  233. if (0 && nop)
  234. fprint(2, "serial: %c, unsupported nop ctl\n", c);
  235. }
  236. if(drain)
  237. serialdrain(p);
  238. if(lines && !set){
  239. if(ser->sendlines != nil && ser->sendlines(p) < 0)
  240. return -1;
  241. } else if(set){
  242. if(ser->setparam != nil && ser->setparam(p) < 0)
  243. return -1;
  244. }
  245. return 0;
  246. }
  247. char *pformat = "noems";
  248. char *
  249. serdumpst(Serialport *p, char *buf, int bufsz)
  250. {
  251. char *e, *s;
  252. Serial *ser;
  253. ser = p->s;
  254. e = buf + bufsz;
  255. s = seprint(buf, e, "b%d ", p->baud);
  256. s = seprint(s, e, "c%d ", p->dcd); /* unimplemented */
  257. s = seprint(s, e, "d%d ", p->dtr);
  258. s = seprint(s, e, "e%d ", p->dsr); /* unimplemented */
  259. s = seprint(s, e, "l%d ", p->bits);
  260. s = seprint(s, e, "m%d ", p->mctl);
  261. if(p->parity >= 0 || p->parity < strlen(pformat))
  262. s = seprint(s, e, "p%c ", pformat[p->parity]);
  263. else
  264. s = seprint(s, e, "p%c ", '?');
  265. s = seprint(s, e, "r%d ", p->rts);
  266. s = seprint(s, e, "s%d ", p->stop);
  267. s = seprint(s, e, "i%d ", p->fifo);
  268. s = seprint(s, e, "\ndev(%d) ", 0);
  269. s = seprint(s, e, "type(%d) ", ser->type);
  270. s = seprint(s, e, "framing(%d) ", p->nframeerr);
  271. s = seprint(s, e, "overruns(%d) ", p->novererr);
  272. s = seprint(s, e, "berr(%d) ", p->nbreakerr);
  273. s = seprint(s, e, " serr(%d)\n", p->nparityerr);
  274. return s;
  275. }
  276. static int
  277. serinit(Serialport *p)
  278. {
  279. int res;
  280. res = 0;
  281. Serial *ser;
  282. ser = p->s;
  283. if(ser->init != nil)
  284. res = ser->init(p);
  285. if(ser->getparam != nil)
  286. ser->getparam(p);
  287. p->nframeerr = p->nparityerr = p->nbreakerr = p->novererr = 0;
  288. return res;
  289. }
  290. static int
  291. dwalk(Usbfs *fs, Fid *fid, char *name)
  292. {
  293. int i;
  294. char *dname;
  295. Qid qid;
  296. Serialport *p;
  297. qid = fid->qid;
  298. if((qid.type & QTDIR) == 0){
  299. werrstr("walk in non-directory");
  300. return -1;
  301. }
  302. if(strcmp(name, "..") == 0){
  303. /* must be /eiaU%d; i.e. our root dir. */
  304. fid->qid.path = Qroot | fs->qid;
  305. fid->qid.vers = 0;
  306. fid->qid.type = QTDIR;
  307. return 0;
  308. }
  309. p = fs->aux;
  310. for(i = 1; i < nelem(dirtab); i++){
  311. dname = smprint(dirtab[i].name, p->name);
  312. if(strcmp(name, dname) == 0){
  313. qid.path = i | fs->qid;
  314. qid.vers = 0;
  315. qid.type = dirtab[i].mode >> 24;
  316. fid->qid = qid;
  317. free(dname);
  318. return 0;
  319. } else
  320. free(dname);
  321. }
  322. werrstr(Enotfound);
  323. return -1;
  324. }
  325. static void
  326. dostat(Usbfs *fs, int path, Dir *d)
  327. {
  328. Dirtab *t;
  329. Serialport *p;
  330. t = &dirtab[path];
  331. d->qid.path = path;
  332. d->qid.type = t->mode >> 24;
  333. d->mode = t->mode;
  334. p = fs->aux;
  335. if(strcmp(t->name, "/") == 0)
  336. d->name = t->name;
  337. else
  338. snprint(d->name, Namesz, t->name, p->fs.name);
  339. d->length = 0;
  340. }
  341. static int
  342. dstat(Usbfs *fs, Qid qid, Dir *d)
  343. {
  344. int path;
  345. path = qid.path & ~fs->qid;
  346. dostat(fs, path, d);
  347. d->qid.path |= fs->qid;
  348. return 0;
  349. }
  350. static int
  351. dopen(Usbfs *fs, Fid *fid, int)
  352. {
  353. ulong path;
  354. Serialport *p;
  355. path = fid->qid.path & ~fs->qid;
  356. p = fs->aux;
  357. switch(path){ /* BUG: unneeded? */
  358. case Qdata:
  359. dsprint(2, "serial, opened data\n");
  360. break;
  361. case Qctl:
  362. dsprint(2, "serial, opened ctl\n");
  363. if(p->isjtag)
  364. return 0;
  365. serialctl(p, "l8 i1"); /* default line parameters */
  366. break;
  367. }
  368. return 0;
  369. }
  370. static void
  371. filldir(Usbfs *fs, Dir *d, Dirtab *tab, int i, void *v)
  372. {
  373. Serialport *p;
  374. p = v;
  375. d->qid.path = i | fs->qid;
  376. d->mode = tab->mode;
  377. if((d->mode & DMDIR) != 0)
  378. d->qid.type = QTDIR;
  379. else
  380. d->qid.type = QTFILE;
  381. sprint(d->name, tab->name, p->name); /* hope it fits */
  382. }
  383. static int
  384. dirgen(Usbfs *fs, Qid, int i, Dir *d, void *p)
  385. {
  386. i++; /* skip root */
  387. if(i >= nelem(dirtab))
  388. return -1;
  389. filldir(fs, d, &dirtab[i], i, p);
  390. return 0;
  391. }
  392. enum {
  393. Serbufsize = 255,
  394. };
  395. static long
  396. dread(Usbfs *fs, Fid *fid, void *data, long count, vlong offset)
  397. {
  398. int dfd;
  399. long rcount;
  400. ulong path;
  401. char *e, *buf, *err; /* change */
  402. Qid q;
  403. Serialport *p;
  404. Serial *ser;
  405. static int errrun, good;
  406. q = fid->qid;
  407. path = fid->qid.path & ~fs->qid;
  408. p = fs->aux;
  409. ser = p->s;
  410. buf = emallocz(Serbufsize, 1);
  411. err = emallocz(Serbufsize, 1);
  412. qlock(ser);
  413. switch(path){
  414. case Qroot:
  415. count = usbdirread(fs, q, data, count, offset, dirgen, p);
  416. break;
  417. case Qdata:
  418. if(count > ser->maxread)
  419. count = ser->maxread;
  420. dsprint(2, "serial: reading from data\n");
  421. do {
  422. err[0] = 0;
  423. dfd = p->epin->dfd;
  424. if(usbdebug >= 3)
  425. dsprint(2, "serial: reading: %ld\n", count);
  426. assert(count > 0);
  427. if(ser->wait4data != nil)
  428. rcount = ser->wait4data(p, data, count);
  429. else{
  430. qunlock(ser);
  431. rcount = read(dfd, data, count);
  432. qlock(ser);
  433. }
  434. /*
  435. * if we encounter a long run of continuous read
  436. * errors, do something drastic so that our caller
  437. * doesn't just spin its wheels forever.
  438. */
  439. if(rcount < 0) {
  440. snprint(err, Serbufsize, "%r");
  441. ++errrun;
  442. sleep(20);
  443. if (good > 0 && errrun > 10000) {
  444. /* the line has been dropped; give up */
  445. qunlock(ser);
  446. fprint(2, "%s: line %s is gone: %r\n",
  447. argv0, p->fs.name);
  448. threadexitsall("serial line gone");
  449. }
  450. } else {
  451. errrun = 0;
  452. good++;
  453. }
  454. if(usbdebug >= 3)
  455. dsprint(2, "serial: read: %s %ld\n", err, rcount);
  456. } while(rcount < 0 && strstr(err, "timed out") != nil);
  457. dsprint(2, "serial: read from bulk %ld, %10.10s\n", rcount, err);
  458. if(rcount < 0){
  459. dsprint(2, "serial: need to recover, data read %ld %r\n",
  460. count);
  461. serialrecover(ser, err);
  462. }
  463. dsprint(2, "serial: read from bulk %ld\n", rcount);
  464. count = rcount;
  465. break;
  466. case Qctl:
  467. if(offset != 0)
  468. count = 0;
  469. else {
  470. if(!p->isjtag){
  471. e = serdumpst(p, buf, Serbufsize);
  472. count = usbreadbuf(data, count, 0, buf, e - buf);
  473. }
  474. }
  475. break;
  476. }
  477. qunlock(ser);
  478. free(err);
  479. free(buf);
  480. return count;
  481. }
  482. static long
  483. altwrite(Serialport *p, uchar *buf, long count)
  484. {
  485. int nw, dfd;
  486. char err[128];
  487. Serial *ser;
  488. ser = p->s;
  489. do{
  490. dsprint(2, "serial: write to bulk %ld\n", count);
  491. if(ser->wait4write != nil)
  492. /* unlocked inside later */
  493. nw = ser->wait4write(p, buf, count);
  494. else{
  495. dfd = p->epout->dfd;
  496. qunlock(ser);
  497. nw = write(dfd, buf, count);
  498. qlock(ser);
  499. }
  500. rerrstr(err, sizeof err);
  501. dsprint(2, "serial: written %s %d\n", err, nw);
  502. } while(nw < 0 && strstr(err, "timed out") != nil);
  503. if(nw != count){
  504. dsprint(2, "serial: need to recover, status in write %d %r\n",
  505. nw);
  506. snprint(err, sizeof err, "%r");
  507. serialrecover(p->s, err);
  508. }
  509. return nw;
  510. }
  511. static long
  512. dwrite(Usbfs *fs, Fid *fid, void *buf, long count, vlong)
  513. {
  514. ulong path;
  515. char *cmd;
  516. Serialport *p;
  517. Serial *ser;
  518. p = fs->aux;
  519. ser = p->s;
  520. path = fid->qid.path & ~fs->qid;
  521. qlock(ser);
  522. switch(path){
  523. case Qdata:
  524. count = altwrite(p, (uchar *)buf, count);
  525. break;
  526. case Qctl:
  527. if(p->isjtag)
  528. break;
  529. cmd = emallocz(count+1, 1);
  530. memmove(cmd, buf, count);
  531. cmd[count] = 0;
  532. if(serialctl(p, cmd) < 0){
  533. qunlock(ser);
  534. werrstr(Ebadctl);
  535. free(cmd);
  536. return -1;
  537. }
  538. free(cmd);
  539. break;
  540. default:
  541. qunlock(ser);
  542. werrstr(Eperm);
  543. return -1;
  544. }
  545. qunlock(ser);
  546. return count;
  547. }
  548. static int
  549. openeps(Serialport *p, int epin, int epout, int epintr)
  550. {
  551. Serial *ser;
  552. ser = p->s;
  553. p->epin = openep(ser->dev, epin);
  554. if(p->epin == nil){
  555. fprint(2, "serial: openep %d: %r\n", epin);
  556. return -1;
  557. }
  558. p->epout = openep(ser->dev, epout);
  559. if(p->epout == nil){
  560. fprint(2, "serial: openep %d: %r\n", epout);
  561. closedev(p->epin);
  562. return -1;
  563. }
  564. if(!p->isjtag){
  565. devctl(p->epin, "timeout 1000");
  566. devctl(p->epout, "timeout 1000");
  567. }
  568. if(ser->hasepintr){
  569. p->epintr = openep(ser->dev, epintr);
  570. if(p->epintr == nil){
  571. fprint(2, "serial: openep %d: %r\n", epintr);
  572. closedev(p->epin);
  573. closedev(p->epout);
  574. return -1;
  575. }
  576. opendevdata(p->epintr, OREAD);
  577. devctl(p->epintr, "timeout 1000");
  578. }
  579. if(ser->seteps!= nil)
  580. ser->seteps(p);
  581. opendevdata(p->epin, OREAD);
  582. opendevdata(p->epout, OWRITE);
  583. if(p->epin->dfd < 0 ||p->epout->dfd < 0 ||
  584. (ser->hasepintr && p->epintr->dfd < 0)){
  585. fprint(2, "serial: open i/o ep data: %r\n");
  586. closedev(p->epin);
  587. closedev(p->epout);
  588. if(ser->hasepintr)
  589. closedev(p->epintr);
  590. return -1;
  591. }
  592. return 0;
  593. }
  594. static int
  595. findendpoints(Serial *ser, int ifc)
  596. {
  597. int i, epin, epout, epintr;
  598. Ep *ep, **eps;
  599. epintr = epin = epout = -1;
  600. /*
  601. * interfc 0 means start from the start which is equiv to
  602. * iterate through endpoints probably, could be done better
  603. */
  604. eps = ser->dev->usb->conf[0]->iface[ifc]->ep;
  605. for(i = 0; i < Niface; i++){
  606. if((ep = eps[i]) == nil)
  607. continue;
  608. if(ser->hasepintr && ep->type == Eintr &&
  609. ep->dir == Ein && epintr == -1)
  610. epintr = ep->id;
  611. if(ep->type == Ebulk){
  612. if(ep->dir == Ein && epin == -1)
  613. epin = ep->id;
  614. if(ep->dir == Eout && epout == -1)
  615. epout = ep->id;
  616. }
  617. }
  618. dprint(2, "serial[%d]: ep ids: in %d out %d intr %d\n", ifc, epin, epout, epintr);
  619. if(epin == -1 || epout == -1 || (ser->hasepintr && epintr == -1))
  620. return -1;
  621. if(openeps(&ser->p[ifc], epin, epout, epintr) < 0)
  622. return -1;
  623. dprint(2, "serial: ep in %s out %s\n", ser->p[ifc].epin->dir, ser->p[ifc].epout->dir);
  624. if(ser->hasepintr)
  625. dprint(2, "serial: ep intr %s\n", ser->p[ifc].epintr->dir);
  626. if(usbdebug > 1 || serialdebug > 2){
  627. devctl(ser->p[ifc].epin, "debug 1");
  628. devctl(ser->p[ifc].epout, "debug 1");
  629. if(ser->hasepintr)
  630. devctl(ser->p[ifc].epintr, "debug 1");
  631. devctl(ser->dev, "debug 1");
  632. }
  633. return 0;
  634. }
  635. /* keep in sync with main.c */
  636. static int
  637. usage(void)
  638. {
  639. werrstr("usage: usb/serial [-dD] [-m mtpt] [-s srv]");
  640. return -1;
  641. }
  642. static void
  643. serdevfree(void *a)
  644. {
  645. Serial *ser = a;
  646. Serialport *p;
  647. int i;
  648. if(ser == nil)
  649. return;
  650. for(i = 0; i < ser->nifcs; i++){
  651. p = &ser->p[i];
  652. if(ser->hasepintr)
  653. closedev(p->epintr);
  654. closedev(p->epin);
  655. closedev(p->epout);
  656. p->epintr = p->epin = p->epout = nil;
  657. if(p->w4data != nil)
  658. chanfree(p->w4data);
  659. if(p->gotdata != nil)
  660. chanfree(p->gotdata);
  661. if(p->readc)
  662. chanfree(p->readc);
  663. }
  664. free(ser);
  665. }
  666. static Usbfs serialfs = {
  667. .walk = dwalk,
  668. .open = dopen,
  669. .read = dread,
  670. .write= dwrite,
  671. .stat = dstat,
  672. };
  673. static void
  674. serialfsend(Usbfs *fs)
  675. {
  676. Serialport *p;
  677. p = fs->aux;
  678. if(p->w4data != nil)
  679. chanclose(p->w4data);
  680. if(p->gotdata != nil)
  681. chanclose(p->gotdata);
  682. if(p->readc)
  683. chanclose(p->readc);
  684. }
  685. int
  686. serialmain(Dev *dev, int argc, char* argv[])
  687. {
  688. Serial *ser;
  689. Serialport *p;
  690. char buf[50];
  691. int i, devid;
  692. devid = dev->id;
  693. ARGBEGIN{
  694. case 'd':
  695. serialdebug++;
  696. break;
  697. case 'N':
  698. devid = atoi(EARGF(usage()));
  699. break;
  700. default:
  701. return usage();
  702. }ARGEND
  703. if(argc != 0)
  704. return usage();
  705. ser = dev->aux = emallocz(sizeof(Serial), 1);
  706. ser->maxrtrans = ser->maxwtrans = sizeof ser->p[0].data;
  707. ser->maxread = ser->maxwrite = sizeof ser->p[0].data;
  708. ser->dev = dev;
  709. dev->free = serdevfree;
  710. ser->jtag = -1;
  711. ser->nifcs = 1;
  712. snprint(buf, sizeof buf, "vid %#06x did %#06x",
  713. dev->usb->vid, dev->usb->did);
  714. if(plmatch(buf) == 0){
  715. ser->hasepintr = 1;
  716. ser->Serialops = plops;
  717. } else if(uconsmatch(buf) == 0)
  718. ser->Serialops = uconsops;
  719. else if(ftmatch(ser, buf) == 0)
  720. ser->Serialops = ftops;
  721. else {
  722. werrstr("serial: no serial devices found");
  723. return -1;
  724. }
  725. for(i = 0; i < ser->nifcs; i++){
  726. p = &ser->p[i];
  727. p->interfc = i;
  728. p->s = ser;
  729. p->fs = serialfs;
  730. if(i == ser->jtag){
  731. p->isjtag++;
  732. }
  733. if(findendpoints(ser, i) < 0){
  734. werrstr("serial: no endpoints found for ifc %d", i);
  735. return -1;
  736. }
  737. p->w4data = chancreate(sizeof(ulong), 0);
  738. p->gotdata = chancreate(sizeof(ulong), 0);
  739. }
  740. qlock(ser);
  741. serialreset(ser);
  742. for(i = 0; i < ser->nifcs; i++){
  743. p = &ser->p[i];
  744. dprint(2, "serial: valid interface, calling serinit\n");
  745. if(serinit(p) < 0){
  746. dprint(2, "serial: serinit: %r\n");
  747. return -1;
  748. }
  749. dsprint(2, "serial: adding interface %d, %p\n", p->interfc, p);
  750. if(p->isjtag){
  751. snprint(p->name, sizeof p->name, "jtag");
  752. dsprint(2, "serial: JTAG interface %d %p\n", i, p);
  753. snprint(p->fs.name, sizeof p->fs.name, "jtag%d.%d", devid, i);
  754. } else {
  755. snprint(p->name, sizeof p->name, "eiaU");
  756. if(i == 0)
  757. snprint(p->fs.name, sizeof p->fs.name, "eiaU%d", devid);
  758. else
  759. snprint(p->fs.name, sizeof p->fs.name, "eiaU%d.%d", devid, i);
  760. }
  761. fprint(2, "%s\n", p->fs.name);
  762. p->fs.dev = dev;
  763. incref(dev);
  764. p->fs.aux = p;
  765. p->fs.end = serialfsend;
  766. usbfsadd(&p->fs);
  767. }
  768. qunlock(ser);
  769. return 0;
  770. }