diff options
author | smh <smh@FreeBSD.org> | 2013-05-02 14:37:23 +0000 |
---|---|---|
committer | smh <smh@FreeBSD.org> | 2013-05-02 14:37:23 +0000 |
commit | 369aaa137fa560e2c940db2b0bdc8f9d4bdfff49 (patch) | |
tree | e36c3eeb69c2c7e813ebfec6f388dcbc2918772a /sys/cam/scsi | |
parent | b26d00ee134eaefb8e2977a314386efaef2eda2b (diff) | |
download | FreeBSD-src-369aaa137fa560e2c940db2b0bdc8f9d4bdfff49.zip FreeBSD-src-369aaa137fa560e2c940db2b0bdc8f9d4bdfff49.tar.gz |
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
Diffstat (limited to 'sys/cam/scsi')
-rw-r--r-- | sys/cam/scsi/scsi_all.h | 6 | ||||
-rw-r--r-- | 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 2953731..aff655e 100644 --- a/sys/cam/scsi/scsi_all.h +++ b/sys/cam/scsi/scsi_all.h @@ -1430,6 +1430,12 @@ struct scsi_diag_page { }; /* + * 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 c98799c3..c485d53 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; @@ -1680,6 +1681,65 @@ dadeletemaxsize(struct da_softc *softc, da_delete_methods delete_method) } 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) { int i, delete_method; @@ -2457,6 +2517,11 @@ out: { 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: |