must allocate from lo memory, and allocb doesn't guarentee this. Reference: /n/atom/patch/applied/loallocb Date: Wed Feb 26 02:22:24 CET 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/nix/k10/usbohci.c Wed Feb 26 02:22:15 2014 +++ /sys/src/nix/k10/usbohci.c Wed Feb 26 02:22:18 2014 @@ -409,10 +409,66 @@ return 0; pa = PADDR(p); if(sizeof(pa) > 4 && pa > 0xffffffff) - panic("usb: ohci: highmemptr %#p", p); + panic("usb: ohci: highmemptr %#P", pa); return pa; } +enum { + Hdrspc = 64, /* leave room for high-level headers */ + Bdead = 0x51494F42, /* "QIOB" */ +// Align = BLOCKALIGN, +}; + +/* this is the guts of ../port/qallocb.c */ +static Block* +binit(uchar *p, int size, uchar** next) +{ + int n; + Block *b; + + n = Align + ROUNDUP(size+Hdrspc, Align) + sizeof(Block); + b = (Block*)(p + n - sizeof(Block)); /* block at end of allocated space */ + b->base = p; + b->next = nil; + b->list = nil; + b->free = nil; + b->flag = 0; + + /* align base and bounds of data */ + b->lim = (uchar*)(PTR2UINT(b) & ~(Align-1)); + + /* align start of writable data, leaving space below for added headers */ + b->rp = b->lim - ROUNDUP(size, Align); + b->wp = b->rp; + + if(b->rp < b->base || b->lim - b->rp < size) + panic("binit"); + if(next != nil) + *next = p + n; + return b; +} + +/* + * allocb may use memory outside the normal malloc arena + * this is so gross. + */ +static Block* +loallocb(int size) +{ + uchar *p; + + p = malloc(Align + ROUNDUP(size+Hdrspc, Align) + sizeof(Block)); + assert(PADDR(p) <= 0xffffffff); + return binit(p, size, nil); +} + +static void +lofreeb(Block *b) +{ + if(b != nil) + free(b->base); +} + static void waitSOF(Ctlr *ub) { @@ -630,7 +686,7 @@ { if(td == nil) return; - freeb(td->bp); + lofreeb(td->bp); td->bp = nil; lock(&tdpool); if(td->nexttd == 0x77777777) @@ -1350,12 +1406,12 @@ Block *bp; if(count <= PGSZ) - bp = allocb(count); + bp = loallocb(count); else{ if(count > 2*PGSZ) panic("ohci: transfer > two pages"); /* maximum of one physical page crossing allowed */ - bp = allocb(count+PGSZ); + bp = loallocb(count+PGSZ); bp->rp = (uchar*)ROUNDUP((uintptr)bp->rp, PGSZ); bp->wp = bp->rp; } @@ -2002,14 +2058,14 @@ td = tdalloc(); td->ep = ep; td->io = iso; - td->bp = allocb(ep->maxpkt); + td->bp = loallocb(ep->maxpkt); td->anext = iso->atds; /* link as avail */ iso->atds = td; td->next = edtds; edtds = td; } newed(ctlr, ep, iso, "iso"); /* allocates a dummy td */ - iso->ed->tds->bp = allocb(ep->maxpkt); /* but not its block */ + iso->ed->tds->bp = loallocb(ep->maxpkt); /* but not its block */ iso->ed->tds->next = edtds; isodtdinit(ep, iso, iso->ed->tds); }