usbxhci: handle out of memory in controller initialization
This commit is contained in:
parent
1ea109345b
commit
83b87729d9
2 changed files with 47 additions and 17 deletions
|
@ -303,8 +303,7 @@ freering(Ring *r)
|
|||
{
|
||||
if(r == nil)
|
||||
return;
|
||||
if(r->base != nil)
|
||||
free(r->base);
|
||||
free(r->base);
|
||||
memset(r, 0, sizeof(*r));
|
||||
}
|
||||
|
||||
|
@ -394,6 +393,19 @@ handoff(Ctlr *ctlr)
|
|||
r[0] &= ~(1<<16); /* in case of timeout */
|
||||
}
|
||||
|
||||
static void
|
||||
shutdown(Hci *hp)
|
||||
{
|
||||
Ctlr *ctlr = hp->aux;
|
||||
int i;
|
||||
|
||||
ctlr->opr[USBCMD] = 0;
|
||||
for(i=0; (ctlr->opr[USBSTS] & HCH) == 0 && i < 10; i++)
|
||||
delay(10);
|
||||
intrdisable(ctlr->pcidev->intl, hp->interrupt, hp, ctlr->pcidev->tbdf, hp->type);
|
||||
pciclrbme(ctlr->pcidev);
|
||||
}
|
||||
|
||||
static void
|
||||
init(Hci *hp)
|
||||
{
|
||||
|
@ -423,6 +435,22 @@ init(Hci *hp)
|
|||
pcisetpms(ctlr->pcidev, 0);
|
||||
intrenable(ctlr->pcidev->intl, hp->interrupt, hp, ctlr->pcidev->tbdf, hp->type);
|
||||
|
||||
if(waserror()){
|
||||
shutdown(hp);
|
||||
freering(ctlr->cr);
|
||||
for(i=0; i<nelem(ctlr->er); i++){
|
||||
freering(&ctlr->er[i]);
|
||||
free(ctlr->erst[i]);
|
||||
ctlr->erst[i] = nil;
|
||||
}
|
||||
free(ctlr->port), ctlr->port = nil;
|
||||
free(ctlr->slot), ctlr->slot = nil;
|
||||
free(ctlr->dcba), ctlr->dcba = nil;
|
||||
free(ctlr->sba), ctlr->sba = nil;
|
||||
free(ctlr->sbp), ctlr->sbp = nil;
|
||||
nexterror();
|
||||
}
|
||||
|
||||
ctlr->csz = (ctlr->hccparams & CSZ) != 0;
|
||||
if(ctlr->hccparams & AC64)
|
||||
ctlr->setrptr = setrptr64;
|
||||
|
@ -438,6 +466,8 @@ init(Hci *hp)
|
|||
hp->superspeed = 0;
|
||||
hp->nports = (ctlr->mmio[HCSPARAMS1] >> 24) & 0xFF;
|
||||
ctlr->port = malloc(hp->nports * sizeof(Port));
|
||||
if(ctlr->port == nil)
|
||||
error(Enomem);
|
||||
for(i=0; i<hp->nports; i++)
|
||||
ctlr->port[i].reg = &ctlr->opr[0x400/4 + i*4];
|
||||
|
||||
|
@ -459,9 +489,13 @@ init(Hci *hp)
|
|||
|
||||
ctlr->slot = malloc((1+ctlr->nslots)*sizeof(ctlr->slot[0]));
|
||||
ctlr->dcba = mallocalign((1+ctlr->nslots)*8, 64, 0, ctlr->pagesize);
|
||||
if(ctlr->slot == nil || ctlr->dcba == nil)
|
||||
error(Enomem);
|
||||
if(ctlr->nscratch != 0){
|
||||
ctlr->sba = mallocalign(ctlr->nscratch*8, 64, 0, ctlr->pagesize);
|
||||
ctlr->sbp = mallocalign(ctlr->nscratch*ctlr->pagesize, ctlr->pagesize, 0, 0);
|
||||
if(ctlr->sba == nil || ctlr->sbp == nil)
|
||||
error(Enomem);
|
||||
for(i=0, p = ctlr->sbp; i<ctlr->nscratch; i++, p += ctlr->pagesize){
|
||||
memset(p, 0, ctlr->pagesize);
|
||||
ctlr->sba[i] = PADDR(p);
|
||||
|
@ -491,6 +525,8 @@ init(Hci *hp)
|
|||
/* allocate and link into event ring segment table */
|
||||
initring(&ctlr->er[i], 8); /* 256 entries */
|
||||
ctlr->erst[i] = mallocalign(16, 64, 0, 0);
|
||||
if(ctlr->erst[i] == nil)
|
||||
error(Enomem);
|
||||
*((u64int*)ctlr->erst[i]) = PADDR(ctlr->er[i].base);
|
||||
ctlr->erst[i][2] = ctlr->er[i].mask+1;
|
||||
ctlr->erst[i][3] = 0;
|
||||
|
@ -502,6 +538,7 @@ init(Hci *hp)
|
|||
irs[IMAN] = 3;
|
||||
irs[IMOD] = 0;
|
||||
}
|
||||
poperror();
|
||||
|
||||
ctlr->µframe = 0;
|
||||
ctlr->opr[USBCMD] = RUNSTOP|INTE|HSEE|EWE;
|
||||
|
@ -829,19 +866,6 @@ allocslot(Ctlr *ctlr, Udev *dev)
|
|||
return slot;
|
||||
}
|
||||
|
||||
static void
|
||||
shutdown(Hci *hp)
|
||||
{
|
||||
Ctlr *ctlr = hp->aux;
|
||||
int i;
|
||||
|
||||
ctlr->opr[USBCMD] = 0;
|
||||
for(i=0; (ctlr->opr[USBSTS] & HCH) == 0 && i < 10; i++)
|
||||
delay(10);
|
||||
intrdisable(ctlr->pcidev->intl, hp->interrupt, hp, ctlr->pcidev->tbdf, hp->type);
|
||||
pciclrbme(ctlr->pcidev);
|
||||
}
|
||||
|
||||
static void
|
||||
setdebug(Hci *, int)
|
||||
{
|
||||
|
|
|
@ -769,8 +769,14 @@ usbinit(void)
|
|||
if(hp != nil){
|
||||
int n;
|
||||
|
||||
if(hp->init != nil)
|
||||
if(hp->init != nil){
|
||||
if(waserror()){
|
||||
print("usbinit: %s: %s\n", hp->type, up->errstr);
|
||||
continue;
|
||||
}
|
||||
hp->init(hp);
|
||||
poperror();
|
||||
}
|
||||
|
||||
hp->superspeed &= (1<<hp->nports)-1;
|
||||
n = hp->nports - numbits(hp->superspeed);
|
||||
|
|
Loading…
Reference in a new issue