summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/drivers/ata.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 2140456..4780cf5 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -1351,20 +1351,6 @@ int ata_init(void)
DEBUGF("ata: %d sectors per ata request\n",multisectors);
-#ifdef MAX_PHYS_SECTOR_SIZE
- /* Find out the physical sector size */
- if((identify_info[106] & 0xe000) == 0x6000)
- phys_sector_mult = BIT_N(identify_info[106] & 0x000f);
- else
- phys_sector_mult = 1;
-
- DEBUGF("ata: %d logical sectors per phys sector", phys_sector_mult);
-
- if (phys_sector_mult > (MAX_PHYS_SECTOR_SIZE/SECTOR_SIZE))
- panicf("Unsupported physical sector size: %d",
- phys_sector_mult * SECTOR_SIZE);
-#endif
-
total_sectors = identify_info[60] | (identify_info[61] << 16);
#ifdef HAVE_LBA48
@@ -1387,6 +1373,32 @@ int ata_init(void)
if (rc)
return -60 + rc;
+#ifdef MAX_PHYS_SECTOR_SIZE
+ /* Find out the physical sector size */
+ if((identify_info[106] & 0xe000) == 0x6000)
+ phys_sector_mult = BIT_N(identify_info[106] & 0x000f);
+ else
+ phys_sector_mult = 1;
+
+ DEBUGF("ata: %d logical sectors per phys sector", phys_sector_mult);
+
+ if (phys_sector_mult > 1)
+ {
+ /* Check if drive really needs emulation - if we can access
+ * sector 1 then assume the drive will handle it better than
+ * us, and ignore the large physical sectors.
+ */
+ char throwaway[SECTOR_SIZE];
+ rc = ata_transfer_sectors(1, 1, &throwaway, false);
+ if (rc == 0)
+ phys_sector_mult = 1;
+ }
+
+ if (phys_sector_mult > (MAX_PHYS_SECTOR_SIZE/SECTOR_SIZE))
+ panicf("Unsupported physical sector size: %d",
+ phys_sector_mult * SECTOR_SIZE);
+#endif
+
mutex_lock(&ata_mtx); /* Balance unlock below */
last_disk_activity = current_tick;