devuart.c 11 KB

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