Improve error handling. Related to PR/21900.

This commit is contained in:
ad 2006-11-28 20:29:14 +00:00
parent 0dd37417ef
commit 8b4b54cb8d
4 changed files with 37 additions and 18 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cac_eisa.c,v 1.15 2006/11/16 01:32:50 christos Exp $ */
/* $NetBSD: cac_eisa.c,v 1.16 2006/11/28 20:29:14 ad Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cac_eisa.c,v 1.15 2006/11/16 01:32:50 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: cac_eisa.c,v 1.16 2006/11/28 20:29:14 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -269,6 +269,10 @@ cac_eisa_l0_completed(struct cac_softc *sc)
BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
ccb->ccb_req.error = status;
if ((off & 3) != 0 && ccb->ccb_req.error == 0)
ccb->ccb_req.error = CAC_RET_CMD_REJECTED;
return (ccb);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: cac.c,v 1.36 2006/11/16 01:32:51 christos Exp $ */
/* $NetBSD: cac.c,v 1.37 2006/11/28 20:29:14 ad Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cac.c,v 1.36 2006/11/16 01:32:51 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: cac.c,v 1.37 2006/11/28 20:29:14 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -304,9 +304,13 @@ cac_cmd(struct cac_softc *sc, int command, void *data, int datasize,
}
ccb->ccb_hdr.drive = drive;
ccb->ccb_hdr.priority = 0;
ccb->ccb_hdr.size = htole16((sizeof(struct cac_req) +
sizeof(struct cac_sgb) * CAC_SG_SIZE) >> 2);
ccb->ccb_req.next = 0;
ccb->ccb_req.error = 0;
ccb->ccb_req.reserved = 0;
ccb->ccb_req.bcount = htole16(howmany(size, DEV_BSIZE));
ccb->ccb_req.command = command;
ccb->ccb_req.sgcount = nsegs;
@ -520,6 +524,9 @@ cac_l0_completed(struct cac_softc *sc)
bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, off, sizeof(struct cac_ccb),
BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
if ((off & 3) != 0 && ccb->ccb_req.error == 0)
ccb->ccb_req.error = CAC_RET_CMD_REJECTED;
return (ccb);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ld_cac.c,v 1.15 2006/11/16 01:32:51 christos Exp $ */
/* $NetBSD: ld_cac.c,v 1.16 2006/11/28 20:29:14 ad Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ld_cac.c,v 1.15 2006/11/16 01:32:51 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: ld_cac.c,v 1.16 2006/11/28 20:29:14 ad Exp $");
#include "rnd.h"
@ -190,18 +190,24 @@ ld_cac_done(struct device *dv, void *context, int error)
{
struct buf *bp;
struct ld_cac_softc *sc;
int rv;
bp = context;
rv = 0;
if ((error & CAC_RET_HARD_ERROR) != 0) {
if ((error & CAC_RET_CMD_REJECTED) == CAC_RET_CMD_REJECTED) {
printf("%s: command rejected\n", dv->dv_xname);
rv = EIO;
}
if (rv == 0 && (error & CAC_RET_INVAL_BLOCK) != 0) {
printf("%s: invalid request block\n", dv->dv_xname);
rv = EIO;
}
if (rv == 0 && (error & CAC_RET_HARD_ERROR) != 0) {
printf("%s: hard error\n", dv->dv_xname);
error = EIO;
rv = EIO;
}
if ((error & CAC_RET_CMD_REJECTED) != 0) {
printf("%s: invalid request\n", dv->dv_xname);
error = EIO;
}
if ((error & CAC_RET_SOFT_ERROR) != 0) {
if (rv == 0 && (error & CAC_RET_SOFT_ERROR) != 0) {
sc = (struct ld_cac_softc *)dv;
sc->sc_serrcnt++;
if (ratecheck(&sc->sc_serrtm, &ld_cac_serrintvl)) {
@ -209,12 +215,11 @@ ld_cac_done(struct device *dv, void *context, int error)
dv->dv_xname, sc->sc_serrcnt);
sc->sc_serrcnt = 0;
}
error = 0;
}
if (error) {
if (rv) {
bp->b_flags |= B_ERROR;
bp->b_error = error;
bp->b_error = rv;
bp->b_resid = bp->b_bcount;
} else
bp->b_resid = 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: cac_pci.c,v 1.23 2006/11/16 01:33:08 christos Exp $ */
/* $NetBSD: cac_pci.c,v 1.24 2006/11/28 20:29:14 ad Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cac_pci.c,v 1.23 2006/11/16 01:33:08 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: cac_pci.c,v 1.24 2006/11/28 20:29:14 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -260,6 +260,9 @@ cac_pci_l0_completed(struct cac_softc *sc)
bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, off, sizeof(struct cac_ccb),
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
if ((off & 3) != 0 && ccb->ccb_req.error == 0)
ccb->ccb_req.error = CAC_RET_CMD_REJECTED;
return (ccb);
}