devuart.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  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. uartdrainoutput(Uart *p)
  253. {
  254. if(!p->enabled)
  255. return;
  256. p->drain = 1;
  257. if(waserror()){
  258. p->drain = 0;
  259. nexterror();
  260. }
  261. sleep(&p->r, uartdrained, p);
  262. poperror();
  263. }
  264. static void
  265. uartclose(Chan *c)
  266. {
  267. Uart *p;
  268. if(c->qid.type & QTDIR)
  269. return;
  270. if((c->flag & COPEN) == 0)
  271. return;
  272. switch(NETTYPE(c->qid.path)){
  273. case Ndataqid:
  274. case Nctlqid:
  275. p = uart[NETID(c->qid.path)];
  276. qlock(p);
  277. if(--(p->opens) == 0){
  278. qclose(p->iq);
  279. p->ir = p->iw = p->istage;
  280. /*
  281. */
  282. qhangup(p->oq, nil);
  283. if(!waserror()){
  284. uartdrainoutput(p);
  285. poperror();
  286. }
  287. qclose(p->oq);
  288. uartdisable(p);
  289. p->dcd = p->dsr = p->dohup = 0;
  290. }
  291. qunlock(p);
  292. break;
  293. }
  294. }
  295. static long
  296. uartread(Chan *c, void *buf, long n, vlong off)
  297. {
  298. Uart *p;
  299. ulong offset = off;
  300. if(c->qid.type & QTDIR){
  301. setlength(-1);
  302. return devdirread(c, buf, n, uartdir, uartndir, devgen);
  303. }
  304. p = uart[NETID(c->qid.path)];
  305. switch(NETTYPE(c->qid.path)){
  306. case Ndataqid:
  307. return qread(p->iq, buf, n);
  308. case Nctlqid:
  309. return readnum(offset, buf, n, NETID(c->qid.path), NUMSIZE);
  310. case Nstatqid:
  311. return (*p->phys->status)(p, buf, n, offset);
  312. }
  313. return 0;
  314. }
  315. int
  316. uartctl(Uart *p, char *cmd)
  317. {
  318. char *f[16];
  319. int i, n, nf;
  320. nf = tokenize(cmd, f, nelem(f));
  321. for(i = 0; i < nf; i++){
  322. if(strncmp(f[i], "break", 5) == 0){
  323. (*p->phys->dobreak)(p, 0);
  324. continue;
  325. }
  326. n = atoi(f[i]+1);
  327. switch(*f[i]){
  328. case 'B':
  329. case 'b':
  330. uartdrainoutput(p);
  331. if((*p->phys->baud)(p, n) < 0)
  332. return -1;
  333. break;
  334. case 'C':
  335. case 'c':
  336. p->hup_dcd = n;
  337. break;
  338. case 'D':
  339. case 'd':
  340. uartdrainoutput(p);
  341. (*p->phys->dtr)(p, n);
  342. break;
  343. case 'E':
  344. case 'e':
  345. p->hup_dsr = n;
  346. break;
  347. case 'f':
  348. case 'F':
  349. if(p->oq != nil)
  350. qflush(p->oq);
  351. break;
  352. case 'H':
  353. case 'h':
  354. if(p->iq != nil)
  355. qhangup(p->iq, 0);
  356. if(p->oq != nil)
  357. qhangup(p->oq, 0);
  358. break;
  359. case 'i':
  360. case 'I':
  361. uartdrainoutput(p);
  362. (*p->phys->fifo)(p, n);
  363. break;
  364. case 'K':
  365. case 'k':
  366. uartdrainoutput(p);
  367. (*p->phys->dobreak)(p, n);
  368. break;
  369. case 'L':
  370. case 'l':
  371. uartdrainoutput(p);
  372. if((*p->phys->bits)(p, n) < 0)
  373. return -1;
  374. break;
  375. case 'm':
  376. case 'M':
  377. uartdrainoutput(p);
  378. (*p->phys->modemctl)(p, n);
  379. break;
  380. case 'n':
  381. case 'N':
  382. if(p->oq != nil)
  383. qnoblock(p->oq, n);
  384. break;
  385. case 'P':
  386. case 'p':
  387. uartdrainoutput(p);
  388. if((*p->phys->parity)(p, *(f[i]+1)) < 0)
  389. return -1;
  390. break;
  391. case 'Q':
  392. case 'q':
  393. if(p->iq != nil)
  394. qsetlimit(p->iq, n);
  395. if(p->oq != nil)
  396. qsetlimit(p->oq, n);
  397. break;
  398. case 'R':
  399. case 'r':
  400. uartdrainoutput(p);
  401. (*p->phys->rts)(p, n);
  402. break;
  403. case 'S':
  404. case 's':
  405. uartdrainoutput(p);
  406. if((*p->phys->stop)(p, n) < 0)
  407. return -1;
  408. break;
  409. case 'T':
  410. case 't':
  411. p->dcdts = n;
  412. break;
  413. case 'W':
  414. case 'w':
  415. /* obsolete */
  416. break;
  417. case 'X':
  418. case 'x':
  419. if(p->enabled){
  420. ilock(&p->tlock);
  421. p->xonoff = n;
  422. iunlock(&p->tlock);
  423. }
  424. break;
  425. }
  426. }
  427. return 0;
  428. }
  429. static long
  430. uartwrite(Chan *c, void *buf, long n, vlong)
  431. {
  432. Uart *p;
  433. char *cmd;
  434. if(c->qid.type & QTDIR)
  435. error(Eperm);
  436. p = uart[NETID(c->qid.path)];
  437. switch(NETTYPE(c->qid.path)){
  438. case Ndataqid:
  439. qlock(p);
  440. if(waserror()){
  441. qunlock(p);
  442. nexterror();
  443. }
  444. n = qwrite(p->oq, buf, n);
  445. qunlock(p);
  446. poperror();
  447. break;
  448. case Nctlqid:
  449. cmd = malloc(n+1);
  450. memmove(cmd, buf, n);
  451. cmd[n] = 0;
  452. qlock(p);
  453. if(waserror()){
  454. qunlock(p);
  455. free(cmd);
  456. nexterror();
  457. }
  458. /* let output drain */
  459. if(uartctl(p, cmd) < 0)
  460. error(Ebadarg);
  461. qunlock(p);
  462. poperror();
  463. free(cmd);
  464. break;
  465. }
  466. return n;
  467. }
  468. static int
  469. uartwstat(Chan *c, uchar *dp, int n)
  470. {
  471. Dir d;
  472. Dirtab *dt;
  473. if(!iseve())
  474. error(Eperm);
  475. if(QTDIR & c->qid.type)
  476. error(Eperm);
  477. if(NETTYPE(c->qid.path) == Nstatqid)
  478. error(Eperm);
  479. dt = &uartdir[1 + 3 * NETID(c->qid.path)];
  480. n = convM2D(dp, n, &d, nil);
  481. if(n == 0)
  482. error(Eshortstat);
  483. if(d.mode != ~0UL)
  484. dt[0].perm = dt[1].perm = d.mode;
  485. return n;
  486. }
  487. void
  488. uartpower(int on)
  489. {
  490. Uart *p;
  491. for(p = uartlist; p != nil; p = p->next) {
  492. if(p->phys->power)
  493. (*p->phys->power)(p, on);
  494. }
  495. }
  496. Dev uartdevtab = {
  497. 't',
  498. "uart",
  499. uartreset,
  500. devinit,
  501. devshutdown,
  502. uartattach,
  503. uartwalk,
  504. uartstat,
  505. uartopen,
  506. devcreate,
  507. uartclose,
  508. uartread,
  509. devbread,
  510. uartwrite,
  511. devbwrite,
  512. devremove,
  513. uartwstat,
  514. uartpower,
  515. };
  516. /*
  517. * restart input if it's off
  518. */
  519. static void
  520. uartflow(void *v)
  521. {
  522. Uart *p;
  523. p = v;
  524. if(p->modem)
  525. (*p->phys->rts)(p, 1);
  526. }
  527. /*
  528. * put some bytes into the local queue to avoid calling
  529. * qconsume for every character
  530. */
  531. int
  532. uartstageoutput(Uart *p)
  533. {
  534. int n;
  535. n = qconsume(p->oq, p->ostage, Stagesize);
  536. if(n <= 0)
  537. return 0;
  538. p->op = p->ostage;
  539. p->oe = p->ostage + n;
  540. return n;
  541. }
  542. /*
  543. * restart output
  544. */
  545. void
  546. uartkick(void *v)
  547. {
  548. Uart *p = v;
  549. if(p->blocked)
  550. return;
  551. ilock(&p->tlock);
  552. (*p->phys->kick)(p);
  553. iunlock(&p->tlock);
  554. if(p->drain && uartdrained(p)){
  555. p->drain = 0;
  556. wakeup(&p->r);
  557. }
  558. }
  559. /*
  560. * receive a character at interrupt time
  561. */
  562. void
  563. uartrecv(Uart *p, char ch)
  564. {
  565. uchar *next;
  566. /* software flow control */
  567. if(p->xonoff){
  568. if(ch == CTLS){
  569. p->blocked = 1;
  570. }else if(ch == CTLQ){
  571. p->blocked = 0;
  572. p->ctsbackoff = 2; /* clock gets output going again */
  573. }
  574. }
  575. /* receive the character */
  576. if(p->putc)
  577. p->putc(p->iq, ch);
  578. else{
  579. next = p->iw + 1;
  580. if(next == p->ie)
  581. next = p->istage;
  582. if(next != p->ir){
  583. *p->iw = ch;
  584. p->iw = next;
  585. }
  586. }
  587. }
  588. /*
  589. * we save up input characters till clock time to reduce
  590. * per character interrupt overhead.
  591. */
  592. static void
  593. uartclock(void)
  594. {
  595. Uart *p;
  596. uchar *iw;
  597. for(p = uartalloc.elist; p; p = p->elist){
  598. /* this amortizes cost of qproduce to many chars */
  599. if(p->iw != p->ir){
  600. iw = p->iw;
  601. if(iw < p->ir){
  602. if(qproduce(p->iq, p->ir, p->ie-p->ir) < 0)
  603. (*p->phys->rts)(p, 0);
  604. p->ir = p->istage;
  605. }
  606. if(iw > p->ir)
  607. if(qproduce(p->iq, p->ir, iw-p->ir) < 0)
  608. (*p->phys->rts)(p, 0);
  609. p->ir = iw;
  610. }
  611. /* hang up if requested */
  612. if(p->dohup){
  613. qhangup(p->iq, 0);
  614. qhangup(p->oq, 0);
  615. p->dohup = 0;
  616. }
  617. /* this adds hysteresis to hardware/software flow control */
  618. if(p->ctsbackoff){
  619. ilock(&p->tlock);
  620. if(p->ctsbackoff){
  621. if(--(p->ctsbackoff) == 0)
  622. (*p->phys->kick)(p);
  623. }
  624. iunlock(&p->tlock);
  625. }
  626. }
  627. }
  628. /*
  629. * polling console input, output
  630. */
  631. Uart* consuart;
  632. int
  633. uartgetc(void)
  634. {
  635. if(consuart == nil || consuart->phys->getc == nil)
  636. return -1;
  637. return consuart->phys->getc(consuart);
  638. }
  639. void
  640. uartputc(int c)
  641. {
  642. if(consuart == nil || consuart->phys->putc == nil)
  643. return;
  644. consuart->phys->putc(consuart, c);
  645. }
  646. void
  647. uartputs(char *s, int n)
  648. {
  649. char *e;
  650. if(consuart == nil || consuart->phys->putc == nil)
  651. return;
  652. e = s+n;
  653. for(; s<e; s++){
  654. if(*s == '\n')
  655. consuart->phys->putc(consuart, '\r');
  656. consuart->phys->putc(consuart, *s);
  657. }
  658. }