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
This commit is contained in:
Steven Hartland 2013-05-02 14:37:23 +00:00
parent dcf0e9d179
commit a428909068
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=250181
2 changed files with 73 additions and 19 deletions

View File

@ -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

View File

@ -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: