fix: READ_CAPACITY command for 12 bytes CDB SCSI device.
[lunaix-os.git] / lunaix-os / includes / hal / ahci / hba.h
1 #ifndef __LUNAIX_HBA_H
2 #define __LUNAIX_HBA_H
3
4 #include <stdint.h>
5
6 #define HBA_RCAP 0
7 #define HBA_RGHC 1
8 #define HBA_RIS 2
9 #define HBA_RPI 3
10 #define HBA_RVER 4
11
12 #define HBA_RPBASE (0x40)
13 #define HBA_RPSIZE (0x80 >> 2)
14 #define HBA_RPxCLB 0
15 #define HBA_RPxFB 2
16 #define HBA_RPxIS 4
17 #define HBA_RPxIE 5
18 #define HBA_RPxCMD 6
19 #define HBA_RPxTFD 8
20 #define HBA_RPxSIG 9
21 #define HBA_RPxSSTS 10
22 #define HBA_RPxSCTL 11
23 #define HBA_RPxSERR 12
24 #define HBA_RPxSACT 13
25 #define HBA_RPxCI 14
26 #define HBA_RPxSNTF 15
27 #define HBA_RPxFBS 16
28
29 #define HBA_PxCMD_FRE (1 << 4)
30 #define HBA_PxCMD_CR (1 << 15)
31 #define HBA_PxCMD_FR (1 << 14)
32 #define HBA_PxCMD_ST (1)
33 #define HBA_PxINTR_DMA (1 << 2)
34 #define HBA_PxINTR_DHR (1)
35 #define HBA_PxINTR_DPS (1 << 5)
36 #define HBA_PxINTR_TFEE (1 << 30)
37 #define HBA_PxINTR_IFE (1 << 27)
38 #define HBA_PxTFD_ERR (1)
39 #define HBA_PxTFD_BSY (1 << 7)
40 #define HBA_PxTFD_DRQ (1 << 3)
41
42 #define HBA_RGHC_ACHI_ENABLE (1 << 31)
43 #define HBA_RGHC_INTR_ENABLE (1 << 1)
44 #define HBA_RGHC_RESET 1
45
46 #define HBA_RPxSSTS_PWR(x) (((x) >> 8) & 0xf)
47 #define HBA_RPxSSTS_IF(x) (((x) >> 4) & 0xf)
48 #define HBA_RPxSSTS_PHYSTATE(x) ((x)&0xf)
49
50 #define HBA_DEV_SIG_ATAPI 0xeb140101
51 #define HBA_DEV_SIG_ATA 0x00000101
52
53 #define __HBA_PACKED__ __attribute__((packed))
54
55 typedef unsigned int hba_reg_t;
56
57 #define HBA_CMDH_FIS_LEN(fis_bytes) (((fis_bytes) / 4) & 0x1f)
58 #define HBA_CMDH_ATAPI (1 << 5)
59 #define HBA_CMDH_WRITE (1 << 6)
60 #define HBA_CMDH_PREFETCH (1 << 7)
61 #define HBA_CMDH_R (1 << 8)
62 #define HBA_CMDH_CLR_BUSY (1 << 10)
63 #define HBA_CMDH_PRDT_LEN(entries) (((entries)&0xffff) << 16)
64
65 struct hba_cmdh
66 {
67     uint16_t options;
68     uint16_t prdt_len;
69     uint32_t transferred_size;
70     uint32_t cmd_table_base;
71     uint32_t reserved[5];
72 } __HBA_PACKED__;
73
74 #define HBA_PRDTE_BYTE_CNT(cnt) ((cnt & 0x3FFFFF) | 0x1)
75
76 struct hba_prdte
77 {
78     uint32_t data_base;
79     uint32_t reserved[2];
80     uint32_t byte_count;
81 } __HBA_PACKED__;
82
83 struct hba_cmdt
84 {
85     uint8_t command_fis[64];
86     uint8_t atapi_cmd[16];
87     uint8_t reserved[0x30];
88     struct hba_prdte entries[3];
89 } __HBA_PACKED__;
90
91 #define HBA_DEV_FEXTLBA 1
92 #define HBA_DEV_FATAPI (1 << 1)
93
94 struct hba_port;
95
96 struct hba_device
97 {
98     char serial_num[20];
99     char model[40];
100     uint32_t flags;
101     uint64_t max_lba;
102     uint32_t block_size;
103     uint64_t wwn;
104     uint8_t cbd_size;
105     struct
106     {
107         uint8_t sense_key;
108         uint8_t error;
109         uint8_t status;
110         uint8_t reserve;
111     } last_result;
112     uint32_t alignment_offset;
113     uint32_t block_per_sec;
114     uint32_t capabilities;
115     struct hba_port* port;
116
117     struct
118     {
119         int (*identify)(struct hba_device* dev);
120         int (*read_buffer)(struct hba_device* dev,
121                            uint64_t lba,
122                            void* buffer,
123                            uint32_t size);
124         int (*write_buffer)(struct hba_device* dev,
125                             uint64_t lba,
126                             void* buffer,
127                             uint32_t size);
128     } ops;
129 };
130
131 struct hba_port
132 {
133     volatile hba_reg_t* regs;
134     unsigned int ssts;
135     struct hba_cmdh* cmdlst;
136     void* fis;
137     struct hba_device* device;
138 };
139
140 struct ahci_hba
141 {
142     volatile hba_reg_t* base;
143     unsigned int ports_num;
144     unsigned int ports_bmp;
145     unsigned int cmd_slots;
146     unsigned int version;
147     struct hba_port* ports[32];
148 };
149
150 int
151 hba_prepare_cmd(struct hba_port* port,
152                 struct hba_cmdt** cmdt,
153                 struct hba_cmdh** cmdh,
154                 void* buffer,
155                 unsigned int size);
156
157 #endif /* __LUNAIX_HBA_H */