devuart.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "io.h"
  7. #include "../port/error.h"
  8. #include "../port/netif.h"
  9. enum
  10. {
  11. /* soft flow control chars */
  12. CTLS= 023,
  13. CTLQ= 021,
  14. };
  15. extern Dev uartdevtab;
  16. extern PhysUart* physuart[];
  17. static Uart* uartlist;
  18. static Uart** uart;
  19. static int uartnuart;
  20. static Dirtab *uartdir;
  21. static int uartndir;
  22. static Timer *uarttimer;
  23. struct Uartalloc {
  24. Lock;
  25. Uart *elist; /* list of enabled interfaces */
  26. } uartalloc;
  27. static void uartclock(void);
  28. static void uartflow(void*);
  29. /*
  30. * enable/disable uart and add/remove to list of enabled uarts
  31. */
  32. static Uart*
  33. uartenable(Uart *p)
  34. {
  35. Uart **l;
  36. if(p->iq == nil){
  37. if((p->iq = qopen(8*1024, 0, uartflow, p)) == nil)
  38. return nil;
  39. }
  40. else
  41. qreopen(p->iq);
  42. if(p->oq == nil){
  43. if((p->oq = qopen(8*1024, 0, uartkick, p)) == nil){
  44. qfree(p->iq);
  45. p->iq = nil;
  46. return nil;
  47. }
  48. }
  49. else
  50. qreopen(p->oq);
  51. p->ir = p->istage;
  52. p->iw = p->istage;
  53. p->ie = &p->istage[Stagesize];
  54. p->op = p->ostage;
  55. p->oe = p->ostage;
  56. p->hup_dsr = p->hup_dcd = 0;
  57. p->dsr = p->dcd = 0;
  58. /* assume we can send */
  59. p->cts = 1;
  60. p->ctsbackoff = 0;
  61. if(p->bits == 0)
  62. uartctl(p, "l8");
  63. if(p->stop == 0)
  64. uartctl(p, "s1");
  65. if(p->parity == 0)
  66. uartctl(p, "pn");
  67. if(p->baud == 0)
  68. uartctl(p, "b9600");
  69. (*p->phys->enable)(p, 1);
  70. lock(&uartalloc);
  71. for(l = &uartalloc.elist; *l; l = &(*l)->elist){
  72. if(*l == p)
  73. break;
  74. }
  75. if(*l == 0){
  76. p->elist = uartalloc.elist;
  77. uartalloc.elist = p;
  78. }
  79. p->enabled = 1;
  80. unlock(&uartalloc);
  81. return p;
  82. }
  83. static void
  84. uartdisable(Uart *p)
  85. {
  86. Uart **l;
  87. (*p->phys->disable)(p);
  88. lock(&uartalloc);
  89. for(l = &uartalloc.elist; *l; l = &(*l)->elist){
  90. if(*l == p){
  91. *l = p->elist;
  92. break;
  93. }
  94. }
  95. p->enabled = 0;
  96. unlock(&uartalloc);
  97. }
  98. void
  99. uartmouse(Uart* p, int (*putc)(Queue*, int), int setb1200)
  100. {
  101. qlock(p);
  102. if(p->opens++ == 0 && uartenable(p) == nil){
  103. qunlock(p);
  104. error(Enodev);
  105. }
  106. if(setb1200)
  107. uartctl(p, "b1200");
  108. p->putc = putc;
  109. p->special = 1;
  110. qunlock(p);
  111. }
  112. void
  113. uartsetmouseputc(Uart* p, int (*putc)(Queue*, int))
  114. {
  115. qlock(p);
  116. if(p->opens == 0 || p->special == 0){
  117. qunlock(p);
  118. error(Enodev);
  119. }
  120. p->putc = putc;
  121. qunlock(p);
  122. }
  123. static void
  124. setlength(int i)
  125. {
  126. Uart *p;
  127. if(i > 0){
  128. p = uart[i];
  129. if(p && p->opens && p->iq)
  130. uartdir[1+3*i].length = qlen(p->iq);
  131. } else for(i = 0; i < uartnuart; i++){
  132. p = uart[i];
  133. if(p && p->opens && p->iq)
  134. uartdir[1+3*i].length = qlen(p->iq);
  135. }
  136. }
  137. /*
  138. * set up the '#t' directory
  139. */
  140. static void
  141. uartreset(void)
  142. {
  143. int i;
  144. Dirtab *dp;
  145. Uart *p, *tail;
  146. tail = nil;
  147. for(i = 0; physuart[i] != nil; i++){
  148. if(physuart[i]->pnp == nil)
  149. continue;
  150. if((p = physuart[i]->pnp()) == nil)
  151. continue;
  152. if(uartlist != nil)
  153. tail->next = p;
  154. else
  155. uartlist = p;
  156. for(tail = p; tail->next != nil; tail = tail->next)
  157. uartnuart++;
  158. uartnuart++;
  159. }
  160. if(uartnuart)
  161. uart = xalloc(uartnuart*sizeof(Uart*));
  162. uartndir = 1 + 3*uartnuart;
  163. uartdir = xalloc(uartndir * sizeof(Dirtab));
  164. if (uart == nil || uartdir == nil)
  165. panic("uartreset: no memory");
  166. dp = uartdir;
  167. strcpy(dp->name, ".");
  168. mkqid(&dp->qid, 0, 0, QTDIR);
  169. dp->length = 0;
  170. dp->perm = DMDIR|0555;
  171. dp++;
  172. p = uartlist;
  173. for(i = 0; i < uartnuart; i++){
  174. /* 3 directory entries per port */
  175. sprint(dp->name, "eia%d", i);
  176. dp->qid.path = NETQID(i, Ndataqid);
  177. dp->perm = 0660;
  178. dp++;
  179. sprint(dp->name, "eia%dctl", i);
  180. dp->qid.path = NETQID(i, Nctlqid);
  181. dp->perm = 0660;
  182. dp++;
  183. sprint(dp->name, "eia%dstatus", i);
  184. dp->qid.path = NETQID(i, Nstatqid);
  185. dp->perm = 0444;
  186. dp++;
  187. uart[i] = p;
  188. p->dev = i;
  189. if(p->console || p->special){
  190. if(uartenable(p) != nil){
  191. if(p->console){
  192. kbdq = p->iq;
  193. serialoq = p->oq;
  194. p->putc = kbdcr2nl;
  195. }
  196. p->opens++;
  197. }
  198. }
  199. p = p->next;
  200. }
  201. if(uartnuart){
  202. /*
  203. * at 115200 baud, the 1024 char buffer takes 56 ms to process,
  204. * processing it every 22 ms should be fine.
  205. */
  206. uarttimer = addclock0link(uartclock, 22);
  207. }
  208. }
  209. static Chan*
  210. uartattach(char *spec)
  211. {
  212. return devattach('t', spec);
  213. }
  214. static Walkqid*
  215. uartwalk(Chan *c, Chan *nc, char **name, int nname)
  216. {
  217. return devwalk(c, nc, name, nname, uartdir, uartndir, devgen);
  218. }
  219. static int
  220. uartstat(Chan *c, uchar *dp, int n)
  221. {
  222. if(NETTYPE(c->qid.path) == Ndataqid)
  223. setlength(NETID(c->qid.path));
  224. return devstat(c, dp, n, uartdir, uartndir, devgen);
  225. }
  226. static Chan*
  227. uartopen(Chan *c, int omode)
  228. {
  229. Uart *p;
  230. c = devopen(c, omode, uartdir, uartndir, devgen);
  231. switch(NETTYPE(c->qid.path)){
  232. case Nctlqid:
  233. case Ndataqid:
  234. p = uart[NETID(c->qid.path)];
  235. qlock(p);
  236. if(p->opens++ == 0 && uartenable(p) == nil){
  237. qunlock(p);
  238. c->flag &= ~COPEN;
  239. error(Enodev);
  240. }
  241. qunlock(p);
  242. break;
  243. }
  244. c->iounit = qiomaxatomic;
  245. return c;
  246. }
  247. static int
  248. uartdrained(void* arg)
  249. {
  250. Uart *p;
  251. p = arg;
  252. return qlen(p->oq) == 0 && p->op == p->oe;
  253. }
  254. static void
  255. uartdrainoutput(Uart *p)
  256. {
  257. if(!p->enabled)
  258. return;
  259. p->drain = 1;
  260. if(waserror()){
  261. p->drain = 0;
  262. nexterror();
  263. }
  264. sleep(&p->r, uartdrained, p);
  265. poperror();
  266. }
  267. static void
  268. uartclose(Chan *c)
  269. {
  270. Uart *p;
  271. if(c->qid.type & QTDIR)
  272. return;
  273. if((c->flag & COPEN) == 0)
  274. return;
  275. switch(NETTYPE(c->qid.path)){
  276. case Ndataqid:
  277. case Nctlqid:
  278. p = uart[NETID(c->qid.path)];
  279. qlock(p);
  280. if(--(p->opens) == 0){
  281. qclose(p->iq);
  282. ilock(&p->rlock);
  283. p->ir = p->iw = p->istage;
  284. iunlock(&p->rlock);
  285. /*
  286. */
  287. qhangup(p->oq, nil);
  288. if(!waserror()){
  289. uartdrainoutput(p);
  290. poperror();
  291. }
  292. qclose(p->oq);
  293. uartdisable(p);
  294. p->dcd = p->dsr = p->dohup = 0;
  295. }
  296. qunlock(p);
  297. break;
  298. }
  299. }
  300. static long
  301. uartread(Chan *c, void *buf, long n, vlong off)
  302. {
  303. Uart *p;
  304. ulong offset = off;
  305. if(c->qid.type & QTDIR){
  306. setlength(-1);
  307. return devdirread(c, buf, n, uartdir, uartndir, devgen);
  308. }
  309. p = uart[NETID(c->qid.path)];
  310. switch(NETTYPE(c->qid.path)){
  311. case Ndataqid:
  312. return qread(p->iq, buf, n);
  313. case Nctlqid:
  314. return readnum(offset, buf, n, NETID(c->qid.path), NUMSIZE);
  315. case Nstatqid:
  316. return (*p->phys->status)(p, buf, n, offset);
  317. }
  318. return 0;
  319. }
  320. int
  321. uartctl(Uart *p, char *cmd)
  322. {
  323. char *f[16];
  324. int i, n, nf;
  325. nf = tokenize(cmd, f, nelem(f));
  326. for(i = 0; i < nf; i++){
  327. if(strncmp(f[i], "break", 5) == 0){
  328. (*p->phys->dobreak)(p, 0);
  329. continue;
  330. }
  331. n = atoi(f[i]+1);
  332. switch(*f[i]){
  333. case 'B':
  334. case 'b':
  335. uartdrainoutput(p);
  336. if((*p->phys->baud)(p, n) < 0)
  337. return -1;
  338. break;
  339. case 'C':
  340. case 'c':
  341. p->hup_dcd = n;
  342. break;
  343. case 'D':
  344. case 'd':
  345. uartdrainoutput(p);
  346. (*p->phys->dtr)(p, n);
  347. break;
  348. case 'E':
  349. case 'e':
  350. p->hup_dsr = n;
  351. break;
  352. case 'f':
  353. case 'F':
  354. if(p->oq != nil)
  355. qflush(p->oq);
  356. break;
  357. case 'H':
  358. case 'h':
  359. if(p->iq != nil)
  360. qhangup(p->iq, 0);
  361. if(p->oq != nil)
  362. qhangup(p->oq, 0);
  363. break;
  364. case 'i':
  365. case 'I':
  366. uartdrainoutput(p);
  367. (*p->phys->fifo)(p, n);
  368. break;
  369. case 'K':
  370. case 'k':
  371. uartdrainoutput(p);
  372. (*p->phys->dobreak)(p, n);
  373. break;
  374. case 'L':
  375. case 'l':
  376. uartdrainoutput(p);
  377. if((*p->phys->bits)(p, n) < 0)
  378. return -1;
  379. break;
  380. case 'm':
  381. case 'M':
  382. uartdrainoutput(p);
  383. (*p->phys->modemctl)(p, n);
  384. break;
  385. case 'n':
  386. case 'N':
  387. if(p->oq != nil)
  388. qnoblock(p->oq, n);
  389. break;
  390. case 'P':
  391. case 'p':
  392. uartdrainoutput(p);
  393. if((*p->phys->parity)(p, *(f[i]+1)) < 0)
  394. return -1;
  395. break;
  396. case 'Q':
  397. case 'q':
  398. if(p->iq != nil)
  399. qsetlimit(p->iq, n);
  400. if(p->oq != nil)
  401. qsetlimit(p->oq, n);
  402. break;
  403. case 'R':
  404. case 'r':
  405. uartdrainoutput(p);
  406. (*p->phys->rts)(p, n);
  407. break;
  408. case 'S':
  409. case 's':
  410. uartdrainoutput(p);
  411. if((*p->phys->stop)(p, n) < 0)
  412. return -1;
  413. break;
  414. case 'W':
  415. case 'w':
  416. if(uarttimer == nil || n < 1)
  417. return -1;
  418. uarttimer->tns = (vlong)n * 100000LL;
  419. break;
  420. case 'X':
  421. case 'x':
  422. if(p->enabled){
  423. ilock(&p->tlock);
  424. p->xonoff = n;
  425. iunlock(&p->tlock);
  426. }
  427. break;
  428. }
  429. }
  430. return 0;
  431. }
  432. static long
  433. uartwrite(Chan *c, void *buf, long n, vlong)
  434. {
  435. Uart *p;
  436. char *cmd;
  437. if(c->qid.type & QTDIR)
  438. error(Eperm);
  439. p = uart[NETID(c->qid.path)];
  440. switch(NETTYPE(c->qid.path)){
  441. case Ndataqid:
  442. qlock(p);
  443. if(waserror()){
  444. qunlock(p);
  445. nexterror();
  446. }
  447. n = qwrite(p->oq, buf, n);
  448. qunlock(p);
  449. poperror();
  450. break;
  451. case Nctlqid:
  452. cmd = malloc(n+1);
  453. memmove(cmd, buf, n);
  454. cmd[n] = 0;
  455. qlock(p);
  456. if(waserror()){
  457. qunlock(p);
  458. free(cmd);
  459. nexterror();
  460. }
  461. /* let output drain */
  462. if(uartctl(p, cmd) < 0)
  463. error(Ebadarg);
  464. qunlock(p);
  465. poperror();
  466. free(cmd);
  467. break;
  468. }
  469. return n;
  470. }
  471. static int
  472. uartwstat(Chan *c, uchar *dp, int n)
  473. {
  474. Dir d;
  475. Dirtab *dt;
  476. if(!iseve())
  477. error(Eperm);
  478. if(QTDIR & c->qid.type)
  479. error(Eperm);
  480. if(NETTYPE(c->qid.path) == Nstatqid)
  481. error(Eperm);
  482. dt = &uartdir[1 + 3 * NETID(c->qid.path)];
  483. n = convM2D(dp, n, &d, nil);
  484. if(n == 0)
  485. error(Eshortstat);
  486. if(d.mode != ~0UL)
  487. dt[0].perm = dt[1].perm = d.mode;
  488. return n;
  489. }
  490. void
  491. uartpower(int on)
  492. {
  493. Uart *p;
  494. for(p = uartlist; p != nil; p = p->next) {
  495. if(p->phys->power)
  496. (*p->phys->power)(p, on);
  497. }
  498. }
  499. Dev uartdevtab = {
  500. 't',
  501. "uart",
  502. uartreset,
  503. devinit,
  504. devshutdown,
  505. uartattach,
  506. uartwalk,
  507. uartstat,
  508. uartopen,
  509. devcreate,
  510. uartclose,
  511. uartread,
  512. devbread,
  513. uartwrite,
  514. devbwrite,
  515. devremove,
  516. uartwstat,
  517. uartpower,
  518. };
  519. /*
  520. * restart input if it's off
  521. */
  522. static void
  523. uartflow(void *v)
  524. {
  525. Uart *p;
  526. p = v;
  527. if(p->modem)
  528. (*p->phys->rts)(p, 1);
  529. }
  530. /*
  531. * put some bytes into the local queue to avoid calling
  532. * qconsume for every character
  533. */
  534. int
  535. uartstageoutput(Uart *p)
  536. {
  537. int n;
  538. n = qconsume(p->oq, p->ostage, Stagesize);
  539. if(n <= 0)
  540. return 0;
  541. p->op = p->ostage;
  542. p->oe = p->ostage + n;
  543. return n;
  544. }
  545. /*
  546. * restart output
  547. */
  548. void
  549. uartkick(void *v)
  550. {
  551. Uart *p = v;
  552. if(p->blocked)
  553. return;
  554. ilock(&p->tlock);
  555. (*p->phys->kick)(p);
  556. iunlock(&p->tlock);
  557. if(p->drain && uartdrained(p)){
  558. p->drain = 0;
  559. wakeup(&p->r);
  560. }
  561. }
  562. /*
  563. * Move data from the interrupt staging area to
  564. * the input Queue.
  565. */
  566. static void
  567. uartstageinput(Uart *p)
  568. {
  569. int n;
  570. uchar *ir, *iw;
  571. while(p->ir != p->iw){
  572. ir = p->ir;
  573. if(p->ir > p->iw){
  574. iw = p->ie;
  575. p->ir = p->istage;
  576. }
  577. else{
  578. iw = p->iw;
  579. p->ir = p->iw;
  580. }
  581. if((n = qproduce(p->iq, ir, iw - ir)) < 0){
  582. p->serr++;
  583. (*p->phys->rts)(p, 0);
  584. }
  585. else if(n == 0)
  586. p->berr++;
  587. }
  588. }
  589. /*
  590. * receive a character at interrupt time
  591. */
  592. void
  593. uartrecv(Uart *p, char ch)
  594. {
  595. uchar *next;
  596. /* software flow control */
  597. if(p->xonoff){
  598. if(ch == CTLS){
  599. p->blocked = 1;
  600. }else if(ch == CTLQ){
  601. p->blocked = 0;
  602. p->ctsbackoff = 2; /* clock gets output going again */
  603. }
  604. }
  605. /* receive the character */
  606. if(p->putc)
  607. p->putc(p->iq, ch);
  608. else if (p->iw) { /* maybe the line isn't enabled yet */
  609. ilock(&p->rlock);
  610. next = p->iw + 1;
  611. if(next == p->ie)
  612. next = p->istage;
  613. if(next == p->ir)
  614. uartstageinput(p);
  615. if(next != p->ir){
  616. *p->iw = ch;
  617. p->iw = next;
  618. }
  619. iunlock(&p->rlock);
  620. }
  621. }
  622. /*
  623. * we save up input characters till clock time to reduce
  624. * per character interrupt overhead.
  625. */
  626. static void
  627. uartclock(void)
  628. {
  629. Uart *p;
  630. lock(&uartalloc);
  631. for(p = uartalloc.elist; p; p = p->elist){
  632. /* this hopefully amortizes cost of qproduce to many chars */
  633. if(p->iw != p->ir){
  634. ilock(&p->rlock);
  635. uartstageinput(p);
  636. iunlock(&p->rlock);
  637. }
  638. /* hang up if requested */
  639. if(p->dohup){
  640. qhangup(p->iq, 0);
  641. qhangup(p->oq, 0);
  642. p->dohup = 0;
  643. }
  644. /* this adds hysteresis to hardware/software flow control */
  645. if(p->ctsbackoff){
  646. ilock(&p->tlock);
  647. if(p->ctsbackoff){
  648. if(--(p->ctsbackoff) == 0)
  649. (*p->phys->kick)(p);
  650. }
  651. iunlock(&p->tlock);
  652. }
  653. }
  654. unlock(&uartalloc);
  655. }
  656. /*
  657. * polling console input, output
  658. */
  659. Uart* consuart;
  660. int
  661. uartgetc(void)
  662. {
  663. if(consuart == nil || consuart->phys->getc == nil)
  664. return -1;
  665. return consuart->phys->getc(consuart);
  666. }
  667. void
  668. uartputc(int c)
  669. {
  670. if(consuart == nil || consuart->phys->putc == nil)
  671. return;
  672. consuart->phys->putc(consuart, c);
  673. }
  674. void
  675. uartputs(char *s, int n)
  676. {
  677. char *e;
  678. if(consuart == nil || consuart->phys->putc == nil)
  679. return;
  680. e = s+n;
  681. for(; s<e; s++){
  682. if(*s == '\n')
  683. consuart->phys->putc(consuart, '\r');
  684. consuart->phys->putc(consuart, *s);
  685. }
  686. }