Make "kldunload atapicam" return EBUSY instead of deadlocking when a device
created by atapicam is being kept opened or mounted. This is probably just a temporary solution until we invent something better. Reviewed by: scottl Approved by: rwatson (mentor) Sponsored by: FreeBSD Foundation Reported by: Jaakko Heinonen
This commit is contained in:
parent
10ad9a77f3
commit
02caf36ee1
@ -2642,6 +2642,39 @@ xptbustraverse(struct cam_eb *start_bus, xpt_busfunc_t *tr_func, void *arg)
|
||||
return(retval);
|
||||
}
|
||||
|
||||
int
|
||||
xpt_sim_opened(struct cam_sim *sim)
|
||||
{
|
||||
struct cam_eb *bus;
|
||||
struct cam_et *target;
|
||||
struct cam_ed *device;
|
||||
struct cam_periph *periph;
|
||||
|
||||
KASSERT(sim->refcount >= 1, ("sim->refcount >= 1"));
|
||||
mtx_assert(sim->mtx, MA_OWNED);
|
||||
|
||||
mtx_lock(&xsoftc.xpt_topo_lock);
|
||||
TAILQ_FOREACH(bus, &xsoftc.xpt_busses, links) {
|
||||
if (bus->sim != sim)
|
||||
continue;
|
||||
|
||||
TAILQ_FOREACH(target, &bus->et_entries, links) {
|
||||
TAILQ_FOREACH(device, &target->ed_entries, links) {
|
||||
SLIST_FOREACH(periph, &device->periphs,
|
||||
periph_links) {
|
||||
if (periph->refcount > 0) {
|
||||
mtx_unlock(&xsoftc.xpt_topo_lock);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mtx_unlock(&xsoftc.xpt_topo_lock);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
xpttargettraverse(struct cam_eb *bus, struct cam_et *start_target,
|
||||
xpt_targetfunc_t *tr_func, void *arg)
|
||||
@ -4277,7 +4310,7 @@ xpt_release_ccb(union ccb *free_ccb)
|
||||
* for this new bus and places it in the array of busses and assigns
|
||||
* it a path_id. The path_id may be influenced by "hard wiring"
|
||||
* information specified by the user. Once interrupt services are
|
||||
* availible, the bus will be probed.
|
||||
* available, the bus will be probed.
|
||||
*/
|
||||
int32_t
|
||||
xpt_bus_register(struct cam_sim *sim, device_t parent, u_int32_t bus)
|
||||
|
@ -45,6 +45,7 @@ void xpt_release_simq(struct cam_sim *sim, int run_queue);
|
||||
u_int32_t xpt_freeze_devq(struct cam_path *path, u_int count);
|
||||
void xpt_release_devq(struct cam_path *path, u_int count,
|
||||
int run_queue);
|
||||
int xpt_sim_opened(struct cam_sim *sim);
|
||||
void xpt_done(union ccb *done_ccb);
|
||||
#endif
|
||||
|
||||
|
@ -254,6 +254,10 @@ atapi_cam_detach(device_t dev)
|
||||
struct atapi_xpt_softc *scp = device_get_softc(dev);
|
||||
|
||||
mtx_lock(&scp->state_lock);
|
||||
if (xpt_sim_opened(scp->sim)) {
|
||||
mtx_unlock(&scp->state_lock);
|
||||
return (EBUSY);
|
||||
}
|
||||
xpt_freeze_simq(scp->sim, 1 /*count*/);
|
||||
scp->flags |= DETACHING;
|
||||
mtx_unlock(&scp->state_lock);
|
||||
|
Loading…
Reference in New Issue
Block a user