From 369aaa137fa560e2c940db2b0bdc8f9d4bdfff49 Mon Sep 17 00:00:00 2001 From: smh Date: Thu, 2 May 2013 14:37:23 +0000 Subject: [PATCH] Use the existence of ATA Information VPD to determine if we should attempt to query ATA functionality via ATA Pass-Through (16) as this page is defined as "must" for SATL devices, hence indicating that the device is at least likely to support Pass-Through (16). This eliminates errors produced by CTL when ATA Pass-Through (16) fails. Switch ATA probe daerror call to SF_NO_PRINT to avoid errors printing out for devices which return invalid errors. Output details about supported and choosen delete method when verbose booted. Reviewed by: mav Approved by: pjd (mentor) MFC after: 1 week --- sys/cam/scsi/scsi_all.h | 6 +++ sys/cam/scsi/scsi_da.c | 86 ++++++++++++++++++++++++++++++++--------- 2 files changed, 73 insertions(+), 19 deletions(-) diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h index 295373100517..aff655e79286 100644 --- a/sys/cam/scsi/scsi_all.h +++ b/sys/cam/scsi/scsi_all.h @@ -1429,6 +1429,12 @@ struct scsi_diag_page { uint8_t params[0]; }; +/* + * ATA Information VPD Page based on + * T10/2126-D Revision 04 + */ +#define SVPD_ATA_INFORMATION 0x89 + /* * Block Device Characteristics VPD Page based on * T10/1799-D Revision 31 diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index c98799c3fb2b..c485d537f546 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -918,6 +918,7 @@ static off_t dadeletemaxsize(struct da_softc *softc, da_delete_methods delete_method); static void dadeletemethodchoose(struct da_softc *softc, da_delete_methods default_method); +static void daprobedone(struct cam_periph *periph, union ccb *ccb); static periph_ctor_t daregister; static periph_dtor_t dacleanup; @@ -1679,6 +1680,65 @@ dadeletemaxsize(struct da_softc *softc, da_delete_methods delete_method) min(sectors, (off_t)softc->params.sectors); } +static void +daprobedone(struct cam_periph *periph, union ccb *ccb) +{ + struct da_softc *softc; + + softc = (struct da_softc *)periph->softc; + + dadeletemethodchoose(softc, DA_DELETE_NONE); + + if (bootverbose && (softc->flags & DA_FLAG_PROBED) == 0) { + char buf[80]; + int i, sep; + + snprintf(buf, sizeof(buf), "Delete methods: <"); + sep = 0; + for (i = DA_DELETE_MIN; i <= DA_DELETE_MAX; i++) { + if (softc->delete_available & (1 << i)) { + if (sep) { + strlcat(buf, ",", sizeof(buf)); + } else { + sep = 1; + } + strlcat(buf, da_delete_method_names[i], + sizeof(buf)); + if (i == softc->delete_method) { + strlcat(buf, "(*)", sizeof(buf)); + } + } + } + if (sep == 0) { + if (softc->delete_method == DA_DELETE_NONE) + strlcat(buf, "NONE(*)", sizeof(buf)); + else + strlcat(buf, "DISABLED(*)", sizeof(buf)); + } + strlcat(buf, ">", sizeof(buf)); + printf("%s%d: %s\n", periph->periph_name, + periph->unit_number, buf); + } + + /* + * Since our peripheral may be invalidated by an error + * above or an external event, we must release our CCB + * before releasing the probe lock on the peripheral. + * The peripheral will only go away once the last lock + * is removed, and we need it around for the CCB release + * operation. + */ + xpt_release_ccb(ccb); + softc->state = DA_STATE_NORMAL; + daschedule(periph); + wakeup(&softc->disk->d_mediasize); + if ((softc->flags & DA_FLAG_PROBED) == 0) { + softc->flags |= DA_FLAG_PROBED; + cam_periph_unhold(periph); + } else + cam_periph_release_locked(periph); +} + static void dadeletemethodchoose(struct da_softc *softc, da_delete_methods default_method) { @@ -2457,6 +2517,11 @@ dastart(struct cam_periph *periph, union ccb *start_ccb) { struct ata_params *ata_params; + if (!scsi_vpd_supported_page(periph, SVPD_ATA_INFORMATION)) { + daprobedone(periph, start_ccb); + break; + } + ata_params = (struct ata_params*) malloc(sizeof(*ata_params), M_SCSIDA, M_NOWAIT|M_ZERO); @@ -3121,7 +3186,7 @@ dadone(struct cam_periph *periph, union ccb *done_ccb) } else { int error; error = daerror(done_ccb, CAM_RETRY_SELTO, - SF_RETRY_UA|SF_QUIET_IR); + SF_RETRY_UA|SF_NO_PRINT); if (error == ERESTART) return; else if (error != 0) { @@ -3137,24 +3202,7 @@ dadone(struct cam_periph *periph, union ccb *done_ccb) } free(ata_params, M_SCSIDA); - dadeletemethodchoose(softc, DA_DELETE_NONE); - /* - * Since our peripheral may be invalidated by an error - * above or an external event, we must release our CCB - * before releasing the probe lock on the peripheral. - * The peripheral will only go away once the last lock - * is removed, and we need it around for the CCB release - * operation. - */ - xpt_release_ccb(done_ccb); - softc->state = DA_STATE_NORMAL; - daschedule(periph); - wakeup(&softc->disk->d_mediasize); - if ((softc->flags & DA_FLAG_PROBED) == 0) { - softc->flags |= DA_FLAG_PROBED; - cam_periph_unhold(periph); - } else - cam_periph_release_locked(periph); + daprobedone(periph, done_ccb); return; } case DA_CCB_WAITING: