1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-16 10:20:30 +00:00

Fix async notifications for listners registered to wildcard nodes. For

example, a client registered to receive specific events for bus 0, target *,
lun *, was not receiving notifications.

Reviewed by:	ken@FreeBSD.org
This commit is contained in:
Justin T. Gibbs 2000-11-06 20:12:07 +00:00
parent 47c2d60f79
commit 2f22d08de1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=68403

View File

@ -658,6 +658,11 @@ static void xpt_async_bcast(struct async_list *async_head,
u_int32_t async_code,
struct cam_path *path,
void *async_arg);
static void xpt_dev_async(u_int32_t async_code,
struct cam_eb *bus,
struct cam_et *target,
struct cam_ed *device,
void *async_arg);
static path_id_t xptnextfreepathid(void);
static path_id_t xptpathid(const char *sim_name, int sim_unit, int sim_bus);
static union ccb *xpt_get_ccb(struct cam_ed *device);
@ -4244,7 +4249,8 @@ xpt_async(u_int32_t async_code, struct cam_path *path, void *async_arg)
next_target = TAILQ_NEXT(target, links);
if (path->target != target
&& path->target->target_id != CAM_TARGET_WILDCARD)
&& path->target->target_id != CAM_TARGET_WILDCARD
&& target->target_id != CAM_TARGET_WILDCARD)
continue;
if (async_code == AC_SENT_BDR) {
@ -4259,67 +4265,19 @@ xpt_async(u_int32_t async_code, struct cam_path *path, void *async_arg)
for (device = TAILQ_FIRST(&target->ed_entries);
device != NULL;
device = next_device) {
cam_status status;
struct cam_path newpath;
next_device = TAILQ_NEXT(device, links);
if (path->device != device
&& path->device->lun_id != CAM_LUN_WILDCARD)
&& path->device->lun_id != CAM_LUN_WILDCARD
&& device->lun_id != CAM_LUN_WILDCARD)
continue;
/*
* We need our own path with wildcards expanded to
* handle certain types of events.
*/
if ((async_code == AC_SENT_BDR)
|| (async_code == AC_BUS_RESET)
|| (async_code == AC_INQ_CHANGED))
status = xpt_compile_path(&newpath, NULL,
bus->path_id,
target->target_id,
device->lun_id);
else
status = CAM_REQ_CMP_ERR;
xpt_dev_async(async_code, bus, target,
device, async_arg);
if (status == CAM_REQ_CMP) {
/*
* Allow transfer negotiation to occur in a
* tag free environment.
*/
if (async_code == AC_SENT_BDR
|| async_code == AC_BUS_RESET)
xpt_toggle_tags(&newpath);
if (async_code == AC_INQ_CHANGED) {
/*
* We've sent a start unit command, or
* something similar to a device that
* may have caused its inquiry data to
* change. So we re-scan the device to
* refresh the inquiry data for it.
*/
xpt_scan_lun(newpath.periph, &newpath,
CAM_EXPECT_INQ_CHANGE,
NULL);
}
xpt_release_path(&newpath);
} else if (async_code == AC_LOST_DEVICE) {
device->flags |= CAM_DEV_UNCONFIGURED;
} else if (async_code == AC_TRANSFER_NEG) {
struct ccb_trans_settings *settings;
settings =
(struct ccb_trans_settings *)async_arg;
xpt_set_transfer_settings(settings, device,
/*async_update*/TRUE);
}
xpt_async_bcast(&device->asyncs,
async_code,
path,
async_arg);
xpt_async_bcast(&device->asyncs, async_code,
path, async_arg);
}
}
@ -4357,6 +4315,70 @@ xpt_async_bcast(struct async_list *async_head,
}
}
/*
* Handle any per-device event notifications that require action by the XPT.
*/
static void
xpt_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target,
struct cam_ed *device, void *async_arg)
{
cam_status status;
struct cam_path newpath;
/*
* We only need to handle events for real devices.
*/
if (target->target_id == CAM_TARGET_WILDCARD
|| device->lun_id == CAM_LUN_WILDCARD)
return;
/*
* We need our own path with wildcards expanded to
* handle certain types of events.
*/
if ((async_code == AC_SENT_BDR)
|| (async_code == AC_BUS_RESET)
|| (async_code == AC_INQ_CHANGED))
status = xpt_compile_path(&newpath, NULL,
bus->path_id,
target->target_id,
device->lun_id);
else
status = CAM_REQ_CMP_ERR;
if (status == CAM_REQ_CMP) {
/*
* Allow transfer negotiation to occur in a
* tag free environment.
*/
if (async_code == AC_SENT_BDR
|| async_code == AC_BUS_RESET)
xpt_toggle_tags(&newpath);
if (async_code == AC_INQ_CHANGED) {
/*
* We've sent a start unit command, or
* something similar to a device that
* may have caused its inquiry data to
* change. So we re-scan the device to
* refresh the inquiry data for it.
*/
xpt_scan_lun(newpath.periph, &newpath,
CAM_EXPECT_INQ_CHANGE, NULL);
}
xpt_release_path(&newpath);
} else if (async_code == AC_LOST_DEVICE) {
device->flags |= CAM_DEV_UNCONFIGURED;
} else if (async_code == AC_TRANSFER_NEG) {
struct ccb_trans_settings *settings;
settings = (struct ccb_trans_settings *)async_arg;
xpt_set_transfer_settings(settings, device,
/*async_update*/TRUE);
}
}
u_int32_t
xpt_freeze_devq(struct cam_path *path, u_int count)
{