patch-2.3.4 linux/drivers/block/ide.c

Next file: linux/drivers/block/loop.c
Previous file: linux/drivers/block/ide-probe.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.3/linux/drivers/block/ide.c linux/drivers/block/ide.c
@@ -230,7 +230,6 @@
 		drive->media			= ide_disk;
 		drive->select.all		= (unit<<4)|0xa0;
 		drive->hwif			= hwif;
-		init_waitqueue_head(&drive->wqueue);
 		drive->ctl			= 0x08;
 		drive->ready_stat		= READY_STAT;
 		drive->bad_wstat		= BAD_W_STAT;
@@ -296,8 +295,9 @@
 
 	if (drive->removable && id != NULL) {
 		if (!strncmp(id->model, "KODAK ATA_FLASH", 15)	/* Kodak */
-		 || !strncmp(id->model, "Hitachi CV", 10)		/* Hitachi */
-		 || !strncmp(id->model, "SunDisk SDCFB", 13))	/* SunDisk */
+		 || !strncmp(id->model, "Hitachi CV", 10)	/* Hitachi */
+		 || !strncmp(id->model, "SunDisk SDCFB", 13)	/* SunDisk */
+		 || !strncmp(id->model, "HAGIWARA HPC", 12))	/* Hagiwara */
 		{
 			return 1;	/* yes, it is a flash memory card */
 		}
@@ -956,6 +956,7 @@
 int ide_wait_stat (ide_drive_t *drive, byte good, byte bad, unsigned long timeout)
 {
 	byte stat;
+	int i;
 	unsigned long flags;
 
 	udelay(1);	/* spec allows drive 400ns to assert "BUSY" */
@@ -972,9 +973,18 @@
 		}
 		__restore_flags(flags);	/* local CPU only */
 	}
-	udelay(1);	/* allow status to settle, then read it again */
-	if (OK_STAT((stat = GET_STAT()), good, bad))
-		return 0;
+	/*
+	 * Allow status to settle, then read it again.
+	 * A few rare drives vastly violate the 400ns spec here,
+	 * so we'll wait up to 10usec for a "good" status
+	 * rather than expensively fail things immediately.
+	 * This fix courtesy of Matthew Faupel & Niccolo Rigacci.
+	 */
+	for (i = 0; i < 10; i++) {
+		udelay(1);
+		if (OK_STAT((stat = GET_STAT()), good, bad))
+			return 0;
+	}
 	ide_error(drive, "status error", stat);
 	return 1;
 }
@@ -1540,8 +1550,10 @@
 	struct request *cur_rq;
 	DECLARE_MUTEX_LOCKED(sem);
 
-	if (IS_PDC4030_DRIVE && rq->buffer != NULL)
+#ifdef CONFIG_BLK_DEV_PDC4030
+	if (HWIF(drive)->chipset == ide_pdc4030 && rq->buffer != NULL)
 		return -ENOSYS;  /* special drive cmds not supported */
+#endif
 	rq->errors = 0;
 	rq->rq_status = RQ_ACTIVE;
 	rq->rq_dev = MKDEV(major,(drive->select.b.unit)<<PARTN_BITS);
@@ -1770,6 +1782,8 @@
 	sti();
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
 		drive = &hwif->drives[unit];
+		if (!drive->present)
+			continue;
 		minor = drive->select.b.unit << PARTN_BITS;
 		for (p = 0; p < (1<<PARTN_BITS); ++p) {
 			if (drive->part[p].nr_sects > 0) {
@@ -2777,8 +2791,8 @@
 #ifdef CONFIG_BLK_DEV_PDC4030
 			case -14: /* "dc4030" */
 			{
-				extern void setup_pdc4030(ide_hwif_t *);
-				setup_pdc4030(hwif);
+				extern void init_pdc4030(void);
+				init_pdc4030();
 				goto done;
 			}
 #endif /* CONFIG_BLK_DEV_PDC4030 */
@@ -3031,8 +3045,8 @@
 #endif /* CONFIG_BLK_DEV_CMD640 */
 #ifdef CONFIG_BLK_DEV_PDC4030
 	{
-		extern int init_pdc4030(void);
-		(void) init_pdc4030();
+		extern int ide_probe_for_pdc4030(void);
+		(void) ide_probe_for_pdc4030();
 	}
 #endif /* CONFIG_BLK_DEV_PDC4030 */
 #ifdef CONFIG_BLK_DEV_IDE_PMAC

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)