static int plreadstatus(Serialport *p) { int nr, dfd; char err[40]; uint8_t buf[VendorReqSz]; Serial *ser; ser = p->s; qlock(ser); dsprint(2, "serial: reading from interrupt\n"); dfd = p->epintr->dfd; qunlock(ser); nr = read(dfd, buf, sizeof buf); qlock(ser); snprint(err, sizeof err, "%r"); dsprint(2, "serial: interrupt read %d %r\n", nr); if(nr < 0 && strstr(err, "timed out") == nil){ dsprint(2, "serial: need to recover, status read %d %r\n", nr); if(serialrecover(ser, nil, nil, err) < 0){ qunlock(ser); return -1; } } if(nr < 0) dsprint(2, "serial: reading status: %r"); else if(nr >= sizeof buf - 1){ 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) p->nframeerr++; if(buf[8] & ParerrStatus) p->nparityerr++; if(buf[8] & OvererrStatus) p->novererr++; } else dsprint(2, "serial: bad status read %d\n", nr); dsprint(2, "serial: finished read from interrupt %d\n", nr); qunlock(ser); return 0; }
static void epreader(void *u) { int dfd, rcount, cl, ntries, recov; Areader *a; Channel *c; Packser *pk; Serial *ser; Serialport *p; threadsetname("epreader proc"); a = u; p = a->p; ser = p->s; c = a->c; free(a); qlock(ser); /* this makes the reader wait end of initialization too */ dfd = p->epin->dfd; qunlock(ser); ntries = 0; pk = nil; for(;;) { if (pk == nil) pk = emallocz(sizeof(Packser), 1); Eagain: rcount = read(dfd, pk->b, sizeof pk->b); if(serialdebug > 5) dsprint(2, "%d %#ux%#ux ", rcount, p->data[0], p->data[1]); if(rcount < 0) { if(ntries++ > 100) break; qlock(ser); recov = serialrecover(ser, p, nil, "epreader: bulkin error"); qunlock(ser); if(recov >= 0) goto Eagain; } if(rcount == 0) continue; if(rcount >= ser->inhdrsz) { rcount = cpdata(ser, p, pk->b, pk->b, rcount); if(rcount != 0) { pk->nb = rcount; cl = sendp(c, pk); if(cl < 0) { /* * if it was a time-out, I don't want * to give back an error. */ rcount = 0; break; } } else free(pk); qlock(ser); ser->recover = 0; qunlock(ser); ntries = 0; pk = nil; } } if(rcount < 0) fprint(2, "%s: error reading %s: %r\n", argv0, p->name); free(pk); nbsendp(c, nil); if(p->w4data != nil) chanclose(p->w4data); if(p->gotdata != nil) chanclose(p->gotdata); devctl(ser->dev, "detach"); closedev(ser->dev); }