diff options
author | gibbs <gibbs@FreeBSD.org> | 2000-11-06 20:12:07 +0000 |
---|---|---|
committer | gibbs <gibbs@FreeBSD.org> | 2000-11-06 20:12:07 +0000 |
commit | 00e9873da77c2e082fafe47e29c197745b8f779d (patch) | |
tree | d5b7e6cf9c03b812e386befa193457f090144238 /sys/cam | |
parent | 13459a7344194f03540cfd2d91e74114d63217f0 (diff) | |
download | FreeBSD-src-00e9873da77c2e082fafe47e29c197745b8f779d.zip FreeBSD-src-00e9873da77c2e082fafe47e29c197745b8f779d.tar.gz |
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
Diffstat (limited to 'sys/cam')
-rw-r--r-- | sys/cam/cam_xpt.c | 132 |
1 files changed, 77 insertions, 55 deletions
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index 66270ae..70d6b65 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -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; - - 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_dev_async(async_code, bus, target, + device, async_arg); - 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) { |