1
0

devuart.c 12 KB

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