[LinuxBIOS] r38 - trunk/filo-0.5/drivers

svn at openbios.org svn at openbios.org
Thu Oct 4 08:12:32 CEST 2007


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 <nikolaypetukhov at gmail.com> 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 <rminnich at gmail.com>
Acked-by: Stefan Reinauer <stepan at coresystems.de>

                                                                  


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;





More information about the coreboot mailing list