diff options
author | gibbs <gibbs@FreeBSD.org> | 1999-01-14 06:03:59 +0000 |
---|---|---|
committer | gibbs <gibbs@FreeBSD.org> | 1999-01-14 06:03:59 +0000 |
commit | eec3d5cfc887b77bd68687cd2cd39b51e2068162 (patch) | |
tree | e5bc5b80391cae230378209f5b1e5ff5886d5c28 | |
parent | 15f5575a82eb82f8a87d6dfcf93810075404c010 (diff) | |
download | FreeBSD-src-eec3d5cfc887b77bd68687cd2cd39b51e2068162.zip FreeBSD-src-eec3d5cfc887b77bd68687cd2cd39b51e2068162.tar.gz |
Add support for wildcard device entries in the EDT. The target mode
'Black Hole' device uses this feature to schedule itself against any
target or lun attached to a controller that receives an unwanted request
from an initiator instead of having an instance per potential target/lun
request.
Use the wildcard entries to simplify wildcard async callback storage.
Don't announce devices twice to peripheral drivers. The devices will
be announced as soon as the AC_PATH_REGISTERED event is registered by
the peripheral driver, so no manaul push of this event is required.
Reviewed by: Kenneth Merry <ken@FreeBSD.org>
-rw-r--r-- | sys/cam/cam_xpt.c | 136 |
1 files changed, 42 insertions, 94 deletions
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index e541f86..7408662 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -1,7 +1,7 @@ /* * Implementation of the Common Access Method Transport (XPT) layer. * - * Copyright (c) 1997, 1998 Justin T. Gibbs. + * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs. * Copyright (c) 1997, 1998 Kenneth D. Merry. * All rights reserved. * @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cam_xpt.c,v 1.34 1999/01/05 21:37:07 ken Exp $ + * $Id: cam_xpt.c,v 1.35 1999/01/07 01:11:24 ken Exp $ */ #include <sys/param.h> #include <sys/systm.h> @@ -197,7 +197,6 @@ struct cam_et { struct cam_eb { TAILQ_HEAD(, cam_et) et_entries; TAILQ_ENTRY(cam_eb) links; - struct async_list asyncs; /* Async callback info for this B/T/L */ path_id_t path_id; struct cam_sim *sim; u_int32_t flags; @@ -332,17 +331,6 @@ static struct xpt_quirk_entry xpt_quirk_table[] = { T_DIRECT, SIP_MEDIA_FIXED, "SAMSUNG", "WN321010S*", "*" }, /*quirks*/0, /*mintags*/2, /*maxtags*/32 }, - { - /* - * Hack until multiple-luns are supported by - * the target mode code. - */ - { - T_PROCESSOR, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED, - "FreeBSD", "TM-PT", "*" - }, - CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0 - }, { /* Really only one LUN */ { @@ -590,7 +578,6 @@ static void xptscandone(struct cam_periph *periph, union ccb *done_ccb); static xpt_busfunc_t xptconfigbuscountfunc; static xpt_busfunc_t xptconfigfunc; static void xpt_config(void *arg); -static xpt_devicefunc_t xptfinishconfigfunc; static xpt_devicefunc_t xptpassannouncefunc; static void xpt_finishconfig(struct cam_periph *periph, union ccb *ccb); static void xptaction(struct cam_sim *sim, union ccb *work_ccb); @@ -2547,6 +2534,15 @@ xptsetasyncfunc(struct cam_ed *device, void *arg) cur_entry = (struct async_node *)arg; + /* + * Don't report unconfigured devices (Wildcard devs, + * devices only for target mode, device instances + * that have been invalidated but are waiting for + * their last reference count to be released). + */ + if ((device->flags & CAM_DEV_UNCONFIGURED) != 0) + return (1); + xpt_compile_path(&path, NULL, device->target->bus->path_id, @@ -2562,6 +2558,7 @@ xptsetasyncfunc(struct cam_ed *device, void *arg) return(1); } + static int xptsetasyncbusfunc(struct cam_eb *bus, void *arg) { @@ -2875,10 +2872,6 @@ xpt_action(union ccb *start_ccb) } case XPT_SASYNC_CB: { - /* - * First off, determine the list we want to - * be insterted into. - */ struct ccb_setasync *csa; struct async_node *cur_entry; struct async_list *async_head; @@ -2887,11 +2880,7 @@ xpt_action(union ccb *start_ccb) csa = &start_ccb->csa; added = csa->event_enable; - if (csa->ccb_h.path->device != NULL) { - async_head = &csa->ccb_h.path->device->asyncs; - } else { - async_head = &csa->ccb_h.path->bus->asyncs; - } + async_head = &csa->ccb_h.path->device->asyncs; /* * If there is already an entry for us, simply @@ -2915,6 +2904,7 @@ xpt_action(union ccb *start_ccb) if (csa->event_enable == 0) { SLIST_REMOVE(async_head, cur_entry, async_node, links); + csa->ccb_h.path->device->refcount--; free(cur_entry, M_DEVBUF); } else { cur_entry->event_enable = csa->event_enable; @@ -2931,6 +2921,7 @@ xpt_action(union ccb *start_ccb) cur_entry->callback = csa->callback; cur_entry->event_enable = csa->event_enable; SLIST_INSERT_HEAD(async_head, cur_entry, links); + csa->ccb_h.path->device->refcount++; } if ((added & AC_FOUND_DEVICE) != 0) { @@ -3566,49 +3557,35 @@ xpt_compile_path(struct cam_path *new_path, struct cam_periph *perph, bus = xpt_find_bus(path_id); if (bus == NULL) { status = CAM_PATH_INVALID; - } else if (target_id != CAM_TARGET_WILDCARD) { + } else { target = xpt_find_target(bus, target_id); if (target == NULL) { - if (path_id == CAM_XPT_PATH_ID) { - status = CAM_TID_INVALID; - } else { - /* Create one */ - struct cam_et *new_target; + /* Create one */ + struct cam_et *new_target; - new_target = xpt_alloc_target(bus, target_id); - if (new_target == NULL) { - status = CAM_RESRC_UNAVAIL; - } else { - target = new_target; - } + new_target = xpt_alloc_target(bus, target_id); + if (new_target == NULL) { + status = CAM_RESRC_UNAVAIL; + } else { + target = new_target; } } - if (target != NULL && lun_id != CAM_LUN_WILDCARD) { + if (target != NULL) { device = xpt_find_device(target, lun_id); if (device == NULL) { - if (path_id == CAM_XPT_PATH_ID) { - status = CAM_LUN_INVALID; + /* Create one */ + struct cam_ed *new_device; + + new_device = xpt_alloc_device(bus, + target, + lun_id); + if (new_device == NULL) { + status = CAM_RESRC_UNAVAIL; } else { - /* Create one */ - struct cam_ed *new_device; - - new_device = xpt_alloc_device(bus, - target, - lun_id); - if (new_device == NULL) { - status = CAM_RESRC_UNAVAIL; - } else { - device = new_device; - } + device = new_device; } } } - } else if (lun_id != CAM_LUN_WILDCARD) { - /* - * Specific luns are not allowed if the - * target is wildcarded - */ - status = CAM_LUN_INVALID; } /* @@ -3823,7 +3800,6 @@ xpt_bus_register(struct cam_sim *sim, u_int32_t bus) new_bus->path_id = sim->path_id; new_bus->sim = sim; - SLIST_INIT(&new_bus->asyncs); TAILQ_INIT(&new_bus->et_entries); s = splsoftcam(); TAILQ_INSERT_TAIL(&xpt_busses, new_bus, links); @@ -4059,15 +4035,20 @@ xpt_async(u_int32_t async_code, struct cam_path *path, void *async_arg) /*async_update*/TRUE); } - xpt_async_bcast(&device->asyncs, async_code, path, async_arg); } } - xpt_async_bcast(&bus->asyncs, async_code, - path, async_arg); + + /* + * If this wasn't a fully wildcarded async, tell all + * clients that want all async events. + */ + if (bus != xpt_periph->path->bus) + xpt_async_bcast(&xpt_periph->path->device->asyncs, async_code, + path, async_arg); splx(s); } @@ -4934,7 +4915,7 @@ probeschedule(struct cam_periph *periph) * lun 0. This will insure that any bogus transfer settings are * invalidated. */ - if (((ccb->ccb_h.path->device->flags & CAM_DEV_UNCONFIGURED)==0) + if (((ccb->ccb_h.path->device->flags & CAM_DEV_UNCONFIGURED) == 0) && (ccb->ccb_h.target_lun == 0)) softc->action = PROBE_TUR; else @@ -5622,7 +5603,6 @@ xptconfigfunc(struct cam_eb *bus, void *arg) } return(1); - } static void @@ -5669,32 +5649,6 @@ xpt_config(void *arg) } } -static int -xptfinishconfigfunc(struct cam_ed *device, void *arg) -{ - union ccb work_ccb; - struct cam_path path; - cam_status status; - - if ((status = xpt_compile_path(&path, xpt_periph, - device->target->bus->path_id, - device->target->target_id, - device->lun_id)) != CAM_REQ_CMP) { - printf("xptfinishconfig: xpt_compile_path failed with status" - " %#x, halting device registration\n", status); - return(0); - } - - xpt_setup_ccb(&work_ccb.ccb_h, &path, /*priority*/1); - - work_ccb.ccb_h.func_code = XPT_GDEV_TYPE; - xpt_action(&work_ccb); - xpt_async(AC_FOUND_DEVICE, &path, &work_ccb); - - xpt_release_path(&path); - return(1); -} - /* * If the given device only has one peripheral attached to it, and if that * peripheral is the passthrough driver, announce it. This insures that the @@ -5752,12 +5706,6 @@ xpt_finishconfig(struct cam_periph *periph, union ccb *done_ccb) } /* - * Itterate through our devices announcing - * them in probed bus order. - */ - xpt_for_all_devices(xptfinishconfigfunc, NULL); - - /* * Check for devices with no "standard" peripheral driver * attached. For any devices like that, announce the * passthrough driver so the user will see something. |