class Ufs
Defined at line 174 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_
Public Methods
void ProcessIoSubmissions ()
Convert block operations to UPIU commands and submit them asynchronously.
Defined at line 128 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 60 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 67 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<uint16_t> TranslateUfsLunToScsiLun (uint8_t ufs_lun)
Defined at line 97 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<uint8_t> TranslateScsiLunToUfsLun (uint16_t scsi_lun)
Defined at line 111 of file ../../src/devices/block/drivers/ufs/ufs.cc
bool SuspendEnabled ()
Defined at line 197 of file ../../src/devices/block/drivers/ufs/ufs.h
std::optional<fidl::ServerEnd<fuchsia_power_broker::ElementRunner>> take_power_element_runner ()
Defined at line 200 of file ../../src/devices/block/drivers/ufs/ufs.h
fidl::WireSyncClient<fuchsia_driver_framework::Node> & root_node ()
scsi::Controller
Defined at line 205 of file ../../src/devices/block/drivers/ufs/ufs.h
std::string_view driver_name ()
Defined at line 206 of file ../../src/devices/block/drivers/ufs/ufs.h
const std::shared_ptr<fdf::Namespace> & driver_incoming ()
Defined at line 207 of file ../../src/devices/block/drivers/ufs/ufs.h
std::shared_ptr<fdf::OutgoingDirectory> & driver_outgoing ()
Defined at line 208 of file ../../src/devices/block/drivers/ufs/ufs.h
async_dispatcher_t * driver_async_dispatcher ()
Defined at line 209 of file ../../src/devices/block/drivers/ufs/ufs.h
const std::optional<std::string> & driver_node_name ()
Defined at line 210 of file ../../src/devices/block/drivers/ufs/ufs.h
fdf::Logger & driver_logger ()
Defined at line 211 of file ../../src/devices/block/drivers/ufs/ufs.h
const ufs_config::Config & config ()
Defined at line 212 of file ../../src/devices/block/drivers/ufs/ufs.h
bool SupportsInlineEncryption ()
Defined at line 218 of file ../../src/devices/block/drivers/ufs/ufs.h
const fdf::MmioBuffer & GetMmio ()
Defined at line 223 of file ../../src/devices/block/drivers/ufs/ufs.h
DeviceManager & GetDeviceManager ()
Defined at line 228 of file ../../src/devices/block/drivers/ufs/ufs.h
TransferRequestProcessor & GetTransferRequestProcessor ()
Defined at line 232 of file ../../src/devices/block/drivers/ufs/ufs.h
TaskManagementRequestProcessor & GetTaskManagementRequestProcessor ()
Defined at line 236 of file ../../src/devices/block/drivers/ufs/ufs.h
fdf::Dispatcher & exception_event_dispatcher ()
Defined at line 268 of file ../../src/devices/block/drivers/ufs/ufs.h
fdf::UnownedDispatcher io_worker_dispatcher ()
Defined at line 270 of file ../../src/devices/block/drivers/ufs/ufs.h
fdf::UnownedDispatcher admin_worker_dispatcher ()
Defined at line 271 of file ../../src/devices/block/drivers/ufs/ufs.h
uint32_t GetLogicalUnitCount ()
for test
Defined at line 276 of file ../../src/devices/block/drivers/ufs/ufs.h
size_t GetPendingCommandsCount ()
Defined at line 277 of file ../../src/devices/block/drivers/ufs/ufs.h
bool HasWellKnownLun (WellKnownLuns lun)
Defined at line 284 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 293 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 296 of file ../../src/devices/block/drivers/ufs/ufs.h
bool SupportsPowerDownSuspend ()
Defined at line 298 of file ../../src/devices/block/drivers/ufs/ufs.h
bool IsHardwarePoweredOff ()
Defined at line 316 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 334 of file ../../src/devices/block/drivers/ufs/ufs.h
bool IsResumed ()
Defined at line 338 of file ../../src/devices/block/drivers/ufs/ufs.h
const inspect::Inspector & inspect ()
Defined at line 340 of file ../../src/devices/block/drivers/ufs/ufs.h
void Ufs ()
Defined at line 683 of file ../../src/devices/block/drivers/ufs/ufs.cc
void ~Ufs ()
Defined at line 1865 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<> Start (fdf::DriverContext context)
Defined at line 1603 of file ../../src/devices/block/drivers/ufs/ufs.cc
void Stop (fdf::StopCompleter completer)
Defined at line 1804 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 1535 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 1505 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx_status_t ExecuteCommandSync (uint8_ttarget,uint16_tlun,ioveccdb,boolis_write,iovecdata)
Defined at line 545 of file ../../src/devices/block/drivers/ufs/ufs.cc
void ExecuteCommandsAsync (uint8_ttarget,uint16_tlun,std::span<scsi::ScsiRequest>batch)
Defined at line 498 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 1676 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 1729 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 260 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 264 of file ../../src/devices/block/drivers/ufs/ufs.cc
void ProcessErrors ()
Recover errors in the request list.
Defined at line 266 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 37 of file ../../src/devices/block/drivers/ufs/ufs.cc
void SetHostControllerCallback (HostControllerCallback callback)
Used to register a platform-specific NotifyEventCallback, which handles variants and quirks for
each host interface platform.
Defined at line 252 of file ../../src/devices/block/drivers/ufs/ufs.h
void DumpRegisters ()
Defined at line 1356 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 1089 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 1180 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<> ConfigureAutoHibernate ()
Defined at line 1054 of file ../../src/devices/block/drivers/ufs/ufs.cc
zx::result<> DisableAutoHibernate ()
Defined at line 1077 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 446 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 474 of file ../../src/devices/block/drivers/ufs/ufs.cc
void TriggerIoWork ()
Defined at line 403 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 347 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 685 of file ../../src/devices/block/drivers/ufs/ufs.cc
void OnDispatcherShutdown ()
Defined at line 1744 of file ../../src/devices/block/drivers/ufs/ufs.cc
void FinishStop (fdf::StopCompleter completer)
Defined at line 1759 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 1580 of file ../../src/devices/block/drivers/ufs/ufs.cc
void ScheduleResumeRetry ()
Defined at line 1564 of file ../../src/devices/block/drivers/ufs/ufs.cc
void CompletePendingResume ()
Defined at line 1571 of file ../../src/devices/block/drivers/ufs/ufs.cc
Friends
class RequestProcessor
class UfsTest