serial.c 17 KB

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