Hi.
I have the same problem with iei/juki-511 and iei/lx-800.
This patch allow to load from slave.

-- 
Nikolay
diff -Nru filo-0.5/drivers/ide.c filo-0.5-slave/drivers/ide.c
--- filo-0.5/drivers/ide.c	2006-09-06 13:43:26.000000000 +0600
+++ filo-0.5-slave/drivers/ide.c	2007-09-17 15:18:20.000000000 +0600
@@ -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);
@@ -886,21 +910,37 @@
 	 */
 
 	/* 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);
+
+	/* 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 */
+	info = &harddisk_info[drive];
+	if (!info->drive_exists && drive & 1) {
+		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);
+	}
+
 	return 0;
 }
 
@@ -1123,7 +1163,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
[email protected]
http://www.linuxbios.org/mailman/listinfo/linuxbios

Reply via email to