Add support for probing the SCSI VPD Extended Inquiry page (0x86).
This VPD page is effectively an extension of the standard Inquiry data page, and includes lots of additional bits. This commit includes support for probing the page in the SCSI probe code, and an additional request type for the XPT_DEV_ADVINFO CCB. CTL already supports the Extended Inquiry page. Support for querying this page in the sa(4) driver will come later. sys/cam/scsi/scsi_xpt.c: Probe the Extended Inquiry page, if the device supports it, and return it in response to a XPT_DEV_ADVINFO CCB if it is requested. sys/cam/scsi/cam_ccb.h: Define a new advanced information CCB data type, CDAI_TYPE_EXT_INQ. sys/cam/cam_xpt.c: Free the extended inquiry data in a device when the device goes away. sys/cam/cam_xpt_internal.h: Add an extended inquiry data pointer and length to struct cam_ed. sys/sys/param.h Bump __FreeBSD_version for the addition of the new CDAI_TYPE_EXT_INQ advanced information type. Sponsored by: Spectra Logic MFC after: 1 week
This commit is contained in:
parent
5ecbbe6415
commit
3bba3152a7
@ -1147,6 +1147,7 @@ struct ccb_dev_advinfo {
|
||||
#define CDAI_TYPE_SERIAL_NUM 2
|
||||
#define CDAI_TYPE_PHYS_PATH 3
|
||||
#define CDAI_TYPE_RCAPLONG 4
|
||||
#define CDAI_TYPE_EXT_INQ 5
|
||||
off_t bufsiz; /* IN: Size of external buffer */
|
||||
#define CAM_SCSI_DEVID_MAXLEN 65536 /* length in buffer is an uint16_t */
|
||||
off_t provsiz; /* OUT: Size required/used */
|
||||
|
@ -4795,6 +4795,7 @@ xpt_release_device(struct cam_ed *device)
|
||||
*/
|
||||
free(device->supported_vpds, M_CAMXPT);
|
||||
free(device->device_id, M_CAMXPT);
|
||||
free(device->ext_inq, M_CAMXPT);
|
||||
free(device->physpath, M_CAMXPT);
|
||||
free(device->rcap_buf, M_CAMXPT);
|
||||
free(device->serial_num, M_CAMXPT);
|
||||
|
@ -83,6 +83,8 @@ struct cam_ed {
|
||||
uint8_t supported_vpds_len;
|
||||
uint32_t device_id_len;
|
||||
uint8_t *device_id;
|
||||
uint32_t ext_inq_len;
|
||||
uint8_t *ext_inq;
|
||||
uint8_t physpath_len;
|
||||
uint8_t *physpath; /* physical path string form */
|
||||
uint32_t rcap_len;
|
||||
|
@ -139,6 +139,7 @@ typedef enum {
|
||||
PROBE_MODE_SENSE,
|
||||
PROBE_SUPPORTED_VPD_LIST,
|
||||
PROBE_DEVICE_ID,
|
||||
PROBE_EXTENDED_INQUIRY,
|
||||
PROBE_SERIAL_NUM,
|
||||
PROBE_TUR_FOR_NEGOTIATION,
|
||||
PROBE_INQUIRY_BASIC_DV1,
|
||||
@ -156,6 +157,7 @@ static char *probe_action_text[] = {
|
||||
"PROBE_MODE_SENSE",
|
||||
"PROBE_SUPPORTED_VPD_LIST",
|
||||
"PROBE_DEVICE_ID",
|
||||
"PROBE_EXTENDED_INQUIRY",
|
||||
"PROBE_SERIAL_NUM",
|
||||
"PROBE_TUR_FOR_NEGOTIATION",
|
||||
"PROBE_INQUIRY_BASIC_DV1",
|
||||
@ -923,6 +925,34 @@ done:
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
case PROBE_EXTENDED_INQUIRY:
|
||||
{
|
||||
struct scsi_vpd_extended_inquiry_data *ext_inq;
|
||||
|
||||
ext_inq = NULL;
|
||||
if (scsi_vpd_supported_page(periph, SVPD_EXTENDED_INQUIRY_DATA))
|
||||
ext_inq = malloc(sizeof(*ext_inq), M_CAMXPT,
|
||||
M_NOWAIT | M_ZERO);
|
||||
|
||||
if (ext_inq != NULL) {
|
||||
scsi_inquiry(csio,
|
||||
/*retries*/4,
|
||||
probedone,
|
||||
MSG_SIMPLE_Q_TAG,
|
||||
(uint8_t *)ext_inq,
|
||||
sizeof(*ext_inq),
|
||||
/*evpd*/TRUE,
|
||||
SVPD_EXTENDED_INQUIRY_DATA,
|
||||
SSD_MIN_SIZE,
|
||||
/*timeout*/60 * 1000);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* We'll have to do without, let our probedone
|
||||
* routine finish up for us.
|
||||
*/
|
||||
goto done;
|
||||
}
|
||||
case PROBE_SERIAL_NUM:
|
||||
{
|
||||
struct scsi_vpd_unit_serial_number *serial_buf;
|
||||
@ -1454,6 +1484,50 @@ out:
|
||||
if (devid && length == 0)
|
||||
free(devid, M_CAMXPT);
|
||||
xpt_release_ccb(done_ccb);
|
||||
PROBE_SET_ACTION(softc, PROBE_EXTENDED_INQUIRY);
|
||||
xpt_schedule(periph, priority);
|
||||
goto out;
|
||||
}
|
||||
case PROBE_EXTENDED_INQUIRY: {
|
||||
struct scsi_vpd_extended_inquiry_data *ext_inq;
|
||||
struct ccb_scsiio *csio;
|
||||
int32_t length = 0;
|
||||
|
||||
csio = &done_ccb->csio;
|
||||
ext_inq = (struct scsi_vpd_extended_inquiry_data *)
|
||||
csio->data_ptr;
|
||||
if (path->device->ext_inq != NULL) {
|
||||
path->device->ext_inq_len = 0;
|
||||
free(path->device->ext_inq, M_CAMXPT);
|
||||
path->device->ext_inq = NULL;
|
||||
}
|
||||
|
||||
if (ext_inq == NULL) {
|
||||
/* Don't process the command as it was never sent */
|
||||
} else if (CCB_COMPLETED_OK(csio->ccb_h)) {
|
||||
length = scsi_2btoul(ext_inq->page_length) +
|
||||
__offsetof(struct scsi_vpd_extended_inquiry_data,
|
||||
flags1);
|
||||
length = min(length, sizeof(*ext_inq));
|
||||
length -= csio->resid;
|
||||
if (length > 0) {
|
||||
path->device->ext_inq_len = length;
|
||||
path->device->ext_inq = (uint8_t *)ext_inq;
|
||||
}
|
||||
} else if (cam_periph_error(done_ccb, 0,
|
||||
SF_RETRY_UA,
|
||||
&softc->saved_ccb) == ERESTART) {
|
||||
return;
|
||||
} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
|
||||
/* Don't wedge the queue */
|
||||
xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
|
||||
/*run_queue*/TRUE);
|
||||
}
|
||||
|
||||
/* Free the device id space if we don't use it */
|
||||
if (ext_inq && length <= 0)
|
||||
free(ext_inq, M_CAMXPT);
|
||||
xpt_release_ccb(done_ccb);
|
||||
PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM);
|
||||
xpt_schedule(periph, priority);
|
||||
goto out;
|
||||
@ -2477,6 +2551,21 @@ scsi_dev_advinfo(union ccb *start_ccb)
|
||||
memcpy(cdai->buf, device->rcap_buf, amt);
|
||||
}
|
||||
break;
|
||||
case CDAI_TYPE_EXT_INQ:
|
||||
/*
|
||||
* We fetch extended inquiry data during probe, if
|
||||
* available. We don't allow changing it.
|
||||
*/
|
||||
if (cdai->flags & CDAI_FLAG_STORE)
|
||||
return;
|
||||
cdai->provsiz = device->ext_inq_len;
|
||||
if (device->ext_inq_len == 0)
|
||||
break;
|
||||
amt = device->ext_inq_len;
|
||||
if (cdai->provsiz > cdai->bufsiz)
|
||||
amt = cdai->bufsiz;
|
||||
memcpy(cdai->buf, device->ext_inq, amt);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@
|
||||
* in the range 5 to 9.
|
||||
*/
|
||||
#undef __FreeBSD_version
|
||||
#define __FreeBSD_version 1100057 /* Master, propagated to newvers */
|
||||
#define __FreeBSD_version 1100058 /* Master, propagated to newvers */
|
||||
|
||||
/*
|
||||
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
|
||||
|
Loading…
x
Reference in New Issue
Block a user