mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
sdhci: Defer XPT_SET_TRAN_SETTINGS to the slot taskqueue
Only XPT_MMC_SET_TRAN_SETTINGS was handed to the slot taskqueue. XPT_SET_TRAN_SETTINGS, which mmc_xpt.c issues too, still called sdhci_cam_settran_settings() directly from the CAM done thread with the CAM device lock held. Changing the bus clock can sleep (clk_set_freq() takes the clock topology sx lock), which panics with "sleeping thread holds CAM device lock". Handle both opcodes the same way and complete the request from the taskqueue. Differential Revision: https://reviews.freebsd.org/D61013
This commit is contained in:
1 parent
3e9ff26d2a
commit
bbb90912eb
1 file changed
+4
-9
@@ -2784,9 +2784,12 @@ sdhci_cam_action(struct cam_sim *sim, union ccb *ccb)
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
break;
|
||||
}
|
||||
case XPT_SET_TRAN_SETTINGS:
|
||||
case XPT_MMC_SET_TRAN_SETTINGS:
|
||||
if (sdhci_debug > 1)
|
||||
slot_printf(slot, "Got XPT_MMC_SET_TRAN_SETTINGS\n");
|
||||
slot_printf(slot, "Got XPT_%sSET_TRAN_SETTINGS\n",
|
||||
ccb->ccb_h.func_code == XPT_MMC_SET_TRAN_SETTINGS ?
|
||||
"MMC_" : "");
|
||||
if (slot->settran_ccb != NULL) {
|
||||
ccb->ccb_h.status = CAM_BUSY;
|
||||
break;
|
||||
@@ -2796,14 +2799,6 @@ sdhci_cam_action(struct cam_sim *sim, union ccb *ccb)
|
||||
slot->settran_ccb = ccb;
|
||||
taskqueue_enqueue(slot->tq, &slot->settran_task);
|
||||
return;
|
||||
case XPT_SET_TRAN_SETTINGS:
|
||||
if (sdhci_debug > 1)
|
||||
slot_printf(slot, "Got XPT_SET_TRAN_SETTINGS\n");
|
||||
if (sdhci_cam_settran_settings(slot, ccb) != 0)
|
||||
ccb->ccb_h.status = CAM_REQ_INVALID;
|
||||
else
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
break;
|
||||
case XPT_RESET_BUS:
|
||||
if (sdhci_debug > 1)
|
||||
slot_printf(slot, "Got XPT_RESET_BUS, ACK it...\n");
|
||||
|
||||
Reference in new issue
Block a user