diff options
author | Martin Reindl <martin@cvs.openbsd.org> | 2005-11-03 11:00:38 +0000 |
---|---|---|
committer | Martin Reindl <martin@cvs.openbsd.org> | 2005-11-03 11:00:38 +0000 |
commit | 6008a0e1896f2bf50b3981451b4d5286a0a8ef69 (patch) | |
tree | 15822d54c79d2652b4751625982c348fc63a3985 /sys/dev/ic/siop.c | |
parent | d7bc70ab5c5d436373f07e5b91e0d7e1395c2e92 (diff) |
revert to 20051009 for now, need to investigate strange behaviour with
some controllers
discussed with otto@ and henning@, first noted by miod@
Diffstat (limited to 'sys/dev/ic/siop.c')
-rw-r--r-- | sys/dev/ic/siop.c | 93 |
1 files changed, 35 insertions, 58 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); } |