/* * Look for free space in the vmap. */ static uintptr_t vmapalloc(usize size) { int i, n, o; PTE *pd, *pt; int pdsz, ptsz; pd = (PTE*)(PDMAP+PDX(PDMAP)*4096); pd += PDX(VMAP); pdsz = VMAPSZ/PGLSZ(1); /* * Look directly in the PD entries if the size is * larger than the range mapped by a single entry. */ if(size >= PGLSZ(1)) { n = HOWMANY(size, PGLSZ(1)); if((o = findhole(pd, pdsz, n)) != -1) return VMAP + o*PGLSZ(1); return 0; } /* * Size is smaller than that mapped by a single PD entry. * Look for an already mapped PT page that has room. */ n = HOWMANY(size, PGLSZ(0)); ptsz = PGLSZ(0)/sizeof(PTE); for(i = 0; i < pdsz; i++) { if(!(pd[i] & PteP) || (pd[i] & PtePS)) continue; pt = (PTE*)(PDMAP+(PDX(VMAP)+i)*4096); if((o = findhole(pt, ptsz, n)) != -1) return VMAP + i*PGLSZ(1) + o*PGLSZ(0); } /* * Nothing suitable, start using a new PD entry. */ if((o = findhole(pd, pdsz, 1)) != -1) return VMAP + o*PGLSZ(1); return 0; }
void printamt(vlong amt, char *name) { if (readflg) return; if (autoscale) { int scale = 0; double val = (double)amt/unit; while (fabs(val) >= 1024 && scale < nelem(pfxes)-1) { scale++; val /= 1024; } print("%.6g%s\t%q\n", val, pfxes[scale], name); } else if (fltflag) print("%.6g\t%q\n", (double)amt/unit, name); else print(fmt, HOWMANY(amt, unit), name); }
static int reset(Ether* ether) { ushort buf[16]; ulong port; Dp8390 *ctlr; int i, slot; uchar ea[Eaddrlen], sum, x; Ec2t *ec2t, tmpec2t; /* * Set up the software configuration. * Use defaults for port, irq, mem and size * if not specified. * The manual says 16KB memory, the box * says 32KB. The manual seems to be correct. */ if(ether->port == 0) ether->port = 0x300; if(ether->irq == 0) ether->irq = 9; if(ether->mem == 0) ether->mem = 0x4000; if(ether->size == 0) ether->size = 16*1024; port = ether->port; if(ioalloc(ether->port, 0x20, 0, "ec2t") < 0) return -1; slot = -1; for(ec2t = ec2tpcmcia; ec2t->name != nil; ec2t++){ if((slot = pcmspecial(ec2t->name, ether)) >= 0) break; } if(ec2t->name == nil){ ec2t = &tmpec2t; ec2t->name = nil; ec2t->iochecksum = 0; for(i = 0; i < ether->nopt; i++){ if(cistrncmp(ether->opt[i], "id=", 3) == 0){ ec2t->name = ðer->opt[i][3]; slot = pcmspecial(ec2t->name, ether); } else if(cistrncmp(ether->opt[i], "iochecksum", 10) == 0) ec2t->iochecksum = 1; } } ctlr = malloc(sizeof(Dp8390)); if(ctlr == nil || slot < 0){ iofree(port); free(ctlr); return -1; } ether->ctlr = ctlr; ctlr->width = 2; ctlr->ram = 0; ctlr->port = port; ctlr->data = port+Data; ctlr->tstart = HOWMANY(ether->mem, Dp8390BufSz); ctlr->pstart = ctlr->tstart + HOWMANY(sizeof(Etherpkt), Dp8390BufSz); ctlr->pstop = ctlr->tstart + HOWMANY(ether->size, Dp8390BufSz); ctlr->dummyrr = 0; for(i = 0; i < ether->nopt; i++){ if(cistrcmp(ether->opt[i], "nodummyrr") == 0) ctlr->dummyrr = 0; else if(cistrncmp(ether->opt[i], "dummyrr=", 8) == 0) ctlr->dummyrr = strtol(ðer->opt[i][8], nil, 0); } /* * Reset the board. This is done by doing a read * followed by a write to the Reset address. */ buf[0] = inb(port+Reset); delay(2); outb(port+Reset, buf[0]); delay(2); /* * Init the (possible) chip, then use the (possible) * chip to read the (possible) PROM for ethernet address * and a marker byte. * Could just look at the DP8390 command register after * initialisation has been tried, but that wouldn't be * enough, there are other ethernet boards which could * match. */ dp8390reset(ether); sum = 0; if(ec2t->iochecksum){ /* * These cards have the ethernet address in I/O space. * There's a checksum over 8 bytes which sums to 0xFF. */ for(i = 0; i < 8; i++){ x = inb(port+0x14+i); sum += x; buf[i] = (x<<8)|x; } } else{ memset(buf, 0, sizeof(buf)); dp8390read(ctlr, buf, 0, sizeof(buf)); if((buf[0x0E] & 0xFF) == 0x57 && (buf[0x0F] & 0xFF) == 0x57) sum = 0xFF; } if(sum != 0xFF){ pcmspecialclose(slot); iofree(ether->port); free(ether->ctlr); return -1; } /* * Stupid machine. Shorts were asked for, * shorts were delivered, although the PROM is a byte array. * Set the ethernet address. */ memset(ea, 0, Eaddrlen); if(memcmp(ea, ether->ea, Eaddrlen) == 0){ for(i = 0; i < sizeof(ether->ea); i++) ether->ea[i] = buf[i]; } dp8390setea(ether); return 0; }
static int ne2000reset(Ether* edev) { ushort buf[16]; ulong port; Dp8390 *dp8390; int i; uchar ea[Eaddrlen]; if(edev->port == 0) ne2000pnp(edev); /* * Set up the software configuration. * Use defaults for irq, mem and size * if not specified. * Must have a port, no more default. */ if(edev->port == 0) return -1; if(edev->irq == 0) edev->irq = 2; if(edev->mem == 0) edev->mem = 0x4000; if(edev->size == 0) edev->size = 16*1024; port = edev->port; if(ioalloc(edev->port, 0x20, 0, "ne2000") < 0) return -1; edev->ctlr = malloc(sizeof(Dp8390)); dp8390 = edev->ctlr; if(dp8390 == nil) error(Enomem); dp8390->width = 2; dp8390->ram = 0; dp8390->port = port; dp8390->data = port+Data; dp8390->tstart = HOWMANY(edev->mem, Dp8390BufSz); dp8390->pstart = dp8390->tstart + HOWMANY(sizeof(Etherpkt), Dp8390BufSz); dp8390->pstop = dp8390->tstart + HOWMANY(edev->size, Dp8390BufSz); dp8390->dummyrr = 1; for(i = 0; i < edev->nopt; i++){ if(strcmp(edev->opt[i], "nodummyrr")) continue; dp8390->dummyrr = 0; break; } /* * Reset the board. This is done by doing a read * followed by a write to the Reset address. */ buf[0] = inb(port+Reset); delay(2); outb(port+Reset, buf[0]); delay(2); /* * Init the (possible) chip, then use the (possible) * chip to read the (possible) PROM for ethernet address * and a marker byte. * Could just look at the DP8390 command register after * initialisation has been tried, but that wouldn't be * enough, there are other ethernet boards which could * match. * Parallels has buf[0x0E] == 0x00 whereas real hardware * usually has 0x57. */ dp8390reset(edev); memset(buf, 0, sizeof(buf)); dp8390read(dp8390, buf, 0, sizeof(buf)); i = buf[0x0E] & 0xFF; if((i != 0x00 && i != 0x57) || (buf[0x0F] & 0xFF) != 0x57){ iofree(edev->port); free(edev->ctlr); return -1; } /* * Stupid machine. Shorts were asked for, * shorts were delivered, although the PROM is a byte array. * Set the ethernet address. */ memset(ea, 0, Eaddrlen); if(memcmp(ea, edev->ea, Eaddrlen) == 0){ for(i = 0; i < sizeof(edev->ea); i++) edev->ea[i] = buf[i]; } dp8390setea(edev); return 0; }
static int chanio(Ep *ep, Hostchan *hc, int dir, int pid, void *a, int len) { Ctlr *ctlr; int nleft, n, nt, i, maxpkt, npkt; uint hcdma, hctsiz; ctlr = ep->hp->aux; maxpkt = ep->maxpkt; npkt = HOWMANY(len, ep->maxpkt); if(npkt == 0) npkt = 1; hc->hcchar = (hc->hcchar & ~Epdir) | dir; if(dir == Epin) n = ROUND(len, ep->maxpkt); else n = len; hc->hctsiz = n | npkt<<OPktcnt | pid; hc->hcdma = dmaaddr(a); nleft = len; logstart(ep); for(;;){ hcdma = hc->hcdma; hctsiz = hc->hctsiz; hc->hctsiz = hctsiz & ~Dopng; if(hc->hcchar&Chen){ dprint("ep%d.%d before chanio hcchar=%8.8ux\n", ep->dev->nb, ep->nb, hc->hcchar); hc->hcchar |= Chen | Chdis; while(hc->hcchar&Chen) ; hc->hcint = Chhltd; } if((i = hc->hcint) != 0){ dprint("ep%d.%d before chanio hcint=%8.8ux\n", ep->dev->nb, ep->nb, i); hc->hcint = i; } if(hc->hcsplt & Spltena){ qlock(&ctlr->split); sofwait(ctlr, hc - ctlr->regs->hchan); if((dwc.regs->hfnum & 1) == 0) hc->hcchar &= ~Oddfrm; else hc->hcchar |= Oddfrm; } hc->hcchar = (hc->hcchar &~ Chdis) | Chen; clog(ep, hc); wait: if(ep->ttype == Tbulk && dir == Epin) i = chanwait(ep, ctlr, hc, Chhltd); else if(ep->ttype == Tintr && (hc->hcsplt & Spltena)) i = chanwait(ep, ctlr, hc, Chhltd); else i = chanwait(ep, ctlr, hc, Chhltd|Nak); clog(ep, hc); if(hc->hcint != i){ dprint("chanwait intr %ux->%ux\n", i, hc->hcint); if((i = hc->hcint) == 0) goto wait; } hc->hcint = i; if(hc->hcsplt & Spltena){ hc->hcsplt &= ~Compsplt; qunlock(&ctlr->split); } if((i & Xfercomp) == 0 && i != (Chhltd|Ack) && i != Chhltd){ if(i & Stall) error(Estalled); if(i & (Nyet|Frmovrun)) continue; if(i & Nak){ if(ep->ttype == Tintr) tsleep(&up->sleep, return0, 0, ep->pollival); else tsleep(&up->sleep, return0, 0, 1); continue; } logdump(ep); print("usbotg: ep%d.%d error intr %8.8ux\n", ep->dev->nb, ep->nb, i); if(i & ~(Chhltd|Ack)) error(Eio); if(hc->hcdma != hcdma) print("usbotg: weird hcdma %ux->%ux intr %ux->%ux\n", hcdma, hc->hcdma, i, hc->hcint); } n = hc->hcdma - hcdma; if(n == 0){ if((hc->hctsiz & Pktcnt) != (hctsiz & Pktcnt)) break; else continue; } if(dir == Epin && ep->ttype == Tbulk){ nt = (hctsiz & Xfersize) - (hc->hctsiz & Xfersize); if(nt != n){ if(n == ROUND(nt, 4)) n = nt; else print("usbotg: intr %8.8ux " "dma %8.8ux-%8.8ux " "hctsiz %8.8ux-%8.ux\n", i, hcdma, hc->hcdma, hctsiz, hc->hctsiz); } } if(n > nleft){ if(n != ROUND(nleft, 4)) dprint("too much: wanted %d got %d\n", len, len - nleft + n); n = nleft; } nleft -= n; if(nleft == 0 || (n % maxpkt) != 0) break; if((i & Xfercomp) && ep->ttype != Tctl) break; if(dir == Epout) dprint("too little: nleft %d hcdma %x->%x hctsiz %x->%x intr %x\n", nleft, hcdma, hc->hcdma, hctsiz, hc->hctsiz, i); } logdump(ep); return len - nleft; }
struct prefix_option { const char *string; void (*func)(const struct place *, char *); }; struct arg_option { const char *string; void (*func)(const struct place *, char *); }; static const struct ignore_option ignore_options[] = { { "m32" }, { "traditional" }, }; static const unsigned num_ignore_options = HOWMANY(ignore_options); static const struct flag_option flag_options[] = { { "C", &mode.output_retain_comments, true }, { "CC", &mode.output_retain_comments, true }, { "MG", &mode.depend_assume_generated, true }, { "MP", &mode.depend_issue_fakerules, true }, { "P", &mode.output_linenumbers, false }, { "Wcomment", &warns.nestcomment, true }, { "Wendif-labels", &warns.endiflabels, true }, { "Werror", &mode.werror, true }, { "Wno-comment", &warns.nestcomment, false }, { "Wno-endif-labels", &warns.endiflabels, false }, { "Wno-error", &mode.werror, false }, { "Wno-undef", &warns.undef, false }, { "Wno-unused-macros", &warns.unused, false },
/* may be called more than once */ int ne2000reset(Ether* ether) { ushort buf[16]; ulong port; Dp8390 *ctlr; int i; uchar ea[Eaddrlen]; if(ether->port == 0) ne2000pnp(ether); /* * port == 0 is a desperate attempt to find something at the * default port. only allow one of these to be found, and * only if no other card has been found. */ if(ether->port == 0 && ether->ctlrno > 0) return -1; /* * Set up the software configuration. * Use defaults for port, irq, mem and size * if not specified. */ if(ether->port == 0) ether->port = 0x300; if(ether->irq == 0) ether->irq = 2; if(ether->mem == 0) ether->mem = 0x4000; if(ether->size == 0) ether->size = 16*1024; port = ether->port; if(inuse(ether->port)) return -1; ether->ctlr = malloc(sizeof(Dp8390)); ctlr = ether->ctlr; ctlr->width = 2; ctlr->ram = 0; ctlr->port = port; ctlr->data = port+Data; ctlr->tstart = HOWMANY(ether->mem, Dp8390BufSz); ctlr->pstart = ctlr->tstart + HOWMANY(sizeof(Etherpkt), Dp8390BufSz); ctlr->pstop = ctlr->tstart + HOWMANY(ether->size, Dp8390BufSz); ctlr->dummyrr = 1; for(i = 0; i < ether->nopt; i++){ if(strcmp(ether->opt[i], "nodummyrr")) continue; ctlr->dummyrr = 0; break; } /* * Reset the board. This is done by doing a read * followed by a write to the Reset address. */ buf[0] = inb(port+Reset); delay(2); outb(port+Reset, buf[0]); delay(2); /* * Init the (possible) chip, then use the (possible) * chip to read the (possible) PROM for ethernet address * and a marker byte. * Could just look at the DP8390 command register after * initialisation has been tried, but that wouldn't be * enough, there are other ethernet boards which could * match. * Parallels has buf[0x0E] == 0x00 whereas real hardware * usually has 0x57. */ dp8390reset(ether); memset(buf, 0, sizeof(buf)); dp8390read(ctlr, buf, 0, sizeof(buf)); i = buf[0x0E] & 0xFF; if((i != 0x00 && i != 0x57) || (buf[0x0F] & 0xFF) != 0x57){ free(ether->ctlr); return -1; } /* * Stupid machine. Shorts were asked for, * shorts were delivered, although the PROM is a byte array. * Set the ethernet address. */ memset(ea, 0, Eaddrlen); if(memcmp(ea, ether->ea, Eaddrlen) == 0){ for(i = 0; i < sizeof(ether->ea); i++) ether->ea[i] = buf[i]; } dp8390setea(ether); return 0; }