summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2013-04-27 12:39:28 +0000
committermav <mav@FreeBSD.org>2013-04-27 12:39:28 +0000
commit61b0409c0519fbf1a42e0cba6b35104b3dd84d51 (patch)
treebf581c59d8844308f913f9972a5f58fb79642d60 /sys/cam
parent535eef9123da965e52b90116817cca79fd7c58ed (diff)
downloadFreeBSD-src-61b0409c0519fbf1a42e0cba6b35104b3dd84d51.zip
FreeBSD-src-61b0409c0519fbf1a42e0cba6b35104b3dd84d51.tar.gz
MFprojects/camlock r249541:
Give periph validity flag own periph reference. That slightly simplifies the release logic and covers hypothetical case if lock is dropped inside the periph_oninval() method.
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/cam_periph.c21
1 files changed, 8 insertions, 13 deletions
diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c
index 8f7a37b..c3e3bd4 100644
--- a/sys/cam/cam_periph.c
+++ b/sys/cam/cam_periph.c
@@ -203,7 +203,7 @@ cam_periph_alloc(periph_ctor_t *periph_ctor,
periph->type = type;
periph->periph_name = name;
periph->immediate_priority = CAM_PRIORITY_NONE;
- periph->refcount = 0;
+ periph->refcount = 1; /* Dropped by invalidation. */
periph->sim = sim;
SLIST_INIT(&periph->ccb_list);
status = xpt_create_path(&path, periph, path_id, target_id, lun_id);
@@ -381,10 +381,8 @@ cam_periph_release_locked_buses(struct cam_periph *periph)
mtx_assert(periph->sim->mtx, MA_OWNED);
KASSERT(periph->refcount >= 1, ("periph->refcount >= 1"));
- if (--periph->refcount == 0
- && (periph->flags & CAM_PERIPH_INVALID)) {
+ if (--periph->refcount == 0)
camperiphfree(periph);
- }
}
void
@@ -579,23 +577,20 @@ void
cam_periph_invalidate(struct cam_periph *periph)
{
- CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Periph invalidated\n"));
mtx_assert(periph->sim->mtx, MA_OWNED);
/*
* We only call this routine the first time a peripheral is
* invalidated.
*/
- if (((periph->flags & CAM_PERIPH_INVALID) == 0)
- && (periph->periph_oninval != NULL))
- periph->periph_oninval(periph);
+ if ((periph->flags & CAM_PERIPH_INVALID) != 0)
+ return;
+ CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Periph invalidated\n"));
periph->flags |= CAM_PERIPH_INVALID;
periph->flags &= ~CAM_PERIPH_NEW_DEV_FOUND;
-
- xpt_lock_buses();
- if (periph->refcount == 0)
- camperiphfree(periph);
- xpt_unlock_buses();
+ if (periph->periph_oninval != NULL)
+ periph->periph_oninval(periph);
+ cam_periph_release_locked(periph);
}
static void
OpenPOWER on IntegriCloud