diff options
author | mjacob <mjacob@FreeBSD.org> | 2001-07-30 00:22:57 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 2001-07-30 00:22:57 +0000 |
commit | b28272b3c008762104985f73eec175d37e187743 (patch) | |
tree | 26a5aada1b3eb49741a6b2b6650d0f021df7d34f /sys | |
parent | 92a303b01ec8836b5335f612e5396b03fd0e5e7d (diff) | |
download | FreeBSD-src-b28272b3c008762104985f73eec175d37e187743.zip FreeBSD-src-b28272b3c008762104985f73eec175d37e187743.tar.gz |
backout last commit- inadvertant
Diffstat (limited to 'sys')
-rw-r--r-- | sys/cam/scsi/scsi_sa.c | 117 |
1 files changed, 47 insertions, 70 deletions
diff --git a/sys/cam/scsi/scsi_sa.c b/sys/cam/scsi/scsi_sa.c index b1862ef..ae1ed57 100644 --- a/sys/cam/scsi/scsi_sa.c +++ b/sys/cam/scsi/scsi_sa.c @@ -1917,10 +1917,6 @@ samount(struct cam_periph *periph, int oflags, dev_t dev) xpt_release_ccb(ccb); goto exit; } - /* - * Clear I/O residual. - */ - softc->last_io_resid = 0; } /* @@ -2290,24 +2286,20 @@ saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs) struct scsi_sense_data *sense; u_int32_t resid = 0; int32_t info = 0; - cam_status status; - int error_code, sense_key, asc, ascq, error, defer_action, aqvalid; + int error_code, sense_key, asc, ascq; + int error, defer_action, no_actual_error = FALSE; periph = xpt_path_periph(ccb->ccb_h.path); softc = (struct sa_softc *)periph->softc; csio = &ccb->csio; sense = &csio->sense_data; scsi_extract_sense(sense, &error_code, &sense_key, &asc, &ascq); - aqvalid = sense->extra_len >= 6; error = 0; - status = csio->ccb_h.status & CAM_STATUS_MASK; - /* - * Calculate/latch up, any residuals... We do this in a funny 2-step - * so we can print stuff locally. + * Calculate/latch up, any residuals... */ - if (status == CAM_SCSI_STATUS_ERROR) { + if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR) { if ((sense->error_code & SSD_ERRCODE_VALID) != 0) { info = (int32_t) scsi_4btoul(sense->info); resid = info; @@ -2336,49 +2328,21 @@ saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs) softc->last_ctl_resid = resid; softc->last_resid_was_io = 0; } - CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("CDB[0]=0x%x Key 0x%x " - "ASC/ASCQ 0x%x/0x%x CAM STATUS 0x%x flags 0x%x resid %d " - "dxfer_len %d\n", csio->cdb_io.cdb_bytes[0] & 0xff, - sense_key, asc, ascq, status, - sense->flags & ~SSD_KEY_RESERVED, resid, csio->dxfer_len)); + CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Key 0x%x ASC/ASCQ " + "0x%x 0x%x flags 0x%x resid %d dxfer_len %d\n", sense_key, + asc, ascq, sense->flags & ~SSD_KEY_RESERVED, resid, + csio->dxfer_len)); } else { - CAM_DEBUG(periph->path, CAM_DEBUG_INFO, - ("Cam Status 0x%x\n", status)); + CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Cam Status 0x%x\n", + csio->ccb_h.status & CAM_STATUS_MASK)); } - switch (status) { - case CAM_REQ_CMP: - return (0); - case CAM_SCSI_STATUS_ERROR: - /* - * If a read/write command, we handle it here. - */ - if (CCB_Type(csio) != SA_CCB_WAITING) { - break; - } - /* - * If this was just EOM/EOP, Filemark, Setmark or ILI detected - * on a non read/write command, we assume it's not an error. - */ - if ((aqvalid && asc == 0 && ascq > 0 && ascq <= 5) || - (aqvalid == 0 && sense_key == SSD_KEY_NO_SENSE)) { - csio->resid = resid; - QFRLS(ccb); - return (0); - } - return (cam_periph_error(ccb, cflgs, sflgs, &softc->saved_ccb)); /* - * We can no longer depend upon CAM honoring retry counts for these. + * If it's neither a SCSI Check Condition Error nor a non-read/write + * command, let the common code deal with it the error setting. */ - case CAM_SCSI_BUS_RESET: - case CAM_BDR_SENT: - case CAM_REQUEUE_REQ: - if (ccb->ccb_h.retry_count <= 0) { - return (EIO); - break; - } - /* FALLTHROUGH */ - default: + if ((csio->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR || + (CCB_Type(csio) == SA_CCB_WAITING)) { return (cam_periph_error(ccb, cflgs, sflgs, &softc->saved_ccb)); } @@ -2398,26 +2362,29 @@ saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs) * From this point out, we're only handling read/write cases. * Handle writes && reads differently. */ - + if (csio->cdb_io.cdb_bytes[0] == SA_WRITE) { - if (sense_key == SSD_KEY_VOLUME_OVERFLOW) { + if (sense->flags & SSD_FILEMARK) { + xpt_print_path(csio->ccb_h.path); + printf("filemark detected on write?\n"); + if (softc->fileno != (daddr_t) -1) { + softc->fileno++; + softc->blkno = 0; + csio->ccb_h.ccb_pflags |= SA_POSITION_UPDATED; + } + } + if (sense->flags & SSD_EOM) { csio->resid = resid; - error = ENOSPC; - } else if (sense->flags & SSD_EOM) { if (defer_action) { error = -1; softc->flags |= SA_FLAG_EOM_PENDING; } else { -printf("EOM at %u.%u info %d resid %d\n", softc->fileno, softc->blkno, info, resid); - /* experiment */ - softc->flags |= SA_FLAG_EOM_PENDING; -/* csio->resid = resid; */ - csio->resid = 0; + error = ENOSPC; } } } else { - csio->resid = resid; if (sense_key == SSD_KEY_BLANK_CHECK) { + csio->resid = resid; if (defer_action) { error = -1; softc->flags |= SA_FLAG_EOM_PENDING; @@ -2426,9 +2393,12 @@ printf("EOM at %u.%u info %d resid %d\n", softc->fileno, softc->blkno, info, res } } if (sense->flags & SSD_FILEMARK) { + csio->resid = resid; if (defer_action) { error = -1; softc->flags |= SA_FLAG_EOF_PENDING; + } else { + no_actual_error = TRUE; } /* * Unconditionally, if we detected a filemark on a read, @@ -2457,6 +2427,8 @@ printf("EOM at %u.%u info %d resid %d\n", softc->fileno, softc->blkno, info, res softc->flags |= SA_FLAG_EIO_PENDING; else error = EIO; + } else { + no_actual_error = TRUE; } /* * Bump the block number if we hadn't seen a filemark. @@ -2471,17 +2443,22 @@ printf("EOM at %u.%u info %d resid %d\n", softc->fileno, softc->blkno, info, res } } } - - if (error <= 0) { - /* - * Unfreeze the queue if frozen as we're not returning anything - * to our waiters that would indicate an I/O error has occurred - * (yet). - */ - QFRLS(ccb); - error = 0; + if (error == 0 && !no_actual_error) + return (cam_periph_error(ccb, cflgs, sflgs, &softc->saved_ccb)); + if (no_actual_error) { + if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) + cam_release_devq(ccb->ccb_h.path, + /* relsim_flags */0, + /* openings */0, + /* timeout */0, + /* getcount_only */ FALSE); + return (0); } - return (error); + + if (error == -1) + return (0); + else + return (error); } static int |