diff options
author | 2005-11-03 11:00:36 +0000 | |
---|---|---|
committer | 2005-11-03 11:00:36 +0000 | |
commit | 4ddf9cadb463dbf8706f75761482ddc1ab5a6937 (patch) | |
tree | 272e198f42cf438634c80078ffea05bfe6fab8d2 | |
parent | use splvm() here instead of splimp(). in currently unused MULTIPROCESSOR code. (diff) | |
download | wireguard-openbsd-4ddf9cadb463dbf8706f75761482ddc1ab5a6937.tar.xz wireguard-openbsd-4ddf9cadb463dbf8706f75761482ddc1ab5a6937.zip |
revert to 20051009 for now, need to investigate strange behaviour with
some controllers
discussed with otto@ and henning@, first noted by miod@
-rw-r--r-- | sys/dev/ic/siop.c | 93 | ||||
-rw-r--r-- | sys/dev/ic/siop_common.c | 177 | ||||
-rw-r--r-- | sys/dev/ic/siopvar_common.h | 9 |
3 files changed, 54 insertions, 225 deletions
diff --git a/sys/dev/ic/siop.c b/sys/dev/ic/siop.c index 15b14e60696..9bad2466ee6 100644 --- a/sys/dev/ic/siop.c +++ b/sys/dev/ic/siop.c @@ -1,5 +1,5 @@ -/* $OpenBSD: siop.c,v 1.40 2005/10/10 16:27:23 krw Exp $ */ -/* $NetBSD: siop.c,v 1.78 2005/02/27 00:27:02 perry Exp $ */ +/* $OpenBSD: siop.c,v 1.41 2005/11/03 11:00:36 martin Exp $ */ +/* $NetBSD: siop.c,v 1.65 2002/11/08 22:04:41 bouyer Exp $ */ /* * Copyright (c) 2000 Manuel Bouyer. @@ -343,7 +343,7 @@ siop_intr(v) struct siop_cmd *siop_cmd; struct siop_lun *siop_lun; struct scsi_xfer *xs; - int istat, sist, sstat1, dstat = 0; + int istat, sist, sstat1, dstat; u_int32_t irqcode; int need_reset = 0; int offset, target, lun, tag; @@ -518,31 +518,31 @@ siop_intr(v) /* * previous phase may be aborted for any reason * ( for example, the target has less data to - * transfer than requested). Compute resid and - * just go to status, the command should - * terminate. + * transfer than requested). Just go to status + * and the command should terminate. */ INCSTAT(siop_stat_intr_shortxfer); - if (scratcha0 & A_flag_data) - siop_ma(&siop_cmd->cmd_c); - else if ((dstat & DSTAT_DFE) == 0) + if ((dstat & DSTAT_DFE) == 0) siop_clearfifo(&sc->sc_c); + /* no table to flush here */ CALL_SCRIPT(Ent_status); return 1; case SSTAT1_PHASE_MSGIN: - /* - * target may be ready to disconnect - * Compute resid which would be used later - * if a save data pointer is needed. - */ + /* + * target may be ready to disconnect + * Save data pointers just in case. + */ INCSTAT(siop_stat_intr_xferdisc); if (scratcha0 & A_flag_data) - siop_ma(&siop_cmd->cmd_c); + siop_sdp(&siop_cmd->cmd_c); else if ((dstat & DSTAT_DFE) == 0) siop_clearfifo(&sc->sc_c); bus_space_write_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_SCRATCHA, scratcha0 & ~A_flag_data); + siop_table_sync(siop_cmd, + BUS_DMASYNC_PREREAD | + BUS_DMASYNC_PREWRITE); CALL_SCRIPT(Ent_msgin); return 1; } @@ -816,15 +816,6 @@ scintr: CALL_SCRIPT(Ent_msgin_ack); return 1; } - if (msgin == MSG_IGN_WIDE_RESIDUE) { - /* use the extmsgdata table to get the second byte */ - siop_cmd->cmd_tables->t_extmsgdata.count = - htole32(1); - siop_table_sync(siop_cmd, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - CALL_SCRIPT(Ent_get_extmsgdata); - return 1; - } if (xs) sc_print_addr(xs->sc_link); else @@ -868,29 +859,6 @@ scintr: printf("\n"); } #endif - if (siop_cmd->cmd_tables->msg_in[0] == - MSG_IGN_WIDE_RESIDUE) { - /* we got the second byte of MSG_IGN_WIDE_RESIDUE */ - if (siop_cmd->cmd_tables->msg_in[3] != 1) - printf("MSG_IGN_WIDE_RESIDUE: " - "bad len %d\n", - siop_cmd->cmd_tables->msg_in[3]); - switch (siop_iwr(&siop_cmd->cmd_c)) { - case SIOP_NEG_MSGOUT: - siop_table_sync(siop_cmd, - BUS_DMASYNC_PREREAD | - BUS_DMASYNC_PREWRITE); - CALL_SCRIPT(Ent_send_msgout); - return(1); - case SIOP_NEG_ACK: - CALL_SCRIPT(Ent_msgin_ack); - return(1); - default: - panic("invalid retval from " - "siop_iwr()"); - } - return(1); - } if (siop_cmd->cmd_tables->msg_in[2] == MSG_EXT_WDTR) { switch (siop_wdtr_neg(&siop_cmd->cmd_c)) { case SIOP_NEG_MSGOUT: @@ -968,9 +936,25 @@ scintr: #ifdef SIOP_DEBUG_DR printf("disconnect offset %d\n", offset); #endif - siop_sdp(&siop_cmd->cmd_c, offset); - siop_table_sync(siop_cmd, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + if (offset > SIOP_NSG) { + printf("%s: bad offset for disconnect (%d)\n", + sc->sc_c.sc_dev.dv_xname, offset); + goto reset; + } + /* + * offset == SIOP_NSG may be a valid condition if + * we get a sdp when the xfer is done. + * Don't call bcopy in this case. + */ + if (offset < SIOP_NSG) { + bcopy(&siop_cmd->cmd_tables->data[offset], + &siop_cmd->cmd_tables->data[0], + (SIOP_NSG - offset) * sizeof(scr_table_t)); + siop_table_sync(siop_cmd, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + } + /* check if we can put some command in scheduler */ + siop_start(sc); CALL_SCRIPT(Ent_script_sched); return 1; case A_int_resfail: @@ -997,10 +981,6 @@ scintr: letoh32(siop_cmd->cmd_tables->status)); #endif INCSTAT(siop_stat_intr_done); - /* update resid. */ - offset = bus_space_read_1(sc->sc_c.sc_rt, - sc->sc_c.sc_rh, SIOP_SCRATCHA + 1); - 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; else @@ -1165,10 +1145,7 @@ out: xs->flags |= ITSDONE; siop_cmd->cmd_c.status = CMDST_FREE; TAILQ_INSERT_TAIL(&sc->free_list, siop_cmd, next); -#if 0 - if (xs->resid != 0) - printf("resid %d datalen %d\n", xs->resid, xs->datalen); -#endif + xs->resid = 0; scsi_done(xs); } diff --git a/sys/dev/ic/siop_common.c b/sys/dev/ic/siop_common.c index 4d51b36f05b..73a6dccb34f 100644 --- a/sys/dev/ic/siop_common.c +++ b/sys/dev/ic/siop_common.c @@ -1,5 +1,5 @@ -/* $OpenBSD: siop_common.c,v 1.25 2005/10/31 19:02:06 miod Exp $ */ -/* $NetBSD: siop_common.c,v 1.37 2005/02/27 00:27:02 perry Exp $ */ +/* $OpenBSD: siop_common.c,v 1.26 2005/11/03 11:00:36 martin Exp $ */ +/* $NetBSD: siop_common.c,v 1.31 2002/09/27 15:37:18 provos Exp $ */ /* * Copyright (c) 2000, 2002 Manuel Bouyer. @@ -21,7 +21,7 @@ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY @@ -68,7 +68,7 @@ siop_common_attach(sc) * Allocate DMA-safe memory for the script and map it. */ if ((sc->features & SF_CHIP_RAM) == 0) { - error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, + 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 script DMA memory, " @@ -441,7 +441,7 @@ siop_ppr_neg(siop_cmd) siop_target->period = 0; goto reject; } - + if (offset > sc->maxoff || sync < sc->dt_minsync || sync > sc->dt_maxsync) { printf("%s: ppr negotiation for target %d: " @@ -714,21 +714,17 @@ siop_minphys(bp) } void -siop_ma(siop_cmd) +siop_sdp(siop_cmd) struct siop_common_cmd *siop_cmd; { + /* save data pointer. Handle async only for now */ int offset, dbc, sstat; struct siop_common_softc *sc = siop_cmd->siop_sc; - scr_table_t *table; /* table with partial xfer */ + scr_table_t *table; /* table to patch */ - /* - * compute how much of the current table didn't get handled when - * a phase mismatch occurs - */ if ((siop_cmd->xs->flags & (SCSI_DATA_OUT | SCSI_DATA_IN)) == 0) - return; /* no valid data transfer */ - + return; /* no data pointers to save */ offset = bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_SCRATCHA + 1); if (offset >= SIOP_NSG) { printf("%s: bad offset in siop_sdp (%d)\n", @@ -737,8 +733,8 @@ siop_ma(siop_cmd) } table = &siop_cmd->siop_tables->data[offset]; #ifdef DEBUG_DR - printf("siop_ma: offset %d count=%d addr=0x%x ", offset, - table->count, table->addr); + printf("sdp: offset %d count=%d addr=0x%x ", offset, + 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) { @@ -776,152 +772,13 @@ siop_ma(siop_cmd) bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST3) | CTEST3_CLF); } - siop_cmd->flags |= CMDFL_RESID; - siop_cmd->resid = dbc; -} - -void -siop_sdp(siop_cmd, offset) - struct siop_common_cmd *siop_cmd; - int offset; -{ - scr_table_t *table; - - if ((siop_cmd->xs->flags & (SCSI_DATA_OUT | SCSI_DATA_IN)) - == 0) - return; /* no data pointers to save */ - - /* - * offset == SIOP_NSG may be a valid condition if we get a Save data - * pointer when the xfer is done. Just ignore the Save data pointer - * in this case - */ - if (offset == SIOP_NSG) - return; -#ifdef DIAGNOSTIC - if (offset > SIOP_NSG) { - sc_print_addr(siop_cmd->xs->sc_link); - printf(": offset %d > %d\n", offset, SIOP_NSG); - panic("siop_sdp: offset"); - } + table->addr = + htole32(letoh32(table->addr) + letoh32(table->count) - dbc); + table->count = htole32(dbc); +#ifdef DEBUG_DR + printf("now count=%d addr=0x%x\n", + letoh32(table->count), letoh32(table->addr)); #endif - /* - * Save data pointer. We do this by adjusting the tables to point - * at the begginning of the data not yet transfered. - * offset points to the first table with untransfered data. - */ - - /* - * before doing that we decrease resid from the amount of data which - * has been transfered. - */ - siop_update_resid(siop_cmd, offset); - - /* - * First let see if we have a resid from a phase mismatch. If so, - * we have to adjst the table at offset to remove transfered data. - */ - if (siop_cmd->flags & CMDFL_RESID) { - siop_cmd->flags &= ~CMDFL_RESID; - table = &siop_cmd->siop_tables->data[offset]; - /* "cut" already transfered data from this table */ - table->addr = - htole32(letoh32(table->addr) + - letoh32(table->count) - siop_cmd->resid); - table->count = htole32(siop_cmd->resid); - } - - /* - * now we can remove entries which have been transfered. - * We just move the entries with data left at the beggining of the - * tables - */ - bcopy(&siop_cmd->siop_tables->data[offset], - &siop_cmd->siop_tables->data[0], - (SIOP_NSG - offset) * sizeof(scr_table_t)); -} - -void -siop_update_resid(siop_cmd, offset) - struct siop_common_cmd *siop_cmd; - int offset; -{ - scr_table_t *table; - int i; - - if ((siop_cmd->xs->flags & (SCSI_DATA_OUT | SCSI_DATA_IN)) - == 0) - return; /* no data to transfer */ - - /* - * update resid. First account for the table entries which have - * been fully completed. - */ - for (i = 0; i < offset; i++) - siop_cmd->xs->resid -= - letoh32(siop_cmd->siop_tables->data[i].count); - /* - * if CMDFL_RESID is set, the last table (pointed by offset) is a - * partial transfers. If not, offset points to the entry folloing - * the last full transfer. - */ - if (siop_cmd->flags & CMDFL_RESID) { - table = &siop_cmd->siop_tables->data[offset]; - siop_cmd->xs->resid -= letoh32(table->count) - siop_cmd->resid; - } -} - -int -siop_iwr(siop_cmd) - struct siop_common_cmd *siop_cmd; -{ - int offset; - scr_table_t *table; /* table with IWR */ - struct siop_common_softc *sc = siop_cmd->siop_sc; - /* handle ignore wide residue messages */ - - /* if target isn't wide, reject */ - if ((siop_cmd->siop_target->flags & TARF_ISWIDE) == 0) { - siop_cmd->siop_tables->t_msgout.count= htole32(1); - siop_cmd->siop_tables->msg_out[0] = MSG_MESSAGE_REJECT; - return SIOP_NEG_MSGOUT; - } - /* get index of current command in table */ - offset = bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_SCRATCHA + 1); - /* - * if the current table did complete, we're now pointing at the - * next one. Go back one if we didn't see a phase mismatch. - */ - if ((siop_cmd->flags & CMDFL_RESID) == 0) - offset--; - table = &siop_cmd->siop_tables->data[offset]; - - if ((siop_cmd->flags & CMDFL_RESID) == 0) { - if (letoh32(table->count) & 1) { - /* we really got the number of bytes we expected */ - return SIOP_NEG_ACK; - } else { - /* - * now we really had a short xfer, by one byte. - * handle it just as if we had a phase mistmatch - * (there is a resid of one for this table). - * Update scratcha1 to reflect the fact that - * this xfer isn't complete. - */ - siop_cmd->flags |= CMDFL_RESID; - siop_cmd->resid = 1; - bus_space_write_1(sc->sc_rt, sc->sc_rh, - SIOP_SCRATCHA + 1, offset); - return SIOP_NEG_ACK; - } - } else { - /* - * we already have a short xfer for this table; it's - * just one byte less than we though it was - */ - siop_cmd->resid--; - return SIOP_NEG_ACK; - } } void diff --git a/sys/dev/ic/siopvar_common.h b/sys/dev/ic/siopvar_common.h index c9db45647d3..efe32a8e41b 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.21 2005/10/10 16:27:23 krw Exp $ */ +/* $OpenBSD: siopvar_common.h,v 1.22 2005/11/03 11:00:37 martin Exp $ */ /* $NetBSD: siopvar_common.h,v 1.32 2005/02/27 00:27:02 perry Exp $ */ /* @@ -86,7 +86,6 @@ struct siop_common_cmd { int status; int flags; int tag; /* tag used for tagged command queuing */ - int resid; /* valid when CMDFL_RESID is set */ }; /* status defs */ @@ -100,7 +99,6 @@ struct siop_common_cmd { /* flags defs */ #define CMDFL_TIMEOUT 0x0001 /* cmd timed out */ #define CMDFL_TAG 0x0002 /* tagged cmd */ -#define CMDFL_RESID 0x0004 /* current offset in table is partial */ /* per-target struct */ struct siop_common_target { @@ -194,15 +192,12 @@ void siop_sdtr_msg(struct siop_common_cmd *, int, int, int); void siop_wdtr_msg(struct siop_common_cmd *, int, int); void siop_ppr_msg(struct siop_common_cmd *, int, int, int); void siop_update_xfer_mode(struct siop_common_softc *, int); -int siop_iwr(struct siop_common_cmd *); /* actions to take at return of siop_wdtr_neg() and siop_sdtr_neg() */ #define SIOP_NEG_NOP 0x0 #define SIOP_NEG_MSGOUT 0x1 #define SIOP_NEG_ACK 0x2 void siop_minphys(struct buf *); -void siop_ma(struct siop_common_cmd *); -void siop_sdp(struct siop_common_cmd *, int); -void siop_update_resid(struct siop_common_cmd *, int); +void siop_sdp(struct siop_common_cmd *); void siop_clearfifo(struct siop_common_softc *); void siop_resetbus(struct siop_common_softc *); |