summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/ata.c60
1 files changed, 34 insertions, 26 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index b665dc09fd..fb60ae3895 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -797,6 +797,9 @@ unsigned short* ata_get_identify(void)
797 797
798int ata_init(void) 798int ata_init(void)
799{ 799{
800 int rc;
801 bool coldstart = (PACR2 & 0x4000) != 0;
802
800 mutex_init(&ata_mtx); 803 mutex_init(&ata_mtx);
801 804
802 led(false); 805 led(false);
@@ -809,33 +812,38 @@ int ata_init(void)
809 ata_enable(true); 812 ata_enable(true);
810 813
811 if ( !initialized ) { 814 if ( !initialized ) {
812 /* When starting from Flash, the disk is not yet ready when we get here. */ 815 if (coldstart)
813 /* Crude first fix is to block and poll here for a while,
814 can we do better? */
815 int time = 0;
816 while ((ATA_STATUS & STATUS_BSY))
817 { 816 {
818 if (time >= HZ*10) /* timeout, disk is not coming up */ 817 /* Reset both master and slave, we don't yet know what's in */
819 return -6; 818 /* this is safe because non-present devices don't report busy */
819 ata_device = 0;
820 if (ata_hard_reset())
821 return -1;
822 ata_device = SELECT_DEVICE1;
823 if (ata_hard_reset())
824 return -2;
825 }
820 826
821 sleep(HZ/10); 827 if (rc = master_slave_detect())
822 time += HZ/10; 828 return -10 + rc;
823 }; 829
824 830 if (rc = io_address_detect())
825 if (master_slave_detect()) 831 return -20 + rc;
826 return -1; 832
827 833 /* symptom fix: else check_registers() below may fail */
828 if (io_address_detect()) 834 if (coldstart && !wait_for_bsy())
829 return -2; 835 {
830 836 return -29;
831 if (check_registers()) 837 }
832 return -3;
833
834 if (freeze_lock())
835 return -4;
836 838
837 if (identify()) 839 if (rc = check_registers())
838 return -5; 840 return -30 + rc;
841
842 if (rc = freeze_lock())
843 return -40 + rc;
844
845 if (rc = identify())
846 return -50 + rc;
839 multisectors = identify_info[47] & 0xff; 847 multisectors = identify_info[47] & 0xff;
840 DEBUGF("ata: %d sectors per ata request\n",multisectors); 848 DEBUGF("ata: %d sectors per ata request\n",multisectors);
841 849
@@ -844,8 +852,8 @@ int ata_init(void)
844 sizeof(ata_stack), ata_thread_name); 852 sizeof(ata_stack), ata_thread_name);
845 initialized = true; 853 initialized = true;
846 } 854 }
847 if (set_multiple_mode(multisectors)) 855 if (rc = set_multiple_mode(multisectors))
848 return -6; 856 return -60 + rc;
849 857
850 return 0; 858 return 0;
851} 859}