Overview of Universal Flash Storage Subsystem
- Mohammad Faiz Abbas Rizvi, Texas Instruments India PVT LTD [Open Source Summit EU 2019]

UFS is the new standard for managed flash, replacing eMMC.

Mohammad has worked on mainlining the UFS driver for TI SoCs to U-Boot.

Flash needs some control to manage bad blocks, ECC and wear levelling. A managed flash contains a controller that takes care of this. This controller communicates with the host over a defined communication protocol: MMC, SATA (SPI, HyperFlash for unmanaged flash).

UFS is a high-performance serial interface that is also low-power. It is a replacement both for eMMC and for SD cards, i.e. it also supports removable storage. It has full duplex capability. It can reach speeds up to 1.45 GByte/s (theoretical), which is a 3.5x speed-up compared to eMMC 5.1. Same for random read speed. It is differential, with a much lower voltage, which gives power savings. It also supports much bigger sizes (>100TB).

The application layer is SCSI. Transactions consist of a fixed length Command Descriptor Block (CBD). It has an opcode, an initiator, a target and Logical Unit, and a query. Important commands are READ, WRITE, READ CAPACITY, REPORT LUNS, TEST UNIT READY, START STOP UNIT (manage power modes), INQUIRY (get info about a LUN, e.g. vendor ID etc.).

The device has Logical Units. Each one has a capacity, write protection, boot flag, memory type, priority, RPMB. The boot LU is one that can be served very fast at boot time, without much setup. Memory type “system code” is used for memory that is not written very often, which allows the controller to optimise it for reading. Memory type “non-persistent” tells the controller that it will not be read after powercycle, which also allows optimisation. Priority tells the controller which requests need to be served faster in case of conflict. RPMB is used for secure boot. Maximum 32 LUs per device. 4 Well-Known LUNS for specific functions, combined with specific commands. E.g. REPORT LUNS command targets the REPORT LUNS W-LUN.

When starting up, the host starts with REPORT LUNS and READ CAPACITY commands to discover the layout of the device. Then each LUN appears as a /dev/sdX device.

The physical layer is defined by MIPI-PHY and MIPI-Unipro standards. There are 4 signals: reset, reference clock, and pairs of input and output signals. There can be up to 2 input and output lanes.

UFS defines a number of power modes.

  • Active. Can have up to 16 levels of power consumption / performance points. This can be used to e.g. lower the power consumption while on battery.
  • Idle. Is automatically entered when no requests are on-going.
  • Sleep. Explicitly entered from software. No commands can be sent. Some of the power supplies to the device can be removed.
  • Power down. Non-persistent storage is lost.

These modes match very well with the Linux power ops: runtime suspend for sleep, and suspend for power down. Power modes are set with the START STOP UNIT command.

The UFS transport layer sits between the SCSI commands and the MIPI-Unipro bus. Transactions consist of UFS Protool Information Units. Different types for SCSI commans, data. Adds header and CRC. The header corresponds to a lot of features in the transport layer.

  • NOP OUT and NOP IN UPIUs are used for debugging, to test physical connection to the device.
  • Command and Response is for passing SCSI commands.
  • Data Out and Data In for data transfer.
  • Task Management Request and Response is for managing outstanding request.
  • Response is used to signal end of data transfer.
  • Ready to Transfer is used for flow control.

In the kernel, this is managed in a utp_transfer_req_desc that contains command and response UPIU buffers and if needed a pointer to the data buffer. The device can have up to 32 such requests queued. A task tag is used to manage them. The task management UPIU is used to abort them or query their status. Because of these limits, the host controller driver always pre-allocates 32 descriptors.

The source can be found under drivers/scsi/ufs. Device tree bindings for the host controller are very simple because it’s very standardized. You just need to set up a base address, clocks and interrupts.

ufs-utils tool exist from Western Digital that allows to look at desriptors. These are exposed through ioctls in /dev/bsg/ufs-bsg. But even that tool just gives the binary dump of the descriptor data.

Mohammad’s U-Boot implementation of UFS got merged last week. It doesn’t contain commands to access descriptors, flags, attributes.

A question was if S.M.A.R.T. data is available. Mohammad didn’t know.