summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Yurchenko <grange@cvs.openbsd.org>2009-03-13 07:49:29 +0000
committerAlexander Yurchenko <grange@cvs.openbsd.org>2009-03-13 07:49:29 +0000
commitb765636febfa3de2deb27037e13e2ae93b88a8c6 (patch)
treef50447b91421f4080b1f522a9713ab787fd94612
parentd901ce9ccd1f8deec38a1f21b9277da45d579d4a (diff)
Process command completion errors while polling, too.
-rw-r--r--sys/dev/pci/ips.c40
1 files changed, 22 insertions, 18 deletions
diff --git a/sys/dev/pci/ips.c b/sys/dev/pci/ips.c
index 11faccad127..6b4f13f3abe 100644
--- a/sys/dev/pci/ips.c
+++ b/sys/dev/pci/ips.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ips.c,v 1.61 2009/03/12 21:20:05 grange Exp $ */
+/* $OpenBSD: ips.c,v 1.62 2009/03/13 07:49:28 grange Exp $ */
/*
* Copyright (c) 2006, 2007, 2009 Alexander Yurchenko <grange@openbsd.org>
@@ -316,6 +316,7 @@ struct ips_ccb {
u_int8_t c_stat; /* status byte copy */
u_int8_t c_estat; /* ext status byte copy */
+ int c_error; /* completion error */
void (*c_done)(struct ips_softc *, /* cmd done */
struct ips_ccb *); /* callback */
@@ -1176,7 +1177,7 @@ int
ips_poll(struct ips_softc *sc, struct ips_ccb *ccb)
{
struct timeval tv;
- int timo;
+ int error, timo;
splassert(IPL_BIO);
@@ -1207,9 +1208,12 @@ ips_poll(struct ips_softc *sc, struct ips_ccb *ccb)
if (ccb->c_state != IPS_CCB_DONE)
return (ETIMEDOUT);
+
ips_done(sc, ccb);
+ error = ccb->c_error;
+ ips_ccb_put(sc, ccb);
- return (0);
+ return (error);
}
void
@@ -1220,17 +1224,14 @@ ips_done(struct ips_softc *sc, struct ips_ccb *ccb)
DPRINTF(IPS_D_XFER, ("%s: ips_done: id 0x%02x, flags 0x%x, xs %p\n",
sc->sc_dev.dv_xname, ccb->c_id, ccb->c_flags, ccb->c_xfer));
+ ccb->c_error = ips_error(sc, ccb);
ccb->c_done(sc, ccb);
-
- ccb->c_state = IPS_CCB_FREE;
- ips_ccb_put(sc, ccb);
}
void
ips_done_xs(struct ips_softc *sc, struct ips_ccb *ccb)
{
struct scsi_xfer *xs = ccb->c_xfer;
- int error;
if (!(xs->flags & SCSI_POLL))
timeout_del(&xs->stimeout);
@@ -1242,13 +1243,15 @@ ips_done_xs(struct ips_softc *sc, struct ips_ccb *ccb)
bus_dmamap_unload(sc->sc_dmat, ccb->c_dmam);
}
- if ((error = ips_error(sc, ccb))) {
- if (error == ETIMEDOUT)
- xs->error = XS_TIMEOUT;
- else
- xs->error = XS_DRIVER_STUFFUP;
- } else {
+ switch (ccb->c_error) {
+ case 0:
xs->resid = 0;
+ break;
+ case ETIMEDOUT:
+ xs->error = XS_TIMEOUT;
+ break;
+ default:
+ xs->error = XS_DRIVER_STUFFUP;
}
xs->flags |= ITSDONE;
scsi_done(xs);
@@ -1262,9 +1265,6 @@ ips_done_mgmt(struct ips_softc *sc, struct ips_ccb *ccb)
sc->sc_infom.dm_map->dm_mapsize,
ccb->c_flags & SCSI_DATA_IN ? BUS_DMASYNC_POSTREAD :
BUS_DMASYNC_POSTWRITE);
-
- /* XXX: error checking */
- (void)ips_error(sc, ccb);
}
int
@@ -1355,10 +1355,12 @@ ips_intr(void *arg)
ccb->c_stat = IPS_STAT_BASIC(status);
ccb->c_estat = IPS_STAT_EXT(status);
- if (ccb->c_flags & SCSI_POLL)
+ if (ccb->c_flags & SCSI_POLL) {
wakeup(ccb);
- else
+ } else {
ips_done(sc, ccb);
+ ips_ccb_put(sc, ccb);
+ }
}
return (1);
@@ -1692,6 +1694,8 @@ void
ips_ccb_put(struct ips_softc *sc, struct ips_ccb *ccb)
{
splassert(IPL_BIO);
+
+ ccb->c_state = IPS_CCB_FREE;
TAILQ_INSERT_TAIL(&sc->sc_ccbq_free, ccb, c_link);
}