Author: stepan
Date: 2007-10-04 08:12:32 +0200 (Thu, 04 Oct 2007)
New Revision: 38

Modified:
   trunk/filo-0.5/drivers/ide.c
Log:
This code is originally from Nikolay Petukhov <[EMAIL PROTECTED]> with
one minor change                                           
from me. It enables the option of having only slaves on ide, such as the CF
found on the msm800sev.                                       
                                                                                
                                                          
This code has been tested on the msm800sev with one master, master and slave,
and only slave and works. I'd like to see some other tests before we commit.
IDE is touchy.  

Signed-off-by: Ronald G. Minnich <[EMAIL PROTECTED]>
Acked-by: Stefan Reinauer <[EMAIL PROTECTED]>

                                                                  


Modified: trunk/filo-0.5/drivers/ide.c
===================================================================
--- trunk/filo-0.5/drivers/ide.c        2007-10-02 19:30:23 UTC (rev 37)
+++ trunk/filo-0.5/drivers/ide.c        2007-10-04 06:12:32 UTC (rev 38)
@@ -280,8 +280,29 @@
                        inb(IDE_REG_STATUS(ctrl)), inb(IDE_REG_ERROR(ctrl)));
 }
 
+int select_drive(struct controller *ctrl, int drive)
+{
+       int device, status;
+
+       outb(0xa0 | (drive << 4), IDE_REG_DEVICE(ctrl));
+       status = inb(IDE_REG_STATUS(ctrl));
+
+       mdelay(10);
+       
+       device = inb(IDE_REG_DEVICE(ctrl));
+       status = inb(IDE_REG_STATUS(ctrl));
+       
+       if (device == (0xa0 | (drive<<4)))
+               return 1;
+       else
+               return 0;
+}
+
 static int ide_software_reset(struct controller *ctrl)
 {
+       int master_exist = select_drive(ctrl, 0);
+       int slave_exist = select_drive(ctrl, 1);
+
        /* Wait a little bit in case this is immediately after
         * hardware reset.
         */
@@ -303,7 +324,10 @@
                IDE_REG_DEVICE_CONTROL(ctrl));
        /* If BSY bit is not asserted within 400ns, no device there */
        if (await_ide(bsy, ctrl, currticks() + IDE_RESET_PULSE) < 0) {
-               return -1;
+               if (slave_exist)
+                       printf ("reset failed, but slave maybe exist\n");
+               else
+                       return -1;
        }
        outb(IDE_CTRL_HD15 | IDE_CTRL_NIEN, IDE_REG_DEVICE_CONTROL(ctrl));
        mdelay(2);
@@ -863,6 +887,7 @@
         * is quite rare.
         * 
         */
+       debug("init_controller: drive %d\n", drive);
 #if !BSY_SET_DURING_SPINUP
        if (await_ide(timeout, ctrl, currticks() + IDE_TIMEOUT) < 0) {
                return -1;
@@ -886,21 +911,44 @@
         */
 
        /* Now initialize the individual drives */
-       info = &harddisk_info[drive];
-       init_drive(info, ctrl, 0, drive, buffer, IDE_CMD_IDENTIFY_DEVICE);
+       int master_drive = drive & ~1;
+       info = &harddisk_info[master_drive];
+
+       /* master */
+       init_drive(info, ctrl, 0, master_drive, buffer, 
IDE_CMD_IDENTIFY_DEVICE);
+
        if (!info->drive_exists)
-               init_drive(info, ctrl, 0, drive, buffer,
+               init_drive(info, ctrl, 0, master_drive, buffer,
                                IDE_CMD_IDENTIFY_PACKET_DEVICE);
+
+       debug("MASTER CHECK: master %s\n", 
+                       info->drive_exists ? "yes" : "no");
+       /* slave and master */
        if (info->drive_exists && !info->slave_absent) {
-               drive++;
+               master_drive++;
                info++;
-               init_drive(info, ctrl, 1, drive, buffer,
+               init_drive(info, ctrl, 1, master_drive, buffer,
                                IDE_CMD_IDENTIFY_DEVICE);
                if (!info->drive_exists)
-                       init_drive(info, ctrl, 1, drive, buffer,
+                       init_drive(info, ctrl, 1, master_drive, buffer,
                                        IDE_CMD_IDENTIFY_PACKET_DEVICE);
        }
 
+
+       /* slave */
+       debug("/*slave */ -- drive is %d\n", drive);
+       info = &harddisk_info[drive];
+       if (!info->drive_exists) {
+               debug("NO MASTER -- check slave!\n");
+               init_drive(info, ctrl, 1, drive, buffer, 
IDE_CMD_IDENTIFY_DEVICE);
+               
+               if (!info->drive_exists)
+                       init_drive(info, ctrl, 1, drive, buffer,
+                               IDE_CMD_IDENTIFY_PACKET_DEVICE);
+               debug("SLAVE ONLY CHECK: slave %s\n", 
+                               info->drive_exists ? "yes" : "no");
+       }
+
        return 0;
 }
 
@@ -1123,7 +1171,7 @@
                        printf("IDE channel %d not found\n", ctrl_index);
                        return -1;
                }
-               if (init_controller(ctrl, drive & ~1, ide_buffer) != 0) {
+               if (init_controller(ctrl, drive, ide_buffer) != 0) {
                        printf("No drive detected on IDE channel %d\n",
                                        ctrl_index);
                        return -1;


-- 
linuxbios mailing list
linuxbios@linuxbios.org
http://www.linuxbios.org/mailman/listinfo/linuxbios

Reply via email to