kexts: ahci: implement identification of ATAPI devices

This commit is contained in:
2023-07-08 22:15:22 +01:00
parent 8463423c10
commit 2ac75cd541
2 changed files with 216 additions and 108 deletions

View File

@@ -26,9 +26,15 @@
#define HBA_PxCMD_CR 0x8000
#define HBA_PxIS_TFES 0x40000000
#define HBA_PxIS_DPS 0x20u
#define ATA_CMD_READ_DMA_EX 0x25u
#define ATA_CMD_IDENTIFY_DEVICE 0xECu
#define ATA_CMD_PACKET 0xA0u
#define ATA_CMD_IDENTIFY_PACKET_DEVICE 0xA1u
#define SCSI_CMD_READ 0xA8u
#define SCSI_CMD_READ_CAPACITY 0x25u
enum fis_type {
FIS_TYPE_REG_H2D = 0x27u,
@@ -193,10 +199,37 @@ struct hba_prdt_entry {
uint32_t i : 1;
} __packed;
struct scsi_command {
uint8_t cmd;
union {
struct {
uint8_t rsvd[15];
} read_capacity;
struct {
uint8_t rdprotect : 3;
uint8_t dpo : 1;
uint8_t fua : 1;
uint8_t rarc : 1;
uint8_t obsolete : 2;
uint32_t lba;
uint32_t count;
} read;
} __packed;
} __packed;
/* struct scsi_command /must/ be exactly 16 bytes long, so that it fits properly
within struct hba_cmd_table */
_Static_assert(sizeof(struct scsi_command) == 16, "ahci: scsi_command must be 16 bytes");
_Static_assert(sizeof(struct fis_dma_setup) == 28, "ahci: fis_dma_setup must be 28 bytes");
_Static_assert(sizeof(struct fis_pio_setup) == 20, "ahci: fis_pio_set must be 20 bytes");
_Static_assert(sizeof(struct fis_reg_d2h) == 20, "ahci: fis_reg_d2h must be 20 bytes");
struct hba_cmd_table {
uint8_t cfis[64];
uint8_t acmd[16];
struct scsi_command acmd;
uint8_t rsv[48];
@@ -245,28 +278,40 @@ struct hba_config {
struct hba_port ports[32];
} __packed;
struct ata_identify_device_data {
uint16_t g_config;
uint8_t rsv0[2];
uint16_t s_config;
uint8_t rsv1[14];
uint8_t serial_number[20];
uint8_t rsv2[6];
uint32_t firmware;
char model[40];
} __packed;
struct identify_device_data {
struct {
uint16_t reserved_1 : 1;
uint16_t retired_3 : 1;
uint16_t response_incomplete : 1;
uint16_t retired_2 : 3;
uint16_t fixed_device : 1;
uint16_t removable_media : 1;
uint16_t retired_1 : 7;
uint16_t device_type : 1;
} general_config;
union {
struct {
uint16_t reserved_1 : 1;
uint16_t retired_3 : 1;
uint16_t response_incomplete : 1;
uint16_t retired_2 : 3;
uint16_t fixed_device : 1;
uint16_t removable_media : 1;
uint16_t retired_1 : 7;
uint16_t device_type : 1;
} general_config;
struct {
/*
uint16_t is_atapi : 2;
uint16_t reserved_1: 1;
uint16_t command_set : 5;
uint16_t obsolete_1: 1;
uint16_t packet_drq_time : 2;
uint16_t reserved_2 : 2;
uint16_t identify_incomplete : 1;
uint16_t packet_size : 2;
*/
uint16_t packet_size : 2;
uint16_t identify_incomplete : 1;
uint16_t reserved_2 : 2;
uint16_t packet_drq_time : 2;
uint16_t obsolete_1: 1;
uint16_t command_set : 5;
uint16_t reserved_1: 1;
uint16_t is_atapi : 2;
} atapi_general_config;
};
uint16_t num_cylinders;
uint16_t specific_configuration;
uint16_t num_heads;
@@ -628,4 +673,9 @@ struct identify_device_data {
uint16_t check_sum : 8;
} __packed;
struct scsi_read_capacity_data {
uint32_t last_sector;
uint32_t block_size;
} __packed;
#endif