haiku/headers/private/drivers/mmc.h

88 lines
2.1 KiB
C
Raw Normal View History

/*
* Copyright 2019-2020, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Adrien Destugues, pulkomandy@pulkomandy.tk
*/
#ifndef _MMC_H
#define _MMC_H
#include <device_manager.h>
#define MMC_BUS_MODULE_NAME "bus_managers/mmc/driver_v1"
enum {
CARD_TYPE_MMC,
CARD_TYPE_SD,
CARD_TYPE_SDHC,
CARD_TYPE_UHS1,
CARD_TYPE_UHS2,
CARD_TYPE_SDIO
};
sd/mmc: read, naive method First implementation of reading sectors from an SD card. This is not the best performance for many reasons: - No DMA - Reads only one sector at a time - Cannot read more than 512 bytes per syscall Also there are major limitations: - Cannot read less than 512 bytes. The hardware of course works in full sectors. The mmc_disk driver should go through the io scheduler to make sure requests have a reasonable size and offset, and nothing tries to read just a few bytes in the middle of a sector. - SD cards only (no SDHC, no MMC) Architecture problems: I think too much of the implementation is done in sdhci_pci and should be moved to the upper layers. However it is difficult to say without having implemented DMA (which indeed will be at the low level of the sdhci controller). It doesn't help that the order of operations is a bit different depending on wether there is DMA or not. In DMA mode you first prepare the buffer, then run the command. In non-DMA mode you first send the command, then read the data into the buffer. We need an API at the mmc_bus level that doesn't care about that low-level detail. There are other things that the MMC bus should be doing however, such as switching to different clock speeds depending on which card is activated and how fast it can go. At least the following should be done: - The read method for mmc_bus and sdhci_pci should use a scatter-gather structure as a parameter instead of a single buffer - See if can be integrated into ExecuteCommand at sdhci level (it's essentially a command with an additional data phase) Change-Id: I688b6c694561074535c9c0c2545f06dc04b06e7d Reviewed-on: https://review.haiku-os.org/c/haiku/+/3466 Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
2020-10-14 16:10:01 +03:00
// Commands for SD cards defined in SD Specifications Part 1:
// Physical Layer Simplified Specification Version 8.00
// They are in the common .h file for the mmc stack because the SDHCI driver
// currently needs to map them to the corresponding expected response types.
enum SD_COMMANDS {
// Basic commands, class 0
SD_GO_IDLE_STATE = 0,
SD_ALL_SEND_CID = 2,
SD_SEND_RELATIVE_ADDR = 3,
SD_SELECT_DESELECT_CARD = 7,
SD_SEND_IF_COND = 8,
SD_SEND_CSD = 9,
SD_STOP_TRANSMISSION = 12,
// Block oriented read commands, class 2
SD_READ_SINGLE_BLOCK = 17,
SD_READ_MULTIPLE_BLOCKS = 18,
// Application specific commands, class 8
SD_APP_CMD = 55,
// I/O mode commands, class 9
SD_IO_ABORT = 52,
};
enum SDHCI_APPLICATION_COMMANDS {
SD_SEND_OP_COND = 41,
};
// Interface between mmc_bus and underlying implementation (sdhci_pci or any
// other thing that can execute mmc commands)
typedef struct mmc_bus_interface {
driver_module_info info;
status_t (*set_clock)(void* controller, uint32_t kilohertz);
status_t (*execute_command)(void* controller, uint8_t command,
uint32_t argument, uint32_t* result);
sd/mmc: read, naive method First implementation of reading sectors from an SD card. This is not the best performance for many reasons: - No DMA - Reads only one sector at a time - Cannot read more than 512 bytes per syscall Also there are major limitations: - Cannot read less than 512 bytes. The hardware of course works in full sectors. The mmc_disk driver should go through the io scheduler to make sure requests have a reasonable size and offset, and nothing tries to read just a few bytes in the middle of a sector. - SD cards only (no SDHC, no MMC) Architecture problems: I think too much of the implementation is done in sdhci_pci and should be moved to the upper layers. However it is difficult to say without having implemented DMA (which indeed will be at the low level of the sdhci controller). It doesn't help that the order of operations is a bit different depending on wether there is DMA or not. In DMA mode you first prepare the buffer, then run the command. In non-DMA mode you first send the command, then read the data into the buffer. We need an API at the mmc_bus level that doesn't care about that low-level detail. There are other things that the MMC bus should be doing however, such as switching to different clock speeds depending on which card is activated and how fast it can go. At least the following should be done: - The read method for mmc_bus and sdhci_pci should use a scatter-gather structure as a parameter instead of a single buffer - See if can be integrated into ExecuteCommand at sdhci level (it's essentially a command with an additional data phase) Change-Id: I688b6c694561074535c9c0c2545f06dc04b06e7d Reviewed-on: https://review.haiku-os.org/c/haiku/+/3466 Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
2020-10-14 16:10:01 +03:00
status_t (*read_naive)(void* controller, off_t pos,
void* buffer, size_t* _length);
} mmc_bus_interface;
// Interface between mmc device driver (mmc_disk, sdio drivers, ...) and mmc_bus
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);
sd/mmc: read, naive method First implementation of reading sectors from an SD card. This is not the best performance for many reasons: - No DMA - Reads only one sector at a time - Cannot read more than 512 bytes per syscall Also there are major limitations: - Cannot read less than 512 bytes. The hardware of course works in full sectors. The mmc_disk driver should go through the io scheduler to make sure requests have a reasonable size and offset, and nothing tries to read just a few bytes in the middle of a sector. - SD cards only (no SDHC, no MMC) Architecture problems: I think too much of the implementation is done in sdhci_pci and should be moved to the upper layers. However it is difficult to say without having implemented DMA (which indeed will be at the low level of the sdhci controller). It doesn't help that the order of operations is a bit different depending on wether there is DMA or not. In DMA mode you first prepare the buffer, then run the command. In non-DMA mode you first send the command, then read the data into the buffer. We need an API at the mmc_bus level that doesn't care about that low-level detail. There are other things that the MMC bus should be doing however, such as switching to different clock speeds depending on which card is activated and how fast it can go. At least the following should be done: - The read method for mmc_bus and sdhci_pci should use a scatter-gather structure as a parameter instead of a single buffer - See if can be integrated into ExecuteCommand at sdhci level (it's essentially a command with an additional data phase) Change-Id: I688b6c694561074535c9c0c2545f06dc04b06e7d Reviewed-on: https://review.haiku-os.org/c/haiku/+/3466 Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
2020-10-14 16:10:01 +03:00
status_t (*read_naive)(device_node* controller, uint16_t rca, off_t pos,
void* buffer, size_t* _length);
} mmc_device_interface;
// Device attribute paths for the MMC device
static const char* kMmcRcaAttribute = "mmc/rca";
static const char* kMmcTypeAttribute = "mmc/type";
#endif /* _MMC_H */