Correct some stupid mistakes which prevented prolific to work. Reference: /n/sources/patch/applied/prolific Date: Mon Jun 14 17:51:11 CES 2010 Signed-off-by: paurea@lsub.org --- /sys/src/cmd/usb/serial/serial.c Mon Jun 14 17:50:54 2010 +++ /sys/src/cmd/usb/serial/serial.c Tue Jun 15 23:21:03 2010 @@ -1,8 +1,6 @@ /* * This part takes care of locking except for initialization and * other threads created by the hw dep. drivers. - * BUG: An error on the device does not make the driver exit. - * It probably should. */ #include @@ -40,48 +38,65 @@ static int sdebug; -int -serialnop(Serial *) -{ - return 0; -} - -int -serialnopctl(Serial *, int) -{ - return 0; -} - static void serialfatal(Serial *ser) { + Serialport *p; + int i; + dsprint(2, "serial: fatal error, detaching\n"); devctl(ser->dev, "detach"); - usbfsdel(&ser->fs); + + for(i = 0; i < ser->nifcs; i++){ + p = &ser->p[i]; + if(p->isjtag) + continue; + usbfsdel(&p->fs); + if(p->w4data != nil) + chanclose(p->w4data); + if(p->gotdata != nil) + chanclose(p->gotdata); + if(p->readc) + chanclose(p->readc); + } } /* I sleep with the lock... only way to drain in general */ static void -serialdrain(Serial *ser) +serialdrain(Serialport *p) { + Serial *ser; uint baud, pipesize; - if(ser->maxwrite < 256) + ser = p->s; + baud = p->baud; + + if(p->baud == ~0) + return; + if(ser->maxwtrans < 256) pipesize = 256; else - pipesize = ser->maxwrite; - baud = ser->baud; + pipesize = ser->maxwtrans; /* wait for the at least 256-byte pipe to clear */ sleep(10 + pipesize/((1 + baud)*1000)); if(ser->clearpipes != nil) - ser->clearpipes(ser); + ser->clearpipes(p); } +/* BUG: separate reset per port */ int serialreset(Serial *ser) { + Serialport *p; + int i; + /* cmd for reset */ - serialdrain(ser); + for(i = 0; i < ser->nifcs; i++){ + p = &ser->p[i]; + if(p->isjtag) + continue; + serialdrain(p); + } if(ser->reset != nil) ser->reset(ser); return 0; @@ -103,18 +118,20 @@ } static int -serialctl(Serial *p, char *cmd) +serialctl(Serialport *p, char *cmd) { + Serial *ser; int c, i, n, nf, nop, nw, par, drain, set, lines; char *f[16]; uchar x; + ser = p->s; drain = set = lines = 0; nf = tokenize(cmd, f, nelem(f)); for(i = 0; i < nf; i++){ if(strncmp(f[i], "break", 5) == 0){ - if(p->setbreak != nil) - p->setbreak(p, 1); + if(ser->setbreak != nil) + ser->setbreak(p, 1); continue; } @@ -156,9 +173,9 @@ break; case 'k': drain++; - p->setbreak(p, 1); + ser->setbreak(p, 1); sleep(n); - p->setbreak(p, 0); + ser->setbreak(p, 0); break; case 'l': drain++; @@ -167,8 +184,8 @@ break; case 'm': drain++; - if(p->modemctl != nil) - p->modemctl(p, n); + if(ser->modemctl != nil) + ser->modemctl(p, n); if(n == 0) p->cts = 0; break; @@ -220,12 +237,12 @@ x = CTLS; else x = CTLQ; - if(p->wait4write != nil) - nw = p->wait4write(p, &x, 1); + if(ser->wait4write != nil) + nw = ser->wait4write(p, &x, 1); else nw = write(p->epout->dfd, &x, 1); if(nw != 1){ - serialrecover(p, ""); + serialrecover(ser, ""); return -1; } break; @@ -241,10 +258,10 @@ if(drain) serialdrain(p); if(lines && !set){ - if(p->sendlines != nil && p->sendlines(p) < 0) + if(ser->sendlines != nil && ser->sendlines(p) < 0) return -1; } else if(set){ - if(p->setparam != nil && p->setparam(p) < 0) + if(ser->setparam != nil && ser->setparam(p) < 0) return -1; } return 0; @@ -253,44 +270,51 @@ char *pformat = "noems"; char * -serdumpst(Serial *ser, char *buf, int bufsz) +serdumpst(Serialport *p, char *buf, int bufsz) { char *e, *s; + Serial *ser; + + ser = p->s; e = buf + bufsz; - s = seprint(buf, e, "b%d ", ser->baud); - s = seprint(s, e, "c%d ", ser->dcd); /* unimplemented */ - s = seprint(s, e, "d%d ", ser->dtr); - s = seprint(s, e, "e%d ", ser->dsr); /* unimplemented */ - s = seprint(s, e, "l%d ", ser->bits); - s = seprint(s, e, "m%d ", ser->mctl); - if(ser->parity >= 0 || ser->parity < strlen(pformat)) - s = seprint(s, e, "p%c ", pformat[ser->parity]); + s = seprint(buf, e, "b%d ", p->baud); + s = seprint(s, e, "c%d ", p->dcd); /* unimplemented */ + s = seprint(s, e, "d%d ", p->dtr); + s = seprint(s, e, "e%d ", p->dsr); /* unimplemented */ + s = seprint(s, e, "l%d ", p->bits); + s = seprint(s, e, "m%d ", p->mctl); + if(p->parity >= 0 || p->parity < strlen(pformat)) + s = seprint(s, e, "p%c ", pformat[p->parity]); else s = seprint(s, e, "p%c ", '?'); - s = seprint(s, e, "r%d ", ser->rts); - s = seprint(s, e, "s%d ", ser->stop); - s = seprint(s, e, "i%d ", ser->fifo); + s = seprint(s, e, "r%d ", p->rts); + s = seprint(s, e, "s%d ", p->stop); + s = seprint(s, e, "i%d ", p->fifo); s = seprint(s, e, "\ndev(%d) ", 0); s = seprint(s, e, "type(%d) ", ser->type); - s = seprint(s, e, "framing(%d) ", ser->nframeerr); - s = seprint(s, e, "overruns(%d) ", ser->novererr); - s = seprint(s, e, "berr(%d) ", ser->nbreakerr); - s = seprint(s, e, " serr(%d) ", ser->nparityerr); + s = seprint(s, e, "framing(%d) ", p->nframeerr); + s = seprint(s, e, "overruns(%d) ", p->novererr); + s = seprint(s, e, "berr(%d) ", p->nbreakerr); + s = seprint(s, e, " serr(%d) ", p->nparityerr); return s; } static int -serinit(Serial *ser) +serinit(Serialport *p) { int res; - res = 0; + Serial *ser; + + ser = p->s; + if(ser->init != nil) - res = ser->init(ser); + res = ser->init(p); if(ser->getparam != nil) - ser->getparam(ser); - ser->nframeerr = ser->nparityerr = ser->nbreakerr = ser->novererr = 0; + ser->getparam(p); + p->nframeerr = p->nparityerr = p->nbreakerr = p->novererr = 0; + return res; } @@ -300,7 +324,7 @@ int i; char *dname; Qid qid; - Serial *ser; + Serialport *p; qid = fid->qid; if((qid.type & QTDIR) == 0){ @@ -316,9 +340,9 @@ return 0; } - ser = fs->aux; + p = fs->aux; for(i = 1; i < nelem(dirtab); i++){ - dname = smprint(dirtab[i].name, ser->fs.name); + dname = smprint(dirtab[i].name, p->fs.name); if(strcmp(name, dname) == 0){ qid.path = i | fs->qid; qid.vers = 0; @@ -337,18 +361,18 @@ dostat(Usbfs *fs, int path, Dir *d) { Dirtab *t; - Serial *ser; + Serialport *p; t = &dirtab[path]; d->qid.path = path; d->qid.type = t->mode >> 24; d->mode = t->mode; - ser = fs->aux; + p = fs->aux; if(strcmp(t->name, "/") == 0) d->name = t->name; else - snprint(d->name, Namesz, t->name, ser->fs.name); + snprint(d->name, Namesz, t->name, p->fs.name); d->length = 0; } @@ -367,10 +391,10 @@ dopen(Usbfs *fs, Fid *fid, int) { ulong path; - // Serial *ser; + // Serialport *p; path = fid->qid.path & ~fs->qid; - // ser = fs->aux; + // p = fs->aux; switch(path){ /* BUG: unneeded? */ case Qdata: dsprint(2, "serial, opened data\n"); @@ -417,12 +441,14 @@ ulong path; char *e, *buf, *err; /* change */ Qid q; + Serialport *p; Serial *ser; static int errrun, good; q = fid->qid; path = fid->qid.path & ~fs->qid; - ser = fs->aux; + p = fs->aux; + ser = p->s; buf = emallocz(Serbufsize, 1); err = emallocz(Serbufsize, 1); @@ -437,13 +463,13 @@ dsprint(2, "serial: reading from data\n"); do { err[0] = 0; - dfd = ser->epin->dfd; + dfd = p->epin->dfd; if(usbdebug >= 3) dsprint(2, "serial: reading: %ld\n", count); assert(count > 0); if(ser->wait4data != nil) - rcount = ser->wait4data(ser, data, count); + rcount = ser->wait4data(p, data, count); else{ qunlock(ser); rcount = read(dfd, data, count); @@ -462,7 +488,7 @@ /* the line has been dropped; give up */ qunlock(ser); fprint(2, "%s: line %s is gone: %r\n", - argv0, ser->fs.name); + argv0, p->fs.name); threadexitsall("serial line gone"); } } else { @@ -486,7 +512,7 @@ if(offset != 0) count = 0; else { - e = serdumpst(ser, buf, Serbufsize); + e = serdumpst(p, buf, Serbufsize); count = usbreadbuf(data, count, 0, buf, e - buf); } break; @@ -498,17 +524,19 @@ } static long -altwrite(Serial *ser, uchar *buf, long count) +altwrite(Serialport *p, uchar *buf, long count) { int nw, dfd; char err[128]; + Serial *ser; + ser = p->s; do{ if(ser->wait4write != nil) /* unlocked inside later */ - nw = ser->wait4write(ser, buf, count); + nw = ser->wait4write(p, buf, count); else{ - dfd = ser->epout->dfd; + dfd = p->epout->dfd; qunlock(ser); nw = write(dfd, buf, count); qlock(ser); @@ -520,7 +548,7 @@ dsprint(2, "serial: need to recover, status in write %d %r\n", nw); snprint(err, sizeof err, "%r"); - serialrecover(ser, err); + serialrecover(p->s, err); } return nw; } @@ -530,21 +558,23 @@ { ulong path; char *cmd; + Serialport *p; Serial *ser; - ser = fs->aux; + p = fs->aux; + ser = p->s; path = fid->qid.path & ~fs->qid; qlock(ser); switch(path){ case Qdata: - count = altwrite(ser, (uchar *)buf, count); + count = altwrite(p, (uchar *)buf, count); break; case Qctl: cmd = emallocz(count+1, 1); memmove(cmd, buf, count); cmd[count] = 0; - if(serialctl(ser, cmd) < 0){ + if(serialctl(p, cmd) < 0){ qunlock(ser); werrstr(Ebadctl); free(cmd); @@ -562,69 +592,69 @@ } static int -openeps(Serial *ser, int epin, int epout, int epintr) +openeps(Serialport *p, int epin, int epout, int epintr) { - ser->epin = openep(ser->dev, epin); - if(ser->epin == nil){ + Serial *ser; + + ser = p->s; + p->epin = openep(ser->dev, epin); + if(p->epin == nil){ fprint(2, "serial: openep %d: %r\n", epin); return -1; } - ser->epout = openep(ser->dev, epout); - if(ser->epout == nil){ + p->epout = openep(ser->dev, epout); + if(p->epout == nil){ fprint(2, "serial: openep %d: %r\n", epout); - closedev(ser->epin); + closedev(p->epin); return -1; } - devctl(ser->epin, "timeout 1000"); - devctl(ser->epout, "timeout 1000"); + devctl(p->epin, "timeout 1000"); + devctl(p->epout, "timeout 1000"); if(ser->hasepintr){ - ser->epintr = openep(ser->dev, epintr); - if(ser->epintr == nil){ + p->epintr = openep(ser->dev, epintr); + if(p->epintr == nil){ fprint(2, "serial: openep %d: %r\n", epintr); - closedev(ser->epin); - closedev(ser->epout); + closedev(p->epin); + closedev(p->epout); return -1; } - opendevdata(ser->epintr, OREAD); - devctl(ser->epintr, "timeout 1000"); + opendevdata(p->epintr, OREAD); + devctl(p->epintr, "timeout 1000"); } if(ser->seteps!= nil) - ser->seteps(ser); - opendevdata(ser->epin, OREAD); - opendevdata(ser->epout, OWRITE); - if(ser->epin->dfd < 0 || ser->epout->dfd < 0 || - (ser->hasepintr && ser->epintr->dfd < 0)){ + ser->seteps(p); + opendevdata(p->epin, OREAD); + opendevdata(p->epout, OWRITE); + if(p->epin->dfd < 0 ||p->epout->dfd < 0 || + (ser->hasepintr && p->epintr->dfd < 0)){ fprint(2, "serial: open i/o ep data: %r\n"); - closedev(ser->epin); - closedev(ser->epout); + closedev(p->epin); + closedev(p->epout); if(ser->hasepintr) - closedev(ser->epintr); + closedev(p->epintr); return -1; } return 0; } static int -findendpoints(Serial *ser) +findendpoints(Serial *ser, int ifc) { int i, epin, epout, epintr; Ep *ep, **eps; - Usbdev *ud; + ///Usbdev *ud; epintr = epin = epout = -1; - ud = ser->dev->usb; + //ud = ser->dev->usb; /* * interfc 0 means start from the start which is equiv to * iterate through endpoints probably, could be done better */ - if(ser->interfc == 0) - eps = ud->ep; - else - eps = ser->dev->usb->conf[0]->iface[ser->interfc]->ep; + eps = ser->dev->usb->conf[0]->iface[ifc]->ep; for(i = 0; i < Niface; i++){ if((ep = eps[i]) == nil) @@ -639,22 +669,22 @@ epout = ep->id; } } - dprint(2, "serial: ep ids: in %d out %d intr %d\n", epin, epout, epintr); + dprint(2, "serial[%d]: ep ids: in %d out %d intr %d\n", ifc, epin, epout, epintr); if(epin == -1 || epout == -1 || (ser->hasepintr && epintr == -1)) return -1; - if(openeps(ser, epin, epout, epintr) < 0) + if(openeps(&ser->p[ifc], epin, epout, epintr) < 0) return -1; - dprint(2, "serial: ep in %s out %s\n", ser->epin->dir, ser->epout->dir); + dprint(2, "serial: ep in %s out %s\n", ser->p[ifc].epin->dir, ser->p[ifc].epout->dir); if(ser->hasepintr) - dprint(2, "serial: ep intr %s\n", ser->epintr->dir); + dprint(2, "serial: ep intr %s\n", ser->p[ifc].epintr->dir); if(usbdebug > 1 || serialdebug > 2){ - devctl(ser->epin, "debug 1"); - devctl(ser->epout, "debug 1"); + devctl(ser->p[ifc].epin, "debug 1"); + devctl(ser->p[ifc].epout, "debug 1"); if(ser->hasepintr) - devctl(ser->epintr, "debug 1"); + devctl(ser->p[ifc].epintr, "debug 1"); devctl(ser->dev, "debug 1"); } return 0; @@ -672,17 +702,28 @@ serdevfree(void *a) { Serial *ser = a; + Serialport *p; + int i; if(ser == nil) return; - if(ser->hasepintr) - closedev(ser->epintr); - closedev(ser->epin); - closedev(ser->epout); - ser->epintr = ser->epin = ser->epout = nil; - chanfree(ser->w4data); - chanfree(ser->gotdata); - chanfree(ser->w4empty); + + for(i = 0; i < ser->nifcs; i++){ + p = &ser->p[i]; + + if(ser->hasepintr) + closedev(p->epintr); + closedev(p->epin); + closedev(p->epout); + p->epintr = p->epin = p->epout = nil; + if(p->w4data != nil) + chanfree(p->w4data); + if(p->gotdata != nil) + chanfree(p->gotdata); + if(p->readc) + chanfree(p->readc); + + } free(ser); } @@ -694,11 +735,28 @@ .stat = dstat, }; +static void +serialfsend(Usbfs *fs) +{ + Serialport *p; + + p = fs->aux; + + if(p->w4data != nil) + chanclose(p->w4data); + if(p->gotdata != nil) + chanclose(p->gotdata); + if(p->readc) + chanclose(p->readc); +} + int serialmain(Dev *dev, int argc, char* argv[]) { Serial *ser; + Serialport *p; char buf[50]; + int i; ARGBEGIN{ case 'd': @@ -711,55 +769,68 @@ return usage(); ser = dev->aux = emallocz(sizeof(Serial), 1); - /* BUG: could this go wrong? channel leaks? */ - ser->w4data = chancreate(sizeof(ulong), 0); - ser->gotdata = chancreate(sizeof(ulong), 0); - ser->w4empty = chancreate(sizeof(ulong), 0); - ser->maxread = ser->maxwrite = sizeof ser->data; + ser->maxrtrans = ser->maxwtrans = sizeof ser->p[0].data; + ser->maxread = ser->maxwrite = sizeof ser->p[0].data; ser->dev = dev; dev->free = serdevfree; + ser->jtag = -1; + ser->nifcs = 1; snprint(buf, sizeof buf, "vid %#06x did %#06x", dev->usb->vid, dev->usb->did); - ser->fs = serialfs; if(plmatch(buf) == 0){ ser->hasepintr = 1; ser->Serialops = plops; - } else if(uconsmatch(buf) == 0) + } else if(uconsmatch(buf) == 0){ ser->Serialops = uconsops; - else if(ftmatch(ser, buf) == 0) + } else if(ftmatch(ser, buf) == 0) ser->Serialops = ftops; else { werrstr("serial: no serial devices found"); - closedev(dev); return -1; } - if(findendpoints(ser) < 0){ - werrstr("serial: no endpoints found"); - closedev(dev); - return -1; - } - if(serinit(ser) < 0){ - dprint(2, "serial: serinit: %r\n"); - closedev(dev); - return -1; + for(i = 0; i < ser->nifcs; i++){ + p = &ser->p[i]; + p->interfc = i; + if(i == ser->jtag){ + p->isjtag++; + continue; + } + p->s = ser; + p->fs = serialfs; + if(findendpoints(ser, i) < 0){ + werrstr("serial: no endpoints found for ifc %d", i); + return -1; + } + p->w4data = chancreate(sizeof(ulong), 0); + p->gotdata = chancreate(sizeof(ulong), 0); } - dirtab[Qdata].name = smprint("eiau%d", dev->id); - dirtab[Qctl].name = smprint("eiau%dctl", dev->id); - /* - * it would nice to get rid of this extra level of directory, - * thus reducing /dev/eiaU6/eiau6* to /dev/eiau6* - * for easier binding into /dev with `bind -a /dev/eiaU* /dev'. - */ - snprint(ser->fs.name, sizeof ser->fs.name, "eiaU%d", dev->id); - fprint(2, "%s\n", ser->fs.name); - ser->fs.dev = dev; - incref(dev); - ser->fs.aux = ser; - usbfsadd(&ser->fs); + qlock(ser); + serialreset(ser); + for(i = 0; i < ser->nifcs; i++){ + p = &ser->p[i]; + if(p->isjtag){ + dsprint(2, "serial: ignoring JTAG interface %d %p\n", i, p); + continue; + } + dprint(2, "serial: valid interface, calling serinit\n"); + if(serinit(p) < 0){ + dprint(2, "serial: serinit: %r\n"); + return -1; + } + + dsprint(2, "serial: adding interface %d, %p\n", p->interfc, p); + snprint(p->fs.name, sizeof p->fs.name, "eiaU%d", dev->id+i-1); + fprint(2, "%s\n", p->fs.name); + p->fs.dev = dev; + incref(dev); + p->fs.aux = p; + p->fs.end = serialfsend; + usbfsadd(&p->fs); + } - closedev(dev); + qunlock(ser); return 0; } --- /sys/src/cmd/usb/serial/prolific.c Mon Jun 14 17:50:59 2010 +++ /sys/src/cmd/usb/serial/prolific.c Mon Jun 14 17:50:56 2010 @@ -81,9 +81,12 @@ } static int -vendorread(Serial *ser, int val, int index, uchar *buf) +vendorread(Serialport *p, int val, int index, uchar *buf) { int res; + Serial *ser; + + ser = p->s; dsprint(2, "serial: vendorread val: 0x%x idx:%d buf:%p\n", val, index, buf); @@ -94,9 +97,12 @@ } static int -vendorwrite(Serial *ser, int val, int index) +vendorwrite(Serialport *p, int val, int index) { int res; + Serial *ser; + + ser = p->s; dsprint(2, "serial: vendorwrite val: 0x%x idx:%d\n", val, index); res = usbcmd(ser->dev, Rh2d | Rvendor | Rdev, VendorWriteReq, @@ -107,31 +113,39 @@ /* BUG: I could probably read Dcr0 and set only the bits */ static int -plmodemctl(Serial *ser, int set) +plmodemctl(Serialport *p, int set) { + Serial *ser; + + ser = p->s; + if(set == 0){ - ser->mctl = 0; - vendorwrite(ser, Dcr0Idx|DcrSet, Dcr0Init); + p->mctl = 0; + vendorwrite(p, Dcr0Idx|DcrSet, Dcr0Init); return 0; } - ser->mctl = 1; + p->mctl = 1; if(ser->type == TypeHX) - vendorwrite(ser, Dcr0Idx|DcrSet, Dcr0Init|Dcr0HwFcX); + vendorwrite(p, Dcr0Idx|DcrSet, Dcr0Init|Dcr0HwFcX); else - vendorwrite(ser, Dcr0Idx|DcrSet, Dcr0Init|Dcr0HwFcH); + vendorwrite(p, Dcr0Idx|DcrSet, Dcr0Init|Dcr0HwFcH); return 0; } static int -plgetparam(Serial *ser) +plgetparam(Serialport *p) { uchar buf[ParamReqSz]; int res; + Serial *ser; + + ser = p->s; + res = usbcmd(ser->dev, Rd2h | Rclass | Riface, GetLineReq, 0, 0, buf, sizeof buf); - ser->baud = GET4(buf); + p->baud = GET4(buf); /* * with the Pl9 interface it is not possible to set `1.5' as stop bits @@ -143,11 +157,11 @@ if(buf[4] == 1) fprint(2, "warning, stop bit set to 1.5 unsupported"); else if(buf[4] == 0) - ser->stop = 1; + p->stop = 1; else if(buf[4] == 2) - ser->stop = 2; - ser->parity = buf[5]; - ser->bits = buf[6]; + p->stop = 2; + p->parity = buf[5]; + p->bits = buf[6]; dsprint(2, "serial: getparam: "); if(serialdebug) @@ -157,27 +171,30 @@ } static int -plsetparam(Serial *ser) +plsetparam(Serialport *p) { uchar buf[ParamReqSz]; int res; + Serial *ser; + + ser = p->s; - PUT4(buf, ser->baud); + PUT4(buf, p->baud); - if(ser->stop == 1) + if(p->stop == 1) buf[4] = 0; - else if(ser->stop == 2) + else if(p->stop == 2) buf[4] = 2; /* see comment in getparam */ - buf[5] = ser->parity; - buf[6] = ser->bits; + buf[5] = p->parity; + buf[6] = p->bits; dsprint(2, "serial: setparam: "); if(serialdebug) dumpbuf(buf, sizeof buf); res = usbcmd(ser->dev, Rh2d | Rclass | Riface, SetLineReq, 0, 0, buf, sizeof buf); - plmodemctl(ser, ser->mctl); - plgetparam(ser); /* make sure our state corresponds */ + plmodemctl(p, p->mctl); + plgetparam(p); /* make sure our state corresponds */ dsprint(2, "serial: setparam res: %d\n", res); return res; @@ -215,15 +232,16 @@ } static int -plinit(Serial *ser) +plinit(Serialport *p) { char *st; uchar *buf; ulong csp, maxpkt, dno; + Serial *ser; + ser = p->s; buf = emallocz(VendorReqSz, 1); - qlock(ser); - serialreset(ser); + dsprint(2, "plinit\n"); csp = ser->dev->usb->csp; maxpkt = ser->dev->maxpkt; @@ -234,105 +252,117 @@ dsprint(2, "serial: type %d\n", ser->type); - vendorread(ser, 0x8484, 0, buf); - vendorwrite(ser, 0x0404, 0); - vendorread(ser, 0x8484, 0, buf); - vendorread(ser, 0x8383, 0, buf); - vendorread(ser, 0x8484, 0, buf); - vendorwrite(ser, 0x0404, 1); - vendorread(ser, 0x8484, 0, buf); - vendorread(ser, 0x8383, 0, buf); + vendorread(p, 0x8484, 0, buf); + vendorwrite(p, 0x0404, 0); + vendorread(p, 0x8484, 0, buf); + vendorread(p, 0x8383, 0, buf); + vendorread(p, 0x8484, 0, buf); + vendorwrite(p, 0x0404, 1); + vendorread(p, 0x8484, 0, buf); + vendorread(p, 0x8383, 0, buf); - vendorwrite(ser, Dcr0Idx|DcrSet, Dcr0Init); - vendorwrite(ser, Dcr1Idx|DcrSet, Dcr1Init); + vendorwrite(p, Dcr0Idx|DcrSet, Dcr0Init); + vendorwrite(p, Dcr1Idx|DcrSet, Dcr1Init); if(ser->type == TypeHX) - vendorwrite(ser, Dcr2Idx|DcrSet, Dcr2InitX); + vendorwrite(p, Dcr2Idx|DcrSet, Dcr2InitX); else - vendorwrite(ser, Dcr2Idx|DcrSet, Dcr2InitH); + vendorwrite(p, Dcr2Idx|DcrSet, Dcr2InitH); - plgetparam(ser); + plgetparam(p); qunlock(ser); free(buf); st = emallocz(255, 1); qlock(ser); if(serialdebug) - serdumpst(ser, st, 255); + serdumpst(p, st, 255); dsprint(2, st); - qunlock(ser); free(st); - /* ser gets freed by closedev, the process has a reference */ + /* p gets freed by closedev, the process has a reference */ incref(ser->dev); - proccreate(statusreader, ser, 8*1024); + proccreate(statusreader, p, 8*1024); return 0; } static int -plsetbreak(Serial *ser, int val) +plsetbreak(Serialport *p, int val) { + Serial *ser; + + ser = p->s; return usbcmd(ser->dev, Rh2d | Rclass | Riface, (val != 0? BreakOn: BreakOff), val, 0, nil, 0); } static int -plclearpipes(Serial *ser) +plclearpipes(Serialport *p) { + Serial *ser; + + ser = p->s; + if(ser->type == TypeHX){ - vendorwrite(ser, PipeDSRst, 0); - vendorwrite(ser, PipeUSRst, 0); + vendorwrite(p, PipeDSRst, 0); + vendorwrite(p, PipeUSRst, 0); }else{ - if(unstall(ser->dev, ser->epout, Eout) < 0) + if(unstall(ser->dev, p->epout, Eout) < 0) dprint(2, "disk: unstall epout: %r\n"); - if(unstall(ser->dev, ser->epin, Ein) < 0) + if(unstall(ser->dev, p->epin, Ein) < 0) dprint(2, "disk: unstall epin: %r\n"); - if(unstall(ser->dev, ser->epintr, Ein) < 0) + if(unstall(ser->dev, p->epintr, Ein) < 0) dprint(2, "disk: unstall epintr: %r\n"); } return 0; } static int -setctlline(Serial *ser, uchar val) +setctlline(Serialport *p, uchar val) { + Serial *ser; + + ser = p->s; return usbcmd(ser->dev, Rh2d | Rclass | Riface, SetCtlReq, val, 0, nil, 0); } static void -composectl(Serial *ser) +composectl(Serialport *p) { - if(ser->rts) - ser->ctlstate |= CtlRTS; + if(p->rts) + p->ctlstate |= CtlRTS; else - ser->ctlstate &= ~CtlRTS; - if(ser->dtr) - ser->ctlstate |= CtlDTR; + p->ctlstate &= ~CtlRTS; + if(p->dtr) + p->ctlstate |= CtlDTR; else - ser->ctlstate &= ~CtlDTR; + p->ctlstate &= ~CtlDTR; } -int -plsendlines(Serial *ser) +static int +plsendlines(Serialport *p) { int res; - dsprint(2, "serial: sendlines: %#2.2x\n", ser->ctlstate); - composectl(ser); - res = setctlline(ser, ser->ctlstate); + dsprint(2, "serial: sendlines: %#2.2x\n", p->ctlstate); + composectl(p); + res = setctlline(p, p->ctlstate); dsprint(2, "serial: sendlines res: %d\n", res); return 0; } static int -plreadstatus(Serial *ser) +plreadstatus(Serialport *p) { int nr, dfd; char err[40]; uchar buf[VendorReqSz]; + Serial *ser; + + ser = p->s; qlock(ser); dsprint(2, "serial: reading from interrupt\n"); - dfd = ser->epintr->dfd; + dfd = p->epintr->dfd; qunlock(ser); nr = read(dfd, buf, sizeof buf); @@ -350,17 +380,17 @@ if(nr < 0) dsprint(2, "serial: reading status: %r"); else if(nr >= sizeof buf - 1){ - ser->dcd = buf[8] & DcdStatus; - ser->dsr = buf[8] & DsrStatus; - ser->cts = buf[8] & BreakerrStatus; - ser->ring = buf[8] & RingStatus; - ser->cts = buf[8] & CtsStatus; + p->dcd = buf[8] & DcdStatus; + p->dsr = buf[8] & DsrStatus; + p->cts = buf[8] & BreakerrStatus; + p->ring = buf[8] & RingStatus; + p->cts = buf[8] & CtsStatus; if(buf[8] & FrerrStatus) - ser->nframeerr++; + p->nframeerr++; if(buf[8] & ParerrStatus) - ser->nparityerr++; + p->nparityerr++; if(buf[8] & OvererrStatus) - ser->novererr++; + p->novererr++; } else dsprint(2, "serial: bad status read %d\n", nr); dsprint(2, "serial: finished read from interrupt %d\n", nr); @@ -371,11 +401,13 @@ static void statusreader(void *u) { + Serialport *p; Serial *ser; - ser = u; + p = u; + ser = p->s; threadsetname("statusreaderproc"); - while(plreadstatus(ser) >= 0) + while(plreadstatus(p) >= 0) ; fprint(2, "serial: statusreader exiting\n"); closedev(ser->dev); @@ -387,10 +419,10 @@ */ static int -plseteps(Serial *ser) +plseteps(Serialport *p) { - devctl(ser->epin, "maxpkt 256"); - devctl(ser->epout, "maxpkt 256"); + devctl(p->epin, "maxpkt 256"); + devctl(p->epout, "maxpkt 256"); return 0; }