summaryrefslogtreecommitdiff
path: root/sys/dev/pci/ips.c
diff options
context:
space:
mode:
authorAlexander Yurchenko <grange@cvs.openbsd.org>2009-03-17 08:17:49 +0000
committerAlexander Yurchenko <grange@cvs.openbsd.org>2009-03-17 08:17:49 +0000
commit148a18177e9ccd57f598f4a8ccb8cbae51a880b4 (patch)
treeb32119448e2d36492207b3e619b316f0487a06f9 /sys/dev/pci/ips.c
parented5516e2eadf1633b622c7dd0d6d929ca00f55c6 (diff)
Provide both errno.h codes for the userspace tools like bioctl
and XS_* codes for the scsi layer.
Diffstat (limited to 'sys/dev/pci/ips.c')
-rw-r--r--sys/dev/pci/ips.c73
1 files changed, 52 insertions, 21 deletions
diff --git a/sys/dev/pci/ips.c b/sys/dev/pci/ips.c
index 43ca31837a2..6c3225186ef 100644
--- a/sys/dev/pci/ips.c
+++ b/sys/dev/pci/ips.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ips.c,v 1.71 2009/03/17 07:48:59 grange Exp $ */
+/* $OpenBSD: ips.c,v 1.72 2009/03/17 08:17:48 grange Exp $ */
/*
* Copyright (c) 2006, 2007, 2009 Alexander Yurchenko <grange@openbsd.org>
@@ -453,6 +453,7 @@ void ips_done_xs(struct ips_softc *, struct ips_ccb *);
void ips_done_pt(struct ips_softc *, struct ips_ccb *);
void ips_done_mgmt(struct ips_softc *, struct ips_ccb *);
int ips_error(struct ips_softc *, struct ips_ccb *);
+int ips_error_xs(struct ips_softc *, struct ips_ccb *);
int ips_intr(void *);
void ips_timeout(void *);
@@ -1477,7 +1478,7 @@ ips_done_xs(struct ips_softc *sc, struct ips_ccb *ccb)
}
xs->resid = 0;
- xs->error = ccb->c_error;
+ xs->error = ips_error_xs(sc, ccb);
xs->flags |= ITSDONE;
scsi_done(xs);
}
@@ -1506,7 +1507,7 @@ ips_done_pt(struct ips_softc *sc, struct ips_ccb *ccb)
xs->resid = xs->datalen - done;
else
xs->resid = 0;
- xs->error = ccb->c_error;
+ xs->error = ips_error_xs(sc, ccb);
xs->status = dcdb->status;
if (xs->error == XS_SENSE)
@@ -1552,10 +1553,9 @@ ips_error(struct ips_softc *sc, struct ips_ccb *ccb)
struct ips_dcdb *dcdb = &cmdb->dcdb;
struct scsi_xfer *xs = ccb->c_xfer;
u_int8_t gsc = IPS_STAT_GSC(ccb->c_stat);
- int error = XS_DRIVER_STUFFUP;
if (gsc == IPS_STAT_OK)
- return (XS_NOERROR);
+ return (0);
DPRINTF(IPS_D_ERR, ("%s: ips_error: stat 0x%02x, estat 0x%02x, "
"cmd code 0x%02x, drive %d, sgcnt %d, lba %u, seccnt %d",
@@ -1580,42 +1580,73 @@ ips_error(struct ips_softc *sc, struct ips_ccb *ccb)
}
DPRINTF(IPS_D_ERR, ("\n"));
- /* Map hardware error codes to SCSI ones */
switch (gsc) {
case IPS_STAT_RECOV:
- error = XS_NOERROR;
- break;
+ return (0);
+ case IPS_STAT_INVOP:
+ case IPS_STAT_INVCMD:
+ case IPS_STAT_INVPARM:
+ return (EINVAL);
case IPS_STAT_BUSY:
- error = XS_BUSY;
- break;
+ return (EBUSY);
case IPS_STAT_TIMO:
- error = XS_TIMEOUT;
- break;
+ return (ETIMEDOUT);
case IPS_STAT_PDRVERR:
switch (ccb->c_estat) {
case IPS_ESTAT_SELTIMO:
- error = XS_SELTIMEOUT;
+ return (ENODEV);
+ case IPS_ESTAT_OURUN:
+ if (xs && letoh16(dcdb->datalen) < xs->datalen)
+ /* underrun */
+ return (0);
break;
+ case IPS_ESTAT_RECOV:
+ return (0);
+ }
+ break;
+ }
+
+ return (EIO);
+}
+
+int
+ips_error_xs(struct ips_softc *sc, struct ips_ccb *ccb)
+{
+ struct ips_cmdb *cmdb = ccb->c_cmdbva;
+ struct ips_dcdb *dcdb = &cmdb->dcdb;
+ struct scsi_xfer *xs = ccb->c_xfer;
+ u_int8_t gsc = IPS_STAT_GSC(ccb->c_stat);
+
+ /* Map hardware error codes to SCSI ones */
+ switch (gsc) {
+ case IPS_STAT_OK:
+ case IPS_STAT_RECOV:
+ return (XS_NOERROR);
+ case IPS_STAT_BUSY:
+ return (XS_BUSY);
+ case IPS_STAT_TIMO:
+ return (XS_TIMEOUT);
+ case IPS_STAT_PDRVERR:
+ switch (ccb->c_estat) {
+ case IPS_ESTAT_SELTIMO:
+ return (XS_SELTIMEOUT);
case IPS_ESTAT_OURUN:
if (xs && letoh16(dcdb->datalen) < xs->datalen)
/* underrun */
- error = XS_NOERROR;
+ return (XS_NOERROR);
break;
case IPS_ESTAT_HOSTRST:
case IPS_ESTAT_DEVRST:
- error = XS_RESET;
- break;
+ return (XS_RESET);
case IPS_ESTAT_RECOV:
- error = XS_NOERROR;
- break;
+ return (XS_NOERROR);
case IPS_ESTAT_CKCOND:
- error = XS_SENSE;
- break;
+ return (XS_SENSE);
}
break;
}
- return (error);
+ return (XS_DRIVER_STUFFUP);
}
int