serial.c 14 KB

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