1 /*
2  * Copyright (c) 2006-2020, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2020-08-19     lizhirui     porting to ls2k
9  */
10 
11 #include <rtthread.h>
12 #include <ata_interface.h>
13 #include <libata.h>
14 
ata_id_n_sectors(u16 * id)15 u64 ata_id_n_sectors(u16 *id)
16 {
17     if (ata_id_has_lba(id)) {
18         if (ata_id_has_lba48(id))
19             return ata_id_u64(id, ATA_ID_LBA48_SECTORS);
20         else
21             return ata_id_u32(id, ATA_ID_LBA_SECTORS);
22     } else {
23         return 0;
24     }
25 }
26 
ata_dev_classify(u32 sig)27 u32 ata_dev_classify(u32 sig)
28 {
29     u8 lbam, lbah;
30 
31     lbam = (sig >> 16) & 0xff;
32     lbah = (sig >> 24) & 0xff;
33 
34     if (((lbam == 0) && (lbah == 0)) ||
35         ((lbam == 0x3c) && (lbah == 0xc3)))
36         return ATA_DEV_ATA;
37 
38     if ((lbam == 0x14) && (lbah == 0xeb))
39         return ATA_DEV_ATAPI;
40 
41     if ((lbam == 0x69) && (lbah == 0x96))
42         return ATA_DEV_PMP;
43 
44     return ATA_DEV_UNKNOWN;
45 }
46 
ata_id_string(const u16 * id,unsigned char * s,unsigned int ofs,unsigned int len)47 static void ata_id_string(const u16 *id, unsigned char *s,
48              unsigned int ofs, unsigned int len)
49 {
50     unsigned int c;
51 
52     while (len > 0) {
53         c = id[ofs] >> 8;
54         *s = c;
55         s++;
56 
57         c = id[ofs] & 0xff;
58         *s = c;
59         s++;
60 
61         ofs++;
62         len -= 2;
63     }
64 }
65 
ata_id_c_string(const u16 * id,unsigned char * s,unsigned int ofs,unsigned int len)66 void ata_id_c_string(const u16 *id, unsigned char *s,
67              unsigned int ofs, unsigned int len)
68 {
69     unsigned char *p;
70 
71     ata_id_string(id, s, ofs, len - 1);
72 
73     p = s + strnlen((char *)s, len - 1);
74     while (p > s && p[-1] == ' ')
75         p--;
76     *p = '\0';
77 }
78 
ata_dump_id(u16 * id)79 void ata_dump_id(u16 *id)
80 {
81     unsigned char serial[ATA_ID_SERNO_LEN + 1];
82     unsigned char firmware[ATA_ID_FW_REV_LEN + 1];
83     unsigned char product[ATA_ID_PROD_LEN + 1];
84     u64 n_sectors;
85 
86     /* Serial number */
87     ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
88     printf("S/N: %s\n\r", serial);
89 
90     /* Firmware version */
91     ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
92     printf("Firmware version: %s\n\r", firmware);
93 
94     /* Product model */
95     ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
96     printf("Product model number: %s\n\r", product);
97 
98     /* Total sectors of device  */
99     n_sectors = ata_id_n_sectors(id);
100     printf("Capablity: %lld sectors\n\r", n_sectors);
101 
102     printf ("id[49]: capabilities = 0x%04x\n"
103         "id[53]: field valid = 0x%04x\n"
104         "id[63]: mwdma = 0x%04x\n"
105         "id[64]: pio = 0x%04x\n"
106         "id[75]: queue depth = 0x%04x\n",
107         id[49],
108         id[53],
109         id[63],
110         id[64],
111         id[75]);
112 
113     printf ("id[76]: sata capablity = 0x%04x\n"
114         "id[78]: sata features supported = 0x%04x\n"
115         "id[79]: sata features enable = 0x%04x\n",
116         id[76],
117         id[78],
118         id[79]);
119 
120     printf ("id[80]: major version = 0x%04x\n"
121         "id[81]: minor version = 0x%04x\n"
122         "id[82]: command set supported 1 = 0x%04x\n"
123         "id[83]: command set supported 2 = 0x%04x\n"
124         "id[84]: command set extension = 0x%04x\n",
125         id[80],
126         id[81],
127         id[82],
128         id[83],
129         id[84]);
130     printf ("id[85]: command set enable 1 = 0x%04x\n"
131         "id[86]: command set enable 2 = 0x%04x\n"
132         "id[87]: command set default = 0x%04x\n"
133         "id[88]: udma = 0x%04x\n"
134         "id[93]: hardware reset result = 0x%04x\n",
135         id[85],
136         id[86],
137         id[87],
138         id[88],
139         id[93]);
140 }
141 
ata_swap_buf_le16(u16 * buf,unsigned int buf_words)142 void ata_swap_buf_le16(u16 *buf, unsigned int buf_words)
143 {
144     unsigned int i;
145 
146     for (i = 0; i < buf_words; i++)
147     {
148         buf[i] = le16_to_cpu(buf[i]);
149     }
150 }
151