mirror of
https://github.com/opnsense/src.git
synced 2026-06-11 01:30:30 -04:00
cam(4): Fix quick unplug/replug for SCSI.
If some device is plugged back in after unplug before the probe periph
destroyed, it will just restart the probe process. But I've found that
PROBE_INQUIRY_CKSUM flag not cleared between the iterations may cause
AC_FOUND_DEVICE not reported on the second iteration, and because of
AC_LOST_DEVICE reported during the first iteration, the device end up
configured, but without any periphs attached.
We've found that enabled serial console and 102-disk JBOD cause enough
probe delays to easily trigger the issue for half of the disks. This
change fixes it reliably on my tests.
MFC after: 2 weeks
Sponsored by: iXsystems, Inc.
(cherry picked from commit 84d5b6bd68)
This commit is contained in:
parent
343da8f5e9
commit
bf2cfa495f
1 changed files with 38 additions and 23 deletions
|
|
@ -178,7 +178,6 @@ do { \
|
|||
|
||||
typedef enum {
|
||||
PROBE_INQUIRY_CKSUM = 0x01,
|
||||
PROBE_SERIAL_CKSUM = 0x02,
|
||||
PROBE_NO_ANNOUNCE = 0x04,
|
||||
PROBE_EXTLUN = 0x08
|
||||
} probe_flags;
|
||||
|
|
@ -776,8 +775,6 @@ again:
|
|||
}
|
||||
case PROBE_INQUIRY:
|
||||
case PROBE_FULL_INQUIRY:
|
||||
case PROBE_INQUIRY_BASIC_DV1:
|
||||
case PROBE_INQUIRY_BASIC_DV2:
|
||||
{
|
||||
u_int inquiry_len;
|
||||
struct scsi_inquiry_data *inq_buf;
|
||||
|
|
@ -792,19 +789,19 @@ again:
|
|||
* serial number check finish, we attempt to figure out
|
||||
* whether we still have the same device.
|
||||
*/
|
||||
if (((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
|
||||
&& ((softc->flags & PROBE_INQUIRY_CKSUM) == 0)) {
|
||||
if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
|
||||
softc->flags &= ~PROBE_INQUIRY_CKSUM;
|
||||
} else if ((softc->flags & PROBE_INQUIRY_CKSUM) == 0) {
|
||||
MD5Init(&softc->context);
|
||||
MD5Update(&softc->context, (unsigned char *)inq_buf,
|
||||
sizeof(struct scsi_inquiry_data));
|
||||
softc->flags |= PROBE_INQUIRY_CKSUM;
|
||||
if (periph->path->device->serial_num_len > 0) {
|
||||
MD5Update(&softc->context,
|
||||
periph->path->device->serial_num,
|
||||
periph->path->device->serial_num_len);
|
||||
softc->flags |= PROBE_SERIAL_CKSUM;
|
||||
}
|
||||
MD5Final(softc->digest, &softc->context);
|
||||
softc->flags |= PROBE_INQUIRY_CKSUM;
|
||||
}
|
||||
|
||||
if (softc->action == PROBE_INQUIRY)
|
||||
|
|
@ -820,22 +817,6 @@ again:
|
|||
*/
|
||||
inquiry_len = roundup2(inquiry_len, 2);
|
||||
|
||||
if (softc->action == PROBE_INQUIRY_BASIC_DV1
|
||||
|| softc->action == PROBE_INQUIRY_BASIC_DV2) {
|
||||
inq_buf = malloc(inquiry_len, M_CAMXPT, M_NOWAIT);
|
||||
}
|
||||
if (inq_buf == NULL) {
|
||||
xpt_print(periph->path, "malloc failure- skipping Basic"
|
||||
"Domain Validation\n");
|
||||
PROBE_SET_ACTION(softc, PROBE_DV_EXIT);
|
||||
scsi_test_unit_ready(csio,
|
||||
/*retries*/4,
|
||||
probedone,
|
||||
MSG_SIMPLE_Q_TAG,
|
||||
SSD_FULL_SIZE,
|
||||
/*timeout*/60000);
|
||||
break;
|
||||
}
|
||||
scsi_inquiry(csio,
|
||||
/*retries*/4,
|
||||
probedone,
|
||||
|
|
@ -1020,6 +1001,40 @@ done:
|
|||
}
|
||||
goto done;
|
||||
}
|
||||
case PROBE_INQUIRY_BASIC_DV1:
|
||||
case PROBE_INQUIRY_BASIC_DV2:
|
||||
{
|
||||
u_int inquiry_len;
|
||||
struct scsi_inquiry_data *inq_buf;
|
||||
|
||||
inq_buf = &periph->path->device->inq_data;
|
||||
inquiry_len = roundup2(SID_ADDITIONAL_LENGTH(inq_buf), 2);
|
||||
inq_buf = malloc(inquiry_len, M_CAMXPT, M_NOWAIT);
|
||||
if (inq_buf == NULL) {
|
||||
xpt_print(periph->path, "malloc failure- skipping Basic"
|
||||
"Domain Validation\n");
|
||||
PROBE_SET_ACTION(softc, PROBE_DV_EXIT);
|
||||
scsi_test_unit_ready(csio,
|
||||
/*retries*/4,
|
||||
probedone,
|
||||
MSG_SIMPLE_Q_TAG,
|
||||
SSD_FULL_SIZE,
|
||||
/*timeout*/60000);
|
||||
break;
|
||||
}
|
||||
|
||||
scsi_inquiry(csio,
|
||||
/*retries*/4,
|
||||
probedone,
|
||||
MSG_SIMPLE_Q_TAG,
|
||||
(u_int8_t *)inq_buf,
|
||||
inquiry_len,
|
||||
/*evpd*/FALSE,
|
||||
/*page_code*/0,
|
||||
SSD_MIN_SIZE,
|
||||
/*timeout*/60 * 1000);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
panic("probestart: invalid action state 0x%x\n", softc->action);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue