mmc_disk: read using "simple DMA"

The SDHCI spec also offers an "advanced DMA" mode where we can use
scatter-gather lists. It would allow to remove several of the DMA
restrictions, but hardware support for it is optional, so we need this
version anyway.

The geometry is retrieved on demand in the first read or write or in a
call to the get geometry or get device size ioctl. It is not possible to
retrieve it from the device initialization because that is called as
part of the mmc_bus scanning, which needs a specific sequence of
commands and keeps the bus locked to prevent drivers to insert their own
commands in the middle of that sequence.

TODO:
- Move the DMA restrictions definition to sdhci_pci and forward it up to
  mmc_disk (which is the one creating the IOScheduler)
- Decide if we want to keep non-DMA support (probably should, but it
  makes things more complex, because it uses virtual addresses)

Change-Id: Ib1dd14eacf62052d747bfb3ef7820bc5a34d3030
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3471
Reviewed-by: Alex von Gluck IV <[email protected]>
This commit is contained in:
Adrien Destugues
2021-01-05 02:06:44 +00:00
committed by waddlesplash
parent cc2642c124
commit 7a160a8629
9 changed files with 306 additions and 128 deletions
+6 -4
View File
@@ -15,6 +15,9 @@
#define MMC_BUS_MODULE_NAME "bus_managers/mmc/driver_v1"
struct IOOperation;
enum {
CARD_TYPE_MMC,
CARD_TYPE_SD,
@@ -64,8 +67,7 @@ typedef struct mmc_bus_interface {
status_t (*set_clock)(void* controller, uint32_t kilohertz);
status_t (*execute_command)(void* controller, uint8_t command,
uint32_t argument, uint32_t* result);
status_t (*read_naive)(void* controller, off_t pos,
void* buffer, size_t* _length);
status_t (*do_io)(void* controller, IOOperation* operation);
} mmc_bus_interface;
@@ -74,8 +76,8 @@ typedef struct mmc_device_interface {
driver_module_info info;
status_t (*execute_command)(device_node* node, uint8_t command,
uint32_t argument, uint32_t* result);
status_t (*read_naive)(device_node* controller, uint16_t rca, off_t pos,
void* buffer, size_t* _length);
status_t (*do_io)(device_node* controller, uint16_t rca,
IOOperation* operation);
} mmc_device_interface;