memset(newcbd->cmds, 0, sizeof(struct siop_cmd) * SIOP_NCMDPB); error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE, 0, &seg,
bzero(newcbd->cmds, sizeof(struct siop_cmd) * SIOP_NCMDPB); error = bus_dmamem_alloc(sc->sc_c.sc_dmat, PAGE_SIZE, PAGE_SIZE, 0, &seg,
siop_morecbd(sc)	struct siop_softc *sc;{	int error, i, j;	bus_dma_segment_t seg;	int rseg;	struct siop_cbd *newcbd;	bus_addr_t dsa;	u_int32_t *scr;	/* allocate a new list head */	newcbd = malloc(sizeof(struct siop_cbd), M_DEVBUF, M_NOWAIT);	if (newcbd == NULL) {		printf("%s: can't allocate memory for command descriptors "		    "head\n", sc->sc_dev.dv_xname);		return ENOMEM;	}	memset(newcbd, 0, sizeof(struct siop_cbd));	/* allocate cmd list */	newcbd->cmds =	    malloc(sizeof(struct siop_cmd) * SIOP_NCMDPB, M_DEVBUF, M_NOWAIT);	if (newcbd->cmds == NULL) {		printf("%s: can't allocate memory for command descriptors\n",		    sc->sc_dev.dv_xname);		error = ENOMEM;		goto bad3;	}	memset(newcbd->cmds, 0, sizeof(struct siop_cmd) * SIOP_NCMDPB);	error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE, 0, &seg,	    1, &rseg, BUS_DMA_NOWAIT);	if (error) {		printf("%s: unable to allocate cbd DMA memory, error = %d\n",		    sc->sc_dev.dv_xname, error);		goto bad2;	}	error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, PAGE_SIZE,	    (caddr_t *)&newcbd->xfers, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);	if (error) {		printf("%s: unable to map cbd DMA memory, error = %d\n",		    sc->sc_dev.dv_xname, error);		goto bad2;	}	error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0,	    BUS_DMA_NOWAIT, &newcbd->xferdma);	if (error) {		printf("%s: unable to create cbd DMA map, error = %d\n",		    sc->sc_dev.dv_xname, error);		goto bad1;	}	error = bus_dmamap_load(sc->sc_dmat, newcbd->xferdma, newcbd->xfers,	    PAGE_SIZE, NULL, BUS_DMA_NOWAIT);	if (error) {		printf("%s: unable to load cbd DMA map, error = %d\n",		    sc->sc_dev.dv_xname, error);		goto bad0;	}#ifdef DEBUG	printf("%s: alloc newcdb at PHY addr 0x%lx\n", sc->sc_dev.dv_xname,	    (unsigned long)newcbd->xferdma->dm_segs[0].ds_addr);#endif	for (i = 0; i < SIOP_NCMDPB; i++) {		error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, SIOP_NSG,		    MAXPHYS, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,		    &newcbd->cmds[i].dmamap_data);		if (error) {			printf("%s: unable to create data DMA map for cbd: "			    "error %d\n",			    sc->sc_dev.dv_xname, error);			goto bad0;		}		error = bus_dmamap_create(sc->sc_dmat,		    sizeof(struct scsi_generic), 1,		    sizeof(struct scsi_generic), 0,		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,		    &newcbd->cmds[i].dmamap_cmd);		if (error) {			printf("%s: unable to create cmd DMA map for cbd %d\n",			    sc->sc_dev.dv_xname, error);			goto bad0;		}		newcbd->cmds[i].siop_sc = sc;		newcbd->cmds[i].siop_cbdp = newcbd;		newcbd->cmds[i].siop_xfer = &newcbd->xfers[i];		memset(newcbd->cmds[i].siop_xfer, 0,		    sizeof(struct siop_xfer));		newcbd->cmds[i].dsa = newcbd->xferdma->dm_segs[0].ds_addr +		    i * sizeof(struct siop_xfer);		dsa = newcbd->cmds[i].dsa;		newcbd->cmds[i].status = CMDST_FREE;		newcbd->cmds[i].siop_tables.t_msgout.count= htole32(1);		newcbd->cmds[i].siop_tables.t_msgout.addr = htole32(dsa);		newcbd->cmds[i].siop_tables.t_msgin.count= htole32(1);		newcbd->cmds[i].siop_tables.t_msgin.addr = htole32(dsa + 16);		newcbd->cmds[i].siop_tables.t_extmsgin.count= htole32(2);		newcbd->cmds[i].siop_tables.t_extmsgin.addr = htole32(dsa + 17);		newcbd->cmds[i].siop_tables.t_extmsgdata.addr =		    htole32(dsa + 19);		newcbd->cmds[i].siop_tables.t_status.count= htole32(1);		newcbd->cmds[i].siop_tables.t_status.addr = htole32(dsa + 32);		/* The select/reselect script */		scr = &newcbd->cmds[i].siop_xfer->resel[0];		for (j = 0; j < sizeof(load_dsa) / sizeof(load_dsa[0]); j++)			scr[j] = htole32(load_dsa[j]);		/*		 * 0x78000000 is a 'move data8 to reg'. data8 is the second		 * octet, reg offset is the third.		 */		scr[Ent_rdsa0 / 4] =		    htole32(0x78100000 | ((dsa & 0x000000ff) <<  8));		scr[Ent_rdsa1 / 4] =		    htole32(0x78110000 | ( dsa & 0x0000ff00       ));		scr[Ent_rdsa2 / 4] =		    htole32(0x78120000 | ((dsa & 0x00ff0000) >>  8));		scr[Ent_rdsa3 / 4] =		    htole32(0x78130000 | ((dsa & 0xff000000) >> 16));		scr[E_ldsa_abs_reselected_Used[0]] =		    htole32(sc->sc_scriptaddr + Ent_reselected);		scr[E_ldsa_abs_reselect_Used[0]] =		    htole32(sc->sc_scriptaddr + Ent_reselect);		scr[E_ldsa_abs_selected_Used[0]] =		    htole32(sc->sc_scriptaddr + Ent_selected);		scr[E_ldsa_abs_data_Used[0]] =		    htole32(dsa + sizeof(struct siop_xfer_common) +		    Ent_ldsa_data);		/* JUMP foo, IF FALSE - used by MOVE MEMORY to clear the slot */		scr[Ent_ldsa_data / 4] = htole32(0x80000000);		TAILQ_INSERT_TAIL(&sc->free_list, &newcbd->cmds[i], next);#ifdef SIOP_DEBUG		printf("tables[%d]: in=0x%x out=0x%x status=0x%x\n", i,		    letoh32(newcbd->cmds[i].siop_tables.t_msgin.addr),		    letoh32(newcbd->cmds[i].siop_tables.t_msgout.addr),		    letoh32(newcbd->cmds[i].siop_tables.t_status.addr));#endif	}	TAILQ_INSERT_TAIL(&sc->cmds, newcbd, next);	return 0;bad0:	bus_dmamap_destroy(sc->sc_dmat, newcbd->xferdma);bad1:	bus_dmamem_free(sc->sc_dmat, &seg, rseg);bad2:	free(newcbd->cmds, M_DEVBUF);bad3:	free(newcbd, M_DEVBUF);	return error;}