siop_cmd
(u_long)siop_cmd->cmd_c.dsa);
siop_cmd->cmd_c.status = CMDST_FREE;
"in=0x%x status=0x%x\n", (u_long)siop_cmd->cmd_c.dsa,
siop_ctoh32(&sc->sc_c, siop_cmd->cmd_tables->id),
siop_cmd->cmd_tables->msg_in[0],
siop_cmd->cmd_tables->status));
siop_cmd->saved_offset != SIOP_NOOFFSET)
offset = siop_cmd->saved_offset;
siop_update_resid(&siop_cmd->cmd_c, offset);
if (siop_cmd->cmd_c.status == CMDST_SENSE_ACTIVE)
siop_cmd->cmd_c.status = CMDST_SENSE_DONE;
siop_cmd->cmd_c.status = CMDST_DONE;
(siop_cmd == NULL) ? "== NULL" : "!= NULL");
xs->status = siop_ctoh32(&sc->sc_c, siop_cmd->cmd_tables->status);
siop_scsicmd_end(siop_cmd);
siop_scsicmd_end(struct siop_cmd *siop_cmd)
struct scsi_xfer *xs = siop_cmd->cmd_c.xs;
struct siop_softc *sc = (struct siop_softc *)siop_cmd->cmd_c.siop_sc;
timeout_del(&siop_cmd->cmd_c.xs->stimeout);
xs->error = (siop_cmd->cmd_c.status == CMDST_DONE) ?
if (siop_cmd->cmd_c.status == CMDST_SENSE_DONE) {
siop_cmd->cmd_c.status = CMDST_SENSE;
xs->sc_link->lun, siop_cmd->cmd_c.tag);
siop_cmd->cmd_c.status = CMDST_READY;
siop_setuptables(&siop_cmd->cmd_c);
siop_table_sync(siop_cmd, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
TAILQ_INSERT_TAIL(&sc->urgent_list, siop_cmd, next);
if (siop_cmd->cmd_c.status != CMDST_SENSE_DONE &&
bus_dmamap_sync(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data, 0,
siop_cmd->cmd_c.dmamap_data->dm_mapsize,
bus_dmamap_unload(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data);
if (siop_cmd->cmd_c.status == CMDST_SENSE) {
struct scsi_sense *cmd = (struct scsi_sense *)&siop_cmd->cmd_c.siop_tables->xscmd;
siop_cmd->cmd_c.siop_tables->cmd.count =
siop_cmd->cmd_c.flags &= ~CMDFL_TAG;
siop_cmd->cmd_c.dmamap_data,
siop_cmd->cmd_c.sense, sizeof(struct scsi_sense_data),
bus_dmamap_sync(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data,
0, siop_cmd->cmd_c.dmamap_data->dm_mapsize,
siop_setuptables(&siop_cmd->cmd_c);
siop_table_sync(siop_cmd, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
TAILQ_INSERT_HEAD(&sc->urgent_list, siop_cmd, next);
} else if (siop_cmd->cmd_c.status == CMDST_SENSE_DONE) {
bus_dmamap_sync(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data,
0, siop_cmd->cmd_c.dmamap_data->dm_mapsize,
bus_dmamap_unload(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data);
bcopy(siop_cmd->cmd_c.sense, &xs->sense, sizeof(xs->sense));
siop_handle_qtag_reject(struct siop_cmd *siop_cmd)
struct siop_softc *sc = (struct siop_softc *)siop_cmd->cmd_c.siop_sc;
int target = siop_cmd->cmd_c.xs->sc_link->target;
int lun = siop_cmd->cmd_c.xs->sc_link->lun;
int tag = siop_cmd->cmd_tables->msg_out[2];
sc->sc_c.sc_dev.dv_xname, target, lun, tag, siop_cmd->cmd_c.tag,
siop_cmd->cmd_c.status);
siop_lun->siop_tag[0].active = siop_cmd;
siop_cmd->cmd_c.tag = 0;
siop_cmd->cmd_c.dsa + sizeof(struct siop_common_xfer) +
siop_table_sync(siop_cmd, BUS_DMASYNC_PREWRITE);
struct siop_cmd *siop_cmd, *next_siop_cmd;
siop_table_sync(struct siop_cmd *siop_cmd, int ops)
struct siop_common_softc *sc = siop_cmd->cmd_c.siop_sc;
siop_cmd = siop_lun->siop_tag[tag].active;
if (siop_cmd == NULL)
TAILQ_INSERT_TAIL(&reset_list, siop_cmd, next);
sc_print_addr(siop_cmd->cmd_c.xs->sc_link);
siop_cmd, tag);
for (siop_cmd = TAILQ_FIRST(&sc->urgent_list); siop_cmd != NULL;
siop_cmd = next_siop_cmd) {
next_siop_cmd = TAILQ_NEXT(siop_cmd, next);
offset = siop_cmd->cmd_c.dsa -
TAILQ_REMOVE(&sc->urgent_list, siop_cmd, next);
TAILQ_INSERT_TAIL(&reset_list, siop_cmd, next);
sc_print_addr(siop_cmd->cmd_c.xs->sc_link);
siop_cmd);
for (siop_cmd = TAILQ_FIRST(&sc->ready_list); siop_cmd != NULL;
siop_cmd = next_siop_cmd) {
next_siop_cmd = TAILQ_NEXT(siop_cmd, next);
SIOP_DMA_DVA(siop_cmd->siop_cbdp->xfers);
TAILQ_REMOVE(&sc->ready_list, siop_cmd, next);
TAILQ_INSERT_TAIL(&reset_list, siop_cmd, next);
sc_print_addr(siop_cmd->cmd_c.xs->sc_link);
siop_cmd);
for (siop_cmd = TAILQ_FIRST(&reset_list); siop_cmd != NULL;
siop_cmd = next_siop_cmd) {
next_siop_cmd = TAILQ_NEXT(siop_cmd, next);
siop_cmd->cmd_c.flags &= ~CMDFL_TAG;
siop_cmd->cmd_c.xs->error =
(siop_cmd->cmd_c.flags & CMDFL_TIMEOUT)
siop_cmd->cmd_c.xs->status = SCSI_SIOP_NOCHECK;
sc_print_addr(siop_cmd->cmd_c.xs->sc_link);
siop_cmd, siop_cmd->cmd_c.status);
if (siop_cmd->cmd_c.status == CMDST_SENSE ||
siop_cmd->cmd_c.status == CMDST_SENSE_ACTIVE)
SIOP_DMA_MAP(siop_cmd->siop_cbdp->xfers), offset,
siop_cmd->cmd_c.status = CMDST_SENSE_DONE;
siop_cmd->cmd_c.status = CMDST_DONE;
siop_cmd->cmd_c.status, siop_cmd->cmd_c.xs->error);
TAILQ_REMOVE(&reset_list, siop_cmd, next);
siop_scsicmd_end(siop_cmd);
struct siop_cmd *siop_cmd;
siop_cmd = TAILQ_FIRST(&sc->free_list);
if (siop_cmd != NULL) {
TAILQ_REMOVE(&sc->free_list, siop_cmd, next);
if (siop_cmd->cmd_c.status != CMDST_FREE)
siop_cmd->cmd_c.status = CMDST_READY;
return (siop_cmd);
struct siop_cmd *siop_cmd = io;
siop_cmd->cmd_c.status = CMDST_FREE;
TAILQ_INSERT_TAIL(&sc->free_list, siop_cmd, next);
struct siop_cmd *siop_cmd;
siop_cmd = xs->io;
siop_cmd->cmd_c.status = CMDST_READY;
timeout_set(&xs->stimeout, siop_timeout, siop_cmd);
siop_cmd->cmd_c.siop_target = sc->sc_c.targets[target];
siop_cmd->cmd_c.xs = xs;
siop_cmd->cmd_c.flags = 0;
bzero(&siop_cmd->cmd_c.siop_tables->xscmd,
sizeof(siop_cmd->cmd_c.siop_tables->xscmd));
bcopy(&xs->cmd, &siop_cmd->cmd_c.siop_tables->xscmd, xs->cmdlen);
siop_cmd->cmd_c.siop_tables->cmd.count =
siop_cmd->cmd_c.dmamap_data, xs->data, xs->datalen,
siop_cmd->cmd_c.dmamap_data, 0,
siop_cmd->cmd_c.dmamap_data->dm_mapsize,
siop_setuptables(&siop_cmd->cmd_c);
siop_cmd->saved_offset = SIOP_NOOFFSET;
siop_table_sync(siop_cmd,
TAILQ_INSERT_TAIL(&sc->ready_list, siop_cmd, next);
siop_timeout(siop_cmd);
struct siop_cmd *siop_cmd, *next_siop_cmd;
siop_cmd = TAILQ_FIRST(&sc->urgent_list);
for (; siop_cmd != NULL; siop_cmd = next_siop_cmd) {
next_siop_cmd = TAILQ_NEXT(siop_cmd, next);
if (siop_cmd->cmd_c.status != CMDST_READY &&
siop_cmd->cmd_c.status != CMDST_SENSE)
target = siop_cmd->cmd_c.xs->sc_link->target;
lun = siop_cmd->cmd_c.xs->sc_link->lun;
siop_cmd->cmd_c.status == CMDST_READY)
if (siop_cmd->cmd_c.flags & CMDFL_TAG) {
siop_cmd->cmd_c.tag = tag;
if (siop_cmd->cmd_c.status != CMDST_SENSE) {
(u_long)siop_cmd->cmd_c.dsa);
siop_cmd->cmd_tables->t_msgout.count);
siop_cmd->cmd_tables->msg_out[1] = MSG_SIMPLE_Q_TAG;
siop_cmd->cmd_tables->msg_out[2] = tag;
siop_cmd->cmd_tables->t_msgout.count =
if (siop_cmd->cmd_c.status == CMDST_READY) {
siop_cmd->cmd_c.status = CMDST_ACTIVE;
} else if (siop_cmd->cmd_c.status == CMDST_SENSE) {
siop_cmd->cmd_c.status = CMDST_SENSE_ACTIVE;
TAILQ_REMOVE(&sc->ready_list, siop_cmd, next);
TAILQ_REMOVE(&sc->urgent_list, siop_cmd, next);
siop_lun->siop_tag[tag].active = siop_cmd;
dsa = siop_cmd->cmd_c.dsa;
siop_xfer = (struct siop_xfer*)siop_cmd->cmd_tables;
siop_table_sync(siop_cmd, BUS_DMASYNC_PREWRITE);
if (siop_cmd->cmd_c.status == CMDST_ACTIVE) {
if ((siop_cmd->cmd_c.xs->flags & SCSI_POLL) == 0) {
timeout_add_msec(&siop_cmd->cmd_c.xs->stimeout,
siop_cmd->cmd_c.xs->timeout);
siop_cmd = TAILQ_FIRST(&sc->ready_list);
struct siop_cmd *siop_cmd = v;
struct siop_softc *sc = (struct siop_softc *)siop_cmd->cmd_c.siop_sc;
timeout_del(&siop_cmd->cmd_c.xs->stimeout);
sc_print_addr(siop_cmd->cmd_c.xs->sc_link);
siop_cmd->cmd_c.xs->cmd.opcode);
siop_cmd->cmd_c.flags |= CMDFL_TIMEOUT;
newcbd->cmds = mallocarray(SIOP_NCMDPB, sizeof(struct siop_cmd),
free(newcbd->cmds, M_DEVBUF, SIOP_NCMDPB * sizeof(struct siop_cmd));
siop_cmd->cmd_c.dsa, \
struct siop_cmd *siop_cmd;
siop_cmd = NULL;
siop_cmd = &cbdp->cmds[dsa / sizeof(struct siop_xfer)];
siop_table_sync(siop_cmd,
if (siop_cmd) {
xs = siop_cmd->cmd_c.xs;
siop_target = (struct siop_target *)siop_cmd->cmd_c.siop_target;
target = siop_cmd->cmd_c.xs->sc_link->target;
lun = siop_cmd->cmd_c.xs->sc_link->lun;
tag = siop_cmd->cmd_c.tag;
if (siop_cmd->cmd_c.status != CMDST_ACTIVE &&
siop_cmd->cmd_c.status != CMDST_SENSE_ACTIVE) {
siop_cmd->cmd_c.status);
siop_cmd = NULL;
} else if (siop_lun->siop_tag[tag].active != siop_cmd) {
"active (%p != %p)\n", lun, tag, siop_cmd,
if (siop_cmd)
siop_cmd->cmd_tables->msg_in[0],
siop_cmd->cmd_tables->status));
if (siop_cmd)
if (siop_cmd) {
SIOP_DSA, siop_cmd->cmd_c.dsa);
siop_ma(&siop_cmd->cmd_c);
siop_ma(&siop_cmd->cmd_c);
if (siop_cmd)
if (siop_cmd) {
siop_cmd->cmd_c.status = CMDST_DONE;
if (siop_cmd) {
siop_cmd->cmd_tables->status =
if (siop_cmd) {
siop_cmd->cmd_c.status = CMDST_DONE;
if (siop_cmd == NULL) {
if (siop_cmd->cmd_c.status != CMDST_ACTIVE &&
siop_cmd->cmd_c.status != CMDST_SENSE_ACTIVE) {
irqcode, siop_cmd->cmd_c.status);
siop_cmd = siop_lun->siop_tag[tag].active;
SIOP_DSP, siop_cmd->cmd_c.dsa +
siop_table_sync(siop_cmd, BUS_DMASYNC_PREWRITE);
if (siop_cmd->cmd_tables->msg_out[0] & 0x80) {
siop_cmd->cmd_tables->msg_out[1];
siop_cmd->cmd_tables->msg_out[3];
msg = siop_cmd->cmd_tables->msg_out[0];
siop_cmd->cmd_tables->msg_out[2];
void siop_table_sync(struct siop_cmd *, int);
siop_sdtr_msg(&siop_cmd->cmd_c, 0,
siop_table_sync(siop_cmd,
siop_cmd) == -1)
int siop_handle_qtag_reject(struct siop_cmd *);
void siop_scsicmd_end(struct siop_cmd *);
siop_cmd->cmd_tables->t_extmsgdata.count =
siop_table_sync(siop_cmd,
siop_cmd->cmd_tables->msg_in[0]);
siop_cmd->cmd_tables->msg_out[0] = MSG_MESSAGE_REJECT;
siop_cmd->cmd_tables->t_msgout.count =
siop_table_sync(siop_cmd,
siop_cmd->cmd_tables->msg_in[2],
siop_cmd->cmd_tables->msg_in[1]);
if (siop_cmd->cmd_tables->msg_in[1] >
sizeof(siop_cmd->cmd_tables->msg_in) - 2)
siop_cmd->cmd_tables->msg_in[1]);
siop_cmd->cmd_tables->t_extmsgdata.count =
siop_cmd->cmd_tables->msg_in[1] - 1);
siop_table_sync(siop_cmd,
siop_cmd->cmd_tables->msg_in[2]);
for (i = 3; i < 2 + siop_cmd->cmd_tables->msg_in[1];
siop_cmd->cmd_tables->msg_in[i]);
if (siop_cmd->cmd_tables->msg_in[0] ==
if (siop_cmd->cmd_tables->msg_in[3] != 1)
siop_cmd->cmd_tables->msg_in[3]);
switch (siop_iwr(&siop_cmd->cmd_c)) {
siop_table_sync(siop_cmd,
if (siop_cmd->cmd_tables->msg_in[2] == MSG_EXT_WDTR) {
switch (siop_wdtr_neg(&siop_cmd->cmd_c)) {
siop_cmd->cmd_c.siop_target);
siop_table_sync(siop_cmd,
siop_cmd->cmd_c.siop_target);
if (siop_cmd->cmd_tables->msg_in[2] == MSG_EXT_SDTR) {
switch (siop_sdtr_neg(&siop_cmd->cmd_c)) {
siop_cmd->cmd_c.siop_target);
siop_table_sync(siop_cmd,
siop_cmd->cmd_c.siop_target);
if (siop_cmd->cmd_tables->msg_in[2] == MSG_EXT_PPR) {
switch (siop_ppr_neg(&siop_cmd->cmd_c)) {
siop_cmd->cmd_c.siop_target);
siop_table_sync(siop_cmd,
siop_cmd->cmd_c.siop_target);
siop_cmd->cmd_tables->msg_out[0] = MSG_MESSAGE_REJECT;
siop_cmd->cmd_tables->t_msgout.count =
siop_table_sync(siop_cmd,
siop_sdp(&siop_cmd->cmd_c, offset);
siop_cmd->saved_offset = SIOP_NOOFFSET;
siop_table_sync(siop_cmd,
siop_cmd->saved_offset = offset;
siop_setuptables(struct siop_common_cmd *siop_cmd)
struct siop_common_softc *sc = siop_cmd->siop_sc;
struct scsi_xfer *xs = siop_cmd->xs;
siop_cmd->siop_tables->id = siop_htoc32(sc, sc->targets[target]->id);
memset(siop_cmd->siop_tables->msg_out, 0,
sizeof(siop_cmd->siop_tables->msg_out));
if (siop_cmd->status == CMDST_SENSE)
siop_cmd->siop_tables->msg_out[0] = MSG_IDENTIFY(lun, 0);
siop_cmd->siop_tables->msg_out[0] = MSG_IDENTIFY(lun, 0);
siop_cmd->siop_tables->msg_out[0] = MSG_IDENTIFY(lun, 1);
siop_cmd->siop_tables->t_msgout.count = siop_htoc32(sc, msgoffset);
siop_ppr_msg(siop_cmd, msgoffset, sc->dt_minsync,
siop_wdtr_msg(siop_cmd, msgoffset,
siop_sdtr_msg(siop_cmd, msgoffset, sc->st_minsync,
siop_cmd->status != CMDST_SENSE) {
siop_cmd->flags |= CMDFL_TAG;
siop_cmd->siop_tables->status =
siop_cmd->status == CMDST_SENSE) {
bzero(siop_cmd->siop_tables->data,
sizeof(siop_cmd->siop_tables->data));
for (i = 0; i < siop_cmd->dmamap_data->dm_nsegs; i++) {
siop_cmd->siop_tables->data[i].count =
siop_cmd->dmamap_data->dm_segs[i].ds_len);
siop_cmd->siop_tables->data[i].addr =
siop_cmd->dmamap_data->dm_segs[i].ds_addr);
siop_wdtr_neg(struct siop_common_cmd *siop_cmd)
struct siop_common_softc *sc = siop_cmd->siop_sc;
struct siop_common_target *siop_target = siop_cmd->siop_target;
int target = siop_cmd->xs->sc_link->target;
struct siop_common_xfer *tables = siop_cmd->siop_tables;
siop_sdtr_msg(siop_cmd, 0, sc->st_minsync,
siop_wdtr_msg(siop_cmd, 0, (siop_target->flags & TARF_ISWIDE) ?
siop_ppr_neg(struct siop_common_cmd *siop_cmd)
struct siop_common_softc *sc = siop_cmd->siop_sc;
struct siop_common_target *siop_target = siop_cmd->siop_target;
int target = siop_cmd->xs->sc_link->target;
struct siop_common_xfer *tables = siop_cmd->siop_tables;
siop_sdtr_neg(struct siop_common_cmd *siop_cmd)
struct siop_common_softc *sc = siop_cmd->siop_sc;
struct siop_common_target *siop_target = siop_cmd->siop_target;
int target = siop_cmd->xs->sc_link->target;
struct siop_common_xfer *tables = siop_cmd->siop_tables;
siop_sdtr_msg(siop_cmd, 0, sync, offset);
siop_sdtr_msg(siop_cmd, 0, 0, 0);
siop_sdtr_msg(struct siop_common_cmd *siop_cmd, int offset, int ssync, int soff)
siop_cmd->siop_tables->msg_out[offset + 0] = MSG_EXTENDED;
siop_cmd->siop_tables->msg_out[offset + 1] = MSG_EXT_SDTR_LEN;
siop_cmd->siop_tables->msg_out[offset + 2] = MSG_EXT_SDTR;
siop_cmd->siop_tables->msg_out[offset + 3] = ssync;
siop_cmd->siop_tables->msg_out[offset + 4] = soff;
siop_cmd->siop_tables->t_msgout.count =
siop_htoc32(siop_cmd->siop_sc, offset + MSG_EXT_SDTR_LEN + 2);
siop_wdtr_msg(struct siop_common_cmd *siop_cmd, int offset, int wide)
siop_cmd->siop_tables->msg_out[offset + 0] = MSG_EXTENDED;
siop_cmd->siop_tables->msg_out[offset + 1] = MSG_EXT_WDTR_LEN;
siop_cmd->siop_tables->msg_out[offset + 2] = MSG_EXT_WDTR;
siop_cmd->siop_tables->msg_out[offset + 3] = wide;
siop_cmd->siop_tables->t_msgout.count =
siop_htoc32(siop_cmd->siop_sc, offset + MSG_EXT_WDTR_LEN + 2);
siop_ppr_msg(struct siop_common_cmd *siop_cmd, int offset, int ssync, int soff)
siop_cmd->siop_tables->msg_out[offset + 0] = MSG_EXTENDED;
siop_cmd->siop_tables->msg_out[offset + 1] = MSG_EXT_PPR_LEN;
siop_cmd->siop_tables->msg_out[offset + 2] = MSG_EXT_PPR;
siop_cmd->siop_tables->msg_out[offset + 3] = ssync;
siop_cmd->siop_tables->msg_out[offset + 4] = 0; /* reserved */
siop_cmd->siop_tables->msg_out[offset + 5] = soff;
siop_cmd->siop_tables->msg_out[offset + 6] = 1; /* wide */
siop_cmd->siop_tables->msg_out[offset + 7] = MSG_EXT_PPR_PROT_DT;
siop_cmd->siop_tables->t_msgout.count =
siop_htoc32(siop_cmd->siop_sc, offset + MSG_EXT_PPR_LEN + 2);
siop_ma(struct siop_common_cmd *siop_cmd)
struct siop_common_softc *sc = siop_cmd->siop_sc;
if ((siop_cmd->xs->flags & (SCSI_DATA_OUT | SCSI_DATA_IN))
table = &siop_cmd->siop_tables->data[offset];
if (siop_cmd->xs->flags & SCSI_DATA_OUT) {
if (siop_cmd->siop_target->flags & TARF_ISWIDE) {
siop_cmd->flags |= CMDFL_RESID;
siop_cmd->resid = dbc;
siop_sdp(struct siop_common_cmd *siop_cmd, int offset)
struct siop_common_softc *sc = siop_cmd->siop_sc;
if ((siop_cmd->xs->flags & (SCSI_DATA_OUT | SCSI_DATA_IN))== 0)
sc_print_addr(siop_cmd->xs->sc_link);
siop_update_resid(siop_cmd, offset);
if (siop_cmd->flags & CMDFL_RESID) {
siop_cmd->flags &= ~CMDFL_RESID;
table = &siop_cmd->siop_tables->data[offset];
siop_ctoh32(sc, table->count) - siop_cmd->resid);
table->count = siop_htoc32(sc, siop_cmd->resid);
bcopy(&siop_cmd->siop_tables->data[offset],
&siop_cmd->siop_tables->data[0],
siop_update_resid(struct siop_common_cmd *siop_cmd, int offset)
struct siop_common_softc *sc = siop_cmd->siop_sc;
if ((siop_cmd->xs->flags & (SCSI_DATA_OUT | SCSI_DATA_IN))
siop_cmd->xs->resid -=
siop_ctoh32(sc, siop_cmd->siop_tables->data[i].count);
if (siop_cmd->flags & CMDFL_RESID) {
table = &siop_cmd->siop_tables->data[offset];
siop_cmd->xs->resid -=
siop_ctoh32(sc, table->count) - siop_cmd->resid;
siop_iwr(struct siop_common_cmd *siop_cmd)
struct siop_common_softc *sc = siop_cmd->siop_sc;
if ((siop_cmd->siop_target->flags & TARF_ISWIDE) == 0) {
siop_cmd->siop_tables->t_msgout.count = siop_htoc32(sc, 1);
siop_cmd->siop_tables->msg_out[0] = MSG_MESSAGE_REJECT;
if ((siop_cmd->flags & CMDFL_RESID) == 0)
table = &siop_cmd->siop_tables->data[offset];
if ((siop_cmd->flags & CMDFL_RESID) == 0) {
siop_cmd->flags |= CMDFL_RESID;
siop_cmd->resid = 1;
siop_cmd->resid--;
TAILQ_HEAD(cmd_list, siop_cmd);
TAILQ_ENTRY (siop_cmd) next;
struct siop_cmd *cmds;
struct siop_cmd *active; /* active command */