siop_cmd
if (siop_cmd->flags & CMDFL_RESID) {
siop_cmd->flags &= ~CMDFL_RESID;
siop_cmd->resid);
table->count = htoc32(siop_cmd->resid);
if (siop_cmd->flags & CMDFL_RESID) {
siop_cmd->saved_offset = SIOP_NOOFFSET;
siop_cmd->saved_offset != SIOP_NOOFFSET)
offset = siop_cmd->saved_offset;
if (siop_cmd->flags & CMDFL_RESID) {
siop_cmd->flags &= ~CMDFL_RESID;
siop_cmd->resid);
table->count = htoc32(siop_cmd->resid);
if (siop_cmd->flags & CMDFL_RESID) {
siop_cmd->saved_offset = SIOP_NOOFFSET;
siop_cmd->saved_offset != SIOP_NOOFFSET)
offset = siop_cmd->saved_offset;
siop_scsicmd_end(struct siop_cmd *siop_cmd)
struct scsipi_xfer *xs = siop_cmd->cmd_c.xs;
struct siop_softc *sc = (struct siop_softc *)siop_cmd->cmd_c.siop_sc;
xs->xs_periph->periph_lun, siop_cmd->cmd_c.tag);
bus_dmamap_sync(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data,
0, siop_cmd->cmd_c.dmamap_data->dm_mapsize,
siop_cmd->cmd_c.dmamap_data);
bus_dmamap_unload(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_cmd);
siop_cmd->cmd_c.status = CMDST_FREE;
TAILQ_INSERT_TAIL(&sc->free_list, siop_cmd, next);
struct siop_cmd *siop_cmd;
siop_cmd = siop_lun->siop_tag[tag].active;
siop_cmd->cmd_c.dsa +
siop_cmd->cmd_c.xs->error = XS_REQUEUE;
siop_cmd->cmd_c.xs->status = SCSI_SIOP_NOCHECK;
siop_scsicmd_end(siop_cmd);
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->xs_periph->periph_target;
int lun = siop_cmd->cmd_c.xs->xs_periph->periph_lun;
int tag = siop_cmd->cmd_tables->msg_out[2];
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;
siop_cmd = siop_lun->siop_tag[tag].active;
if (siop_cmd == NULL)
scsipi_printaddr(siop_cmd->cmd_c.xs->xs_periph);
siop_cmd->cmd_c.xs->error =
(siop_cmd->cmd_c.flags & CMDFL_TIMEOUT) ?
siop_cmd->cmd_c.xs->status = SCSI_SIOP_NOCHECK;
siop_cmd->cmd_c.status = CMDST_DONE;
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, next);
siop_cmd, next);
siop_cmd, next);
siop_cmd->cmd_c.siop_target = sc->sc_c.targets[target];
siop_cmd->cmd_c.xs = xs;
siop_cmd->cmd_c.flags = 0;
siop_cmd->cmd_c.status = CMDST_READY;
siop_cmd->cmd_c.dmamap_cmd,
siop_cmd->cmd_c.status = CMDST_FREE;
TAILQ_INSERT_TAIL(&sc->free_list, siop_cmd, next);
siop_cmd->cmd_c.dmamap_data, xs->data, xs->datalen,
siop_cmd->cmd_c.dmamap_cmd);
siop_cmd->cmd_c.status = CMDST_FREE;
siop_cmd, next);
siop_cmd->cmd_c.dmamap_data, 0,
siop_cmd->cmd_c.dmamap_data->dm_mapsize,
bus_dmamap_sync(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_cmd, 0,
siop_cmd->cmd_c.dmamap_cmd->dm_mapsize,
siop_cmd->cmd_c.tag = xs->xs_tag_id + 1;
siop_cmd->cmd_c.tag = 0;
siop_setuptables(&siop_cmd->cmd_c);
siop_cmd->saved_offset = SIOP_NOOFFSET;
siop_table_sync(siop_cmd,
siop_start(sc, siop_cmd);
siop_start(struct siop_softc *sc, struct siop_cmd *siop_cmd)
target = siop_cmd->cmd_c.xs->xs_periph->periph_target;
lun = siop_cmd->cmd_c.xs->xs_periph->periph_lun;
if (siop_cmd->cmd_c.flags & CMDFL_TAG) {
if (siop_lun->siop_tag[siop_cmd->cmd_c.tag].active != NULL)
if (siop_cmd->cmd_c.tag >= SIOP_NTAG) {
scsipi_printaddr(siop_cmd->cmd_c.xs->xs_periph);
printf(": tag id %d\n", siop_cmd->cmd_c.tag);
siop_cmd->cmd_c.xs->error = XS_REQUEUE;
siop_cmd->cmd_c.xs->status = SCSI_SIOP_NOCHECK;
siop_scsicmd_end(siop_cmd);
(u_long)siop_cmd->cmd_c.dsa);
if (siop_cmd->cmd_c.status == CMDST_READY)
siop_cmd->cmd_c.status = CMDST_ACTIVE;
siop_lun->siop_tag[siop_cmd->cmd_c.tag].active = siop_cmd;
dsa = siop_cmd->cmd_c.dsa;
if (siop_lun->siop_tag[siop_cmd->cmd_c.tag].reseloff > 0)
siop_lun->siop_tag[siop_cmd->cmd_c.tag].reseloff + 1,
siop_xfer = (struct siop_xfer*)siop_cmd->cmd_tables;
siop_table_sync(siop_cmd, BUS_DMASYNC_PREWRITE);
if ((siop_cmd->cmd_c.xs->xs_control & XS_CTL_POLL) == 0) {
timeout = mstohz(siop_cmd->cmd_c.xs->timeout);
callout_reset( &siop_cmd->cmd_c.xs->xs_callout,
timeout, siop_timeout, siop_cmd);
struct siop_cmd *siop_cmd = v;
struct siop_softc *sc = (struct siop_softc *)siop_cmd->cmd_c.siop_sc;
scsipi_printaddr(siop_cmd->cmd_c.xs->xs_periph);
scsipi_print_cdb(siop_cmd->cmd_c.xs->cmd);
callout_stop(&siop_cmd->cmd_c.xs->xs_callout);
siop_cmd->cmd_c.flags |= CMDFL_TIMEOUT;
newcbd->cmds = malloc(sizeof(struct siop_cmd) * SIOP_NCMDPB,
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->xs_periph->periph_target;
lun = siop_cmd->cmd_c.xs->xs_periph->periph_lun;
tag = siop_cmd->cmd_c.tag;
if (siop_cmd->cmd_c.status != CMDST_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) {
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];
siop_sdtr_msg(&siop_cmd->cmd_c, 0,
siop_table_sync(siop_cmd,
siop_cmd) == -1)
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 =
int siop_handle_qtag_reject(struct siop_cmd *);
siop_table_sync(siop_cmd,
siop_cmd->cmd_tables->msg_in[2],
siop_cmd->cmd_tables->msg_in[1]);
void siop_scsicmd_end(struct siop_cmd *);
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];
static void siop_start(struct siop_softc *, struct siop_cmd *);
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);
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;
(u_long)siop_cmd->cmd_c.dsa);
siop_cmd->cmd_c.status = CMDST_FREE;
(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);
siop_cmd->cmd_c.status = CMDST_DONE;
xs->status = siop_ctoh32(&sc->sc_c, siop_cmd->cmd_tables->status);
siop_scsicmd_end(siop_cmd);
siop_setuptables(struct siop_common_cmd *siop_cmd)
struct siop_common_softc *sc = siop_cmd->siop_sc;
struct scsipi_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));
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->xs->xs_tag_type, siop_cmd->xs->xs_tag_id);
siop_cmd->flags |= CMDFL_TAG;
siop_cmd->siop_tables->msg_out[1] = siop_cmd->xs->xs_tag_type;
siop_cmd->siop_tables->msg_out[2] = siop_cmd->tag;
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->siop_tables->status =
siop_cmd->siop_tables->cmd.count =
siop_htoc32(sc, siop_cmd->dmamap_cmd->dm_segs[0].ds_len);
siop_cmd->siop_tables->cmd.addr =
siop_htoc32(sc, siop_cmd->dmamap_cmd->dm_segs[0].ds_addr);
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->xs_periph->periph_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->xs_periph->periph_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->xs_periph->periph_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_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->xs_control & (XS_CTL_DATA_OUT | XS_CTL_DATA_IN))
table = &siop_cmd->siop_tables->data[offset];
if (siop_cmd->xs->xs_control & XS_CTL_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->xs_control & (XS_CTL_DATA_OUT | XS_CTL_DATA_IN))
scsipi_printaddr(siop_cmd->xs->xs_periph);
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);
memmove(&siop_cmd->siop_tables->data[0],
&siop_cmd->siop_tables->data[offset],
siop_update_resid(struct siop_common_cmd *siop_cmd, int offset)
struct siop_common_softc *sc = siop_cmd->siop_sc;
if ((siop_cmd->xs->xs_control & (XS_CTL_DATA_OUT | XS_CTL_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--;
struct siop_common_softc *sc = siop_cmd->cmd_c.siop_sc;
offset = siop_cmd->cmd_c.dsa -
siop_cmd->siop_cbdp->xferdma->dm_segs[0].ds_addr;
bus_dmamap_sync(sc->sc_dmat, siop_cmd->siop_cbdp->xferdma, offset,
TAILQ_HEAD(cmd_list, siop_cmd);
TAILQ_ENTRY (siop_cmd) next;
struct siop_cmd *cmds;
struct siop_cmd *active; /* active command */
static __inline void siop_table_sync(struct siop_cmd *, int);
siop_table_sync(struct siop_cmd *siop_cmd, int ops)