2 * This part takes care of locking except for initialization and
3 * other threads created by the hw dep. drivers.
26 serialfatal(Serial *ser)
31 dsprint(2, "serial: fatal error, detaching\n");
32 devctl(ser->dev, "detach");
34 for(i = 0; i < ser->nifcs; i++){
39 chanclose(p->gotdata);
45 /* I sleep with the lock... only way to drain in general */
47 serialdrain(Serialport *p)
57 if(ser->maxwtrans < 256)
60 pipesize = ser->maxwtrans;
61 /* wait for the at least 256-byte pipe to clear */
62 sleep(10 + pipesize/((1 + baud)*1000));
63 if(ser->clearpipes != nil)
68 serialreset(Serial *ser)
75 for(i = 0; i < ser->nifcs; i++){
80 res = ser->reset(ser, nil);
84 /* call this if something goes wrong, must be qlocked */
86 serialrecover(Serial *ser, Serialport *p, Dev *ep, char *err)
89 dprint(2, "serial[%d], %s: %s, level %d\n", p->interfc,
90 p->name, err, ser->recover);
92 dprint(2, "serial[%s], global error, level %d\n",
93 ser->p[0].name, ser->recover);
95 if(strstr(err, "detached") != nil)
101 unstall(ser->dev, p->epintr, Ein);
103 unstall(ser->dev, p->epin, Ein);
105 unstall(ser->dev, p->epout, Eout);
110 unstall(ser->dev, p->epintr, Ein);
112 unstall(ser->dev, p->epin, Ein);
114 unstall(ser->dev, p->epout, Eout);
118 if(ser->recover > 4 && ser->recover < 8)
120 if(ser->recover > 8){
124 if(serialreset(ser) < 0)
130 serialctl(Serialport *p, char *cmd)
133 int c, i, n, nf, nop, nw, par, drain, set, lines;
138 drain = set = lines = 0;
139 nf = tokenize(cmd, f, nelem(f));
140 for(i = 0; i < nf; i++){
141 if(strncmp(f[i], "break", 5) == 0){
142 if(ser->setbreak != nil)
150 if (isascii(c) && isupper(c))
172 case 'f': /* flush the pipes */
175 case 'h': /* hangup?? */
178 fprint(2, "serial: %c, unsure ctl\n", c);
196 if(ser->modemctl != nil)
205 case 'p': /* extended... */
206 if(strlen(f[i]) != 2)
216 else if(par == 'm') /* mark parity */
218 else if(par == 's') /* space parity */
240 /* ?? how do I put this */
241 p->timer = n * 100000LL;
249 if(ser->wait4write != nil)
250 nw = ser->wait4write(p, &x, 1);
252 nw = write(p->epout->dfd, &x, 1);
254 serialrecover(ser, p, p->epout, "");
260 * don't print. the condition is harmless and the print
261 * splatters all over the display.
265 fprint(2, "serial: %c, unsupported nop ctl\n", c);
270 if(ser->sendlines != nil && ser->sendlines(p) < 0)
273 if(ser->setparam != nil && ser->setparam(p) < 0)
280 char *pformat = "noems";
283 serdumpst(Serialport *p, char *buf, int bufsz)
291 s = seprint(buf, e, "b%d ", p->baud);
292 s = seprint(s, e, "c%d ", p->dcd); /* unimplemented */
293 s = seprint(s, e, "d%d ", p->dtr);
294 s = seprint(s, e, "e%d ", p->dsr); /* unimplemented */
295 s = seprint(s, e, "l%d ", p->bits);
296 s = seprint(s, e, "m%d ", p->mctl);
297 if(p->parity >= 0 || p->parity < strlen(pformat))
298 s = seprint(s, e, "p%c ", pformat[p->parity]);
300 s = seprint(s, e, "p%c ", '?');
301 s = seprint(s, e, "r%d ", p->rts);
302 s = seprint(s, e, "s%d ", p->stop);
303 s = seprint(s, e, "i%d ", p->fifo);
304 s = seprint(s, e, "\ndev(%d) ", 0);
305 s = seprint(s, e, "type(%d) ", ser->type);
306 s = seprint(s, e, "framing(%d) ", p->nframeerr);
307 s = seprint(s, e, "overruns(%d) ", p->novererr);
308 s = seprint(s, e, "berr(%d) ", p->nbreakerr);
309 s = seprint(s, e, " serr(%d)\n", p->nparityerr);
314 serinit(Serialport *p)
324 if(ser->getparam != nil)
326 p->nframeerr = p->nparityerr = p->nbreakerr = p->novererr = 0;
334 req->fid->qid = (Qid) {0, 0, QTDIR};
335 req->ofcall.qid = req->fid->qid;
340 dirgen(int n, Dir *d, void *)
350 d->uid = strdup("usb");
351 d->gid = strdup(d->uid);
352 d->muid = strdup(d->uid);
354 d->name = smprint((n & 1) ? "%sctl" : "%s", ports[n/2]->name);
355 d->mode = ((n & 1) ? 0664 : 0660);
357 d->name = strdup("");
358 d->mode = 0555 | QTDIR;
360 d->atime = d->mtime = time(0);
366 dwalk(Fid *fid, char *name, Qid *qidp)
374 if((qid.type & QTDIR) == 0){
375 return "walk in non-directory";
378 if(strcmp(name, "..") == 0){
381 fid->qid.type = QTDIR;
386 for(i = 0; i < nports; i++)
387 if(strncmp(name, ports[i]->name, len = strlen(ports[i]->name)) == 0){
390 fid->qid.path = 2 * i + 1;
391 else if(strcmp(p, "ctl") == 0)
392 fid->qid.path = 2 * i + 2;
400 return "does not exist";
406 if(dirgen(req->fid->qid.path - 1, &req->d, nil) < 0)
407 respond(req, "the front fell off");
425 static int errrun, good;
426 char err[Serbufsize];
432 while(p->readfirst == nil)
433 rsleep(&p->readrend);
435 p->readfirst = req->aux;
436 if(p->readlast == req)
441 count = req->ifcall.count;
442 data = req->ofcall.data;
444 if(count > ser->maxread)
445 count = ser->maxread;
446 dsprint(2, "serial: reading from data\n");
451 dsprint(2, "serial: reading: %ld\n", count);
454 if(ser->wait4data != nil)
455 rcount = ser->wait4data(p, data, count);
458 rcount = read(dfd, data, count);
462 * if we encounter a long run of continuous read
463 * errors, do something drastic so that our caller
464 * doesn't just spin its wheels forever.
467 snprint(err, Serbufsize, "%r");
470 if (good > 0 && errrun > 10000) {
471 /* the line has been dropped; give up */
473 fprint(2, "%s: line %s is gone: %r\n",
475 threadexitsall("serial line gone");
482 dsprint(2, "serial: read: %s %ld\n", err, rcount);
483 } while(rcount < 0 && strstr(err, "timed out") != nil);
485 dsprint(2, "serial: read from bulk %ld, %10.10s\n", rcount, err);
487 dsprint(2, "serial: need to recover, data read %ld %r\n",
489 serialrecover(ser, p, p->epin, err);
491 dsprint(2, "serial: read from bulk %ld\n", rcount);
493 req->ofcall.count = rcount;
504 char *e; /* change */
509 static char buf[Serbufsize];
514 dirread9p(req, dirgen, nil);
519 p = ports[(q.path - 1) / 2];
521 offset = req->ifcall.offset;
523 memset(buf, 0, sizeof buf);
525 switch((long)((q.path - 1) % 2)){
528 if(p->readfirst == nil)
531 p->readlast->aux = req;
533 rwakeup(&p->readrend);
539 e = serdumpst(p, buf, Serbufsize);
540 readbuf(req, buf, e - buf);
550 altwrite(Serialport *p, uchar *buf, long count)
558 dsprint(2, "serial: write to bulk %ld\n", count);
560 if(ser->wait4write != nil)
561 /* unlocked inside later */
562 nw = ser->wait4write(p, buf, count);
566 nw = write(dfd, buf, count);
569 rerrstr(err, sizeof err);
570 dsprint(2, "serial: written %s %d\n", err, nw);
571 } while(nw < 0 && strstr(err, "timed out") != nil);
574 dsprint(2, "serial: need to recover, status in write %d %r\n",
576 snprint(err, sizeof err, "%r");
577 serialrecover(p->s, p, p->epout, err);
592 path = req->fid->qid.path;
593 p = ports[(path-1)/2];
595 count = req->ifcall.count;
596 buf = req->ifcall.data;
599 switch((long)((path-1)%2)){
601 count = altwrite(p, (uchar *)buf, count);
606 cmd = emallocz(count+1, 1);
607 memmove(cmd, buf, count);
609 if(serialctl(p, cmd) < 0){
612 respond(req, "bad control request");
621 serialrecover(ser, p, p->epout, "writing");
624 req->ofcall.count = count;
631 openeps(Serialport *p, int epin, int epout, int epintr)
636 p->epin = openep(ser->dev, epin);
638 fprint(2, "serial: openep %d: %r\n", epin);
645 p->epout = openep(ser->dev, epout);
647 fprint(2, "serial: openep %d: %r\n", epout);
653 devctl(p->epin, "timeout 1000");
654 devctl(p->epout, "timeout 1000");
658 p->epintr = openep(ser->dev, epintr);
659 if(p->epintr == nil){
660 fprint(2, "serial: openep %d: %r\n", epintr);
665 opendevdata(p->epintr, OREAD);
666 devctl(p->epintr, "timeout 1000");
669 if(ser->seteps!= nil)
671 if(p->epin == p->epout)
672 opendevdata(p->epin, ORDWR);
674 opendevdata(p->epin, OREAD);
675 opendevdata(p->epout, OWRITE);
677 if(p->epin->dfd < 0 || p->epout->dfd < 0 ||
678 (ser->hasepintr && p->epintr->dfd < 0)){
679 fprint(2, "serial: open i/o ep data: %r\n");
690 findendpoints(Serial *ser, int ifc)
692 int i, epin, epout, epintr;
695 epintr = epin = epout = -1;
698 * interfc 0 means start from the start which is equiv to
699 * iterate through endpoints probably, could be done better
701 eps = ser->dev->usb->conf[0]->iface[ifc]->ep;
703 for(i = 0; i < Nep; i++){
704 if((ep = eps[i]) == nil)
706 if(ser->hasepintr && ep->type == Eintr &&
707 ep->dir == Ein && epintr == -1)
709 if(ep->type == Ebulk){
710 if((ep->dir == Ein || ep->dir == Eboth) && epin == -1)
712 if((ep->dir == Eout || ep->dir == Eboth) && epout == -1)
716 dprint(2, "serial[%d]: ep ids: in %d out %d intr %d\n", ifc, epin, epout, epintr);
717 if(epin == -1 || epout == -1 || (ser->hasepintr && epintr == -1))
720 if(openeps(&ser->p[ifc], epin, epout, epintr) < 0)
723 dprint(2, "serial: ep in %s out %s\n", ser->p[ifc].epin->dir, ser->p[ifc].epout->dir);
725 dprint(2, "serial: ep intr %s\n", ser->p[ifc].epintr->dir);
727 if(usbdebug > 1 || serialdebug > 2){
728 devctl(ser->p[ifc].epin, "debug 1");
729 devctl(ser->p[ifc].epout, "debug 1");
731 devctl(ser->p[ifc].epintr, "debug 1");
732 devctl(ser->dev, "debug 1");
737 /* keep in sync with main.c */
741 fprint(2, "usage: %s [-d] devid\n", argv0);
742 threadexitsall("usage");
755 for(i = 0; i < ser->nifcs; i++){
762 p->epintr = p->epin = p->epout = nil;
765 if(p->gotdata != nil)
766 chanfree(p->gotdata);
774 static Srv serialfs = {
787 chanclose(p->w4data);
788 if(p->gotdata != nil)
789 chanclose(p->gotdata);
796 threadmain(int argc, char* argv[])
813 dev = getdev(atoi(*argv));
815 sysfatal("getdev: %r");
817 ser = dev->aux = emallocz(sizeof(Serial), 1);
818 ser->maxrtrans = ser->maxwtrans = sizeof ser->p[0].data;
819 ser->maxread = ser->maxwrite = sizeof ser->p[0].data;
821 dev->free = serdevfree;
825 snprint(buf, sizeof buf, "vid %#06x did %#06x",
826 dev->usb->vid, dev->usb->did);
827 if(plmatch(buf) == 0){
829 ser->Serialops = plops;
830 } else if(uconsmatch(buf) == 0)
831 ser->Serialops = uconsops;
832 else if(ftmatch(ser, buf) == 0)
833 ser->Serialops = ftops;
834 else if(slmatch(buf) == 0)
835 ser->Serialops = slops;
837 sysfatal("no serial devices found");
839 for(i = 0; i < ser->nifcs; i++){
846 if(findendpoints(ser, i) < 0)
847 sysfatal("no endpoints found for ifc %d", i);
848 p->w4data = chancreate(sizeof(ulong), 0);
849 p->gotdata = chancreate(sizeof(ulong), 0);
854 for(i = 0; i < ser->nifcs; i++){
856 dprint(2, "serial: valid interface, calling serinit\n");
858 sysfatal("wserinit: %r");
861 dsprint(2, "serial: adding interface %d, %p\n", p->interfc, p);
863 snprint(p->name, sizeof p->name, "jtag");
864 dsprint(2, "serial: JTAG interface %d %p\n", i, p);
865 snprint(p->name, sizeof p->name, "jtag%d.%d", dev->id, i);
867 snprint(p->name, sizeof p->name, "eiaU");
869 snprint(p->name, sizeof p->name, "eiaU%d", dev->id);
871 snprint(p->name, sizeof p->name, "eiaU%d.%d", dev->id, i);
873 fprint(2, "%s...", p->name);
875 p->readrend.l = &p->readq;
876 p->readpid = proccreate(readproc, p, mainstacksize);
877 ports = realloc(ports, (nports + 1) * sizeof(Serialport*));
884 threadexits("no ports");
886 snprint(buf, sizeof buf, "%d.serial", dev->id);
887 threadpostsharesrv(&serialfs, nil, "usb", buf);