Пример #1
0
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;
}
Пример #2
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);
}