devuart.c 12 KB

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