Index: firmware/export/ata.h
===================================================================
--- firmware/export/ata.h	(revision 12067)
+++ firmware/export/ata.h	(working copy)
@@ -36,6 +36,11 @@
 #define NUM_VOLUMES 1
 #endif
 
+#define ATA_SECTOR_SIZE 512
+#ifndef MAX_SECTOR_SIZE
+#define MAX_SECTOR_SIZE 512
+#endif
+
 extern void ata_enable(bool on);
 extern void ata_spindown(int seconds);
 extern void ata_poweroff(bool enable);
@@ -56,4 +61,8 @@
 extern long last_disk_activity;
 extern int ata_spinup_time; /* ticks */
 
+extern int ata_log_sectors_per_phys_sector;
+extern int ata_log_sector_size;
+extern int ata_phys_sector_size;
+
 #endif
Index: firmware/common/disk.c
===================================================================
--- firmware/common/disk.c	(revision 12067)
+++ firmware/common/disk.c	(working copy)
@@ -51,7 +51,7 @@
 struct partinfo* disk_init(IF_MV_NONVOID(int drive))
 {
     int i;
-    unsigned char sector[512];
+    unsigned char sector[MAX_SECTOR_SIZE];
 #ifdef HAVE_MULTIVOLUME
     /* For each drive, start at a different position, in order not to destroy 
        the first entry of drive 0. 
@@ -63,7 +63,8 @@
     struct partinfo* pinfo = part;
 #endif
 
-    ata_read_sectors(IF_MV2(drive,) 0,1,&sector);
+    ata_read_sectors(IF_MV2(drive,) 0,
+                     ata_log_sectors_per_phys_sector, &sector);
 
     /* check that the boot sector is initialized */
     if ( (sector[510] != 0x55) ||
@@ -152,7 +153,7 @@
        real problem. */
     for (i=0; volume != -1 && i<4; i++)
     {
-#ifdef MAX_SECTOR_SIZE
+#if MAX_SECTOR_SIZE > ATA_SECTOR_SIZE
         int j;
 
         for (j = 1; j <= (MAX_SECTOR_SIZE/SECTOR_SIZE); j <<= 1)
Index: firmware/drivers/ata.c
===================================================================
--- firmware/drivers/ata.c	(revision 12067)
+++ firmware/drivers/ata.c	(working copy)
@@ -92,6 +92,10 @@
 static int multisectors; /* number of supported multisectors */
 static unsigned short identify_info[SECTOR_SIZE];
 
+int ata_log_sectors_per_phys_sector;
+int ata_log_sector_size;
+int ata_phys_sector_size;
+
 static int ata_power_on(void);
 static int perform_soft_reset(void);
 static int set_multiple_mode(int sectors);
@@ -318,10 +322,7 @@
             /* read the status register exactly once per loop */
             status = ATA_STATUS;
 
-            /* if destination address is odd, use byte copying,
-               otherwise use word copying */
-
-            if (count >= multisectors )
+            if (multisectors && count >= multisectors )
                 sectors = multisectors;
             else
                 sectors = count;
@@ -724,10 +725,10 @@
     
     SET_REG(ATA_SELECT, SELECT_LBA | ata_device );
     SET_REG(ATA_CONTROL, CONTROL_nIEN|CONTROL_SRST );
-    sleep(1); /* >= 5us */
+    udelay(10); /* >= 5us */
 
     SET_REG(ATA_CONTROL, CONTROL_nIEN);
-    sleep(1); /* >2ms */
+    udelay(2500); /* >2ms */
 
     /* This little sucker can take up to 30 seconds */
     retry_count = 8;
@@ -975,9 +976,38 @@
         if (rc)
             return -40 + rc;
 
-        multisectors = identify_info[47] & 0xff;
-        DEBUGF("ata: %d sectors per ata request\n",multisectors);
+        if(identify_info[47] & 0x100) {
+            multisectors = identify_info[47] & 0xff;
+        } else {
+            /* The identify info is not valid, let's try with 16 */
+            multisectors = 16;
+        }
+        DEBUGF("ata: %d sectors per ata request\n",multisectors);            
 
+        /* Find out the physical sector size */
+        if((identify_info[106] & 0xc000) == 0x4000) {
+            ata_log_sectors_per_phys_sector = 1 << (identify_info[106]&0x000f);
+        } else {
+            ata_log_sectors_per_phys_sector = 1;
+        }
+        
+        DEBUGF("ata: %d log sectors per phys sector",
+               ata_log_sectors_per_phys_sector);
+
+        /* Find out the logical sector size */
+        if((identify_info[106] & 0xe000) == 0x6000) {
+            ata_log_sector_size = identify_info[117]*2;
+        } else {
+            ata_log_sector_size = ATA_SECTOR_SIZE;
+        }
+
+        DEBUGF("ata: log sector size: %d bytes", ata_log_sector_size);
+        
+        ata_phys_sector_size =
+            ata_log_sector_size * ata_log_sectors_per_phys_sector;
+        
+        DEBUGF("ata: phys sector size: %d bytes", ata_phys_sector_size);
+        
 #ifdef HAVE_LBA48
         if (identify_info[83] & 0x0400 /* 48 bit address support */
             && identify_info[60] == 0xFFFF  /* and disk size >= 128 GiB */
