This is tested, it has one small different from the earlier patch.

I don't know where else to send the patch.

ron
Fix filo so that it can run with IDE channels that only have slaves.
Tested on the MSM800SEV, with master only, master and slave, 
and slave only.

From a patch by Nikolay Petukhov <[EMAIL PROTECTED]> with 
one change. 

I have no idea where to send this patch :-)

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

Index: drivers/ide.c
===================================================================
--- drivers/ide.c	(revision 34)
+++ drivers/ide.c	(working copy)
@@ -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