From 78ee7d5717807e6ac779293d0d3c78341de6130a Mon Sep 17 00:00:00 2001 From: "Konstantin Kirik (snegovick)" Date: Sun, 28 Dec 2025 12:27:31 +0300 Subject: Move existing boards into subdits split per arch --- os/pc/devusb.c | 951 --------------------------------------------------------- 1 file changed, 951 deletions(-) delete mode 100644 os/pc/devusb.c (limited to 'os/pc/devusb.c') diff --git a/os/pc/devusb.c b/os/pc/devusb.c deleted file mode 100644 index 56a3442a..00000000 --- a/os/pc/devusb.c +++ /dev/null @@ -1,951 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -#include "usb.h" - -static int debug = 0; - -#define Chatty 1 -#define DPRINT if(Chatty)print -#define XPRINT if(debug)iprint - -Usbhost* usbhost[MaxUsb]; - -static char *devstates[] = { - [Disabled] "Disabled", - [Attached] "Attached", - [Enabled] "Enabled", - [Assigned] "Assigned", - [Configured] "Configured", -}; - -static char Ebadusbmsg[] = "invalid parameters to USB ctl message"; - -enum -{ - Qtopdir = 0, - Q2nd, - Qnew, - Qport, - Q3rd, - Qctl, - Qstatus, - Qep0, - /* other endpoint files */ -}; - -/* - * Qid path is: - * 8 bits of file type (qids above) - * 8 bits of slot number; default address 0 used for per-controller files - * 4 bits of controller number - */ -enum { - TYPEBITS = 8, - SLOTBITS = 8, - CTLRBITS = 4, - - SLOTSHIFT = TYPEBITS, - CTLRSHIFT = SLOTSHIFT+SLOTBITS, - - TYPEMASK = (1<>SLOTSHIFT)&SLOTMASK) -#define CTLR(q) ((((ulong)(q).path)>>CTLRSHIFT)&CTLRMASK) -#define PATH(t, s, c) ((t)|((s)< nelem(uh->dev)) - return nil; - return uh->dev[s]; -} - -static Udev* -usbdevice(Chan *c) -{ - int bus; - Udev *d; - Usbhost *uh; - - bus = CTLR(c->qid); - if(bus > nelem(usbhost) || (uh = usbhost[bus]) == nil) { - error(Egreg); - return nil; /* for compiler */ - } - d = usbdeviceofslot(uh, SLOT(c->qid)); - if(d == nil || d->id != c->qid.vers || d->state == Disabled) - error(Ehungup); - return d; -} - -static Endpt * -devendpt(Udev *d, int id, int add) -{ - Usbhost *uh; - Endpt *e, **p; - - p = &d->ep[id&0xF]; - lock(d); - e = *p; - if(e != nil){ - incref(e); - XPRINT("incref(0x%p) in devendpt, new value %ld\n", e, e->ref); - unlock(d); - return e; - } - unlock(d); - if(!add) - return nil; - - e = mallocz(sizeof(*e), 1); - e->ref = 1; - e->x = id&0xF; - e->id = id; - e->sched = -1; - e->maxpkt = 8; - e->nbuf = 1; - e->dev = d; - e->active = 0; - - uh = d->uh; - uh->epalloc(uh, e); - - lock(d); - if(*p != nil){ - incref(*p); - XPRINT("incref(0x%p) in devendpt, new value %ld\n", *p, (*p)->ref); - unlock(d); - uh->epfree(uh, e); - free(e); - return *p; - } - *p = e; - unlock(d); - e->rq = qopen(8*1024, 0, nil, e); - e->wq = qopen(8*1024, 0, nil, e); - return e; -} - -static void -freept(Endpt *e) -{ - Usbhost *uh; - - if(e != nil && decref(e) == 0){ - XPRINT("freept(%d,%d)\n", e->dev->x, e->x); - uh = e->dev->uh; - uh->epclose(uh, e); - e->dev->ep[e->x] = nil; - uh->epfree(uh, e); - free(e); - } -} - -static Udev* -usbnewdevice(Usbhost *uh) -{ - int i; - Udev *d; - Endpt *e; - - d = nil; - qlock(uh); - if(waserror()){ - qunlock(uh); - nexterror(); - } - for(i=0; idev); i++) - if(uh->dev[i] == nil){ - uh->idgen++; - d = mallocz(sizeof(*d), 1); - d->uh = uh; - d->ref = 1; - d->x = i; - d->id = (uh->idgen << 8) | i; - d->state = Enabled; - XPRINT("calling devendpt in usbnewdevice\n"); - e = devendpt(d, 0, 1); /* always provide control endpoint 0 */ - e->mode = ORDWR; - e->iso = 0; - e->sched = -1; - uh->dev[i] = d; - break; - } - poperror(); - qunlock(uh); - return d; -} - -static void -freedev(Udev *d, int ept) -{ - int i; - Endpt *e; - Usbhost *uh; - - uh = d->uh; - if(decref(d) == 0){ - XPRINT("freedev 0x%p, 0\n", d); - for(i=0; iep); i++) - freept(d->ep[i]); - if(d->x >= 0) - uh->dev[d->x] = nil; - free(d); - } else { - if(ept >= 0 && ept < nelem(d->ep)){ - e = d->ep[ept]; - XPRINT("freedev, freept 0x%p\n", e); - if(e != nil) - uh->epclose(uh, e); - } - } -} - -static int -usbgen(Chan *c, char *, Dirtab*, int, int s, Dir *dp) -{ - Qid q; - Udev *d; - Endpt *e; - Dirtab *tab; - Usbhost *uh; - int t, bus, slot, perm; - - /* - * Top level directory contains the controller names. - */ - if(c->qid.path == Qtopdir){ - if(s == DEVDOTDOT){ - mkqid(&q, Qtopdir, 0, QTDIR); - devdir(c, q, "#U", 0, eve, 0555, dp); - return 1; - } - if(s >= nelem(usbhost) || usbhost[s] == nil) - return -1; - mkqid(&q, PATH(Q2nd, 0, s), 0, QTDIR); - snprint(up->genbuf, sizeof up->genbuf, "usb%d", s); - devdir(c, q, up->genbuf, 0, eve, 0555, dp); - return 1; - } - bus = CTLR(c->qid); - if(bus >= nelem(usbhost) || (uh = usbhost[bus]) == nil) - return -1; - - /* - * Second level contains "new", "port", and a numbered - * directory for each enumerated device on the bus. - */ - t = TYPE(c->qid); - if(t < Q3rd){ - if(s == DEVDOTDOT){ - mkqid(&q, Qtopdir, 0, QTDIR); - devdir(c, q, "#U", 0, eve, 0555, dp); - return 1; - } - if(s < nelem(usbdir2)){ - d = uh->dev[0]; - if(d == nil) - return -1; - tab = &usbdir2[s]; - mkqid(&q, PATH(tab->qid.path, 0, bus), d->id, QTFILE); - devdir(c, q, tab->name, tab->length, eve, tab->perm, dp); - return 1; - } - s -= nelem(usbdir2); - if(s >= 0 && s < nelem(uh->dev)) { - d = uh->dev[s]; - if(d == nil) - return 0; - sprint(up->genbuf, "%d", s); - mkqid(&q, PATH(Q3rd, s, bus), d->id, QTDIR); - devdir(c, q, up->genbuf, 0, eve, 0555, dp); - return 1; - } - return -1; - } - - /* - * Third level. - */ - slot = SLOT(c->qid); - if(s == DEVDOTDOT) { - mkqid(&q, PATH(Q2nd, 0, bus), c->qid.vers, QTDIR); - snprint(up->genbuf, sizeof up->genbuf, "usb%d", bus); - devdir(c, q, up->genbuf, 0, eve, 0555, dp); - return 1; - } - if(s < nelem(usbdir3)) { - tab = &usbdir3[s]; - mkqid(&q, PATH(tab->qid.path, slot, bus), c->qid.vers, QTFILE); - devdir(c, q, tab->name, tab->length, eve, tab->perm, dp); - return 1; - } - s -= nelem(usbdir3); - - /* active endpoints */ - d = usbdeviceofslot(uh, slot); - if(d == nil || s >= nelem(d->ep)) - return -1; - if(s == 0 || (e = d->ep[s]) == nil) /* ep0data is called "setup" */ - return 0; - sprint(up->genbuf, "ep%ddata", s); - mkqid(&q, PATH(Qep0+s, slot, bus), c->qid.vers, QTFILE); - switch(e->mode) { - case OREAD: - perm = 0444; - break; - case OWRITE: - perm = 0222; - break; - default: - perm = 0666; - break; - } - devdir(c, q, up->genbuf, e->buffered, eve, perm, dp); - return 1; -} - -static Usbhost* -usbprobe(int cardno, int ctlrno) -{ - Usbhost *uh; - char buf[128], *ebuf, name[64], *p, *type; - - uh = malloc(sizeof(Usbhost)); - memset(uh, 0, sizeof(Usbhost)); - uh->tbdf = BUSUNKNOWN; - - if(cardno < 0){ - if(isaconfig("usb", ctlrno, uh) == 0){ - free(uh); - return nil; - } - for(cardno = 0; usbtypes[cardno].type; cardno++){ - type = uh->type; - if(type==nil || *type==0) - type = "uhci"; - if(cistrcmp(usbtypes[cardno].type, type)) - continue; - break; - } - } - - if(cardno >= MaxUsb || usbtypes[cardno].type == nil){ - free(uh); - return nil; - } - if(usbtypes[cardno].reset(uh) < 0){ - free(uh); - return nil; - } - - /* - * IRQ2 doesn't really exist, it's used to gang the interrupt - * controllers together. A device set to IRQ2 will appear on - * the second interrupt controller as IRQ9. - */ - if(uh->irq == 2) - uh->irq = 9; - snprint(name, sizeof(name), "usb%d", ctlrno); - intrenable(uh->irq, uh->interrupt, uh, uh->tbdf, name); - - ebuf = buf + sizeof buf; - p = seprint(buf, ebuf, "#U/usb%d: %s: port 0x%luX irq %d", ctlrno, usbtypes[cardno].type, uh->port, uh->irq); - if(uh->mem) - p = seprint(p, ebuf, " addr 0x%luX", PADDR(uh->mem)); - if(uh->size) - seprint(p, ebuf, " size 0x%luX", uh->size); - print("%s\n", buf); - - return uh; -} - -static void -usbreset(void) -{ - int cardno, ctlrno; - Usbhost *uh; - - for(ctlrno = 0; ctlrno < MaxUsb; ctlrno++){ - if((uh = usbprobe(-1, ctlrno)) == nil) - continue; - usbhost[ctlrno] = uh; - } - - if(getconf("*nousbprobe")) - return; - - cardno = ctlrno = 0; - while(usbtypes[cardno].type != nil && ctlrno < MaxUsb){ - if(usbhost[ctlrno] != nil){ - ctlrno++; - continue; - } - if((uh = usbprobe(cardno, ctlrno)) == nil){ - cardno++; - continue; - } - usbhost[ctlrno] = uh; - ctlrno++; - } -} - -void -usbinit(void) -{ - Udev *d; - int ctlrno; - Usbhost *uh; - - for(ctlrno = 0; ctlrno < MaxUsb; ctlrno++){ - uh = usbhost[ctlrno]; - if(uh == nil) - continue; - if(uh->init != 0) - uh->init(uh); - - /* reserve device for configuration */ - d = usbnewdevice(uh); - incref(d); - d->state = Attached; - } -} - -Chan * -usbattach(char *spec) -{ - return devattach('U', spec); -} - -static Walkqid* -usbwalk(Chan *c, Chan *nc, char **name, int nname) -{ - return devwalk(c, nc, name, nname, nil, 0, usbgen); -} - -static int -usbstat(Chan *c, uchar *db, int n) -{ - return devstat(c, db, n, nil, 0, usbgen); -} - -Chan* -usbopen(Chan *c, int omode) -{ - Udev *d; - Endpt *e; - int f, s, type; - Usbhost *uh; - - if(c->qid.type == QTDIR) - return devopen(c, omode, nil, 0, usbgen); - - f = 0; - type = TYPE(c->qid); - if(type == Qnew){ - d = usbdevice(c); - d = usbnewdevice(d->uh); - XPRINT("usbopen, new dev 0x%p\n", d); - if(d == nil) { - XPRINT("usbopen failed (usbnewdevice)\n"); - error(Enodev); - } - type = Qctl; - mkqid(&c->qid, PATH(type, d->x, CTLR(c->qid)), d->id, QTFILE); - f = 1; - } - - if(type < Q3rd){ - XPRINT("usbopen, devopen < Q3rd\n"); - return devopen(c, omode, nil, 0, usbgen); - } - - d = usbdevice(c); - uh = d->uh; - qlock(uh); - if(waserror()){ - qunlock(uh); - nexterror(); - } - - switch(type){ - case Qctl: - if(0&&d->busy) - error(Einuse); - d->busy = 1; - if(!f) - incref(d); - XPRINT("usbopen, Qctl 0x%p\n", d); - break; - - default: - s = type - Qep0; - XPRINT("usbopen, default 0x%p, %d\n", d, s); - if(s >= 0 && s < nelem(d->ep)){ - if((e = d->ep[s]) == nil) { - XPRINT("usbopen failed (endpoint)\n"); - error(Enodev); - } - XPRINT("usbopen: dev 0x%p, ept 0x%p\n", d, e); - uh->epopen(uh, e); - e->foffset = 0; - e->toffset = 0; - e->poffset = 0; - e->buffered = 0; - } - incref(d); - break; - } - poperror(); - qunlock(uh); - c->mode = openmode(omode); - c->flag |= COPEN; - c->offset = 0; - return c; -} - -void -usbclose(Chan *c) -{ - Udev *d; - int ept, type; - Usbhost *uh; - - type = TYPE(c->qid); - if(c->qid.type == QTDIR || type < Q3rd) - return; - d = usbdevice(c); - uh = d->uh; - qlock(uh); - if(waserror()){ - qunlock(uh); - nexterror(); - } - if(type == Qctl) - d->busy = 0; - XPRINT("usbclose: dev 0x%p\n", d); - if(c->flag & COPEN){ - ept = (type != Qctl) ? type - Qep0 : -1; - XPRINT("usbclose: freedev 0x%p\n", d); - freedev(d, ept); - } - poperror(); - qunlock(uh); -} - -static char * -epstatus(char *s, char *se, Endpt *e, int i) -{ - char *p; - - p = seprint(s, se, "%2d %#6.6lux %10lud bytes %10lud blocks\n", i, e->csp, e->nbytes, e->nblocks); - if(e->iso){ - p = seprint(p, se, "bufsize %6d buffered %6d", e->maxpkt, e->buffered); - if(e->toffset) - p = seprint(p, se, " offset %10lud time %19lld\n", e->toffset, e->time); - p = seprint(p, se, "\n"); - } - return p; -} - -long -usbread(Chan *c, void *a, long n, vlong offset) -{ - int t, i; - Udev *d; - Endpt *e; - Usbhost *uh; - char *s, *se, *p; - - if(c->qid.type == QTDIR) - return devdirread(c, a, n, nil, 0, usbgen); - - d = usbdevice(c); - uh = d->uh; - t = TYPE(c->qid); - - if(t >= Qep0) { - t -= Qep0; - if(t >= nelem(d->ep)) - error(Eio); - e = d->ep[t]; - if(e == nil || e->mode == OWRITE) - error(Egreg); - if(t == 0) { - if(e->iso) - error(Egreg); - e->data01 = 1; - n = uh->read(uh, e, a, n, 0LL); - if(e->setin){ - e->setin = 0; - e->data01 = 1; - uh->write(uh, e, "", 0, 0LL, TokOUT); - } - return n; - } - return uh->read(uh, e, a, n, offset); - } - - s = smalloc(READSTR); - se = s+READSTR; - if(waserror()){ - free(s); - nexterror(); - } - switch(t){ - case Qport: - uh->portinfo(uh, s, se); - break; - - case Qctl: - seprint(s, se, "%11d %11d\n", d->x, d->id); - break; - - case Qstatus: - if (d->did || d->vid) - p = seprint(s, se, "%s %#6.6lux %#4.4ux %#4.4ux\n", devstates[d->state], d->csp, d->vid, d->did); - else - p = seprint(s, se, "%s %#6.6lux\n", devstates[d->state], d->csp); - for(i=0; iep); i++) { - e = d->ep[i]; - if(e == nil) - continue; - /* TO DO: freeze e */ - p = epstatus(p, se, e, i); - } - } - n = readstr(offset, a, n, s); - poperror(); - free(s); - return n; -} - -long -usbwrite(Chan *c, void *a, long n, vlong offset) -{ - Udev *d; - Endpt *e; - Cmdtab *ct; - Cmdbuf *cb; - Usbhost *uh; - int id, nw, t, i; - char cmd[50]; - - if(c->qid.type == QTDIR) - error(Egreg); - d = usbdevice(c); - uh = d->uh; - t = TYPE(c->qid); - switch(t){ - case Qport: - cb = parsecmd(a, n); - if(waserror()){ - free(cb); - nexterror(); - } - - ct = lookupcmd(cb, usbportmsg, nelem(usbportmsg)); - id = strtol(cb->f[1], nil, 0); - switch(ct->index){ - case PMdisable: - uh->portenable(uh, id, 0); - break; - case PMenable: - uh->portenable(uh, id, 1); - break; - case PMreset: - uh->portreset(uh, id); - break; - } - - poperror(); - free(cb); - return n; - case Qctl: - cb = parsecmd(a, n); - if(waserror()){ - free(cb); - nexterror(); - } - - ct = lookupcmd(cb, usbctlmsg, nelem(usbctlmsg)); - switch(ct->index){ - case CMspeed: - d->ls = strtoul(cb->f[1], nil, 0) == 0; - break; - case CMclass: - if (cb->nf != 4 && cb->nf != 6) - cmderror(cb, Ebadusbmsg); - /* class #ifc ept csp ( == class subclass proto) [vendor product] */ - d->npt = strtoul(cb->f[1], nil, 0); /* # of interfaces */ - i = strtoul(cb->f[2], nil, 0); /* endpoint */ - if (i < 0 || i >= nelem(d->ep) - || d->npt > nelem(d->ep) || i >= d->npt) - cmderror(cb, Ebadusbmsg); - if (cb->nf == 6) { - d->vid = strtoul(cb->f[4], nil, 0); - d->did = strtoul(cb->f[5], nil, 0); - } - if (i == 0) - d->csp = strtoul(cb->f[3], nil, 0); - if(d->ep[i] == nil){ - XPRINT("calling devendpt in usbwrite (CMclass)\n"); - d->ep[i] = devendpt(d, i, 1); - } - d->ep[i]->csp = strtoul(cb->f[3], nil, 0); - break; - case CMdata: - i = strtoul(cb->f[1], nil, 0); - if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil) - error(Ebadusbmsg); - e = d->ep[i]; - e->data01 = strtoul(cb->f[2], nil, 0) != 0; - break; - case CMmaxpkt: - i = strtoul(cb->f[1], nil, 0); - if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil) - error(Ebadusbmsg); - e = d->ep[i]; - e->maxpkt = strtoul(cb->f[2], nil, 0); - if(e->maxpkt > 1500) - e->maxpkt = 1500; - break; - case CMadjust: - i = strtoul(cb->f[1], nil, 0); - if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil) - error(Ebadusbmsg); - e = d->ep[i]; - if (e->iso == 0) - error(Eperm); - i = strtoul(cb->f[2], nil, 0); - /* speed may not result in change of maxpkt */ - if (i < (e->maxpkt-1)/e->samplesz * 1000/e->pollms - || i > e->maxpkt/e->samplesz * 1000/e->pollms){ - snprint(cmd, sizeof(cmd), "%d < %d < %d?", - (e->maxpkt-1)/e->samplesz * 1000/e->pollms, - i, - e->maxpkt/e->samplesz * 1000/e->pollms); - error(cmd); - } - e->hz = i; - break; - case CMdebug: - i = strtoul(cb->f[1], nil, 0); - if(i < -1 || i >= nelem(d->ep) || d->ep[i] == nil) - error(Ebadusbmsg); - if (i == -1) - debug = 0; - else { - debug = 1; - e = d->ep[i]; - e->debug = strtoul(cb->f[2], nil, 0); - } - break; - case CMunstall: - i = strtoul(cb->f[1], nil, 0); - if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil) - error(Ebadusbmsg); - e = d->ep[i]; - e->err = nil; - break; - case CMep: - /* ep n `bulk' mode maxpkt nbuf OR - * ep n period mode samplesize Hz - */ - i = strtoul(cb->f[1], nil, 0); - if(i < 0 || i >= nelem(d->ep)) { - XPRINT("field 1: 0 <= %d < %d\n", i, nelem(d->ep)); - error(Ebadarg); - } - if((e = d->ep[i]) == nil){ - XPRINT("calling devendpt in usbwrite (CMep)\n"); - e = devendpt(d, i, 1); - } - qlock(uh); - if(waserror()){ - freept(e); - qunlock(uh); - nexterror(); - } - if(e->active) - error(Eperm); - if(strcmp(cb->f[2], "bulk") == 0){ - /* ep n `bulk' mode maxpkt nbuf */ - e->iso = 0; - i = strtoul(cb->f[4], nil, 0); - if(i < 8 || i > 1023) - i = 8; - e->maxpkt = i; - i = strtoul(cb->f[5], nil, 0); - if(i >= 1 && i <= 32) - e->nbuf = i; - } else { - /* ep n period mode samplesize Hz */ - i = strtoul(cb->f[2], nil, 0); - if(i > 0 && i <= 1000){ - e->pollms = i; - }else { - XPRINT("field 4: 0 <= %d <= 1000\n", i); - error(Ebadarg); - } - i = strtoul(cb->f[4], nil, 0); - if(i >= 1 && i <= 8){ - e->samplesz = i; - }else { - XPRINT("field 4: 0 < %d <= 8\n", i); - error(Ebadarg); - } - i = strtoul(cb->f[5], nil, 0); - if(i >= 1 && i*e->samplesz <= 12*1000*1000){ - /* Hz */ - e->hz = i; - e->remain = 0; - }else { - XPRINT("field 5: 1 < %d <= 100000 Hz\n", i); - error(Ebadarg); - } - e->maxpkt = (e->hz * e->pollms + 999)/1000 * e->samplesz; - e->iso = 1; - } - e->mode = strcmp(cb->f[3],"r") == 0? OREAD : - strcmp(cb->f[3],"w") == 0? OWRITE : ORDWR; - uh->epmode(uh, e); - poperror(); - qunlock(uh); - } - - poperror(); - free(cb); - return n; - - case Qep0: /* SETUP endpoint 0 */ - /* should canqlock etc */ - e = d->ep[0]; - if(e == nil || e->iso) - error(Egreg); - if(n < 8) - error(Eio); - nw = *(uchar*)a & RD2H; - e->data01 = 0; - n = uh->write(uh, e, a, n, 0LL, TokSETUP); - if(nw == 0) { /* host to device: use IN[DATA1] to ack */ - e->data01 = 1; - nw = uh->read(uh, e, cmd, 0LL, 8); - if(nw != 0) - error(Eio); /* could provide more status */ - }else - e->setin = 1; /* two-phase */ - break; - - default: /* sends DATA[01] */ - t -= Qep0; - if(t < 0 || t >= nelem(d->ep)) - error(Egreg); - e = d->ep[t]; - if(e == nil || e->mode == OREAD) - error(Egreg); - n = uh->write(uh, e, a, n, offset, TokOUT); - break; - } - return n; -} - -Dev usbdevtab = { - 'U', - "usb", - - usbreset, - usbinit, - devshutdown, - usbattach, - usbwalk, - usbstat, - usbopen, - devcreate, - usbclose, - usbread, - devbread, - usbwrite, - devbwrite, - devremove, - devwstat, -}; -- cgit v1.2.3