diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -4597,33 +4597,32 @@ } bp = (struct bio *)done_ccb->ccb_h.ccb_bp; if (error != 0) { - int queued_error; - - /* - * return all queued I/O with EIO, so that - * the client can retry these I/Os in the - * proper order should it attempt to recover. - */ - queued_error = EIO; - - if (error == ENXIO - && (softc->flags & DA_FLAG_PACK_INVALID)== 0) { + if (error == ENXIO) { /* - * Catastrophic error. Mark our pack as - * invalid. - * - * XXX See if this is really a media - * XXX change first? + * ENXIO flags ASC/ASCQ codes for drive lost. + * Invalidate peripheral on this catestrophic + * error, but only print a message the first + * time through. The invalidation will flush any + * queued I/O. Also short-circuits future + * retriable errors since they are futile. This + * just invalidates the da device. Any passX + * devices remain in place for manual recovery. */ - xpt_print(periph->path, "Invalidating pack\n"); - softc->flags |= DA_FLAG_PACK_INVALID; + if ((softc->flags & DA_FLAG_PACK_INVALID) == 0) + xpt_print(periph->path, + "Invalidating pack\n"); + cam_periph_invalidate(periph); #ifdef CAM_IO_STATS softc->invalidations++; #endif - queued_error = ENXIO; + } else { + /* + * Return all queued I/O with EIO, so that the + * client can retry these I/Os in the proper + * order should it attempt to recover. + */ + cam_iosched_flush(softc->cam_iosched, NULL, EIO); } - cam_iosched_flush(softc->cam_iosched, NULL, - queued_error); if (bp != NULL) { bp->bio_error = error; bp->bio_resid = bp->bio_bcount;