summaryrefslogtreecommitdiff
path: root/sys/dev/ic/siop.c
diff options
context:
space:
mode:
authorMartin Reindl <martin@cvs.openbsd.org>2005-11-03 11:00:38 +0000
committerMartin Reindl <martin@cvs.openbsd.org>2005-11-03 11:00:38 +0000
commit6008a0e1896f2bf50b3981451b4d5286a0a8ef69 (patch)
tree15822d54c79d2652b4751625982c348fc63a3985 /sys/dev/ic/siop.c
parentd7bc70ab5c5d436373f07e5b91e0d7e1395c2e92 (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.c93
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);
}