static void chipdetach(struct bcm4xxx *ch) { ET_TRACE(("et%d: chipdetach\n", ch->etc->unit)); if (ch == NULL) return; #ifdef ETROBO /* free robo state */ if (ch->etc->robo) bcm_robo_detach(ch->etc->robo); #endif /* ETROBO */ #ifdef ETADM /* free ADMtek state */ if (ch->adm) adm_detach(ch->adm); #endif /* ETADM */ /* free dma state */ if (ch->di) dma_detach(ch->di); ch->di = NULL; /* put the core back into reset */ if (ch->sih) si_core_disable(ch->sih, 0); /* free si handle */ si_detach(ch->sih); ch->sih = NULL; /* free vars */ if (ch->vars) MFREE(ch->osh, ch->vars, ch->vars_size); /* free chip private state */ MFREE(ch->osh, ch, sizeof(struct bcm4xxx)); }
void* dma_attach(void *drv, void *dev, char *name, dmaregs_t *regs, uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint ddoffset, uint dataoffset, uint *msg_level) { dma_info_t *di; void *va; ASSERT(ntxd <= MAXDD); ASSERT(nrxd <= MAXDD); /* allocate private info structure */ if ((di = MALLOC(sizeof (dma_info_t))) == NULL) return (NULL); bzero((char*)di, sizeof (dma_info_t)); /* set message level */ di->msg_level = msg_level ? msg_level : &dma_msg_level; DMA_TRACE(("%s: dma_attach: drv 0x%x dev 0x%x regs 0x%x ntxd %d nrxd %d rxbufsize %d nrxpost %d rxoffset %d ddoffset 0x%x dataoffset 0x%x\n", name, (uint)drv, (uint)dev, (uint)regs, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, ddoffset, dataoffset)); /* make a private copy of our callers name */ strncpy(di->name, name, MAXNAMEL); di->name[MAXNAMEL-1] = '\0'; di->drv = drv; di->dev = dev; di->regs = regs; /* allocate transmit descriptor ring */ if (ntxd) { if ((va = DMA_ALLOC_CONSISTENT(dev, (DMAMAXRINGSZ + DMARINGALIGN), &di->txdpa)) == NULL) goto fail; di->txd = (dmadd_t*) ROUNDUP(va, DMARINGALIGN); di->txdalign = ((uint)di->txd - (uint)va); di->txdpa = (void*) ((uint)di->txdpa + di->txdalign); ASSERT(ISALIGNED(di->txd, DMARINGALIGN)); } /* allocate receive descriptor ring */ if (nrxd) { if ((va = DMA_ALLOC_CONSISTENT(dev, (DMAMAXRINGSZ + DMARINGALIGN), &di->rxdpa)) == NULL) goto fail; di->rxd = (dmadd_t*) ROUNDUP(va, DMARINGALIGN); di->rxdalign = ((uint)di->rxd - (uint)va); di->rxdpa = (void*) ((uint)di->rxdpa + di->rxdalign); ASSERT(ISALIGNED(di->rxd, DMARINGALIGN)); } /* save tunables */ di->ntxd = ntxd; di->nrxd = nrxd; di->rxbufsize = rxbufsize; di->nrxpost = nrxpost; di->rxoffset = rxoffset; di->ddoffset = ddoffset; di->dataoffset = dataoffset; return ((void*)di); fail: dma_detach((void*)di); return (NULL); }