class Ufs
Defined at line 179 of file ../../src/devices/block/drivers/ufs/ufs.h
Base class for UFS drivers.
This class is the parent class for both UfsPci and UfsPdev drivers, which bind the UFS
controller via PCI and PDev respectively.
Protected Members
vmo mmio_buffer_vmo_
uint64_t mmio_buffer_size_
interrupt irq_
bti bti_
deque pending_commands_
Dispatcher irq_worker_dispatcher_
Dispatcher io_worker_dispatcher_
Dispatcher admin_worker_dispatcher_
Dispatcher exception_event_dispatcher_
IrqMethod irq_handler_
TaskMethod timeout_task_
unique_ptr device_manager_
unique_ptr transfer_request_processor_
unique_ptr task_management_request_processor_
unique_ptr rpmb_device_
uint32_t logical_unit_count_
unordered_set well_known_lun_set_
function_impl host_controller_callback_
bool shutdown_
uint32_t pending_dispatcher_shutdowns_
optional stop_completer_
uint32_t max_transfer_bytes_
bool qemu_quirk_
bool intel_quirk_
Config config_
InspectProperties properties_
shared_ptr incoming_
optional component_inspector_
optional node_name_
WireSyncClient parent_node_
WireSyncClient root_node_
WireSyncClient node_controller_
event power_element_token_
optional power_element_runner_
bool power_level_on_required_
optional pending_resume_completer_
bool stopping_
TaskMethod resume_retry_task_
duration resume_retry_delay_
atomic hardware_powered_off_
mutex uic_lock_
bool crypto_supported_
WireSyncClient inline_encryption_client_
array crypto_slot_data_unit_size_
Public Methods
void ProcessIoSubmissions ()
Convert block operations to UPIU commands and submit them asynchronously.
Defined at line 143 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<> NotifyEventCallback (NotifyEvent event, uint64_t data)
Defines a callback function to perform when an |event| occurs.
Defined at line 38 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<> Notify (NotifyEvent event, uint64_t data)
The controller notifies the host controller when it takes the action defined in |event|.
Defined at line 61 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx_status_t WaitWithTimeout (fit::function<bool ()>wait_for,zx::durationtimeout,const fbl::String &timeout_message,zx::durationgranularity)
Defined at line 68 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<uint16_t> TranslateUfsLunToScsiLun (uint8_t ufs_lun)
Defined at line 112 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<uint8_t> TranslateScsiLunToUfsLun (uint16_t scsi_lun)
Defined at line 126 of file ../../src/devices/block/drivers/ufs/ufs.cc
bool SuspendEnabled ()
Defined at line 202 of file ../../src/devices/block/drivers/ufs/ufs.h
std::optional<fidl::ServerEnd<fuchsia_power_broker::ElementRunner>> take_power_element_runner ()
Defined at line 205 of file ../../src/devices/block/drivers/ufs/ufs.h
fidl::WireSyncClient<fuchsia_driver_framework::Node> & root_node ()
scsi::Controller
Defined at line 210 of file ../../src/devices/block/drivers/ufs/ufs.h
std::string_view driver_name ()
Defined at line 211 of file ../../src/devices/block/drivers/ufs/ufs.h
const std::shared_ptr<fdf::Namespace> & driver_incoming ()
Defined at line 212 of file ../../src/devices/block/drivers/ufs/ufs.h
std::shared_ptr<fdf::OutgoingDirectory> & driver_outgoing ()
Defined at line 213 of file ../../src/devices/block/drivers/ufs/ufs.h
async_dispatcher_t * driver_async_dispatcher ()
Defined at line 214 of file ../../src/devices/block/drivers/ufs/ufs.h
const std::optional<std::string> & driver_node_name ()
Defined at line 215 of file ../../src/devices/block/drivers/ufs/ufs.h
fdf::Logger & driver_logger ()
Defined at line 216 of file ../../src/devices/block/drivers/ufs/ufs.h
const ufs_config::Config & config ()
Defined at line 217 of file ../../src/devices/block/drivers/ufs/ufs.h
bool SupportsInlineEncryption ()
Defined at line 223 of file ../../src/devices/block/drivers/ufs/ufs.h
const fdf::MmioBuffer & GetMmio ()
Defined at line 228 of file ../../src/devices/block/drivers/ufs/ufs.h
DeviceManager & GetDeviceManager ()
Defined at line 233 of file ../../src/devices/block/drivers/ufs/ufs.h
TransferRequestProcessor & GetTransferRequestProcessor ()
Defined at line 237 of file ../../src/devices/block/drivers/ufs/ufs.h
TaskManagementRequestProcessor & GetTaskManagementRequestProcessor ()
Defined at line 241 of file ../../src/devices/block/drivers/ufs/ufs.h
void SetHostControllerCallback (HostControllerCallback callback)
Used to register a platform-specific NotifyEventCallback, which handles variants and quirks for
each host interface platform.
Defined at line 257 of file ../../src/devices/block/drivers/ufs/ufs.h
fdf::Dispatcher & exception_event_dispatcher ()
Defined at line 273 of file ../../src/devices/block/drivers/ufs/ufs.h
fdf::UnownedDispatcher io_worker_dispatcher ()
Defined at line 275 of file ../../src/devices/block/drivers/ufs/ufs.h
fdf::UnownedDispatcher admin_worker_dispatcher ()
Defined at line 276 of file ../../src/devices/block/drivers/ufs/ufs.h
uint32_t GetLogicalUnitCount ()
for test
Defined at line 281 of file ../../src/devices/block/drivers/ufs/ufs.h
size_t GetPendingCommandsCount ()
Defined at line 282 of file ../../src/devices/block/drivers/ufs/ufs.h
bool HasWellKnownLun (WellKnownLuns lun)
Defined at line 289 of file ../../src/devices/block/drivers/ufs/ufs.h
bool intel_quirk ()
Host-controller quirks detected from the PCI vendor/device ID (see UfsPci::InitQuirk()).
Intel (Lakefield) UFSHCI: uses a 19.2 MHz reference clock instead of 38.4 MHz, needs the
peer's PA_TActivate raised by 200 us, and needs a 1250 us settle followed by a DME_PEER_GET to
clear a spurious DME error after a UIC power mode change.
Defined at line 298 of file ../../src/devices/block/drivers/ufs/ufs.h
bool qemu_quirk ()
QEMU's UFS host controller model does not implement UniPro attributes, UIC power mode
changes or Auto-Hibernate, so those steps are skipped and the link is assumed Active.
Defined at line 301 of file ../../src/devices/block/drivers/ufs/ufs.h
bool SupportsPowerDownSuspend ()
Defined at line 303 of file ../../src/devices/block/drivers/ufs/ufs.h
bool IsHardwarePoweredOff ()
Defined at line 326 of file ../../src/devices/block/drivers/ufs/ufs.h
std::mutex & uic_lock ()
Serialises register accesses that happen outside the I/O worker / ISR paths (UIC commands,
whether issued by this driver, by the PHY driver through fuchsia.hardware.ufs.phy/Ufshci, or
through fuchsia.hardware.ufs, and inline-crypto key-slot programming) against
StopHostControllerForPowerDown(). Must be acquired after DeviceManager::power_lock_ when both
are held, and must never be held across a Notify() callback into the PHY driver (its
Ufshci::DmeSet/DmeGet calls take this lock).
Defined at line 344 of file ../../src/devices/block/drivers/ufs/ufs.h
bool IsResumed ()
Defined at line 348 of file ../../src/devices/block/drivers/ufs/ufs.h
const inspect::Inspector & inspect ()
Defined at line 350 of file ../../src/devices/block/drivers/ufs/ufs.h
void Ufs ()
Defined at line 713 of file ../../src/devices/block/drivers/ufs/ufs.cc
void ~Ufs ()
Defined at line 1950 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<> Start (fdf::DriverContext context)
Defined at line 1640 of file ../../src/devices/block/drivers/ufs/ufs.cc
void Stop (fdf::StopCompleter completer)
Defined at line 1889 of file ../../src/devices/block/drivers/ufs/ufs.cc
void Suspend (fdf_power::SuspendCompleter completer)
fdf_power::Suspendable. Suspend()/Resume() are driven by Power Broker through the
framework-provided ElementRunner (level "off" -> Suspend, "on" -> Resume). The mixin
acknowledges the first "off" before any "on" on its own (first_activation_occurred_), so the
hardware initialized by Init() is not powered down just because the element is created without
a lease; Power Broker raises us to "on" as soon as the Execution State dependency is
registered.
Defined at line 1572 of file ../../src/devices/block/drivers/ufs/ufs.cc
void Resume (fdf_power::ResumeCompleter completer)
Power Broker treats a closed ElementRunner channel as "this element can never transition
again": it logs the error and stops driving the element, so storage would stay unusable until
reboot. A failed transition is therefore never answered by dropping the completer.
A failed "off" is logged and acknowledged: SuspendPower() has already rolled the device back or
recorded PowerDown, and the element genuinely no longer needs its dependencies. A failed "on" is
different: the completer is the signal that the level was reached, and Execution State depends
on it (ConfigurePowerManagement()), so acknowledging it early would let the rest of the system
come up and then stall on page faults against a device that is still down. Instead the completer
is held (pending_resume_completer_) while the driver keeps retrying ResumePower() in the
background (RetryResume()); Power Broker's watchdog reports the stuck element every 10 s, which
points at the real culprit. Power Broker does not send another SetLevel() while one is pending,
so the retry loop is the only path back to "on". DeviceManager keeps the truthful hardware state,
so every retry continues from where the failed attempt left off (see the comments in
SuspendPower()/ResumePower()).
The very first "off" that Power Broker issues when the element is created without a lease is
swallowed by fdf_power::Suspendable (first_activation_occurred_) and never reaches Suspend(), so
the hardware initialized by Init() stays active until the first "on" has been observed.
Defined at line 1542 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx_status_t ExecuteCommandSync (uint8_ttarget,uint16_tlun,ioveccdb,boolis_write,iovecdata)
Defined at line 575 of file ../../src/devices/block/drivers/ufs/ufs.cc
void ExecuteCommandsAsync (uint8_ttarget,uint16_tlun,std::span<scsi::ScsiRequest>batch)
Defined at line 528 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<uint8_t> ProgramKeySlot (fidl::VectorView<uint8_t> wrapped_key, uint32_t data_unit_size)
Defined at line 1713 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<std::vector<uint8_t>> DeriveRawSecret (fidl::VectorView<uint8_t> wrapped_key)
Defined at line 1814 of file ../../src/devices/block/drivers/ufs/ufs.cc
void ProcessAdminCompletions ()
Find the completed Admin commands in the Request List and handle their completion.
Defined at line 290 of file ../../src/devices/block/drivers/ufs/ufs.cc
void ProcessIoCompletions ()
Find the completed IO commands in the Request List and handle their completion.
Defined at line 294 of file ../../src/devices/block/drivers/ufs/ufs.cc
void ProcessErrors ()
Recover errors in the request list.
Defined at line 296 of file ../../src/devices/block/drivers/ufs/ufs.cc
void DumpRegisters ()
Defined at line 1393 of file ../../src/devices/block/drivers/ufs/ufs.cc
bool HasProgrammedCryptoKeys ()
Returns true if any inline encryption key slot has been programmed. Key slot state (UFSHCI
CRYPTOCFG and, on platforms where the key table lives inside the host controller power domain,
the key material itself) does not survive a PowerDown suspend.
Defined at line 1775 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<> ReinitAfterPowerDown ()
Host-controller side of the power sequence, driven by DeviceManager::SuspendPower() /
ResumePower() (the device/link side lives in DeviceManager).
Defined at line 1119 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<> ClearUnitAttentions ()
After the device has been power-cycled (PowerDown suspend), every LU and well-known LU
reports a UNIT ATTENTION (POWER ON / RESET) on its first SCSI command. Clear them with
TEST UNIT READY so that the START STOP UNIT issued by ResumePower() and the first I/O to each
LU do not fail with ZX_ERR_UNAVAILABLE.
Defined at line 1217 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<> ConfigureAutoHibernate ()
Defined at line 1084 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<> DisableAutoHibernate ()
Defined at line 1107 of file ../../src/devices/block/drivers/ufs/ufs.cc
void SetHardwarePoweredOff (bool powered_off)
Marks the UFSHCI register space as inaccessible (power domains/clocks gated). While set, the
interrupt handler and I/O paths must not touch controller registers. Setting it also waits for
any in-progress interrupt handling to finish.
Defined at line 476 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx_status_t StopHostControllerForPowerDown ()
Masks interrupts, disables the host controller and marks the register space as powered off,
ahead of the PHY driver gating the UFSHCI power domains/clocks. Requires that no I/O slot is
allocated (RequestProcessor::BlockSlotAllocation() has run). Holds uic_lock() so that a UIC
command or key-slot write that has already passed its IsHardwarePoweredOff() check finishes
before the controller is stopped. Returns the status of the host controller disable; the
register space is marked powered off regardless.
Defined at line 504 of file ../../src/devices/block/drivers/ufs/ufs.cc
void TriggerIoWork ()
Defined at line 433 of file ../../src/devices/block/drivers/ufs/ufs.cc
Protected Methods
zx::result<fdf::MmioBuffer> CreateMmioBuffer (zx_off_toffset,size_tsize,zx::vmovmo)
Defined at line 357 of file ../../src/devices/block/drivers/ufs/ufs.h
zx_status_t Init ()
Initialize the UFS controller and bind the logical units.
Declare this as virtual to delay driver initialization in tests.
Defined at line 715 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<> ConfigureCryptoSlot (uint8_t slot, uint32_t data_unit_size)
Writes the UFSHCI CRYPTOCFG entry for |slot| and records the slot as programmed with
|data_unit_size|. Called by ProgramKeySlot() after the inline encryption provider has loaded
the key material into the hardware slot. Fails with ZX_ERR_BAD_STATE while the host
controller is powered down, in which case the slot is not recorded.
Defined at line 1745 of file ../../src/devices/block/drivers/ufs/ufs.cc
void OnDispatcherShutdown ()
Defined at line 1829 of file ../../src/devices/block/drivers/ufs/ufs.cc
void FinishStop (fdf::StopCompleter completer)
Defined at line 1844 of file ../../src/devices/block/drivers/ufs/ufs.cc
void RetryResume (async_dispatcher_t *dispatcher,async::TaskBase *task,zx_status_tstatus)
Runs on the default dispatcher, like Suspend()/Resume(), so they never overlap: Suspend() cancels
a pending retry and clears power_level_on_required_.
Defined at line 1617 of file ../../src/devices/block/drivers/ufs/ufs.cc
void ScheduleResumeRetry ()
Defined at line 1601 of file ../../src/devices/block/drivers/ufs/ufs.cc
void CompletePendingResume ()
Defined at line 1608 of file ../../src/devices/block/drivers/ufs/ufs.cc
Friends
class RequestProcessor
class UfsTest