diff options
Diffstat (limited to 'firmware/drivers/ata.c')
-rw-r--r-- | firmware/drivers/ata.c | 198 |
1 files changed, 109 insertions, 89 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index 1d738f5bc2..c9f87a8a70 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c | |||
@@ -19,6 +19,7 @@ | |||
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | #include <stdbool.h> | 21 | #include <stdbool.h> |
22 | #include <inttypes.h> | ||
22 | #include "ata.h" | 23 | #include "ata.h" |
23 | #include "kernel.h" | 24 | #include "kernel.h" |
24 | #include "thread.h" | 25 | #include "thread.h" |
@@ -34,7 +35,37 @@ | |||
34 | #include "ata-target.h" | 35 | #include "ata-target.h" |
35 | #include "storage.h" | 36 | #include "storage.h" |
36 | 37 | ||
37 | #define SECTOR_SIZE (512) | 38 | |
39 | #ifndef ATA_OUT8 | ||
40 | #define ATA_OUT8(reg, data) (reg) = (data) | ||
41 | #endif | ||
42 | #ifndef ATA_OUT16 | ||
43 | #define ATA_OUT16(reg, data) (reg) = (data) | ||
44 | #endif | ||
45 | #ifndef ATA_IN8 | ||
46 | #define ATA_IN8(reg) (reg) | ||
47 | #endif | ||
48 | #ifndef ATA_IN16 | ||
49 | #define ATA_IN16(reg) (reg) | ||
50 | #endif | ||
51 | #ifndef ATA_SWAP_IDENTIFY | ||
52 | #define ATA_SWAP_IDENTIFY(word) (word) | ||
53 | #endif | ||
54 | |||
55 | #define SECTOR_SIZE 512 | ||
56 | |||
57 | #define STATUS_BSY 0x80 | ||
58 | #define STATUS_RDY 0x40 | ||
59 | #define STATUS_DRQ 0x08 | ||
60 | #define STATUS_ERR 0x01 | ||
61 | #define STATUS_DF 0x20 | ||
62 | #define ERROR_IDNF 0x10 | ||
63 | #define ERROR_ABRT 0x04 | ||
64 | |||
65 | #define TEST_PATTERN1 0xa5 | ||
66 | #define TEST_PATTERN2 0x5a | ||
67 | #define TEST_PATTERN3 0xaa | ||
68 | #define TEST_PATTERN4 0x55 | ||
38 | 69 | ||
39 | #define ATA_FEATURE ATA_ERROR | 70 | #define ATA_FEATURE ATA_ERROR |
40 | 71 | ||
@@ -210,7 +241,7 @@ STATICIRAM ICODE_ATTR int wait_for_bsy(void) | |||
210 | 241 | ||
211 | do | 242 | do |
212 | { | 243 | { |
213 | if (!(ATA_STATUS & STATUS_BSY)) | 244 | if (!(ATA_IN8(ATA_STATUS) & STATUS_BSY)) |
214 | return 1; | 245 | return 1; |
215 | last_disk_activity = current_tick; | 246 | last_disk_activity = current_tick; |
216 | yield(); | 247 | yield(); |
@@ -230,7 +261,7 @@ STATICIRAM ICODE_ATTR int wait_for_rdy(void) | |||
230 | 261 | ||
231 | do | 262 | do |
232 | { | 263 | { |
233 | if (ATA_ALT_STATUS & STATUS_RDY) | 264 | if (ATA_IN8(ATA_ALT_STATUS) & STATUS_RDY) |
234 | return 1; | 265 | return 1; |
235 | last_disk_activity = current_tick; | 266 | last_disk_activity = current_tick; |
236 | yield(); | 267 | yield(); |
@@ -244,14 +275,14 @@ STATICIRAM ICODE_ATTR int wait_for_start_of_transfer(void) | |||
244 | if (!wait_for_bsy()) | 275 | if (!wait_for_bsy()) |
245 | return 0; | 276 | return 0; |
246 | 277 | ||
247 | return (ATA_ALT_STATUS & (STATUS_BSY|STATUS_DRQ)) == STATUS_DRQ; | 278 | return (ATA_IN8(ATA_ALT_STATUS) & (STATUS_BSY|STATUS_DRQ)) == STATUS_DRQ; |
248 | } | 279 | } |
249 | 280 | ||
250 | STATICIRAM ICODE_ATTR int wait_for_end_of_transfer(void) | 281 | STATICIRAM ICODE_ATTR int wait_for_end_of_transfer(void) |
251 | { | 282 | { |
252 | if (!wait_for_bsy()) | 283 | if (!wait_for_bsy()) |
253 | return 0; | 284 | return 0; |
254 | return (ATA_ALT_STATUS & | 285 | return (ATA_IN8(ATA_ALT_STATUS) & |
255 | (STATUS_BSY|STATUS_RDY|STATUS_DF|STATUS_DRQ|STATUS_ERR)) | 286 | (STATUS_BSY|STATUS_RDY|STATUS_DF|STATUS_DRQ|STATUS_ERR)) |
256 | == STATUS_RDY; | 287 | == STATUS_RDY; |
257 | } | 288 | } |
@@ -279,8 +310,8 @@ STATICIRAM ICODE_ATTR void copy_read_sectors(unsigned char* buf, int wordcount) | |||
279 | unsigned char* bufend = buf + wordcount*2; | 310 | unsigned char* bufend = buf + wordcount*2; |
280 | do | 311 | do |
281 | { | 312 | { |
282 | tmp = ATA_DATA; | 313 | tmp = ATA_IN16(ATA_DATA); |
283 | #if defined(ATA_SWAP_WORDS) || defined(ROCKBOX_LITTLE_ENDIAN) | 314 | #if defined(ROCKBOX_LITTLE_ENDIAN) |
284 | *buf++ = tmp & 0xff; /* I assume big endian */ | 315 | *buf++ = tmp & 0xff; /* I assume big endian */ |
285 | *buf++ = tmp >> 8; /* and don't use the SWAB16 macro */ | 316 | *buf++ = tmp >> 8; /* and don't use the SWAB16 macro */ |
286 | #else | 317 | #else |
@@ -295,11 +326,7 @@ STATICIRAM ICODE_ATTR void copy_read_sectors(unsigned char* buf, int wordcount) | |||
295 | unsigned short* wbufend = wbuf + wordcount; | 326 | unsigned short* wbufend = wbuf + wordcount; |
296 | do | 327 | do |
297 | { | 328 | { |
298 | #ifdef ATA_SWAP_WORDS | 329 | *wbuf = ATA_IN16(ATA_DATA); |
299 | *wbuf = swap16(ATA_DATA); | ||
300 | #else | ||
301 | *wbuf = ATA_DATA; | ||
302 | #endif | ||
303 | } while (++wbuf < wbufend); /* tail loop is faster */ | 330 | } while (++wbuf < wbufend); /* tail loop is faster */ |
304 | } | 331 | } |
305 | } | 332 | } |
@@ -315,15 +342,14 @@ STATICIRAM ICODE_ATTR void copy_write_sectors(const unsigned char* buf, | |||
315 | const unsigned char* bufend = buf + wordcount*2; | 342 | const unsigned char* bufend = buf + wordcount*2; |
316 | do | 343 | do |
317 | { | 344 | { |
318 | #if defined(ATA_SWAP_WORDS) || defined(ROCKBOX_LITTLE_ENDIAN) | 345 | #if defined(ROCKBOX_LITTLE_ENDIAN) |
319 | tmp = (unsigned short) *buf++; | 346 | tmp = (unsigned short) *buf++; |
320 | tmp |= (unsigned short) *buf++ << 8; | 347 | tmp |= (unsigned short) *buf++ << 8; |
321 | SET_16BITREG(ATA_DATA, tmp); | ||
322 | #else | 348 | #else |
323 | tmp = (unsigned short) *buf++ << 8; | 349 | tmp = (unsigned short) *buf++ << 8; |
324 | tmp |= (unsigned short) *buf++; | 350 | tmp |= (unsigned short) *buf++; |
325 | SET_16BITREG(ATA_DATA, tmp); | ||
326 | #endif | 351 | #endif |
352 | ATA_OUT16(ATA_DATA, tmp); | ||
327 | } while (buf < bufend); /* tail loop is faster */ | 353 | } while (buf < bufend); /* tail loop is faster */ |
328 | } | 354 | } |
329 | else | 355 | else |
@@ -332,11 +358,7 @@ STATICIRAM ICODE_ATTR void copy_write_sectors(const unsigned char* buf, | |||
332 | unsigned short* wbufend = wbuf + wordcount; | 358 | unsigned short* wbufend = wbuf + wordcount; |
333 | do | 359 | do |
334 | { | 360 | { |
335 | #ifdef ATA_SWAP_WORDS | 361 | ATA_OUT16(ATA_DATA, *wbuf); |
336 | SET_16BITREG(ATA_DATA, swap16(*wbuf)); | ||
337 | #else | ||
338 | SET_16BITREG(ATA_DATA, *wbuf); | ||
339 | #endif | ||
340 | } while (++wbuf < wbufend); /* tail loop is faster */ | 362 | } while (++wbuf < wbufend); /* tail loop is faster */ |
341 | } | 363 | } |
342 | } | 364 | } |
@@ -389,7 +411,7 @@ static int ata_transfer_sectors(unsigned long start, | |||
389 | 411 | ||
390 | timeout = current_tick + READWRITE_TIMEOUT; | 412 | timeout = current_tick + READWRITE_TIMEOUT; |
391 | 413 | ||
392 | SET_REG(ATA_SELECT, ata_device); | 414 | ATA_OUT8(ATA_SELECT, ata_device); |
393 | if (!wait_for_rdy()) | 415 | if (!wait_for_rdy()) |
394 | { | 416 | { |
395 | ret = -3; | 417 | ret = -3; |
@@ -412,39 +434,39 @@ static int ata_transfer_sectors(unsigned long start, | |||
412 | #ifdef HAVE_LBA48 | 434 | #ifdef HAVE_LBA48 |
413 | if (lba48) | 435 | if (lba48) |
414 | { | 436 | { |
415 | SET_REG(ATA_NSECTOR, count >> 8); | 437 | ATA_OUT8(ATA_NSECTOR, count >> 8); |
416 | SET_REG(ATA_NSECTOR, count & 0xff); | 438 | ATA_OUT8(ATA_NSECTOR, count & 0xff); |
417 | SET_REG(ATA_SECTOR, (start >> 24) & 0xff); /* 31:24 */ | 439 | ATA_OUT8(ATA_SECTOR, (start >> 24) & 0xff); /* 31:24 */ |
418 | SET_REG(ATA_SECTOR, start & 0xff); /* 7:0 */ | 440 | ATA_OUT8(ATA_SECTOR, start & 0xff); /* 7:0 */ |
419 | SET_REG(ATA_LCYL, 0); /* 39:32 */ | 441 | ATA_OUT8(ATA_LCYL, 0); /* 39:32 */ |
420 | SET_REG(ATA_LCYL, (start >> 8) & 0xff); /* 15:8 */ | 442 | ATA_OUT8(ATA_LCYL, (start >> 8) & 0xff); /* 15:8 */ |
421 | SET_REG(ATA_HCYL, 0); /* 47:40 */ | 443 | ATA_OUT8(ATA_HCYL, 0); /* 47:40 */ |
422 | SET_REG(ATA_HCYL, (start >> 16) & 0xff); /* 23:16 */ | 444 | ATA_OUT8(ATA_HCYL, (start >> 16) & 0xff); /* 23:16 */ |
423 | SET_REG(ATA_SELECT, SELECT_LBA | ata_device); | 445 | ATA_OUT8(ATA_SELECT, SELECT_LBA | ata_device); |
424 | #ifdef HAVE_ATA_DMA | 446 | #ifdef HAVE_ATA_DMA |
425 | if (write) | 447 | if (write) |
426 | SET_REG(ATA_COMMAND, usedma ? CMD_WRITE_DMA_EXT : CMD_WRITE_MULTIPLE_EXT); | 448 | ATA_OUT8(ATA_COMMAND, usedma ? CMD_WRITE_DMA_EXT : CMD_WRITE_MULTIPLE_EXT); |
427 | else | 449 | else |
428 | SET_REG(ATA_COMMAND, usedma ? CMD_READ_DMA_EXT : CMD_READ_MULTIPLE_EXT); | 450 | ATA_OUT8(ATA_COMMAND, usedma ? CMD_READ_DMA_EXT : CMD_READ_MULTIPLE_EXT); |
429 | #else | 451 | #else |
430 | SET_REG(ATA_COMMAND, write ? CMD_WRITE_MULTIPLE_EXT : CMD_READ_MULTIPLE_EXT); | 452 | ATA_OUT8(ATA_COMMAND, write ? CMD_WRITE_MULTIPLE_EXT : CMD_READ_MULTIPLE_EXT); |
431 | #endif | 453 | #endif |
432 | } | 454 | } |
433 | else | 455 | else |
434 | #endif | 456 | #endif |
435 | { | 457 | { |
436 | SET_REG(ATA_NSECTOR, count & 0xff); /* 0 means 256 sectors */ | 458 | ATA_OUT8(ATA_NSECTOR, count & 0xff); /* 0 means 256 sectors */ |
437 | SET_REG(ATA_SECTOR, start & 0xff); | 459 | ATA_OUT8(ATA_SECTOR, start & 0xff); |
438 | SET_REG(ATA_LCYL, (start >> 8) & 0xff); | 460 | ATA_OUT8(ATA_LCYL, (start >> 8) & 0xff); |
439 | SET_REG(ATA_HCYL, (start >> 16) & 0xff); | 461 | ATA_OUT8(ATA_HCYL, (start >> 16) & 0xff); |
440 | SET_REG(ATA_SELECT, ((start >> 24) & 0xf) | SELECT_LBA | ata_device); | 462 | ATA_OUT8(ATA_SELECT, ((start >> 24) & 0xf) | SELECT_LBA | ata_device); |
441 | #ifdef HAVE_ATA_DMA | 463 | #ifdef HAVE_ATA_DMA |
442 | if (write) | 464 | if (write) |
443 | SET_REG(ATA_COMMAND, usedma ? CMD_WRITE_DMA : CMD_WRITE_MULTIPLE); | 465 | ATA_OUT8(ATA_COMMAND, usedma ? CMD_WRITE_DMA : CMD_WRITE_MULTIPLE); |
444 | else | 466 | else |
445 | SET_REG(ATA_COMMAND, usedma ? CMD_READ_DMA : CMD_READ_MULTIPLE); | 467 | ATA_OUT8(ATA_COMMAND, usedma ? CMD_READ_DMA : CMD_READ_MULTIPLE); |
446 | #else | 468 | #else |
447 | SET_REG(ATA_COMMAND, write ? CMD_WRITE_MULTIPLE : CMD_READ_MULTIPLE); | 469 | ATA_OUT8(ATA_COMMAND, write ? CMD_WRITE_MULTIPLE : CMD_READ_MULTIPLE); |
448 | #endif | 470 | #endif |
449 | } | 471 | } |
450 | 472 | ||
@@ -501,10 +523,10 @@ static int ata_transfer_sectors(unsigned long start, | |||
501 | } | 523 | } |
502 | 524 | ||
503 | /* read the status register exactly once per loop */ | 525 | /* read the status register exactly once per loop */ |
504 | status = ATA_STATUS; | 526 | status = ATA_IN8(ATA_STATUS); |
505 | error = ATA_ERROR; | 527 | error = ATA_IN8(ATA_ERROR); |
506 | 528 | ||
507 | if (count >= multisectors ) | 529 | if (count >= multisectors) |
508 | sectors = multisectors; | 530 | sectors = multisectors; |
509 | else | 531 | else |
510 | sectors = count; | 532 | sectors = count; |
@@ -543,7 +565,7 @@ static int ata_transfer_sectors(unsigned long start, | |||
543 | if(!ret && !wait_for_end_of_transfer()) { | 565 | if(!ret && !wait_for_end_of_transfer()) { |
544 | int error; | 566 | int error; |
545 | 567 | ||
546 | error = ATA_ERROR; | 568 | error = ATA_IN8(ATA_ERROR); |
547 | perform_soft_reset(); | 569 | perform_soft_reset(); |
548 | ret = -4; | 570 | ret = -4; |
549 | /* no point retrying IDNF, sector no. was invalid */ | 571 | /* no point retrying IDNF, sector no. was invalid */ |
@@ -767,20 +789,23 @@ int ata_write_sectors(IF_MD2(int drive,) | |||
767 | static int check_registers(void) | 789 | static int check_registers(void) |
768 | { | 790 | { |
769 | int i; | 791 | int i; |
770 | if ( ATA_STATUS & STATUS_BSY ) | 792 | wait_for_bsy(); |
793 | if (ATA_IN8(ATA_STATUS) & STATUS_BSY) | ||
771 | return -1; | 794 | return -1; |
772 | 795 | ||
773 | for (i = 0; i<64; i++) { | 796 | for (i = 0; i<64; i++) { |
774 | SET_REG(ATA_NSECTOR, WRITE_PATTERN1); | 797 | ATA_OUT8(ATA_NSECTOR, TEST_PATTERN1); |
775 | SET_REG(ATA_SECTOR, WRITE_PATTERN2); | 798 | ATA_OUT8(ATA_SECTOR, TEST_PATTERN2); |
776 | SET_REG(ATA_LCYL, WRITE_PATTERN3); | 799 | ATA_OUT8(ATA_LCYL, TEST_PATTERN3); |
777 | SET_REG(ATA_HCYL, WRITE_PATTERN4); | 800 | ATA_OUT8(ATA_HCYL, TEST_PATTERN4); |
778 | 801 | ||
779 | if (((ATA_NSECTOR & READ_PATTERN1_MASK) == READ_PATTERN1) && | 802 | if ((ATA_IN8(ATA_NSECTOR) == TEST_PATTERN1) && |
780 | ((ATA_SECTOR & READ_PATTERN2_MASK) == READ_PATTERN2) && | 803 | (ATA_IN8(ATA_SECTOR) == TEST_PATTERN2) && |
781 | ((ATA_LCYL & READ_PATTERN3_MASK) == READ_PATTERN3) && | 804 | (ATA_IN8(ATA_LCYL) == TEST_PATTERN3) && |
782 | ((ATA_HCYL & READ_PATTERN4_MASK) == READ_PATTERN4)) | 805 | (ATA_IN8(ATA_HCYL) == TEST_PATTERN4)) |
783 | return 0; | 806 | return 0; |
807 | |||
808 | sleep(1); | ||
784 | } | 809 | } |
785 | return -2; | 810 | return -2; |
786 | } | 811 | } |
@@ -790,12 +815,12 @@ static int freeze_lock(void) | |||
790 | /* does the disk support Security Mode feature set? */ | 815 | /* does the disk support Security Mode feature set? */ |
791 | if (identify_info[82] & 2) | 816 | if (identify_info[82] & 2) |
792 | { | 817 | { |
793 | SET_REG(ATA_SELECT, ata_device); | 818 | ATA_OUT8(ATA_SELECT, ata_device); |
794 | 819 | ||
795 | if (!wait_for_rdy()) | 820 | if (!wait_for_rdy()) |
796 | return -1; | 821 | return -1; |
797 | 822 | ||
798 | SET_REG(ATA_COMMAND, CMD_SECURITY_FREEZE_LOCK); | 823 | ATA_OUT8(ATA_COMMAND, CMD_SECURITY_FREEZE_LOCK); |
799 | 824 | ||
800 | if (!wait_for_rdy()) | 825 | if (!wait_for_rdy()) |
801 | return -2; | 826 | return -2; |
@@ -822,14 +847,14 @@ static int ata_perform_sleep(void) | |||
822 | return 0; | 847 | return 0; |
823 | } | 848 | } |
824 | 849 | ||
825 | SET_REG(ATA_SELECT, ata_device); | 850 | ATA_OUT8(ATA_SELECT, ata_device); |
826 | 851 | ||
827 | if(!wait_for_rdy()) { | 852 | if(!wait_for_rdy()) { |
828 | DEBUGF("ata_perform_sleep() - not RDY\n"); | 853 | DEBUGF("ata_perform_sleep() - not RDY\n"); |
829 | return -1; | 854 | return -1; |
830 | } | 855 | } |
831 | 856 | ||
832 | SET_REG(ATA_COMMAND, CMD_SLEEP); | 857 | ATA_OUT8(ATA_COMMAND, CMD_SLEEP); |
833 | 858 | ||
834 | if (!wait_for_rdy()) | 859 | if (!wait_for_rdy()) |
835 | { | 860 | { |
@@ -989,7 +1014,7 @@ static int ata_hard_reset(void) | |||
989 | ata_reset(); | 1014 | ata_reset(); |
990 | 1015 | ||
991 | /* state HRR2 */ | 1016 | /* state HRR2 */ |
992 | SET_REG(ATA_SELECT, ata_device); /* select the right device */ | 1017 | ATA_OUT8(ATA_SELECT, ata_device); /* select the right device */ |
993 | ret = wait_for_bsy(); | 1018 | ret = wait_for_bsy(); |
994 | 1019 | ||
995 | /* Massage the return code so it is 0 on success and -1 on failure */ | 1020 | /* Massage the return code so it is 0 on success and -1 on failure */ |
@@ -1010,15 +1035,15 @@ static int perform_soft_reset(void) | |||
1010 | int ret; | 1035 | int ret; |
1011 | int retry_count; | 1036 | int retry_count; |
1012 | 1037 | ||
1013 | SET_REG(ATA_SELECT, SELECT_LBA | ata_device ); | 1038 | ATA_OUT8(ATA_SELECT, SELECT_LBA | ata_device ); |
1014 | SET_REG(ATA_CONTROL, CONTROL_nIEN|CONTROL_SRST ); | 1039 | ATA_OUT8(ATA_CONTROL, CONTROL_nIEN|CONTROL_SRST ); |
1015 | sleep(1); /* >= 5us */ | 1040 | sleep(1); /* >= 5us */ |
1016 | 1041 | ||
1017 | #ifdef HAVE_ATA_DMA | 1042 | #ifdef HAVE_ATA_DMA |
1018 | /* DMA requires INTRQ be enabled */ | 1043 | /* DMA requires INTRQ be enabled */ |
1019 | SET_REG(ATA_CONTROL, 0); | 1044 | ATA_OUT8(ATA_CONTROL, 0); |
1020 | #else | 1045 | #else |
1021 | SET_REG(ATA_CONTROL, CONTROL_nIEN); | 1046 | ATA_OUT8(ATA_CONTROL, CONTROL_nIEN); |
1022 | #endif | 1047 | #endif |
1023 | sleep(1); /* >2ms */ | 1048 | sleep(1); /* >2ms */ |
1024 | 1049 | ||
@@ -1089,15 +1114,15 @@ static int ata_power_on(void) | |||
1089 | static int master_slave_detect(void) | 1114 | static int master_slave_detect(void) |
1090 | { | 1115 | { |
1091 | /* master? */ | 1116 | /* master? */ |
1092 | SET_REG(ATA_SELECT, 0); | 1117 | ATA_OUT8(ATA_SELECT, 0); |
1093 | if ( ATA_STATUS & (STATUS_RDY|STATUS_BSY) ) { | 1118 | if (ATA_IN8(ATA_STATUS) & (STATUS_RDY|STATUS_BSY)) { |
1094 | ata_device = 0; | 1119 | ata_device = 0; |
1095 | DEBUGF("Found master harddisk\n"); | 1120 | DEBUGF("Found master harddisk\n"); |
1096 | } | 1121 | } |
1097 | else { | 1122 | else { |
1098 | /* slave? */ | 1123 | /* slave? */ |
1099 | SET_REG(ATA_SELECT, SELECT_DEVICE1); | 1124 | ATA_OUT8(ATA_SELECT, SELECT_DEVICE1); |
1100 | if ( ATA_STATUS & (STATUS_RDY|STATUS_BSY) ) { | 1125 | if (ATA_IN8(ATA_STATUS) & (STATUS_RDY|STATUS_BSY)) { |
1101 | ata_device = SELECT_DEVICE1; | 1126 | ata_device = SELECT_DEVICE1; |
1102 | DEBUGF("Found slave harddisk\n"); | 1127 | DEBUGF("Found slave harddisk\n"); |
1103 | } | 1128 | } |
@@ -1111,13 +1136,13 @@ static int identify(void) | |||
1111 | { | 1136 | { |
1112 | int i; | 1137 | int i; |
1113 | 1138 | ||
1114 | SET_REG(ATA_SELECT, ata_device); | 1139 | ATA_OUT8(ATA_SELECT, ata_device); |
1115 | 1140 | ||
1116 | if(!wait_for_rdy()) { | 1141 | if(!wait_for_rdy()) { |
1117 | DEBUGF("identify() - not RDY\n"); | 1142 | DEBUGF("identify() - not RDY\n"); |
1118 | return -1; | 1143 | return -1; |
1119 | } | 1144 | } |
1120 | SET_REG(ATA_COMMAND, CMD_IDENTIFY); | 1145 | ATA_OUT8(ATA_COMMAND, CMD_IDENTIFY); |
1121 | 1146 | ||
1122 | if (!wait_for_start_of_transfer()) | 1147 | if (!wait_for_start_of_transfer()) |
1123 | { | 1148 | { |
@@ -1128,11 +1153,7 @@ static int identify(void) | |||
1128 | for (i=0; i<SECTOR_SIZE/2; i++) { | 1153 | for (i=0; i<SECTOR_SIZE/2; i++) { |
1129 | /* the IDENTIFY words are already swapped, so we need to treat | 1154 | /* the IDENTIFY words are already swapped, so we need to treat |
1130 | this info differently that normal sector data */ | 1155 | this info differently that normal sector data */ |
1131 | #if defined(ROCKBOX_BIG_ENDIAN) && !defined(ATA_SWAP_WORDS) | 1156 | identify_info[i] = ATA_SWAP_IDENTIFY(ATA_IN16(ATA_DATA)); |
1132 | identify_info[i] = swap16(ATA_DATA); | ||
1133 | #else | ||
1134 | identify_info[i] = ATA_DATA; | ||
1135 | #endif | ||
1136 | } | 1157 | } |
1137 | 1158 | ||
1138 | return 0; | 1159 | return 0; |
@@ -1140,15 +1161,15 @@ static int identify(void) | |||
1140 | 1161 | ||
1141 | static int set_multiple_mode(int sectors) | 1162 | static int set_multiple_mode(int sectors) |
1142 | { | 1163 | { |
1143 | SET_REG(ATA_SELECT, ata_device); | 1164 | ATA_OUT8(ATA_SELECT, ata_device); |
1144 | 1165 | ||
1145 | if(!wait_for_rdy()) { | 1166 | if(!wait_for_rdy()) { |
1146 | DEBUGF("set_multiple_mode() - not RDY\n"); | 1167 | DEBUGF("set_multiple_mode() - not RDY\n"); |
1147 | return -1; | 1168 | return -1; |
1148 | } | 1169 | } |
1149 | 1170 | ||
1150 | SET_REG(ATA_NSECTOR, sectors); | 1171 | ATA_OUT8(ATA_NSECTOR, sectors); |
1151 | SET_REG(ATA_COMMAND, CMD_SET_MULTIPLE_MODE); | 1172 | ATA_OUT8(ATA_COMMAND, CMD_SET_MULTIPLE_MODE); |
1152 | 1173 | ||
1153 | if (!wait_for_rdy()) | 1174 | if (!wait_for_rdy()) |
1154 | { | 1175 | { |
@@ -1221,7 +1242,7 @@ static int set_features(void) | |||
1221 | features[4].parameter = dma_mode; | 1242 | features[4].parameter = dma_mode; |
1222 | #endif /* HAVE_ATA_DMA */ | 1243 | #endif /* HAVE_ATA_DMA */ |
1223 | 1244 | ||
1224 | SET_REG(ATA_SELECT, ata_device); | 1245 | ATA_OUT8(ATA_SELECT, ata_device); |
1225 | 1246 | ||
1226 | if (!wait_for_rdy()) { | 1247 | if (!wait_for_rdy()) { |
1227 | DEBUGF("set_features() - not RDY\n"); | 1248 | DEBUGF("set_features() - not RDY\n"); |
@@ -1230,19 +1251,19 @@ static int set_features(void) | |||
1230 | 1251 | ||
1231 | for (i=0; i < (int)(sizeof(features)/sizeof(features[0])); i++) { | 1252 | for (i=0; i < (int)(sizeof(features)/sizeof(features[0])); i++) { |
1232 | if (identify_info[features[i].id_word] & BIT_N(features[i].id_bit)) { | 1253 | if (identify_info[features[i].id_word] & BIT_N(features[i].id_bit)) { |
1233 | SET_REG(ATA_FEATURE, features[i].subcommand); | 1254 | ATA_OUT8(ATA_FEATURE, features[i].subcommand); |
1234 | SET_REG(ATA_NSECTOR, features[i].parameter); | 1255 | ATA_OUT8(ATA_NSECTOR, features[i].parameter); |
1235 | SET_REG(ATA_COMMAND, CMD_SET_FEATURES); | 1256 | ATA_OUT8(ATA_COMMAND, CMD_SET_FEATURES); |
1236 | 1257 | ||
1237 | if (!wait_for_rdy()) { | 1258 | if (!wait_for_rdy()) { |
1238 | DEBUGF("set_features() - CMD failed\n"); | 1259 | DEBUGF("set_features() - CMD failed\n"); |
1239 | return -10 - i; | 1260 | return -10 - i; |
1240 | } | 1261 | } |
1241 | 1262 | ||
1242 | if((ATA_ALT_STATUS & STATUS_ERR) && (i != 1)) { | 1263 | if((ATA_IN8(ATA_ALT_STATUS) & STATUS_ERR) && (i != 1)) { |
1243 | /* some CF cards don't like advanced powermanagement | 1264 | /* some CF cards don't like advanced powermanagement |
1244 | even if they mark it as supported - go figure... */ | 1265 | even if they mark it as supported - go figure... */ |
1245 | if(ATA_ERROR & ERROR_ABRT) { | 1266 | if(ATA_IN8(ATA_ERROR) & ERROR_ABRT) { |
1246 | return -20 - i; | 1267 | return -20 - i; |
1247 | } | 1268 | } |
1248 | } | 1269 | } |
@@ -1327,7 +1348,7 @@ int ata_init(void) | |||
1327 | 1348 | ||
1328 | #ifdef HAVE_ATA_DMA | 1349 | #ifdef HAVE_ATA_DMA |
1329 | /* DMA requires INTRQ be enabled */ | 1350 | /* DMA requires INTRQ be enabled */ |
1330 | SET_REG(ATA_CONTROL, 0); | 1351 | ATA_OUT8(ATA_CONTROL, 0); |
1331 | #endif | 1352 | #endif |
1332 | 1353 | ||
1333 | /* first try, hard reset at cold start only */ | 1354 | /* first try, hard reset at cold start only */ |
@@ -1335,9 +1356,9 @@ int ata_init(void) | |||
1335 | 1356 | ||
1336 | if (rc) | 1357 | if (rc) |
1337 | { /* failed? -> second try, always with hard reset */ | 1358 | { /* failed? -> second try, always with hard reset */ |
1338 | DEBUGF("ata: init failed, retrying...\n"); | 1359 | // DEBUGF("ata: init failed, retrying...\n"); |
1339 | rc = init_and_check(true); | 1360 | // rc = init_and_check(true); |
1340 | if (rc) | 1361 | // if (rc) |
1341 | return rc; | 1362 | return rc; |
1342 | } | 1363 | } |
1343 | 1364 | ||
@@ -1469,7 +1490,6 @@ void ata_get_info(IF_MD2(int drive,)struct storage_info *info) | |||
1469 | #endif | 1490 | #endif |
1470 | int i; | 1491 | int i; |
1471 | info->sector_size = SECTOR_SIZE; | 1492 | info->sector_size = SECTOR_SIZE; |
1472 | info->num_sectors= total_sectors; | ||
1473 | 1493 | ||
1474 | src = (unsigned short*)&identify_info[27]; | 1494 | src = (unsigned short*)&identify_info[27]; |
1475 | dest = (unsigned short*)vendor; | 1495 | dest = (unsigned short*)vendor; |