Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F169486103
D58658.id183756.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D58658.id183756.diff
View Options
diff --git a/sys/dev/ufshci/ufshci_ctrlr.c b/sys/dev/ufshci/ufshci_ctrlr.c
--- a/sys/dev/ufshci/ufshci_ctrlr.c
+++ b/sys/dev/ufshci/ufshci_ctrlr.c
@@ -448,6 +448,8 @@
bus_release_resource(ctrlr->dev, SYS_RES_IRQ,
rman_get_rid(ctrlr->res), ctrlr->res);
+ ufshci_sim_release_wlun_periph(ctrlr);
+
mtx_lock(&ctrlr->sc_mtx);
ufshci_sim_detach(ctrlr);
diff --git a/sys/dev/ufshci/ufshci_dev.c b/sys/dev/ufshci/ufshci_dev.c
--- a/sys/dev/ufshci/ufshci_dev.c
+++ b/sys/dev/ufshci/ufshci_dev.c
@@ -508,12 +508,15 @@
if (ctrlr->quirks & UFSHCI_QUIRK_SKIP_WELL_KNOWN_LUNS)
return (0);
- ctrlr->ufs_device_wlun_periph = ufshci_sim_find_periph(ctrlr,
- UFSHCI_WLUN_UFS_DEVICE);
if (ctrlr->ufs_device_wlun_periph == NULL) {
- ufshci_printf(ctrlr,
- "Well-known LUN `UFS Device (0x50)` not found\n");
- return (0);
+ /* The returned reference is kept by the cached pointer. */
+ ctrlr->ufs_device_wlun_periph = ufshci_sim_find_periph(ctrlr,
+ UFSHCI_WLUN_UFS_DEVICE);
+ if (ctrlr->ufs_device_wlun_periph == NULL) {
+ ufshci_printf(ctrlr,
+ "Well-known LUN `UFS Device (0x50)` not found\n");
+ return (0);
+ }
}
ctrlr->ufs_dev.power_mode_supported = true;
diff --git a/sys/dev/ufshci/ufshci_private.h b/sys/dev/ufshci/ufshci_private.h
--- a/sys/dev/ufshci/ufshci_private.h
+++ b/sys/dev/ufshci/ufshci_private.h
@@ -434,6 +434,7 @@
uint64_t ufshci_sim_translate_ufs_to_scsi_lun(uint8_t ufs_lun);
int ufshci_sim_attach(struct ufshci_controller *ctrlr);
void ufshci_sim_detach(struct ufshci_controller *ctrlr);
+void ufshci_sim_release_wlun_periph(struct ufshci_controller *ctrlr);
struct cam_periph *ufshci_sim_find_periph(struct ufshci_controller *ctrlr,
uint8_t wlun);
int ufshci_sim_send_ssu(struct ufshci_controller *ctrlr, bool start,
diff --git a/sys/dev/ufshci/ufshci_sim.c b/sys/dev/ufshci/ufshci_sim.c
--- a/sys/dev/ufshci/ufshci_sim.c
+++ b/sys/dev/ufshci/ufshci_sim.c
@@ -393,6 +393,20 @@
return (0);
}
+/*
+ * Drop the cached WLUN periph reference. cam_periph_release() takes the
+ * CAM device lock itself, so call this without sc_mtx held: CAM takes
+ * the device lock before the SIM lock, not the other way around.
+ */
+void
+ufshci_sim_release_wlun_periph(struct ufshci_controller *ctrlr)
+{
+ if (ctrlr->ufs_device_wlun_periph != NULL) {
+ cam_periph_release(ctrlr->ufs_device_wlun_periph);
+ ctrlr->ufs_device_wlun_periph = NULL;
+ }
+}
+
void
ufshci_sim_detach(struct ufshci_controller *ctrlr)
{
@@ -425,6 +439,10 @@
}
}
+/*
+ * On success this returns a referenced periph; the caller is responsible
+ * for dropping the reference with cam_periph_release().
+ */
struct cam_periph *
ufshci_sim_find_periph(struct ufshci_controller *ctrlr, uint8_t wlun)
{
@@ -446,6 +464,8 @@
while (1) {
xpt_path_lock(path);
periph = cam_periph_find(path, "pass");
+ if (periph != NULL && cam_periph_acquire(periph) != 0)
+ periph = NULL;
xpt_path_unlock(path);
if (periph)
@@ -474,17 +494,23 @@
union ccb *ccb;
int err;
- /* Acquire periph reference */
- if (periph && cam_periph_acquire(periph) != 0) {
+ /* Acquire a periph reference for the duration of this call. */
+ if (periph != NULL && cam_periph_acquire(periph) != 0) {
+ /* The cached periph is going away; drop its reference. */
+ cam_periph_release(periph);
+ ctrlr->ufs_device_wlun_periph = NULL;
periph = NULL;
}
if (periph == NULL) {
- /* If the periph device does not exist, it will try to find it
- * again */
+ /*
+ * If the periph device does not exist, try to find it again.
+ * The reference returned by ufshci_sim_find_periph() is used
+ * for this call; take an extra one for the cached pointer.
+ */
periph = ufshci_sim_find_periph(ctrlr,
(uint8_t)UFSHCI_WLUN_UFS_DEVICE);
- if (periph)
+ if (periph != NULL && cam_periph_acquire(periph) == 0)
ctrlr->ufs_device_wlun_periph = periph;
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Sep 2, 4:26 PM (15 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37969516
Default Alt Text
D58658.id183756.diff (3 KB)
Attached To
Mode
D58658: ufshci: fix WLUN periph reference counting
Attached
Detach File
Event Timeline
Log In to Comment