svn commit: r189149 - in stable/7/sys: . cam contrib/pf dev/ata dev/cxgb

Edward Tomasz Napierala trasz at FreeBSD.org
Sat Feb 28 02:38:33 PST 2009


Author: trasz
Date: Sat Feb 28 10:38:32 2009
New Revision: 189149
URL: http://svn.freebsd.org/changeset/base/189149

Log:
  MFC r186905:
  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

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/cam/cam_xpt.c
  stable/7/sys/cam/cam_xpt_sim.h
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/ata/atapi-cam.c
  stable/7/sys/dev/cxgb/   (props changed)

Modified: stable/7/sys/cam/cam_xpt.c
==============================================================================
--- stable/7/sys/cam/cam_xpt.c	Sat Feb 28 10:35:30 2009	(r189148)
+++ stable/7/sys/cam/cam_xpt.c	Sat Feb 28 10:38:32 2009	(r189149)
@@ -2642,6 +2642,39 @@ xptbustraverse(struct cam_eb *start_bus,
 	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)

Modified: stable/7/sys/cam/cam_xpt_sim.h
==============================================================================
--- stable/7/sys/cam/cam_xpt_sim.h	Sat Feb 28 10:35:30 2009	(r189148)
+++ stable/7/sys/cam/cam_xpt_sim.h	Sat Feb 28 10:38:32 2009	(r189149)
@@ -45,6 +45,7 @@ void		xpt_release_simq(struct cam_sim *s
 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
 

Modified: stable/7/sys/dev/ata/atapi-cam.c
==============================================================================
--- stable/7/sys/dev/ata/atapi-cam.c	Sat Feb 28 10:35:30 2009	(r189148)
+++ stable/7/sys/dev/ata/atapi-cam.c	Sat Feb 28 10:38:32 2009	(r189149)
@@ -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);


More information about the svn-src-stable mailing list