Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Properly compute xs->resid, instead of assuming it'l...
details: https://anonhg.NetBSD.org/src/rev/8017e3a39851
branches: trunk
changeset: 566683:8017e3a39851
user: bouyer <bouyer%NetBSD.org@localhost>
date: Mon May 17 11:10:24 2004 +0000
description:
Properly compute xs->resid, instead of assuming it'll always be 0 when
a command is done.
diffstat:
sys/dev/ic/esiop.c | 53 ++++++++++++++++++++++++++++++++++------
sys/dev/ic/esiopvar.h | 3 +-
sys/dev/ic/siop.c | 38 ++++++++++++++++++++++++++---
sys/dev/ic/siop_common.c | 12 ++++++--
sys/dev/microcode/siop/esiop.ss | 3 +-
5 files changed, 91 insertions(+), 18 deletions(-)
diffs (291 lines):
diff -r 26818a595447 -r 8017e3a39851 sys/dev/ic/esiop.c
--- a/sys/dev/ic/esiop.c Mon May 17 11:00:01 2004 +0000
+++ b/sys/dev/ic/esiop.c Mon May 17 11:10:24 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: esiop.c,v 1.27 2004/03/16 19:10:43 bouyer Exp $ */
+/* $NetBSD: esiop.c,v 1.28 2004/05/17 11:10:24 bouyer Exp $ */
/*
* Copyright (c) 2002 Manuel Bouyer.
@@ -33,7 +33,7 @@
/* SYM53c7/8xx PCI-SCSI I/O Processors driver */
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: esiop.c,v 1.27 2004/03/16 19:10:43 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: esiop.c,v 1.28 2004/05/17 11:10:24 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -627,7 +627,13 @@
* and the command should terminate.
*/
INCSTAT(esiop_stat_intr_shortxfer);
- if ((dstat & DSTAT_DFE) == 0)
+ /*
+ * sdp not needed here, but this
+ * will cause xs->resid to be adjusted
+ */
+ if (scratchc0 & A_f_c_data)
+ siop_sdp(&esiop_cmd->cmd_c);
+ else if ((dstat & DSTAT_DFE) == 0)
siop_clearfifo(&sc->sc_c);
/* no table to flush here */
CALL_SCRIPT(Ent_status);
@@ -709,7 +715,7 @@
esiop_cmd->cmd_c.status = CMDST_DONE;
xs->error = XS_SELTIMEOUT;
freetarget = 1;
- goto end;
+ goto end_nodata;
} else {
printf("%s: selection timeout without "
"command, target %d (sdid 0x%x), "
@@ -728,7 +734,7 @@
if (esiop_cmd) {
esiop_cmd->cmd_tables->status =
htole32(SCSI_CHECK);
- goto end;
+ goto end_nodata;
}
printf("%s: unexpected disconnect without "
"command\n", sc->sc_c.sc_dev.dv_xname);
@@ -766,7 +772,7 @@
if (esiop_cmd) {
esiop_cmd->cmd_c.status = CMDST_DONE;
xs->error = XS_SELTIMEOUT;
- goto end;
+ goto end_nodata;
}
need_reset = 1;
}
@@ -811,7 +817,7 @@
sc->sc_c.sc_rh, SIOP_DSP) - sc->sc_c.sc_scriptaddr));
if (xs) {
xs->error = XS_SELTIMEOUT;
- goto end;
+ goto end_nodata;
} else {
goto reset;
}
@@ -1050,6 +1056,15 @@
* Don't call memmove in this case.
*/
if (offset < SIOP_NSG) {
+ int i;
+ /*
+ * adjust xs->resid for already-transfered
+ * data
+ */
+ for (i = 0; i < offset; i++)
+ xs->resid -= le32toh(
+ esiop_cmd->cmd_tables->data[i].count
+ );
memmove(&esiop_cmd->cmd_tables->data[0],
&esiop_cmd->cmd_tables->data[offset],
(SIOP_NSG - offset) * sizeof(scr_table_t));
@@ -1083,7 +1098,7 @@
printf("unknown irqcode %x\n", irqcode);
if (xs) {
xs->error = XS_SELTIMEOUT;
- goto end;
+ goto end_nodata;
}
goto reset;
}
@@ -1092,6 +1107,12 @@
/* We just should't get there */
panic("siop_intr: I shouldn't be there !");
+end_nodata:
+ /*
+ * no data was transfered, and the script didn't update tlp with the
+ * current offset (which is still 0)
+ */
+ ((struct esiop_xfer *)esiop_cmd->cmd_tables)->tlq = 0;
end:
/*
* restart the script now if command completed properly
@@ -1119,6 +1140,21 @@
{
struct scsipi_xfer *xs = esiop_cmd->cmd_c.xs;
struct esiop_softc *sc = (struct esiop_softc *)esiop_cmd->cmd_c.siop_sc;
+ int offset, i;
+
+ /* scratcha was saved in tlq by script. fetch offset from it */
+ offset =
+ (le32toh(((struct esiop_xfer *)esiop_cmd->cmd_tables)->tlq) >> 8)
+ & 0xff;
+ /*
+ * update resid. If we completed a xfer with
+ * some data transfers, offset will be at last 1.
+ * If it's 0 then either no data was transfered at
+ * all, or resid was already adjusted by a save
+ * data pointer, or a phase mismatch.
+ */
+ for (i = 0; i < offset; i++)
+ xs->resid -= le32toh(esiop_cmd->cmd_tables->data[i].count);
switch(xs->status) {
case SCSI_OK:
@@ -1173,7 +1209,6 @@
callout_stop(&esiop_cmd->cmd_c.xs->xs_callout);
esiop_cmd->cmd_c.status = CMDST_FREE;
TAILQ_INSERT_TAIL(&sc->free_list, esiop_cmd, next);
- xs->resid = 0;
scsipi_done (xs);
}
diff -r 26818a595447 -r 8017e3a39851 sys/dev/ic/esiopvar.h
--- a/sys/dev/ic/esiopvar.h Mon May 17 11:00:01 2004 +0000
+++ b/sys/dev/ic/esiopvar.h Mon May 17 11:10:24 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: esiopvar.h,v 1.8 2003/11/02 11:07:45 wiz Exp $ */
+/* $NetBSD: esiopvar.h,v 1.9 2004/05/17 11:10:24 bouyer Exp $ */
/*
* Copyright (c) 2002 Manuel Bouyer.
@@ -53,6 +53,7 @@
struct esiop_xfer {
struct siop_common_xfer siop_tables;
u_int32_t tlq; /* target/lun/tag loaded in scratchC by script */
+ /* will also containt scratcha at end of command */
} __attribute__((__packed__));
/*
diff -r 26818a595447 -r 8017e3a39851 sys/dev/ic/siop.c
--- a/sys/dev/ic/siop.c Mon May 17 11:00:01 2004 +0000
+++ b/sys/dev/ic/siop.c Mon May 17 11:10:24 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: siop.c,v 1.72 2004/03/16 19:10:43 bouyer Exp $ */
+/* $NetBSD: siop.c,v 1.73 2004/05/17 11:10:24 bouyer Exp $ */
/*
* Copyright (c) 2000 Manuel Bouyer.
@@ -33,7 +33,7 @@
/* SYM53c7/8xx PCI-SCSI I/O Processors driver */
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: siop.c,v 1.72 2004/03/16 19:10:43 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siop.c,v 1.73 2004/05/17 11:10:24 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -494,7 +494,13 @@
* and the command should terminate.
*/
INCSTAT(siop_stat_intr_shortxfer);
- if ((dstat & DSTAT_DFE) == 0)
+ /*
+ * sdp not needed here, but this
+ * will cause xs->resid to be adjusted
+ */
+ if (scratcha0 & A_flag_data)
+ siop_sdp(&siop_cmd->cmd_c);
+ else if ((dstat & DSTAT_DFE) == 0)
siop_clearfifo(&sc->sc_c);
/* no table to flush here */
CALL_SCRIPT(Ent_status);
@@ -889,6 +895,15 @@
* Don't call memmove in this case.
*/
if (offset < SIOP_NSG) {
+ int i;
+ /*
+ * adjust xs->resid for already-transfered
+ * data
+ */
+ for (i = 0; i < offset; i++)
+ xs->resid -= le32toh(
+ siop_cmd->cmd_tables->data[i].count
+ );
memmove(&siop_cmd->cmd_tables->data[0],
&siop_cmd->cmd_tables->data[offset],
(SIOP_NSG - offset) * sizeof(scr_table_t));
@@ -918,6 +933,22 @@
le32toh(siop_cmd->cmd_tables->status));
#endif
INCSTAT(siop_stat_intr_done);
+ /*
+ * update resid. If we completed a xfer with
+ * some data transfers, offset will be at last 1.
+ * If it's 0 then either no data was transfered at
+ * all, or resid was already adjusted by a save
+ * data pointer, or a phase mismatch.
+ */
+ offset = bus_space_read_1(sc->sc_c.sc_rt,
+ sc->sc_c.sc_rh, SIOP_SCRATCHA + 1);
+ {
+ int i;
+ for (i = 0; i < offset; i++)
+ xs->resid -= le32toh(
+ siop_cmd->cmd_tables->data[i].count
+ );
+ }
siop_cmd->cmd_c.status = CMDST_DONE;
goto end;
default:
@@ -1017,7 +1048,6 @@
callout_stop(&siop_cmd->cmd_c.xs->xs_callout);
siop_cmd->cmd_c.status = CMDST_FREE;
TAILQ_INSERT_TAIL(&sc->free_list, siop_cmd, next);
- xs->resid = 0;
scsipi_done (xs);
}
diff -r 26818a595447 -r 8017e3a39851 sys/dev/ic/siop_common.c
--- a/sys/dev/ic/siop_common.c Mon May 17 11:00:01 2004 +0000
+++ b/sys/dev/ic/siop_common.c Mon May 17 11:10:24 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: siop_common.c,v 1.33 2004/03/10 22:02:53 bouyer Exp $ */
+/* $NetBSD: siop_common.c,v 1.34 2004/05/17 11:10:24 bouyer Exp $ */
/*
* Copyright (c) 2000, 2002 Manuel Bouyer.
@@ -33,7 +33,7 @@
/* SYM53c7/8xx PCI-SCSI I/O Processors driver */
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: siop_common.c,v 1.33 2004/03/10 22:02:53 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siop_common.c,v 1.34 2004/05/17 11:10:24 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -735,7 +735,10 @@
siop_sdp(siop_cmd)
struct siop_common_cmd *siop_cmd;
{
- /* save data pointer. Handle async only for now */
+ /*
+ * Save data pointer when a phase mistmatch occurs. We need to compute
+ * how much of the current table was written.
+ */
int offset, dbc, sstat;
struct siop_common_softc *sc = siop_cmd->siop_sc;
scr_table_t *table; /* table to patch */
@@ -790,6 +793,9 @@
bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST3) |
CTEST3_CLF);
}
+ /* correct xs->resid for this partial transfer */
+ siop_cmd->xs->resid -= le32toh(table->count) - dbc;
+ /* "cut" already transfered data from this table */
table->addr =
htole32(le32toh(table->addr) + le32toh(table->count) - dbc);
table->count = htole32(dbc);
diff -r 26818a595447 -r 8017e3a39851 sys/dev/microcode/siop/esiop.ss
--- a/sys/dev/microcode/siop/esiop.ss Mon May 17 11:00:01 2004 +0000
+++ b/sys/dev/microcode/siop/esiop.ss Mon May 17 11:10:24 2004 +0000
@@ -1,4 +1,4 @@
-; $NetBSD: esiop.ss,v 1.16 2003/10/05 17:48:49 bouyer Exp $
+; $NetBSD: esiop.ss,v 1.17 2004/05/17 11:10:24 bouyer Exp $
;
; Copyright (c) 2002 Manuel Bouyer.
@@ -208,6 +208,7 @@
handle_cmpl:
CALL REL(disconnect);
+ STORE NOFLUSH SCRATCHA0, 4, from tlq_offset; save current offset
MOVE SCRATCHE1 to SFBR;
INT int_done, IF NOT 0x00; if status is not "done", let host handle it
MOVE SCRATCHF0 to SFBR; load pointer in done ring
Home |
Main Index |
Thread Index |
Old Index