diff options
Diffstat (limited to 'firmware/target/arm/s5l8702')
-rw-r--r-- | firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c | 585 |
1 files changed, 342 insertions, 243 deletions
diff --git a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c index 7a3be20577..8cc5b44aca 100644 --- a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c +++ b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c | |||
@@ -29,6 +29,9 @@ | |||
29 | #include "mmcdefs-target.h" | 29 | #include "mmcdefs-target.h" |
30 | #include "s5l8702.h" | 30 | #include "s5l8702.h" |
31 | #include "led.h" | 31 | #include "led.h" |
32 | #include "debug.h" | ||
33 | #include "panic.h" | ||
34 | #include "fs_defines.h" | ||
32 | 35 | ||
33 | #ifndef ATA_RETRIES | 36 | #ifndef ATA_RETRIES |
34 | #define ATA_RETRIES 3 | 37 | #define ATA_RETRIES 3 |
@@ -58,10 +61,9 @@ | |||
58 | #define CEATA_DAT_NONBUSY_TIMEOUT 5000000 | 61 | #define CEATA_DAT_NONBUSY_TIMEOUT 5000000 |
59 | #define CEATA_MMC_RCA 1 | 62 | #define CEATA_MMC_RCA 1 |
60 | 63 | ||
61 | |||
62 | /** static, private data **/ | 64 | /** static, private data **/ |
63 | static uint8_t ceata_taskfile[16] STORAGE_ALIGN_ATTR; | 65 | static uint8_t ceata_taskfile[16] STORAGE_ALIGN_ATTR; |
64 | static uint16_t ata_identify_data[0x100] STORAGE_ALIGN_ATTR; | 66 | static uint16_t identify_info[ATA_IDENTIFY_WORDS] STORAGE_ALIGN_ATTR; |
65 | static bool ceata; | 67 | static bool ceata; |
66 | static bool ata_lba48; | 68 | static bool ata_lba48; |
67 | static bool ata_dma; | 69 | static bool ata_dma; |
@@ -70,18 +72,18 @@ static struct mutex ata_mutex; | |||
70 | static struct semaphore ata_wakeup; | 72 | static struct semaphore ata_wakeup; |
71 | static uint32_t ata_dma_flags; | 73 | static uint32_t ata_dma_flags; |
72 | static long ata_last_activity_value = -1; | 74 | static long ata_last_activity_value = -1; |
73 | static long ata_sleep_timeout = 20 * HZ; | 75 | static long ata_sleep_timeout = 7 * HZ; |
74 | static bool ata_powered; | 76 | static bool ata_powered; |
75 | static const int ata_retries = ATA_RETRIES; | 77 | static bool canflush = true; |
76 | static const bool ata_error_srst = true; | ||
77 | static struct semaphore mmc_wakeup; | 78 | static struct semaphore mmc_wakeup; |
78 | static struct semaphore mmc_comp_wakeup; | 79 | static struct semaphore mmc_comp_wakeup; |
79 | static int spinup_time = 0; | 80 | static int spinup_time = 0; |
80 | static int dma_mode = 0; | 81 | static int dma_mode = 0; |
81 | static char aligned_buffer[SECTOR_SIZE] STORAGE_ALIGN_ATTR; | ||
82 | 82 | ||
83 | static int ata_reset(void); | 83 | static const int ata_retries = ATA_RETRIES; |
84 | static const bool ata_error_srst = true; | ||
84 | 85 | ||
86 | static int ata_reset(void); | ||
85 | 87 | ||
86 | static uint16_t ata_read_cbr(uint32_t volatile* reg) | 88 | static uint16_t ata_read_cbr(uint32_t volatile* reg) |
87 | { | 89 | { |
@@ -103,8 +105,10 @@ static int ata_wait_for_not_bsy(long timeout) | |||
103 | while (true) | 105 | while (true) |
104 | { | 106 | { |
105 | uint8_t csd = ata_read_cbr(&ATA_PIO_CSD); | 107 | uint8_t csd = ata_read_cbr(&ATA_PIO_CSD); |
106 | if (!(csd & BIT(7))) return 0; | 108 | if (!(csd & BIT(7))) |
107 | if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(0); | 109 | return 0; |
110 | if (TIMEOUT_EXPIRED(startusec, timeout)) | ||
111 | RET_ERR(0); | ||
108 | yield(); | 112 | yield(); |
109 | } | 113 | } |
110 | } | 114 | } |
@@ -116,8 +120,10 @@ static int ata_wait_for_rdy(long timeout) | |||
116 | while (true) | 120 | while (true) |
117 | { | 121 | { |
118 | uint8_t dad = ata_read_cbr(&ATA_PIO_DAD); | 122 | uint8_t dad = ata_read_cbr(&ATA_PIO_DAD); |
119 | if (dad & BIT(6)) return 0; | 123 | if (dad & BIT(6)) |
120 | if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(1); | 124 | return 0; |
125 | if (TIMEOUT_EXPIRED(startusec, timeout)) | ||
126 | RET_ERR(1); | ||
121 | yield(); | 127 | yield(); |
122 | } | 128 | } |
123 | } | 129 | } |
@@ -129,9 +135,12 @@ static int ata_wait_for_start_of_transfer(long timeout) | |||
129 | while (true) | 135 | while (true) |
130 | { | 136 | { |
131 | uint8_t dad = ata_read_cbr(&ATA_PIO_DAD); | 137 | uint8_t dad = ata_read_cbr(&ATA_PIO_DAD); |
132 | if (dad & BIT(0)) RET_ERR(1); | 138 | if (dad & BIT(0)) |
133 | if ((dad & (BIT(7) | BIT(3))) == BIT(3)) return 0; | 139 | RET_ERR(1); |
134 | if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(2); | 140 | if ((dad & (BIT(7) | BIT(3))) == BIT(3)) |
141 | return 0; | ||
142 | if (TIMEOUT_EXPIRED(startusec, timeout)) | ||
143 | RET_ERR(2); | ||
135 | yield(); | 144 | yield(); |
136 | } | 145 | } |
137 | } | 146 | } |
@@ -140,8 +149,10 @@ static int ata_wait_for_end_of_transfer(long timeout) | |||
140 | { | 149 | { |
141 | PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0); | 150 | PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0); |
142 | uint8_t dad = ata_read_cbr(&ATA_PIO_DAD); | 151 | uint8_t dad = ata_read_cbr(&ATA_PIO_DAD); |
143 | if (dad & BIT(0)) RET_ERR(1); | 152 | if (dad & BIT(0)) |
144 | if ((dad & (BIT(3) | BITRANGE(5, 7))) == BIT(6)) return 0; | 153 | RET_ERR(1); |
154 | if ((dad & (BIT(3) | BITRANGE(5, 7))) == BIT(6)) | ||
155 | return 0; | ||
145 | RET_ERR(2); | 156 | RET_ERR(2); |
146 | } | 157 | } |
147 | 158 | ||
@@ -149,13 +160,17 @@ static int mmc_dsta_check_command_success(bool disable_crc) | |||
149 | { | 160 | { |
150 | int rc = 0; | 161 | int rc = 0; |
151 | uint32_t dsta = SDCI_DSTA; | 162 | uint32_t dsta = SDCI_DSTA; |
152 | if (dsta & SDCI_DSTA_RESTOUTE) rc |= 1; | 163 | if (dsta & SDCI_DSTA_RESTOUTE) |
153 | if (dsta & SDCI_DSTA_RESENDE) rc |= 2; | 164 | rc |= 1; |
154 | if (dsta & SDCI_DSTA_RESINDE) rc |= 4; | 165 | if (dsta & SDCI_DSTA_RESENDE) |
166 | rc |= 2; | ||
167 | if (dsta & SDCI_DSTA_RESINDE) | ||
168 | rc |= 4; | ||
155 | if (!disable_crc) | 169 | if (!disable_crc) |
156 | if (dsta & SDCI_DSTA_RESCRCE) | 170 | if (dsta & SDCI_DSTA_RESCRCE) |
157 | rc |= 8; | 171 | rc |= 8; |
158 | if (rc) RET_ERR(rc); | 172 | if (rc) |
173 | RET_ERR(rc); | ||
159 | return 0; | 174 | return 0; |
160 | } | 175 | } |
161 | 176 | ||
@@ -164,7 +179,8 @@ static bool mmc_send_command(uint32_t cmd, uint32_t arg, uint32_t* result, int t | |||
164 | long starttime = USEC_TIMER; | 179 | long starttime = USEC_TIMER; |
165 | while ((SDCI_STATE & SDCI_STATE_CMD_STATE_MASK) != SDCI_STATE_CMD_STATE_CMD_IDLE) | 180 | while ((SDCI_STATE & SDCI_STATE_CMD_STATE_MASK) != SDCI_STATE_CMD_STATE_CMD_IDLE) |
166 | { | 181 | { |
167 | if (TIMEOUT_EXPIRED(starttime, timeout)) RET_ERR(0); | 182 | if (TIMEOUT_EXPIRED(starttime, timeout)) |
183 | RET_ERR(0); | ||
168 | yield(); | 184 | yield(); |
169 | } | 185 | } |
170 | SDCI_STAC = SDCI_STAC_CLR_CMDEND | SDCI_STAC_CLR_BIT_3 | 186 | SDCI_STAC = SDCI_STAC_CLR_CMDEND | SDCI_STAC_CLR_BIT_3 |
@@ -179,32 +195,38 @@ static bool mmc_send_command(uint32_t cmd, uint32_t arg, uint32_t* result, int t | |||
179 | | SDCI_STAC_CLR_RD_DATENDE6 | SDCI_STAC_CLR_RD_DATENDE7; | 195 | | SDCI_STAC_CLR_RD_DATENDE6 | SDCI_STAC_CLR_RD_DATENDE7; |
180 | SDCI_ARGU = arg; | 196 | SDCI_ARGU = arg; |
181 | SDCI_CMD = cmd; | 197 | SDCI_CMD = cmd; |
182 | if (!(SDCI_DSTA & SDCI_DSTA_CMDRDY)) RET_ERR(1); | 198 | if (!(SDCI_DSTA & SDCI_DSTA_CMDRDY)) |
199 | RET_ERR(1); | ||
183 | SDCI_CMD = cmd | SDCI_CMD_CMDSTR; | 200 | SDCI_CMD = cmd | SDCI_CMD_CMDSTR; |
184 | long sleepbase = USEC_TIMER; | 201 | long sleepbase = USEC_TIMER; |
185 | while (TIMEOUT_EXPIRED(sleepbase, 1000)) yield(); | 202 | while (TIMEOUT_EXPIRED(sleepbase, 1000)) |
203 | yield(); | ||
186 | while (!(SDCI_DSTA & SDCI_DSTA_CMDEND)) | 204 | while (!(SDCI_DSTA & SDCI_DSTA_CMDEND)) |
187 | { | 205 | { |
188 | if (TIMEOUT_EXPIRED(starttime, timeout)) RET_ERR(2); | 206 | if (TIMEOUT_EXPIRED(starttime, timeout)) |
207 | RET_ERR(2); | ||
189 | yield(); | 208 | yield(); |
190 | } | 209 | } |
191 | if ((cmd & SDCI_CMD_RES_TYPE_MASK) != SDCI_CMD_RES_TYPE_NONE) | 210 | if ((cmd & SDCI_CMD_RES_TYPE_MASK) != SDCI_CMD_RES_TYPE_NONE) |
192 | { | 211 | { |
193 | while (!(SDCI_DSTA & SDCI_DSTA_RESEND)) | 212 | while (!(SDCI_DSTA & SDCI_DSTA_RESEND)) |
194 | { | 213 | { |
195 | if (TIMEOUT_EXPIRED(starttime, timeout)) RET_ERR(3); | 214 | if (TIMEOUT_EXPIRED(starttime, timeout)) |
215 | RET_ERR(3); | ||
196 | yield(); | 216 | yield(); |
197 | } | 217 | } |
198 | if (cmd & SDCI_CMD_RES_BUSY) | 218 | if (cmd & SDCI_CMD_RES_BUSY) |
199 | while (SDCI_DSTA & SDCI_DSTA_DAT_BUSY) | 219 | while (SDCI_DSTA & SDCI_DSTA_DAT_BUSY) |
200 | { | 220 | { |
201 | if (TIMEOUT_EXPIRED(starttime, CEATA_DAT_NONBUSY_TIMEOUT)) RET_ERR(4); | 221 | if (TIMEOUT_EXPIRED(starttime, CEATA_DAT_NONBUSY_TIMEOUT)) |
222 | RET_ERR(4); | ||
202 | yield(); | 223 | yield(); |
203 | } | 224 | } |
204 | } | 225 | } |
205 | bool nocrc = (cmd & SDCI_CMD_RES_SIZE_MASK) == SDCI_CMD_RES_SIZE_136; | 226 | bool nocrc = (cmd & SDCI_CMD_RES_SIZE_MASK) == SDCI_CMD_RES_SIZE_136; |
206 | PASS_RC(mmc_dsta_check_command_success(nocrc), 3, 5); | 227 | PASS_RC(mmc_dsta_check_command_success(nocrc), 3, 5); |
207 | if (result) *result = SDCI_RESP0; | 228 | if (result) |
229 | *result = SDCI_RESP0; | ||
208 | return 0; | 230 | return 0; |
209 | } | 231 | } |
210 | 232 | ||
@@ -227,7 +249,8 @@ static int mmc_init(void) | |||
227 | uint32_t result; | 249 | uint32_t result; |
228 | do | 250 | do |
229 | { | 251 | { |
230 | if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT)) RET_ERR(1); | 252 | if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT)) |
253 | RET_ERR(1); | ||
231 | sleep(HZ / 100); | 254 | sleep(HZ / 100); |
232 | PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SEND_OP_COND) | 255 | PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SEND_OP_COND) |
233 | | SDCI_CMD_CMD_TYPE_BCR | SDCI_CMD_RES_TYPE_R3 | 256 | | SDCI_CMD_CMD_TYPE_BCR | SDCI_CMD_RES_TYPE_R3 |
@@ -252,7 +275,8 @@ static int mmc_init(void) | |||
252 | MMC_CMD_SELECT_CARD_RCA(CEATA_MMC_RCA), | 275 | MMC_CMD_SELECT_CARD_RCA(CEATA_MMC_RCA), |
253 | NULL, CEATA_COMMAND_TIMEOUT), 3, 5); | 276 | NULL, CEATA_COMMAND_TIMEOUT), 3, 5); |
254 | PASS_RC(mmc_get_card_status(&result), 3, 6); | 277 | PASS_RC(mmc_get_card_status(&result), 3, 6); |
255 | if ((result & MMC_STATUS_CURRENT_STATE_MASK) != MMC_STATUS_CURRENT_STATE_TRAN) RET_ERR(7); | 278 | if ((result & MMC_STATUS_CURRENT_STATE_MASK) != MMC_STATUS_CURRENT_STATE_TRAN) |
279 | RET_ERR(7); | ||
256 | return 0; | 280 | return 0; |
257 | } | 281 | } |
258 | 282 | ||
@@ -286,7 +310,8 @@ static int ceata_soft_reset(void) | |||
286 | do | 310 | do |
287 | { | 311 | { |
288 | PASS_RC(mmc_fastio_read(0xf, &status), 2, 2); | 312 | PASS_RC(mmc_fastio_read(0xf, &status), 2, 2); |
289 | if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT)) RET_ERR(3); | 313 | if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT)) |
314 | RET_ERR(3); | ||
290 | sleep(HZ / 100); | 315 | sleep(HZ / 100); |
291 | } | 316 | } |
292 | while (status & 0x80); | 317 | while (status & 0x80); |
@@ -299,16 +324,21 @@ static int mmc_dsta_check_data_success(void) | |||
299 | uint32_t dsta = SDCI_DSTA; | 324 | uint32_t dsta = SDCI_DSTA; |
300 | if (dsta & (SDCI_DSTA_WR_DATCRCE | SDCI_DSTA_RD_DATCRCE)) | 325 | if (dsta & (SDCI_DSTA_WR_DATCRCE | SDCI_DSTA_RD_DATCRCE)) |
301 | { | 326 | { |
302 | if (dsta & SDCI_DSTA_WR_DATCRCE) rc |= 1; | 327 | if (dsta & SDCI_DSTA_WR_DATCRCE) |
303 | if (dsta & SDCI_DSTA_RD_DATCRCE) rc |= 2; | 328 | rc |= 1; |
304 | if ((dsta & SDCI_DSTA_WR_CRC_STATUS_MASK) == SDCI_DSTA_WR_CRC_STATUS_TXERR) rc |= 4; | 329 | if (dsta & SDCI_DSTA_RD_DATCRCE) |
305 | else if ((dsta & SDCI_DSTA_WR_CRC_STATUS_MASK) == SDCI_DSTA_WR_CRC_STATUS_CARDERR) rc |= 8; | 330 | rc |= 2; |
331 | if ((dsta & SDCI_DSTA_WR_CRC_STATUS_MASK) == SDCI_DSTA_WR_CRC_STATUS_TXERR) | ||
332 | rc |= 4; | ||
333 | else if ((dsta & SDCI_DSTA_WR_CRC_STATUS_MASK) == SDCI_DSTA_WR_CRC_STATUS_CARDERR) | ||
334 | rc |= 8; | ||
306 | } | 335 | } |
307 | if (dsta & (SDCI_DSTA_RD_DATENDE0 | SDCI_DSTA_RD_DATENDE1 | SDCI_DSTA_RD_DATENDE2 | 336 | if (dsta & (SDCI_DSTA_RD_DATENDE0 | SDCI_DSTA_RD_DATENDE1 | SDCI_DSTA_RD_DATENDE2 |
308 | | SDCI_DSTA_RD_DATENDE3 | SDCI_DSTA_RD_DATENDE4 | SDCI_DSTA_RD_DATENDE5 | 337 | | SDCI_DSTA_RD_DATENDE3 | SDCI_DSTA_RD_DATENDE4 | SDCI_DSTA_RD_DATENDE5 |
309 | | SDCI_DSTA_RD_DATENDE6 | SDCI_DSTA_RD_DATENDE7)) | 338 | | SDCI_DSTA_RD_DATENDE6 | SDCI_DSTA_RD_DATENDE7)) |
310 | rc |= 16; | 339 | rc |= 16; |
311 | if (rc) RET_ERR(rc); | 340 | if (rc) |
341 | RET_ERR(rc); | ||
312 | return 0; | 342 | return 0; |
313 | } | 343 | } |
314 | 344 | ||
@@ -321,7 +351,8 @@ static void mmc_discard_irq(void) | |||
321 | 351 | ||
322 | static int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size) | 352 | static int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size) |
323 | { | 353 | { |
324 | if (size > 0x10) RET_ERR(0); | 354 | if (size > 0x10) |
355 | RET_ERR(0); | ||
325 | mmc_discard_irq(); | 356 | mmc_discard_irq(); |
326 | SDCI_DMASIZE = size; | 357 | SDCI_DMASIZE = size; |
327 | SDCI_DMACOUNT = 1; | 358 | SDCI_DMACOUNT = 1; |
@@ -335,8 +366,8 @@ static int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size | |||
335 | | MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc) | 366 | | MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc) |
336 | | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc), | 367 | | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc), |
337 | NULL, CEATA_COMMAND_TIMEOUT), 2, 1); | 368 | NULL, CEATA_COMMAND_TIMEOUT), 2, 1); |
338 | if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) | 369 | if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) == OBJ_WAIT_TIMEDOUT) |
339 | == OBJ_WAIT_TIMEDOUT) RET_ERR(2); | 370 | RET_ERR(2); |
340 | PASS_RC(mmc_dsta_check_data_success(), 2, 3); | 371 | PASS_RC(mmc_dsta_check_data_success(), 2, 3); |
341 | return 0; | 372 | return 0; |
342 | } | 373 | } |
@@ -344,7 +375,8 @@ static int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size | |||
344 | static int ceata_write_multiple_register(uint32_t addr, void* dest, uint32_t size) | 375 | static int ceata_write_multiple_register(uint32_t addr, void* dest, uint32_t size) |
345 | { | 376 | { |
346 | uint32_t i; | 377 | uint32_t i; |
347 | if (size > 0x10) RET_ERR(0); | 378 | if (size > 0x10) |
379 | RET_ERR(0); | ||
348 | mmc_discard_irq(); | 380 | mmc_discard_irq(); |
349 | SDCI_DMASIZE = size; | 381 | SDCI_DMASIZE = size; |
350 | SDCI_DMACOUNT = 0; | 382 | SDCI_DMACOUNT = 0; |
@@ -358,13 +390,15 @@ static int ceata_write_multiple_register(uint32_t addr, void* dest, uint32_t siz | |||
358 | | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc), | 390 | | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc), |
359 | NULL, CEATA_COMMAND_TIMEOUT), 3, 1); | 391 | NULL, CEATA_COMMAND_TIMEOUT), 3, 1); |
360 | SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX; | 392 | SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX; |
361 | for (i = 0; i < size / 4; i++) SDCI_DATA = ((uint32_t*)dest)[i]; | 393 | for (i = 0; i < size / 4; i++) |
394 | SDCI_DATA = ((uint32_t*)dest)[i]; | ||
362 | long startusec = USEC_TIMER; | 395 | long startusec = USEC_TIMER; |
363 | if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) | 396 | if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) == OBJ_WAIT_TIMEDOUT) |
364 | == OBJ_WAIT_TIMEDOUT) RET_ERR(2); | 397 | RET_ERR(2); |
365 | while ((SDCI_STATE & SDCI_STATE_DAT_STATE_MASK) != SDCI_STATE_DAT_STATE_IDLE) | 398 | while ((SDCI_STATE & SDCI_STATE_DAT_STATE_MASK) != SDCI_STATE_DAT_STATE_IDLE) |
366 | { | 399 | { |
367 | if (TIMEOUT_EXPIRED(startusec, CEATA_COMMAND_TIMEOUT)) RET_ERR(3); | 400 | if (TIMEOUT_EXPIRED(startusec, CEATA_COMMAND_TIMEOUT)) |
401 | RET_ERR(3); | ||
368 | yield(); | 402 | yield(); |
369 | } | 403 | } |
370 | PASS_RC(mmc_dsta_check_data_success(), 3, 4); | 404 | PASS_RC(mmc_dsta_check_data_success(), 3, 4); |
@@ -381,13 +415,17 @@ static int ceata_init(int buswidth) | |||
381 | | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_HS_TIMING) | 415 | | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_HS_TIMING) |
382 | | MMC_CMD_SWITCH_VALUE(MMC_CMD_SWITCH_FIELD_HS_TIMING_HIGH_SPEED), | 416 | | MMC_CMD_SWITCH_VALUE(MMC_CMD_SWITCH_FIELD_HS_TIMING_HIGH_SPEED), |
383 | &result, CEATA_COMMAND_TIMEOUT), 3, 0); | 417 | &result, CEATA_COMMAND_TIMEOUT), 3, 0); |
384 | if (result & MMC_STATUS_SWITCH_ERROR) RET_ERR(1); | 418 | if (result & MMC_STATUS_SWITCH_ERROR) |
419 | RET_ERR(1); | ||
385 | if (buswidth > 1) | 420 | if (buswidth > 1) |
386 | { | 421 | { |
387 | int setting; | 422 | int setting; |
388 | if (buswidth == 4) setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_4BIT; | 423 | if (buswidth == 4) |
389 | else if (buswidth == 8) setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_8BIT; | 424 | setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_4BIT; |
390 | else setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_1BIT; | 425 | else if (buswidth == 8) |
426 | setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_8BIT; | ||
427 | else | ||
428 | setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_1BIT; | ||
391 | PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SWITCH) | SDCI_CMD_RES_BUSY | 429 | PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SWITCH) | SDCI_CMD_RES_BUSY |
392 | | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1 | 430 | | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1 |
393 | | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR, | 431 | | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR, |
@@ -395,7 +433,8 @@ static int ceata_init(int buswidth) | |||
395 | | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_BUS_WIDTH) | 433 | | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_BUS_WIDTH) |
396 | | MMC_CMD_SWITCH_VALUE(setting), | 434 | | MMC_CMD_SWITCH_VALUE(setting), |
397 | &result, CEATA_COMMAND_TIMEOUT), 3, 2); | 435 | &result, CEATA_COMMAND_TIMEOUT), 3, 2); |
398 | if (result & MMC_STATUS_SWITCH_ERROR) RET_ERR(3); | 436 | if (result & MMC_STATUS_SWITCH_ERROR) |
437 | RET_ERR(3); | ||
399 | if (buswidth == 4) | 438 | if (buswidth == 4) |
400 | SDCI_CTRL = (SDCI_CTRL & ~SDCI_CTRL_BUS_WIDTH_MASK) | SDCI_CTRL_BUS_WIDTH_4BIT; | 439 | SDCI_CTRL = (SDCI_CTRL & ~SDCI_CTRL_BUS_WIDTH_MASK) | SDCI_CTRL_BUS_WIDTH_4BIT; |
401 | else if (buswidth == 8) | 440 | else if (buswidth == 8) |
@@ -403,7 +442,8 @@ static int ceata_init(int buswidth) | |||
403 | } | 442 | } |
404 | PASS_RC(ceata_soft_reset(), 3, 4); | 443 | PASS_RC(ceata_soft_reset(), 3, 4); |
405 | PASS_RC(ceata_read_multiple_register(0, ceata_taskfile, 0x10), 3, 5); | 444 | PASS_RC(ceata_read_multiple_register(0, ceata_taskfile, 0x10), 3, 5); |
406 | if (ceata_taskfile[0xc] != 0xce || ceata_taskfile[0xd] != 0xaa) RET_ERR(6); | 445 | if (ceata_taskfile[0xc] != 0xce || ceata_taskfile[0xd] != 0xaa) |
446 | RET_ERR(6); | ||
407 | PASS_RC(mmc_fastio_write(6, 0), 3, 7); | 447 | PASS_RC(mmc_fastio_write(6, 0), 3, 7); |
408 | return 0; | 448 | return 0; |
409 | } | 449 | } |
@@ -427,8 +467,10 @@ static int ceata_wait_idle(void) | |||
427 | { | 467 | { |
428 | uint32_t status; | 468 | uint32_t status; |
429 | PASS_RC(mmc_fastio_read(0xf, &status), 1, 0); | 469 | PASS_RC(mmc_fastio_read(0xf, &status), 1, 0); |
430 | if (!(status & 0x88)) return 0; | 470 | if (!(status & 0x88)) |
431 | if (TIMEOUT_EXPIRED(startusec, CEATA_DAT_NONBUSY_TIMEOUT)) RET_ERR(1); | 471 | return 0; |
472 | if (TIMEOUT_EXPIRED(startusec, CEATA_DAT_NONBUSY_TIMEOUT)) | ||
473 | RET_ERR(1); | ||
432 | sleep(HZ / 20); | 474 | sleep(HZ / 20); |
433 | } | 475 | } |
434 | } | 476 | } |
@@ -477,7 +519,8 @@ static int ceata_rw_multiple_block(bool write, void* buf, uint32_t count, long t | |||
477 | | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR, | 519 | | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR, |
478 | direction | MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(count), | 520 | direction | MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(count), |
479 | NULL, CEATA_COMMAND_TIMEOUT), 3, 0); | 521 | NULL, CEATA_COMMAND_TIMEOUT), 3, 0); |
480 | if (write) SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX; | 522 | if (write) |
523 | SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX; | ||
481 | if (semaphore_wait(&mmc_wakeup, timeout) == OBJ_WAIT_TIMEDOUT) | 524 | if (semaphore_wait(&mmc_wakeup, timeout) == OBJ_WAIT_TIMEDOUT) |
482 | { | 525 | { |
483 | PASS_RC(ceata_cancel_command(), 3, 1); | 526 | PASS_RC(ceata_cancel_command(), 3, 1); |
@@ -510,7 +553,8 @@ static int ata_identify(uint16_t* buf) | |||
510 | ata_write_cbr(&ATA_PIO_DVR, 0); | 553 | ata_write_cbr(&ATA_PIO_DVR, 0); |
511 | ata_write_cbr(&ATA_PIO_CSD, CMD_IDENTIFY); | 554 | ata_write_cbr(&ATA_PIO_CSD, CMD_IDENTIFY); |
512 | PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1); | 555 | PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1); |
513 | for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR); | 556 | for (i = 0; i < ATA_IDENTIFY_WORDS; i++) |
557 | buf[i] = ata_read_cbr(&ATA_PIO_DTR); | ||
514 | } | 558 | } |
515 | return 0; | 559 | return 0; |
516 | } | 560 | } |
@@ -549,6 +593,41 @@ static int ata_set_feature(uint32_t feature, uint32_t param) | |||
549 | return 0; | 593 | return 0; |
550 | } | 594 | } |
551 | 595 | ||
596 | #ifdef HAVE_ATA_DMA | ||
597 | static int udmatimes[ATA_MAX_UDMA + 1] = { | ||
598 | 0x4071152, | ||
599 | 0x2050d52, | ||
600 | #if ATA_MAX_UDMA >= 2 | ||
601 | 0x2030a52, | ||
602 | #endif | ||
603 | #if ATA_MAX_UDMA >= 3 | ||
604 | 0x1020a52, | ||
605 | #endif | ||
606 | #if ATA_MAX_UDMA >= 4 | ||
607 | 0x1010a52, | ||
608 | #endif | ||
609 | }; | ||
610 | static int mwdmatimes[ATA_MAX_MWDMA + 1] = { | ||
611 | 0x1c175, | ||
612 | 0x7083, | ||
613 | 0x5072, | ||
614 | }; | ||
615 | |||
616 | static int ata_get_best_mode(unsigned short identword, int max, int modetype) | ||
617 | { | ||
618 | unsigned short testbit = BIT_N(max); | ||
619 | |||
620 | while (1) { | ||
621 | if (identword & testbit) | ||
622 | return max | modetype; | ||
623 | testbit >>= 1; | ||
624 | if (!testbit) | ||
625 | return 0; | ||
626 | max--; | ||
627 | } | ||
628 | } | ||
629 | #endif | ||
630 | |||
552 | /* | 631 | /* |
553 | * ATA_UDMA_TIME register is documented on s3c6400 datasheet, information | 632 | * ATA_UDMA_TIME register is documented on s3c6400 datasheet, information |
554 | * included in s5l8700 datasheet is wrong or not valid for s5l8702. | 633 | * included in s5l8700 datasheet is wrong or not valid for s5l8702. |
@@ -573,10 +652,10 @@ static int ata_power_up(void) | |||
573 | ata_set_active(); | 652 | ata_set_active(); |
574 | ide_power_enable(true); | 653 | ide_power_enable(true); |
575 | long spinup_start = current_tick; | 654 | long spinup_start = current_tick; |
576 | if (ceata) | 655 | if (ceata) { |
577 | { | ||
578 | ata_lba48 = true; | 656 | ata_lba48 = true; |
579 | ata_dma = true; | 657 | ata_dma = true; |
658 | dma_mode = 0xff; /* Canary */ | ||
580 | PCON(8) = 0x33333333; | 659 | PCON(8) = 0x33333333; |
581 | PCON(9) = 0x00000033; | 660 | PCON(9) = 0x00000033; |
582 | PCON(11) |= 0xf; | 661 | PCON(11) |= 0xf; |
@@ -596,11 +675,8 @@ static int ata_power_up(void) | |||
596 | SDCI_CDIV = SDCI_CDIV_CLKDIV(4); | 675 | SDCI_CDIV = SDCI_CDIV_CLKDIV(4); |
597 | sleep(HZ / 100); | 676 | sleep(HZ / 100); |
598 | PASS_RC(ceata_init(8), 3, 1); | 677 | PASS_RC(ceata_init(8), 3, 1); |
599 | PASS_RC(ata_identify(ata_identify_data), 3, 2); | 678 | PASS_RC(ata_identify(identify_info), 3, 2); |
600 | dma_mode = 0x44; | 679 | } else { |
601 | } | ||
602 | else | ||
603 | { | ||
604 | PCON(7) = 0x44444444; | 680 | PCON(7) = 0x44444444; |
605 | PCON(8) = 0x44444444; | 681 | PCON(8) = 0x44444444; |
606 | PCON(9) = 0x44444444; | 682 | PCON(9) = 0x44444444; |
@@ -620,88 +696,71 @@ static int ata_power_up(void) | |||
620 | ATA_PIO_LHR = 0; | 696 | ATA_PIO_LHR = 0; |
621 | ATA_CFG = BIT(6); | 697 | ATA_CFG = BIT(6); |
622 | while (!(ATA_PIO_READY & BIT(1))) yield(); | 698 | while (!(ATA_PIO_READY & BIT(1))) yield(); |
623 | PASS_RC(ata_identify(ata_identify_data), 3, 3); | 699 | |
624 | uint32_t piotime = 0x11f3; | 700 | PASS_RC(ata_identify(identify_info), 3, 3); |
625 | uint32_t mdmatime = 0x1c175; | 701 | |
626 | uint32_t udmatime = 0x4071152; | 702 | uint32_t piotime = 0x11f3; /* PIO0-2? */ |
627 | uint32_t param = 0; | 703 | if (identify_info[53] & BIT(1)) /* Word 64..70 valid */ |
628 | ata_dma_flags = 0; | ||
629 | ata_lba48 = ata_identify_data[83] & BIT(10) ? true : false; | ||
630 | if (ata_identify_data[53] & BIT(1)) | ||
631 | { | ||
632 | if (ata_identify_data[64] & BIT(1)) piotime = 0x2072; | ||
633 | else if (ata_identify_data[64] & BIT(0)) piotime = 0x7083; | ||
634 | } | ||
635 | if (ata_identify_data[63] & BIT(2)) | ||
636 | { | 704 | { |
637 | mdmatime = 0x5072; | 705 | if (identify_info[64] & BIT(1)) |
638 | param = 0x22; | 706 | piotime = 0x2072; /* PIO mode 4 */ |
707 | else if (identify_info[64] & BIT(0)) | ||
708 | piotime = 0x7083; /* PIO mode 3 */ | ||
639 | } | 709 | } |
640 | else if (ata_identify_data[63] & BIT(1)) | 710 | ATA_PIO_TIME = piotime; |
711 | |||
712 | uint32_t param = 0; | ||
713 | ata_dma_flags = 0; | ||
714 | #ifdef HAVE_ATA_DMA | ||
715 | if ((identify_info[53] & BIT(2)) && (identify_info[88] & BITRANGE(0, 4))) /* Any UDMA */ | ||
641 | { | 716 | { |
642 | mdmatime = 0x7083; | 717 | int max_udma = ATA_MAX_UDMA; |
643 | param = 0x21; | 718 | #if ATA_MAX_UDMA > 2 |
719 | if (!(identify_info[93] & BIT(13))) | ||
720 | max_udma = 2; | ||
721 | #endif | ||
722 | param = ata_get_best_mode(identify_info[88], max_udma, 0x40); | ||
723 | ATA_UDMA_TIME = udmatimes[param & 0xf]; | ||
724 | ata_dma_flags = BIT(2) | BIT(3) | BIT(9) | BIT(10); | ||
644 | } | 725 | } |
645 | if (ata_identify_data[63] & BITRANGE(0, 2)) | 726 | if (!param && identify_info[63] & BITRANGE(0, 2)) /* Fall back to any MWDMA */ |
646 | { | 727 | { |
728 | param = ata_get_best_mode(identify_info[63], ATA_MAX_MWDMA, 0x20); | ||
729 | ATA_MDMA_TIME = mwdmatimes[param & 0xf]; | ||
647 | ata_dma_flags = BIT(3) | BIT(10); | 730 | ata_dma_flags = BIT(3) | BIT(10); |
648 | param |= 0x20; | ||
649 | } | ||
650 | if (ata_identify_data[53] & BIT(2)) | ||
651 | { | ||
652 | if (ata_identify_data[88] & BIT(4)) | ||
653 | { | ||
654 | udmatime = 0x1010a52; | ||
655 | param = 0x44; | ||
656 | } | ||
657 | else if (ata_identify_data[88] & BIT(3)) | ||
658 | { | ||
659 | udmatime = 0x1020a52; | ||
660 | param = 0x43; | ||
661 | } | ||
662 | else if (ata_identify_data[88] & BIT(2)) | ||
663 | { | ||
664 | udmatime = 0x2030a52; | ||
665 | param = 0x42; | ||
666 | } | ||
667 | else if (ata_identify_data[88] & BIT(1)) | ||
668 | { | ||
669 | udmatime = 0x2050d52; | ||
670 | param = 0x41; | ||
671 | } | ||
672 | else if (ata_identify_data[88] & BIT(0)) | ||
673 | { | ||
674 | param = 0x40; | ||
675 | } | ||
676 | if (ata_identify_data[88] & BITRANGE(0, 4)) | ||
677 | { | ||
678 | ata_dma_flags = BIT(2) | BIT(3) | BIT(9) | BIT(10); | ||
679 | } | ||
680 | } | 731 | } |
732 | #endif /* HAVE_ATA_DMA */ | ||
681 | ata_dma = param ? true : false; | 733 | ata_dma = param ? true : false; |
682 | dma_mode = param; | 734 | dma_mode = param; |
683 | PASS_RC(ata_set_feature(0x03, param), 3, 4); /* Transfer mode */ | 735 | PASS_RC(ata_set_feature(0x03, param), 3, 4); /* Transfer mode */ |
684 | if (ata_identify_data[82] & BIT(5)) | 736 | |
737 | /* SET_FEATURE only supported on PATA, not CE-ATA */ | ||
738 | if (identify_info[82] & BIT(5)) | ||
685 | PASS_RC(ata_set_feature(0x02, 0), 3, 5); /* Enable volatile write cache */ | 739 | PASS_RC(ata_set_feature(0x02, 0), 3, 5); /* Enable volatile write cache */ |
686 | if (ata_identify_data[82] & BIT(6)) | 740 | if (identify_info[82] & BIT(6)) |
687 | PASS_RC(ata_set_feature(0xaa, 0), 3, 6); /* Enable read lookahead */ | 741 | PASS_RC(ata_set_feature(0xaa, 0), 3, 6); /* Enable read lookahead */ |
688 | if (ata_identify_data[83] & BIT(3)) | 742 | if (identify_info[83] & BIT(3)) |
689 | PASS_RC(ata_set_feature(0x05, 0x80), 3, 7); /* Enable lowest power mode w/o standby */ | 743 | PASS_RC(ata_set_feature(0x05, 0x80), 3, 7); /* Enable lowest power mode w/o standby */ |
690 | if (ata_identify_data[83] & BIT(9)) | 744 | if (identify_info[83] & BIT(9)) |
691 | PASS_RC(ata_set_feature(0x42, 0x80), 3, 8); /* Enable lowest noise mode */ | 745 | PASS_RC(ata_set_feature(0x42, 0x80), 3, 8); /* Enable lowest noise mode */ |
692 | ATA_PIO_TIME = piotime; | 746 | |
693 | ATA_MDMA_TIME = mdmatime; | 747 | PASS_RC(ata_identify(identify_info), 3, 9); /* Finally, re-read identify info */ |
694 | ATA_UDMA_TIME = udmatime; | ||
695 | } | 748 | } |
749 | |||
696 | spinup_time = current_tick - spinup_start; | 750 | spinup_time = current_tick - spinup_start; |
697 | if (ata_lba48) | 751 | |
698 | ata_total_sectors = ata_identify_data[100] | 752 | ata_total_sectors = (identify_info[61] << 16) | identify_info[60]; |
699 | | (((uint64_t)ata_identify_data[101]) << 16) | 753 | if ( identify_info[83] & BIT(10) && ata_total_sectors == 0x0FFFFFFF) |
700 | | (((uint64_t)ata_identify_data[102]) << 32) | 754 | { |
701 | | (((uint64_t)ata_identify_data[103]) << 48); | 755 | ata_total_sectors = ((uint64_t)identify_info[103] << 48) | |
702 | else | 756 | ((uint64_t)identify_info[102] << 32) | |
703 | ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16); | 757 | ((uint64_t)identify_info[101] << 16) | |
704 | ata_total_sectors >>= 3; | 758 | identify_info[100]; |
759 | ata_lba48 = true; | ||
760 | } else { | ||
761 | ata_lba48 = false; | ||
762 | } | ||
763 | |||
705 | ata_powered = true; | 764 | ata_powered = true; |
706 | ata_set_active(); | 765 | ata_set_active(); |
707 | return 0; | 766 | return 0; |
@@ -709,28 +768,8 @@ static int ata_power_up(void) | |||
709 | 768 | ||
710 | static void ata_power_down(void) | 769 | static void ata_power_down(void) |
711 | { | 770 | { |
712 | if (!ata_powered) return; | 771 | if (!ata_powered) |
713 | if (ceata) | 772 | return; |
714 | { | ||
715 | memset(ceata_taskfile, 0, 16); | ||
716 | ceata_taskfile[0xf] = CMD_STANDBY_IMMEDIATE; | ||
717 | ceata_wait_idle(); | ||
718 | ceata_write_multiple_register(0, ceata_taskfile, 16); | ||
719 | ceata_wait_idle(); | ||
720 | sleep(HZ); | ||
721 | PWRCON(0) |= (1 << 9); | ||
722 | } | ||
723 | else | ||
724 | { | ||
725 | ata_wait_for_rdy(1000000); | ||
726 | ata_write_cbr(&ATA_PIO_DVR, 0); | ||
727 | ata_write_cbr(&ATA_PIO_CSD, CMD_STANDBY_IMMEDIATE); | ||
728 | ata_wait_for_rdy(1000000); | ||
729 | sleep(HZ / 30); | ||
730 | ATA_CONTROL = 0; | ||
731 | while (!(ATA_CONTROL & BIT(1))) yield(); | ||
732 | PWRCON(0) |= (1 << 5); | ||
733 | } | ||
734 | PCON(7) = 0; | 773 | PCON(7) = 0; |
735 | PCON(8) = 0; | 774 | PCON(8) = 0; |
736 | PCON(9) = 0; | 775 | PCON(9) = 0; |
@@ -745,18 +784,18 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo | |||
745 | if (ceata) | 784 | if (ceata) |
746 | { | 785 | { |
747 | memset(ceata_taskfile, 0, 16); | 786 | memset(ceata_taskfile, 0, 16); |
748 | ceata_taskfile[0x2] = cnt >> 5; | 787 | ceata_taskfile[0x2] = cnt >> 8; |
749 | ceata_taskfile[0x3] = sector >> 21; | 788 | ceata_taskfile[0x3] = sector >> 24; |
750 | ceata_taskfile[0x4] = sector >> 29; | 789 | ceata_taskfile[0x4] = sector >> 32; |
751 | ceata_taskfile[0x5] = sector >> 37; | 790 | ceata_taskfile[0x5] = sector >> 40; |
752 | ceata_taskfile[0xa] = cnt << 3; | 791 | ceata_taskfile[0xa] = cnt; |
753 | ceata_taskfile[0xb] = sector << 3; | 792 | ceata_taskfile[0xb] = sector; |
754 | ceata_taskfile[0xc] = sector >> 5; | 793 | ceata_taskfile[0xc] = sector >> 8; |
755 | ceata_taskfile[0xd] = sector >> 13; | 794 | ceata_taskfile[0xd] = sector >> 16; |
756 | ceata_taskfile[0xf] = write ? CMD_WRITE_DMA_EXT : CMD_READ_DMA_EXT; | 795 | ceata_taskfile[0xf] = write ? CMD_WRITE_DMA_EXT : CMD_READ_DMA_EXT; |
757 | PASS_RC(ceata_wait_idle(), 2, 0); | 796 | PASS_RC(ceata_wait_idle(), 2, 0); |
758 | PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1); | 797 | PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1); |
759 | PASS_RC(ceata_rw_multiple_block(write, buffer, cnt << 3, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 2, 2); | 798 | PASS_RC(ceata_rw_multiple_block(write, buffer, cnt, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 2, 2); |
760 | } | 799 | } |
761 | else | 800 | else |
762 | { | 801 | { |
@@ -764,14 +803,14 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo | |||
764 | ata_write_cbr(&ATA_PIO_DVR, 0); | 803 | ata_write_cbr(&ATA_PIO_DVR, 0); |
765 | if (ata_lba48) | 804 | if (ata_lba48) |
766 | { | 805 | { |
767 | ata_write_cbr(&ATA_PIO_SCR, cnt >> 5); | 806 | ata_write_cbr(&ATA_PIO_SCR, (cnt >> 8) & 0xff); |
768 | ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff); | 807 | ata_write_cbr(&ATA_PIO_SCR, (cnt) & 0xff); |
769 | ata_write_cbr(&ATA_PIO_LHR, (sector >> 37) & 0xff); | 808 | ata_write_cbr(&ATA_PIO_LHR, (sector >> 40) & 0xff); |
770 | ata_write_cbr(&ATA_PIO_LMR, (sector >> 29) & 0xff); | 809 | ata_write_cbr(&ATA_PIO_LMR, (sector >> 32) & 0xff); |
771 | ata_write_cbr(&ATA_PIO_LLR, (sector >> 21) & 0xff); | 810 | ata_write_cbr(&ATA_PIO_LLR, (sector >> 24) & 0xff); |
772 | ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff); | 811 | ata_write_cbr(&ATA_PIO_LHR, (sector >> 16) & 0xff); |
773 | ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff); | 812 | ata_write_cbr(&ATA_PIO_LMR, (sector >> 8) & 0xff); |
774 | ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff); | 813 | ata_write_cbr(&ATA_PIO_LLR, (sector) & 0xff); |
775 | ata_write_cbr(&ATA_PIO_DVR, BIT(6)); | 814 | ata_write_cbr(&ATA_PIO_DVR, BIT(6)); |
776 | if (write) | 815 | if (write) |
777 | ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA_EXT : CMD_WRITE_MULTIPLE_EXT); | 816 | ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA_EXT : CMD_WRITE_MULTIPLE_EXT); |
@@ -780,16 +819,17 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo | |||
780 | } | 819 | } |
781 | else | 820 | else |
782 | { | 821 | { |
783 | ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff); | 822 | ata_write_cbr(&ATA_PIO_SCR, (cnt) & 0xff); |
784 | ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff); | 823 | ata_write_cbr(&ATA_PIO_LHR, (sector >> 16) & 0xff); |
785 | ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff); | 824 | ata_write_cbr(&ATA_PIO_LMR, (sector >> 8) & 0xff); |
786 | ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff); | 825 | ata_write_cbr(&ATA_PIO_LLR, (sector) & 0xff); |
787 | ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 21) & 0xf)); | 826 | ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 24) & 0xf)); /* LBA28, mask off upper 4 bits of 32-bit sector address */ |
788 | if (write) | 827 | if (write) |
789 | ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA : CMD_WRITE_SECTORS); | 828 | ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA : CMD_WRITE_SECTORS); |
790 | else | 829 | else |
791 | ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_READ_DMA : CMD_READ_MULTIPLE); | 830 | ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_READ_DMA : CMD_READ_MULTIPLE); |
792 | } | 831 | } |
832 | #ifdef HAVE_ATA_DMA | ||
793 | if (ata_dma) | 833 | if (ata_dma) |
794 | { | 834 | { |
795 | PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1); | 835 | PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1); |
@@ -812,8 +852,7 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo | |||
812 | ATA_IRQ = BITRANGE(0, 4); | 852 | ATA_IRQ = BITRANGE(0, 4); |
813 | ATA_IRQ_MASK = BIT(0); | 853 | ATA_IRQ_MASK = BIT(0); |
814 | ATA_COMMAND = BIT(0); | 854 | ATA_COMMAND = BIT(0); |
815 | if (semaphore_wait(&ata_wakeup, 500000 * HZ / 1000000) | 855 | if (semaphore_wait(&ata_wakeup, 500000 * HZ / 1000000) == OBJ_WAIT_TIMEDOUT) |
816 | == OBJ_WAIT_TIMEDOUT) | ||
817 | { | 856 | { |
818 | ATA_COMMAND = BIT(1); | 857 | ATA_COMMAND = BIT(1); |
819 | ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12)); | 858 | ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12)); |
@@ -823,19 +862,19 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo | |||
823 | ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12)); | 862 | ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12)); |
824 | } | 863 | } |
825 | else | 864 | else |
865 | #endif // HAVE_ATA_DMA | ||
826 | { | 866 | { |
827 | cnt *= SECTOR_SIZE / 512; | ||
828 | while (cnt--) | 867 | while (cnt--) |
829 | { | 868 | { |
830 | int i; | 869 | int i; |
831 | PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1); | 870 | PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1); |
832 | if (write) | 871 | if (write) |
833 | for (i = 0; i < 256; i++) | 872 | for (i = 0; i < SECTOR_SIZE/2; i++) |
834 | ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)buffer)[i]); | 873 | ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)buffer)[i]); |
835 | else | 874 | else |
836 | for (i = 0; i < 256; i++) | 875 | for (i = 0; i < SECTOR_SIZE/2; i++) |
837 | ((uint16_t*)buffer)[i] = ata_read_cbr(&ATA_PIO_DTR); | 876 | ((uint16_t*)buffer)[i] = ata_read_cbr(&ATA_PIO_DTR); |
838 | buffer += 512; | 877 | buffer += SECTOR_SIZE; |
839 | } | 878 | } |
840 | } | 879 | } |
841 | PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3); | 880 | PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3); |
@@ -851,40 +890,27 @@ static int ata_rw_chunk(uint64_t sector, uint32_t cnt, void* buffer, bool write) | |||
851 | return rc; | 890 | return rc; |
852 | } | 891 | } |
853 | 892 | ||
854 | static int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool write) | 893 | static int ata_transfer_sectors(uint64_t sector, uint32_t count, void* buffer, bool write) |
855 | { | 894 | { |
856 | if (STORAGE_OVERLAP((uint32_t)buffer)) | 895 | if (!ata_powered) |
857 | { | 896 | ata_power_up(); |
858 | while (count) | 897 | if (sector + count > ata_total_sectors) |
859 | { | 898 | RET_ERR(0); |
860 | if (write) | ||
861 | memcpy(aligned_buffer, buffer, SECTOR_SIZE); | ||
862 | |||
863 | PASS_RC(ata_rw_sectors(sector, 1, aligned_buffer, write), 0, 0); | ||
864 | |||
865 | if (!write) | ||
866 | memcpy(buffer, aligned_buffer, SECTOR_SIZE); | ||
867 | |||
868 | buffer += SECTOR_SIZE; | ||
869 | sector++; | ||
870 | count--; | ||
871 | } | ||
872 | |||
873 | return 0; | ||
874 | } | ||
875 | |||
876 | if (!ata_powered) ata_power_up(); | ||
877 | if (sector + count > ata_total_sectors) RET_ERR(0); | ||
878 | ata_set_active(); | 899 | ata_set_active(); |
879 | if (ata_dma && write) commit_dcache(); | 900 | if (ata_dma && write) |
880 | else if (ata_dma) commit_discard_dcache(); | 901 | commit_dcache(); |
881 | if (!ceata) ATA_COMMAND = BIT(1); | 902 | else if (ata_dma) |
903 | commit_discard_dcache(); | ||
904 | if (!ceata) | ||
905 | ATA_COMMAND = BIT(1); | ||
906 | |||
882 | while (count) | 907 | while (count) |
883 | { | 908 | { |
884 | uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count); | 909 | uint32_t cnt = MIN(ata_lba48 ? 65536 : 256, count); |
885 | int rc = -1; | 910 | int rc = -1; |
886 | rc = ata_rw_chunk(sector, cnt, buffer, write); | 911 | rc = ata_rw_chunk(sector, cnt, buffer, write); |
887 | if (rc && ata_error_srst) ata_reset(); | 912 | if (rc && ata_error_srst) |
913 | ata_reset(); | ||
888 | if (rc && ata_retries) | 914 | if (rc && ata_retries) |
889 | { | 915 | { |
890 | void* buf = buffer; | 916 | void* buf = buffer; |
@@ -896,9 +922,11 @@ static int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool wr | |||
896 | while (tries-- && rc) | 922 | while (tries-- && rc) |
897 | { | 923 | { |
898 | rc = ata_rw_chunk(sect, 1, buf, write); | 924 | rc = ata_rw_chunk(sect, 1, buf, write); |
899 | if (rc && ata_error_srst) ata_reset(); | 925 | if (rc && ata_error_srst) |
926 | ata_reset(); | ||
900 | } | 927 | } |
901 | if (rc) break; | 928 | if (rc) |
929 | break; | ||
902 | buf += SECTOR_SIZE; | 930 | buf += SECTOR_SIZE; |
903 | } | 931 | } |
904 | } | 932 | } |
@@ -916,9 +944,13 @@ int ata_soft_reset(void) | |||
916 | { | 944 | { |
917 | int rc; | 945 | int rc; |
918 | mutex_lock(&ata_mutex); | 946 | mutex_lock(&ata_mutex); |
919 | if (!ata_powered) PASS_RC(ata_power_up(), 1, 0); | 947 | if (!ata_powered) |
948 | PASS_RC(ata_power_up(), 1, 0); | ||
920 | ata_set_active(); | 949 | ata_set_active(); |
921 | if (ceata) rc = ceata_soft_reset(); | 950 | if (ceata) |
951 | { | ||
952 | rc = ceata_soft_reset(); | ||
953 | } | ||
922 | else | 954 | else |
923 | { | 955 | { |
924 | ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2)); | 956 | ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2)); |
@@ -945,7 +977,8 @@ static int ata_reset(void) | |||
945 | { | 977 | { |
946 | int rc; | 978 | int rc; |
947 | mutex_lock(&ata_mutex); | 979 | mutex_lock(&ata_mutex); |
948 | if (!ata_powered) PASS_RC(ata_power_up(), 2, 0); | 980 | if (!ata_powered) |
981 | PASS_RC(ata_power_up(), 2, 0); | ||
949 | ata_set_active(); | 982 | ata_set_active(); |
950 | rc = ata_soft_reset(); | 983 | rc = ata_soft_reset(); |
951 | if (IS_ERR(rc)) | 984 | if (IS_ERR(rc)) |
@@ -957,7 +990,8 @@ static int ata_reset(void) | |||
957 | ata_power_down(); | 990 | ata_power_down(); |
958 | sleep(HZ * 3); | 991 | sleep(HZ * 3); |
959 | int rc2 = ata_power_up(); | 992 | int rc2 = ata_power_up(); |
960 | if (IS_ERR(rc2)) rc = ERR_RC((rc << 2) | 2); | 993 | if (IS_ERR(rc2)) |
994 | rc = ERR_RC((rc << 2) | 2); | ||
961 | } | 995 | } |
962 | else rc = 1; | 996 | else rc = 1; |
963 | } | 997 | } |
@@ -966,23 +1000,35 @@ static int ata_reset(void) | |||
966 | return rc; | 1000 | return rc; |
967 | } | 1001 | } |
968 | 1002 | ||
969 | int ata_read_sectors(IF_MD(int drive,) unsigned long start, int incount, | 1003 | #include "ata-common.c" |
1004 | |||
1005 | #ifndef MAX_PHYS_SECTOR_SIZE | ||
1006 | int ata_read_sectors(IF_MD(int drive,) sector_t start, int incount, | ||
970 | void* inbuf) | 1007 | void* inbuf) |
971 | { | 1008 | { |
1009 | #ifdef HAVE_MULTIDRIVE | ||
1010 | (void)drive; /* unused for now */ | ||
1011 | #endif | ||
1012 | |||
972 | mutex_lock(&ata_mutex); | 1013 | mutex_lock(&ata_mutex); |
973 | int rc = ata_rw_sectors(start, incount, inbuf, false); | 1014 | int rc = ata_transfer_sectors(start, incount, inbuf, false); |
974 | mutex_unlock(&ata_mutex); | 1015 | mutex_unlock(&ata_mutex); |
975 | return rc; | 1016 | return rc; |
976 | } | 1017 | } |
977 | 1018 | ||
978 | int ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, | 1019 | int ata_write_sectors(IF_MD(int drive,) sector_t start, int count, |
979 | const void* outbuf) | 1020 | const void* outbuf) |
980 | { | 1021 | { |
1022 | #ifdef HAVE_MULTIDRIVE | ||
1023 | (void)drive; /* unused for now */ | ||
1024 | #endif | ||
1025 | |||
981 | mutex_lock(&ata_mutex); | 1026 | mutex_lock(&ata_mutex); |
982 | int rc = ata_rw_sectors(start, count, (void*)((uint32_t)outbuf), true); | 1027 | int rc = ata_transfer_sectors(start, count, (void*)((uint32_t)outbuf), true); |
983 | mutex_unlock(&ata_mutex); | 1028 | mutex_unlock(&ata_mutex); |
984 | return rc; | 1029 | return rc; |
985 | } | 1030 | } |
1031 | #endif /* ndef MAX_PHYS_SECTOR_SIZE */ | ||
986 | 1032 | ||
987 | void ata_spindown(int seconds) | 1033 | void ata_spindown(int seconds) |
988 | { | 1034 | { |
@@ -993,26 +1039,27 @@ static void ata_flush_cache(void) | |||
993 | { | 1039 | { |
994 | uint8_t cmd; | 1040 | uint8_t cmd; |
995 | 1041 | ||
996 | if (ata_identify_data[83] & BIT(13)) { | 1042 | if (ceata) { |
997 | cmd = CMD_FLUSH_CACHE_EXT; | ||
998 | } else if (ata_identify_data[83] & BIT(12)) { | ||
999 | cmd = CMD_FLUSH_CACHE; | ||
1000 | } else { | ||
1001 | /* If neither (mandatory!) command is supported | ||
1002 | then don't issue it. */ | ||
1003 | return; | ||
1004 | } | ||
1005 | |||
1006 | if (ceata) | ||
1007 | { | ||
1008 | memset(ceata_taskfile, 0, 16); | 1043 | memset(ceata_taskfile, 0, 16); |
1009 | ceata_taskfile[0xf] = cmd; | 1044 | ceata_taskfile[0xf] = CMD_FLUSH_CACHE_EXT; /* CE-ATA only supports EXT */ |
1010 | ceata_wait_idle(); | 1045 | ceata_wait_idle(); |
1011 | ceata_write_multiple_register(0, ceata_taskfile, 16); | 1046 | ceata_write_multiple_register(0, ceata_taskfile, 16); |
1012 | ceata_wait_idle(); | 1047 | ceata_wait_idle(); |
1013 | } | 1048 | } else { |
1014 | else | 1049 | if (!canflush) { |
1015 | { | 1050 | return; |
1051 | } else if (ata_lba48 && identify_info[83] & BIT(13)) { | ||
1052 | cmd = CMD_FLUSH_CACHE_EXT; /* Flag, optional, ATA-6 and up, for use with LBA48 devices. Mandatory for CE-ATA */ | ||
1053 | } else if (identify_info[83] & BIT(12)) { | ||
1054 | cmd = CMD_FLUSH_CACHE; /* Flag, mandatory, ATA-6 and up */ | ||
1055 | } else if (identify_info[80] >= BIT(5)) { /* Use >= instead of '&' because bits lower than the latest standard we support don't have to be set */ | ||
1056 | cmd = CMD_FLUSH_CACHE; /* No flag, mandatory, ATA-5 (Optional for ATA-4) */ | ||
1057 | } else { | ||
1058 | /* If neither command is supported then don't issue it. */ | ||
1059 | canflush = 0; | ||
1060 | return; | ||
1061 | } | ||
1062 | |||
1016 | ata_wait_for_rdy(1000000); | 1063 | ata_wait_for_rdy(1000000); |
1017 | ata_write_cbr(&ATA_PIO_DVR, 0); | 1064 | ata_write_cbr(&ATA_PIO_DVR, 0); |
1018 | ata_write_cbr(&ATA_PIO_CSD, cmd); | 1065 | ata_write_cbr(&ATA_PIO_CSD, cmd); |
@@ -1020,14 +1067,46 @@ static void ata_flush_cache(void) | |||
1020 | } | 1067 | } |
1021 | } | 1068 | } |
1022 | 1069 | ||
1070 | int ata_flush(void) | ||
1071 | { | ||
1072 | if (ata_powered) { | ||
1073 | mutex_lock(&ata_mutex); | ||
1074 | ata_flush_cache(); | ||
1075 | mutex_unlock(&ata_mutex); | ||
1076 | } | ||
1077 | return 0; | ||
1078 | } | ||
1079 | |||
1023 | void ata_sleepnow(void) | 1080 | void ata_sleepnow(void) |
1024 | { | 1081 | { |
1025 | mutex_lock(&ata_mutex); | 1082 | mutex_lock(&ata_mutex); |
1026 | 1083 | ||
1027 | if (ata_disk_can_poweroff()) | 1084 | ata_flush_cache(); |
1028 | ata_power_down(); | 1085 | |
1029 | else | 1086 | if (ata_disk_can_sleep()) { |
1030 | ata_flush_cache(); | 1087 | if (ceata) { |
1088 | memset(ceata_taskfile, 0, 16); | ||
1089 | ceata_taskfile[0xf] = CMD_STANDBY_IMMEDIATE; | ||
1090 | ceata_wait_idle(); | ||
1091 | ceata_write_multiple_register(0, ceata_taskfile, 16); | ||
1092 | ceata_wait_idle(); | ||
1093 | sleep(HZ); | ||
1094 | PWRCON(0) |= (1 << 9); | ||
1095 | } else { | ||
1096 | ata_wait_for_rdy(1000000); | ||
1097 | ata_write_cbr(&ATA_PIO_DVR, 0); | ||
1098 | ata_write_cbr(&ATA_PIO_CSD, CMD_STANDBY_IMMEDIATE); | ||
1099 | ata_wait_for_rdy(1000000); | ||
1100 | sleep(HZ / 30); | ||
1101 | ATA_CONTROL = 0; | ||
1102 | while (!(ATA_CONTROL & BIT(1))) | ||
1103 | yield(); | ||
1104 | PWRCON(0) |= (1 << 5); | ||
1105 | } | ||
1106 | } | ||
1107 | |||
1108 | if (ata_disk_can_sleep() || canflush) | ||
1109 | ata_power_down(); // XXX add a powerdown delay similar to main ATA driver? | ||
1031 | 1110 | ||
1032 | mutex_unlock(&ata_mutex); | 1111 | mutex_unlock(&ata_mutex); |
1033 | } | 1112 | } |
@@ -1037,14 +1116,21 @@ void ata_spin(void) | |||
1037 | ata_set_active(); | 1116 | ata_set_active(); |
1038 | } | 1117 | } |
1039 | 1118 | ||
1119 | #ifdef STORAGE_GET_INFO | ||
1040 | void ata_get_info(IF_MD(int drive,) struct storage_info *info) | 1120 | void ata_get_info(IF_MD(int drive,) struct storage_info *info) |
1041 | { | 1121 | { |
1042 | (*info).sector_size = SECTOR_SIZE; | 1122 | /* Logical sector size */ |
1123 | if ((identify_info[106] & 0xd000) == 0x5000) /* B14, B12 */ | ||
1124 | info->sector_size = (identify_info[117] | (identify_info[118] << 16)) * 2; | ||
1125 | else | ||
1126 | info->sector_size = SECTOR_SIZE; | ||
1127 | |||
1043 | (*info).num_sectors = ata_total_sectors; | 1128 | (*info).num_sectors = ata_total_sectors; |
1044 | (*info).vendor = "Apple"; | 1129 | (*info).vendor = "Apple"; |
1045 | (*info).product = "iPod Classic"; | 1130 | (*info).product = "iPod Classic"; |
1046 | (*info).revision = "1.0"; | 1131 | (*info).revision = "1.0"; |
1047 | } | 1132 | } |
1133 | #endif | ||
1048 | 1134 | ||
1049 | long ata_last_disk_activity(void) | 1135 | long ata_last_disk_activity(void) |
1050 | { | 1136 | { |
@@ -1061,11 +1147,18 @@ int ata_init(void) | |||
1061 | ata_powered = false; | 1147 | ata_powered = false; |
1062 | ata_total_sectors = 0; | 1148 | ata_total_sectors = 0; |
1063 | 1149 | ||
1064 | /* get ata_identify_data */ | 1150 | /* get identify_info */ |
1065 | mutex_lock(&ata_mutex); | 1151 | mutex_lock(&ata_mutex); |
1066 | int rc = ata_power_up(); | 1152 | int rc = ata_power_up(); |
1067 | mutex_unlock(&ata_mutex); | 1153 | mutex_unlock(&ata_mutex); |
1068 | if (IS_ERR(rc)) return rc; | 1154 | if (IS_ERR(rc)) |
1155 | return rc; | ||
1156 | |||
1157 | #ifdef MAX_PHYS_SECTOR_SIZE | ||
1158 | rc = ata_get_phys_sector_mult(); | ||
1159 | if (IS_ERR(rc)) | ||
1160 | return rc; | ||
1161 | #endif | ||
1069 | 1162 | ||
1070 | return 0; | 1163 | return 0; |
1071 | } | 1164 | } |
@@ -1082,7 +1175,7 @@ static int ata_smart(uint16_t* buf) | |||
1082 | ceata_taskfile[0xe] = BIT(6); | 1175 | ceata_taskfile[0xe] = BIT(6); |
1083 | ceata_taskfile[0xf] = CMD_SMART; | 1176 | ceata_taskfile[0xf] = CMD_SMART; |
1084 | PASS_RC(ceata_wait_idle(), 3, 1); | 1177 | PASS_RC(ceata_wait_idle(), 3, 1); |
1085 | if (((uint8_t*)ata_identify_data)[54] != 'A') /* Model != aAmsung */ | 1178 | if (((uint8_t*)identify_info)[54] != 'A') /* Model != aAmsung */ |
1086 | { | 1179 | { |
1087 | ceata_taskfile[0x9] = 0xd8; /* SMART enable operations */ | 1180 | ceata_taskfile[0x9] = 0xd8; /* SMART enable operations */ |
1088 | PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 3, 2); | 1181 | PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 3, 2); |
@@ -1102,7 +1195,8 @@ static int ata_smart(uint16_t* buf) | |||
1102 | ata_write_cbr(&ATA_PIO_DVR, BIT(6)); | 1195 | ata_write_cbr(&ATA_PIO_DVR, BIT(6)); |
1103 | ata_write_cbr(&ATA_PIO_CSD, CMD_SMART); | 1196 | ata_write_cbr(&ATA_PIO_CSD, CMD_SMART); |
1104 | PASS_RC(ata_wait_for_start_of_transfer(10000000), 3, 7); | 1197 | PASS_RC(ata_wait_for_start_of_transfer(10000000), 3, 7); |
1105 | for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR); | 1198 | for (i = 0; i < 0x100; i++) |
1199 | buf[i] = ata_read_cbr(&ATA_PIO_DTR); | ||
1106 | } | 1200 | } |
1107 | ata_set_active(); | 1201 | ata_set_active(); |
1108 | return 0; | 1202 | return 0; |
@@ -1129,7 +1223,7 @@ static int ata_num_drives(int first_drive) | |||
1129 | 1223 | ||
1130 | unsigned short* ata_get_identify(void) | 1224 | unsigned short* ata_get_identify(void) |
1131 | { | 1225 | { |
1132 | return ata_identify_data; | 1226 | return identify_info; |
1133 | } | 1227 | } |
1134 | 1228 | ||
1135 | int ata_spinup_time(void) | 1229 | int ata_spinup_time(void) |
@@ -1137,24 +1231,29 @@ int ata_spinup_time(void) | |||
1137 | return spinup_time; | 1231 | return spinup_time; |
1138 | } | 1232 | } |
1139 | 1233 | ||
1234 | #ifdef HAVE_ATA_DMA | ||
1140 | int ata_get_dma_mode(void) | 1235 | int ata_get_dma_mode(void) |
1141 | { | 1236 | { |
1142 | return dma_mode; | 1237 | return dma_mode; |
1143 | } | 1238 | } |
1239 | #endif | ||
1144 | 1240 | ||
1145 | void INT_ATA(void) | 1241 | void INT_ATA(void) |
1146 | { | 1242 | { |
1147 | uint32_t ata_irq = ATA_IRQ; | 1243 | uint32_t ata_irq = ATA_IRQ; |
1148 | ATA_IRQ = ata_irq; | 1244 | ATA_IRQ = ata_irq; |
1149 | if (ata_irq & ATA_IRQ_MASK) semaphore_release(&ata_wakeup); | 1245 | if (ata_irq & ATA_IRQ_MASK) |
1246 | semaphore_release(&ata_wakeup); | ||
1150 | ATA_IRQ_MASK = 0; | 1247 | ATA_IRQ_MASK = 0; |
1151 | } | 1248 | } |
1152 | 1249 | ||
1153 | void INT_MMC(void) | 1250 | void INT_MMC(void) |
1154 | { | 1251 | { |
1155 | uint32_t irq = SDCI_IRQ; | 1252 | uint32_t irq = SDCI_IRQ; |
1156 | if (irq & SDCI_IRQ_DAT_DONE_INT) semaphore_release(&mmc_wakeup); | 1253 | if (irq & SDCI_IRQ_DAT_DONE_INT) |
1157 | if (irq & SDCI_IRQ_IOCARD_IRQ_INT) semaphore_release(&mmc_comp_wakeup); | 1254 | semaphore_release(&mmc_wakeup); |
1255 | if (irq & SDCI_IRQ_IOCARD_IRQ_INT) | ||
1256 | semaphore_release(&mmc_comp_wakeup); | ||
1158 | SDCI_IRQ = irq; | 1257 | SDCI_IRQ = irq; |
1159 | } | 1258 | } |
1160 | 1259 | ||