Remove garbage collected tags from their usage in the ccb_getdev

structure. Remove usage of the (now gone) pd_type tag of same.

Add an extra probing state such that if we successfully run an
initial inquiry (36 bytes), rerun another one with a longer data
size as informed by the 'additional length' field in the first
returned inquiry data (making sure not to get bigger than the
actual scsi_inquiry_data structure- which has also been modified-
see separate checkin of scsi_all.h). This allows devices such
as SAF-TE devices (which have identifying marks in offsets 48-53
in inquiry data) to be successfully found without special case
inquiry commands. There are also a lot of other things such as
version codes that are coming in in the SPC2 specification that it
would be useful to get our hands on.

Reviewed by:	gibbs@freebsd.org, ken@freebsd.org
This commit is contained in:
Matt Jacob 2000-01-17 06:20:08 +00:00
parent 826eb7c840
commit 9ec5d7cd35
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=56146

View File

@ -124,6 +124,7 @@ struct cam_ed {
struct xpt_quirk_entry *quirk; /* Oddities about this device */
/* Storage for the inquiry data */
struct scsi_inquiry_data inq_data;
u_int8_t inq_len; /* valid length in inq_data */
u_int8_t inq_flags; /*
* Current settings for inquiry flags.
* This allows us to override settings
@ -131,8 +132,8 @@ struct cam_ed {
* queuing for a device.
*/
u_int8_t queue_flags; /* Queue flags from the control page */
u_int8_t *serial_num;
u_int8_t serial_num_len;
u_int8_t *serial_num;
u_int32_t qfrozen_cnt;
u_int32_t flags;
#define CAM_DEV_UNCONFIGURED 0x01
@ -2919,16 +2920,7 @@ xpt_action(union ccb *start_ccb)
bus = cgd->ccb_h.path->bus;
tar = cgd->ccb_h.path->target;
cgd->inq_data = dev->inq_data;
cgd->pd_type = SID_TYPE(&dev->inq_data);
#ifndef GARBAGE_COLLECT
cgd->dev_openings = dev->ccbq.dev_openings;
cgd->dev_active = dev->ccbq.dev_active;
cgd->devq_openings = dev->ccbq.devq_openings;
cgd->devq_queued = dev->ccbq.queue.entries;
cgd->held = dev->ccbq.held;
cgd->maxtags = dev->quirk->maxtags;
cgd->mintags = dev->quirk->mintags;
#endif
cgd->inq_len = dev->inq_len;
cgd->ccb_h.status = CAM_REQ_CMP;
cgd->serial_num_len = dev->serial_num_len;
if ((dev->serial_num_len > 0)
@ -5041,6 +5033,7 @@ xpt_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
typedef enum {
PROBE_TUR,
PROBE_INQUIRY,
PROBE_FULL_INQUIRY,
PROBE_MODE_SENSE,
PROBE_SERIAL_NUM,
PROBE_TUR_FOR_NEGOTIATION
@ -5284,6 +5277,7 @@ probestart(struct cam_periph *periph, union ccb *start_ccb)
break;
}
case PROBE_INQUIRY:
case PROBE_FULL_INQUIRY:
{
struct scsi_inquiry_data *inq_buf;
@ -5311,12 +5305,15 @@ probestart(struct cam_periph *periph, union ccb *start_ccb)
MD5Final(softc->digest, &softc->context);
}
if (softc->action == PROBE_INQUIRY)
periph->path->device->inq_len = SHORT_INQUIRY_LENGTH;
scsi_inquiry(csio,
/*retries*/4,
probedone,
MSG_SIMPLE_Q_TAG,
(u_int8_t *)inq_buf,
sizeof(*inq_buf),
(size_t) periph->path->device->inq_len,
/*evpd*/FALSE,
/*page_code*/0,
SSD_MIN_SIZE,
@ -5439,17 +5436,47 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
return;
}
case PROBE_INQUIRY:
case PROBE_FULL_INQUIRY:
{
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
struct scsi_inquiry_data *inq_buf;
u_int8_t periph_qual;
u_int8_t periph_dtype;
u_int8_t alen;
path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
inq_buf = &path->device->inq_data;
periph_qual = SID_QUAL(inq_buf);
periph_dtype = SID_TYPE(inq_buf);
/*
* We conservatively request only SHORT_INQUIRY_LEN
* bytes of inquiry information during our first try
* at sending an INQUIRY. If the device has more
* information to give, perform a second reques
* specifying the amount of information the device
* is willing to give (but not overflowing the amount
* of room we have for it).
*/
alen = inq_buf->additional_length;
if (periph_dtype != T_NODEVICE
&& periph_qual == SID_QUAL_LU_CONNECTED
&& softc->action == PROBE_INQUIRY
&& alen > (SHORT_INQUIRY_LENGTH - 8)) {
path->device->inq_len =
min(alen + 8, sizeof (*inq_buf));
softc->action = PROBE_FULL_INQUIRY;
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
return;
}
if (periph_dtype != T_NODEVICE) {
switch(periph_qual) {
case SID_QUAL_LU_CONNECTED: