diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2003-07-01 17:15:07 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2003-07-01 17:15:07 +0000 |
commit | 93d92df72e7e3af474865f8f2eb06de7ce91b354 (patch) | |
tree | 9b50a654f37c03f7bad7035ed46717a0b365c2b9 /sys/dev/ic | |
parent | ed03395998fad2d4a56d64c53191b035072f191c (diff) |
Don't dma map the xs->cmd. Copy it to a safe buffer that is already
mapped and sync'ed appropriately, and is guaranteed to be in one
memory page.
Eliminate now unused dmamap_cmd and rs_cmd fields.
Fix another error message (adding active command to reset list) so
that it includes the adapter name.
Add missing letoh32() calls to debug code.
The evils of directly mapping *xs->cmd were pointed out by Mickey
during osiop development. In particular, *xs->cmd may start on one
memory page and run into the next. Since the dma logic in most
cards/drivers (including siop) only allocates one address/size pair to
map *xs->cmd, parts of a command could be lost or corrupted.
The large number of 6 byte dma mappings noted long ago by someone
(Henric?). This change reduces the dma mapping activity per i/o by
1/3 to 1/2 and may give a performance boost of some kind.
Successfully tested on i386, sparc64 (ultra30 - thanks Jolan,
blade100), macppc and alpha.
Unfortunately these changes don't fix the Blade1000 siop problems.
**NOTE** If scsi_generic is ever upped to 16 bytes the offsets in
siop.ss must be updated!
Diffstat (limited to 'sys/dev/ic')
-rw-r--r-- | sys/dev/ic/siop.c | 70 | ||||
-rw-r--r-- | sys/dev/ic/siop_common.c | 13 | ||||
-rw-r--r-- | sys/dev/ic/siopvar_common.h | 34 |
3 files changed, 43 insertions, 74 deletions
diff --git a/sys/dev/ic/siop.c b/sys/dev/ic/siop.c index 87379103d33..e801d8e1294 100644 --- a/sys/dev/ic/siop.c +++ b/sys/dev/ic/siop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: siop.c,v 1.27 2003/06/28 22:16:55 krw Exp $ */ +/* $OpenBSD: siop.c,v 1.28 2003/07/01 17:15:06 krw Exp $ */ /* $NetBSD: siop.c,v 1.65 2002/11/08 22:04:41 bouyer Exp $ */ /* @@ -490,6 +490,7 @@ siop_intr(v) if ((sist & SIST0_MA) && need_reset == 0) { if (siop_cmd) { int scratcha0; + /* XXX Why read DSTAT again? */ dstat = bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSTAT); /* @@ -1082,26 +1083,19 @@ siop_scsicmd_end(siop_cmd) BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data); } - bus_dmamap_unload(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_cmd); if (siop_cmd->cmd_c.status == CMDST_SENSE) { /* issue a request sense for this target */ + struct scsi_sense *cmd = (struct scsi_sense *)&siop_cmd->cmd_c.siop_tables->xscmd; int error; - siop_cmd->cmd_c.rs_cmd.opcode = REQUEST_SENSE; - siop_cmd->cmd_c.rs_cmd.byte2 = xs->sc_link->lun << 5; - siop_cmd->cmd_c.rs_cmd.unused[0] = siop_cmd->cmd_c.rs_cmd.unused[1] = 0; - siop_cmd->cmd_c.rs_cmd.length = sizeof(struct scsi_sense_data); - siop_cmd->cmd_c.rs_cmd.control = 0; + bzero(cmd, sizeof(*cmd)); + siop_cmd->cmd_c.siop_tables->cmd.count = + htole32(sizeof(struct scsi_sense)); + cmd->opcode = REQUEST_SENSE; + cmd->byte2 = xs->sc_link->lun << 5; + cmd->unused[0] = cmd->unused[1] = 0; + cmd->length = sizeof(struct scsi_sense_data); + cmd->control = 0; siop_cmd->cmd_c.flags &= ~CMDFL_TAG; - error = bus_dmamap_load(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_cmd, - &siop_cmd->cmd_c.rs_cmd, sizeof(struct scsi_sense), - NULL, BUS_DMA_NOWAIT); - if (error) { - printf("%s: unable to load cmd DMA map " - "(for SENSE): %d\n", - sc->sc_c.sc_dev.dv_xname, error); - xs->error = XS_DRIVER_STUFFUP; - goto out; - } error = bus_dmamap_load(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data, &xs->sense, sizeof(struct scsi_sense_data), NULL, BUS_DMA_NOWAIT); @@ -1110,15 +1104,11 @@ siop_scsicmd_end(siop_cmd) "(for SENSE): %d\n", sc->sc_c.sc_dev.dv_xname, error); xs->error = XS_DRIVER_STUFFUP; - bus_dmamap_unload(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_cmd); goto out; } bus_dmamap_sync(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data, 0, siop_cmd->cmd_c.dmamap_data->dm_mapsize, BUS_DMASYNC_PREREAD); - bus_dmamap_sync(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_cmd, - 0, siop_cmd->cmd_c.dmamap_cmd->dm_mapsize, - BUS_DMASYNC_PREWRITE); siop_setuptables(&siop_cmd->cmd_c); siop_table_sync(siop_cmd, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -1270,7 +1260,8 @@ siop_handle_reset(sc) (siop_cmd->cmd_c.flags & CMDFL_TIMEOUT) ? XS_TIMEOUT : XS_RESET; siop_cmd->cmd_c.xs->status = SCSI_SIOP_NOCHECK; - printf("cmd %p (status %d) reset ", + sc_print_addr(siop_cmd->cmd_c.xs->sc_link); + printf("cmd %p (status %d) reset", siop_cmd, siop_cmd->cmd_c.status); if (siop_cmd->cmd_c.status == CMDST_SENSE || siop_cmd->cmd_c.status == CMDST_SENSE_ACTIVE) @@ -1373,17 +1364,12 @@ siop_scsicmd(xs) siop_cmd->cmd_c.flags = 0; siop_cmd->cmd_c.status = CMDST_READY; + 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 = htole32(xs->cmdlen); + /* load the DMA maps */ - error = bus_dmamap_load(sc->sc_c.sc_dmat, - siop_cmd->cmd_c.dmamap_cmd, - xs->cmd, xs->cmdlen, NULL, BUS_DMA_NOWAIT); - if (error) { - printf("%s: unable to load cmd DMA map: %d\n", - sc->sc_c.sc_dev.dv_xname, error); - xs->error = XS_DRIVER_STUFFUP; - splx(s); - return(TRY_AGAIN_LATER); - } if (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) { error = bus_dmamap_load(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data, xs->data, xs->datalen, @@ -1391,11 +1377,9 @@ siop_scsicmd(xs) ((xs->flags & SCSI_DATA_IN) ? BUS_DMA_READ : BUS_DMA_WRITE)); if (error) { - printf("%s: unable to load cmd DMA map: %d\n", + printf("%s: unable to load data DMA map: %d\n", sc->sc_c.sc_dev.dv_xname, error); xs->error = XS_DRIVER_STUFFUP; - bus_dmamap_unload(sc->sc_c.sc_dmat, - siop_cmd->cmd_c.dmamap_cmd); splx(s); return(TRY_AGAIN_LATER); } @@ -1405,9 +1389,6 @@ siop_scsicmd(xs) (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); } - bus_dmamap_sync(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_cmd, 0, - siop_cmd->cmd_c.dmamap_cmd->dm_mapsize, - BUS_DMASYNC_PREWRITE); siop_setuptables(&siop_cmd->cmd_c); siop_table_sync(siop_cmd, @@ -1785,16 +1766,6 @@ siop_morecbd(sc) sc->sc_c.sc_dev.dv_xname, error); goto bad0; } - error = bus_dmamap_create(sc->sc_c.sc_dmat, - sizeof(struct scsi_generic), 1, - sizeof(struct scsi_generic), 0, - BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, - &newcbd->cmds[i].cmd_c.dmamap_cmd); - if (error) { - printf("%s: unable to create cmd DMA map for cbd %d\n", - sc->sc_c.sc_dev.dv_xname, error); - goto bad0; - } } /* Use two loops since bailing out above releases allocated memory */ @@ -1821,6 +1792,9 @@ siop_morecbd(sc) xfer->siop_tables.t_status.count= htole32(1); xfer->siop_tables.t_status.addr = htole32(dsa + offsetof(struct siop_common_xfer, status)); + xfer->siop_tables.cmd.count= htole32(0); + xfer->siop_tables.cmd.addr = htole32(dsa + + offsetof(struct siop_common_xfer, xscmd)); /* The select/reselect script */ scr = &xfer->resel[0]; for (j = 0; j < sizeof(load_dsa) / sizeof(load_dsa[0]); j++) diff --git a/sys/dev/ic/siop_common.c b/sys/dev/ic/siop_common.c index c9b10ac5085..814a22a5e3c 100644 --- a/sys/dev/ic/siop_common.c +++ b/sys/dev/ic/siop_common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: siop_common.c,v 1.15 2002/10/09 23:43:11 krw Exp $ */ +/* $OpenBSD: siop_common.c,v 1.16 2003/07/01 17:15:06 krw Exp $ */ /* $NetBSD: siop_common.c,v 1.31 2002/09/27 15:37:18 provos Exp $ */ /* @@ -312,10 +312,6 @@ siop_setuptables(siop_cmd) siop_cmd->siop_tables->status = htole32(SCSI_SIOP_NOSTATUS); /* set invalid status */ - siop_cmd->siop_tables->cmd.count = - htole32(siop_cmd->dmamap_cmd->dm_segs[0].ds_len); - siop_cmd->siop_tables->cmd.addr = - htole32(siop_cmd->dmamap_cmd->dm_segs[0].ds_addr); if ((xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) || siop_cmd->status == CMDST_SENSE) { for (i = 0; i < siop_cmd->dmamap_data->dm_nsegs; i++) { @@ -419,7 +415,7 @@ siop_ppr_neg(siop_cmd) int i; #ifdef DEBUG_NEG - printf("%s: anserw on ppr negotiation:", sc->sc_dev.dv_xname); + printf("%s: answer on ppr negotiation:", sc->sc_dev.dv_xname); for (i = 0; i < 8; i++) printf(" 0x%x", tables->msg_in[i]); printf("\n"); @@ -729,7 +725,7 @@ siop_sdp(siop_cmd) table = &siop_cmd->siop_tables->data[offset]; #ifdef DEBUG_DR printf("sdp: offset %d count=%d addr=0x%x ", offset, - table->count, table->addr); + letoh32(table->count), letoh32(table->addr)); #endif dbc = bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DBC) & 0x00ffffff; if (siop_cmd->xs->flags & SCSI_DATA_OUT) { @@ -771,7 +767,8 @@ siop_sdp(siop_cmd) htole32(letoh32(table->addr) + letoh32(table->count) - dbc); table->count = htole32(dbc); #ifdef DEBUG_DR - printf("now count=%d addr=0x%x\n", table->count, table->addr); + printf("now count=%d addr=0x%x\n", + letoh32(table->count), letoh32(table->addr)); #endif } diff --git a/sys/dev/ic/siopvar_common.h b/sys/dev/ic/siopvar_common.h index a7dd7da789c..ce5741c15b4 100644 --- a/sys/dev/ic/siopvar_common.h +++ b/sys/dev/ic/siopvar_common.h @@ -1,4 +1,4 @@ -/* $OpenBSD: siopvar_common.h,v 1.13 2003/02/11 19:20:27 mickey Exp $ */ +/* $OpenBSD: siopvar_common.h,v 1.14 2003/07/01 17:15:06 krw Exp $ */ /* $NetBSD: siopvar_common.h,v 1.22 2002/10/23 02:32:36 christos Exp $ */ /* @@ -48,23 +48,23 @@ typedef struct scr_table { /* * This structure interfaces the SCRIPT with the driver; it describes a full - * transfer. - * If you change something here, don't forget to update offsets in {s,es}iop.ss + * transfer. If you change something here, don't forget to update offsets in + * {s,es}iop.ss */ struct siop_common_xfer { - u_int8_t msg_out[16]; /* 0 */ - u_int8_t msg_in[16]; /* 16 */ - u_int32_t status; /* 32 */ - u_int32_t pad1; /* 36 */ - u_int32_t id; /* 40 */ - u_int32_t pad2; /* 44 */ - scr_table_t t_msgin; /* 48 */ - scr_table_t t_extmsgin; /* 56 */ - scr_table_t t_extmsgdata; /* 64 */ - scr_table_t t_msgout; /* 72 */ - scr_table_t cmd; /* 80 */ - scr_table_t t_status; /* 88 */ - scr_table_t data[SIOP_NSG]; /* 96 */ + u_int8_t msg_out[16]; /* 0 */ + u_int8_t msg_in[16]; /* 16 */ + u_int32_t status; /* 32 */ + u_int32_t pad1; /* 36 */ + u_int32_t id; /* 40 */ + struct scsi_generic xscmd; /* 44 */ + scr_table_t t_msgin; /* 56 */ + scr_table_t t_extmsgin; /* 64 */ + scr_table_t t_extmsgdata; /* 72 */ + scr_table_t t_msgout; /* 80 */ + scr_table_t cmd; /* 88 */ + scr_table_t t_status; /* 96 */ + scr_table_t data[SIOP_NSG]; /* 104 */ } __attribute__((__packed__)); /* status can hold the SCSI_* status values, and 2 additionnal values: */ @@ -79,9 +79,7 @@ struct siop_common_cmd { struct siop_common_target *siop_target; /* pointer to our target def */ struct scsi_xfer *xs; /* xfer from the upper level */ struct siop_common_xfer *siop_tables; /* tables for this cmd */ - struct scsi_sense rs_cmd; /* request sense command buffer */ bus_addr_t dsa; /* DSA value to load */ - bus_dmamap_t dmamap_cmd; bus_dmamap_t dmamap_data; int status; int flags; |