/* * allocate an SCQ */ struct patm_scd * patm_scd_alloc(struct patm_softc *sc) { u_int sram, next; /* SRAM address of this and next SCD */ int error; void *p; struct patm_scd *scd; bus_dmamap_t map; bus_addr_t phy; /* get an SCD from the free list */ if ((sram = sc->scd_free) == 0) return (NULL); next = patm_sram_read(sc, sram); /* allocate memory for the queue and our host stuff */ error = bus_dmamem_alloc(sc->scd_tag, &p, BUS_DMA_NOWAIT, &map); if (error != 0) return (NULL); phy = 0x3ff; error = bus_dmamap_load(sc->scd_tag, map, p, sizeof(scd->scq), patm_load_callback, &phy, BUS_DMA_NOWAIT); if (error != 0) { bus_dmamem_free(sc->scd_tag, p, map); return (NULL); } KASSERT((phy & 0x1ff) == 0, ("SCD not aligned %lx", (u_long)phy)); scd = p; bzero(scd, sizeof(*scd)); scd->sram = sram; scd->phy = phy; scd->map = map; scd->space = IDT_SCQ_SIZE; scd->last_tag = IDT_TSQE_TAG_SPACE - 1; scd->q.ifq_maxlen = PATM_TX_IFQLEN; /* remove the scd from the free list */ sc->scd_free = next; LIST_INSERT_HEAD(&sc->scd_list, scd, link); return (scd); }
static __inline u_int rct_read(struct patm_softc *sc, u_int cid, u_int w) { return (patm_sram_read(sc, sc->mmap->rct + cid * IDT_RCT_ENTRY_SIZE + w)); }