summaryrefslogtreecommitdiffstats
path: root/sys/cam/scsi
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2009-11-01 11:31:06 +0000
committermav <mav@FreeBSD.org>2009-11-01 11:31:06 +0000
commitf730b0005e8be01d50ff4a09ad56e8156d154185 (patch)
treea839b18708c0447e20fde3a95bf180ebda2046e4 /sys/cam/scsi
parent29890cf9d2809593453bd452d4617e0ef072596c (diff)
downloadFreeBSD-src-f730b0005e8be01d50ff4a09ad56e8156d154185.zip
FreeBSD-src-f730b0005e8be01d50ff4a09ad56e8156d154185.tar.gz
MFp4:
Fix reference counting bug, when device unreferenced before then invalidated. To do it, do not handle validity flag as another reference, but explicitly modify reference count each time flag is modified. Discovered by: thompsa
Diffstat (limited to 'sys/cam/scsi')
-rw-r--r--sys/cam/scsi/scsi_xpt.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/sys/cam/scsi/scsi_xpt.c b/sys/cam/scsi/scsi_xpt.c
index a240db8..d780f9a 100644
--- a/sys/cam/scsi/scsi_xpt.c
+++ b/sys/cam/scsi/scsi_xpt.c
@@ -1076,8 +1076,10 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
else
PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_0);
- path->device->flags &= ~CAM_DEV_UNCONFIGURED;
-
+ if (path->device->flags & CAM_DEV_UNCONFIGURED) {
+ path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+ xpt_acquire_device(path->device);
+ }
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
return;
@@ -1336,8 +1338,12 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
("Leave Domain Validation\n"));
}
+ if (path->device->flags & CAM_DEV_UNCONFIGURED) {
+ path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+ xpt_acquire_device(path->device);
+ }
path->device->flags &=
- ~(CAM_DEV_UNCONFIGURED|CAM_DEV_IN_DV|CAM_DEV_DV_HIT_BOTTOM);
+ ~(CAM_DEV_IN_DV|CAM_DEV_DV_HIT_BOTTOM);
if ((softc->flags & PROBE_NO_ANNOUNCE) == 0) {
/* Inform the XPT that a new device has been found */
done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
@@ -1387,8 +1393,12 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
("Leave Domain Validation Successfully\n"));
}
+ if (path->device->flags & CAM_DEV_UNCONFIGURED) {
+ path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+ xpt_acquire_device(path->device);
+ }
path->device->flags &=
- ~(CAM_DEV_UNCONFIGURED|CAM_DEV_IN_DV|CAM_DEV_DV_HIT_BOTTOM);
+ ~(CAM_DEV_IN_DV|CAM_DEV_DV_HIT_BOTTOM);
if ((softc->flags & PROBE_NO_ANNOUNCE) == 0) {
/* Inform the XPT that a new device has been found */
done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
@@ -2375,8 +2385,10 @@ scsi_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target,
CAM_EXPECT_INQ_CHANGE, NULL);
}
xpt_release_path(&newpath);
- } else if (async_code == AC_LOST_DEVICE) {
+ } else if (async_code == AC_LOST_DEVICE &&
+ (device->flags & CAM_DEV_UNCONFIGURED) == 0) {
device->flags |= CAM_DEV_UNCONFIGURED;
+ xpt_release_device(device);
} else if (async_code == AC_TRANSFER_NEG) {
struct ccb_trans_settings *settings;
OpenPOWER on IntegriCloud