patch-2.0.9 linux/drivers/block/ide.c
Next file: linux/drivers/block/ide.h
Previous file: linux/drivers/block/genhd.c
Back to the patch index
Back to the overall index
- Lines: 181
- Date:
Wed Jul 24 07:48:47 1996
- Orig file:
v2.0.8/linux/drivers/block/ide.c
- Orig date:
Tue Jul 23 08:23:12 1996
diff -u --recursive --new-file v2.0.8/linux/drivers/block/ide.c linux/drivers/block/ide.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/block/ide.c Version 5.43 May 14, 1996
+ * linux/drivers/block/ide.c Version 5.45 Jul 22, 1996
*
* Copyright (C) 1994-1996 Linus Torvalds & authors (see below)
*/
@@ -238,6 +238,11 @@
* Version 5.42 simplify irq-masking after probe
* fix NULL pointer deref in save_match()
* Version 5.43 Ugh.. unexpected_intr is back: try to exterminate it
+ * Version 5.44 Fix for "irq probe failed" on cmd640
+ * change path on message regarding MAKEDEV.ide
+ * add a throttle to the unexpected_intr() messages
+ * Version 5.45 fix ugly parameter parsing bugs (thanks Derek)
+ * include Gadi's magic fix for cmd640 unexpected_intr
*
* Some additional driver compile-time options are in ide.h
*
@@ -284,7 +289,6 @@
#endif /* CONFIG_BLK_DEV_PROMISE */
static const byte ide_hwif_to_major[MAX_HWIFS] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR};
-
static const unsigned short default_io_base[MAX_HWIFS] = {0x1f0, 0x170, 0x1e8, 0x168};
static const byte default_irqs[MAX_HWIFS] = {14, 15, 11, 10};
@@ -580,6 +584,8 @@
gd->part = kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL);
bs = kmalloc (minors*sizeof(int), GFP_KERNEL);
+ memset(gd->part, 0, minors * sizeof(struct hd_struct));
+
/* cdroms and msdos f/s are examples of non-1024 blocksizes */
blksize_size[hwif->major] = bs;
for (unit = 0; unit < minors; ++unit)
@@ -1619,6 +1625,7 @@
byte stat;
unsigned int unit;
ide_hwif_t *hwif = hwgroup->hwif;
+ static unsigned long last_time = 0;
/*
* handle the unexpected interrupt
@@ -1630,8 +1637,12 @@
if (!drive->present)
continue;
SELECT_DRIVE(hwif,drive);
- if (!OK_STAT(stat=GET_STAT(), drive->ready_stat, BAD_STAT))
- (void) ide_dump_status(drive, "unexpected_intr", stat);
+ if (!OK_STAT(stat=GET_STAT(), drive->ready_stat, BAD_STAT)) {
+ if ((last_time + (HZ/2)) < jiffies && !drive->ignore_unexp) {
+ last_time = jiffies;
+ (void) ide_dump_status(drive, "unexpected_intr", stat);
+ }
+ }
if ((stat & DRQ_STAT))
try_to_flush_leftover_data(drive);
}
@@ -1645,8 +1656,8 @@
*/
void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
{
- ide_hwgroup_t *hwgroup = dev_id;
- ide_handler_t *handler;
+ ide_hwgroup_t *hwgroup = dev_id;
+ ide_handler_t *handler;
if (irq == hwgroup->hwif->irq && (handler = hwgroup->handler) != NULL) {
ide_drive_t *drive = hwgroup->drive;
@@ -1658,7 +1669,7 @@
cli(); /* this is necessary, as next rq may be different irq */
if (hwgroup->handler == NULL) {
SET_RECOVERY_TIMER(HWIF(drive));
- ide_do_request(hwgroup);
+ ide_do_request(hwgroup);
}
} else {
unexpected_intr(irq, hwgroup);
@@ -1899,8 +1910,13 @@
};
drive->part[0].nr_sects = current_capacity(drive);
- if (drive->media == ide_disk)
- resetup_one_dev(HWIF(drive)->gd, drive->select.b.unit);
+ if (drive->media != ide_disk)
+ drive->part[0].start_sect = -1;
+ resetup_one_dev(HWIF(drive)->gd, drive->select.b.unit);
+#ifdef CONFIG_BLK_DEV_IDECD
+ if (drive->media == ide_cdrom)
+ ide_cdrom_setup(drive);
+#endif /* CONFIG_BLK_DEV_IDECD */
drive->busy = 0;
wake_up(&drive->wqueue);
@@ -2194,7 +2210,7 @@
if ((id->model[0] == 'N' && id->model[1] == 'E') /* NEC */
|| (id->model[0] == 'F' && id->model[1] == 'X') /* Mitsumi */
|| (id->model[0] == 'P' && id->model[1] == 'i'))/* Pioneer */
- bswap = 0; /* Vertos drives may still be weird */
+ bswap ^= 1; /* Vertos drives may still be weird */
}
ide_fixstring (id->model, sizeof(id->model), bswap);
ide_fixstring (id->fw_rev, sizeof(id->fw_rev), bswap);
@@ -2367,10 +2383,15 @@
*/
static int try_to_identify (ide_drive_t *drive, byte cmd)
{
- int hd_status, rc;
+ int irqs, rc;
unsigned long timeout;
- int irqs = 0;
+#ifdef CONFIG_BLK_DEV_CMD640
+ int retry = 0;
+ int hd_status;
+try_again:
+#endif /* CONFIG_BLK_DEV_CMD640 */
+ irqs = 0;
if (!HWIF(drive)->irq) { /* already got an IRQ? */
probe_irq_off(probe_irq_on()); /* clear dangling irqs */
irqs = probe_irq_on(); /* start monitoring irqs */
@@ -2428,16 +2449,28 @@
irqs = probe_irq_on();
OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* mask device irq */
udelay(5);
- (void) GET_STAT(); /* clear drive IRQ */
(void) probe_irq_off(irqs);
+ (void) probe_irq_off(probe_irq_on()); /* clear self-inflicted irq */
+ (void) GET_STAT(); /* clear drive IRQ */
+
} else { /* Mmmm.. multiple IRQs.. don't know which was ours */
printk("%s: IRQ probe failed (%d)\n", drive->name, irqs);
#ifdef CONFIG_BLK_DEV_CMD640
if (HWIF(drive)->chipset == ide_cmd640) {
extern byte (*get_cmd640_reg)(int);
+ byte reg9 = get_cmd640_reg(0x09);
printk("%s: Hmmm.. probably a driver problem.\n", drive->name);
- printk("%s: cmd640 reg 09h == 0x%02x\n", drive->name, get_cmd640_reg(9));
+ printk("%s: cmd640 reg 09h == 0x%02x\n", drive->name, reg9);
printk("%s: cmd640 reg 51h == 0x%02x\n", drive->name, get_cmd640_reg(0x51));
+ if (reg9 == 0x0a) {
+ printk("%s: perhaps PCI INTA has not been set to IRQ15?\n", drive->name);
+ if (retry++ == 0) {
+ extern void (*put_cmd640_reg)(int, int);
+ printk("%s: switching secondary interface to legacy mode\n", drive->name);
+ put_cmd640_reg(0x09,0x00);
+ goto try_again;
+ }
+ }
}
#endif /* CONFIG_BLK_DEV_CMD640 */
}
@@ -2832,7 +2865,7 @@
/*
* Cryptic check to ensure chipset not already set for hwif:
*/
- if (i != -1 && i != -2) {
+ if (i >= 0 || i <= -5) {
if (hwif->chipset != ide_unknown)
goto bad_option;
if (i < 0 && ide_hwifs[1].chipset != ide_unknown)
@@ -2841,7 +2874,7 @@
/*
* Interface keywords work only for ide0:
*/
- if (i <= -6 && hw != 0)
+ if (i <= -5 && hw != 0)
goto bad_hwif;
switch (i) {
@@ -3058,7 +3091,9 @@
static int init_irq (ide_hwif_t *hwif)
{
unsigned long flags;
+#if MAX_HWIFS > 1
unsigned int index;
+#endif /* MAX_HWIFS > 1 */
ide_hwgroup_t *hwgroup;
ide_hwif_t *match = NULL;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov