summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@trik.(none)>2004-11-06 02:32:42 +0100
committerBartlomiej Zolnierkiewicz <bzolnier@trik.(none)>2004-11-06 02:32:42 +0100
commitdb01db102a3f12c83dc79bc378d4f81e425c4716 (patch)
tree5fdee1e0938bf914d54db4f5b26caf3ea8f55859
parentdc3f1bf75e1d7c37b1e7ed49294fc6753f81e2ab (diff)
[ide] siimage: fix the various SI3112 hangs
From: Alan Cox <alan@lxorguk.ukuu.org.uk> (some changes by me - bart) The current driver looks at fields before it is safe to, we move the mod15rm bug handler to be a fixup and this ensures the probe has been completed before we use the ident data. Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r--drivers/ide/pci/siimage.c22
-rw-r--r--drivers/ide/setup-pci.c4
-rw-r--r--include/linux/ide.h1
3 files changed, 22 insertions, 5 deletions
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index ab303f422f0a..17089f3eb350 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -955,6 +955,22 @@ static int is_dev_seagate_sata(ide_drive_t *drive)
}
/**
+ * siimage_fixup - post probe fixups
+ * @hwif: interface to fix up
+ *
+ * Called after drive probe we use this to decide whether the
+ * Seagate fixup must be applied. This used to be in init_iops but
+ * that can occur before we know what drives are present.
+ */
+
+static void __devinit siimage_fixup(ide_hwif_t *hwif)
+{
+ /* Try and raise the rqsize */
+ if (!is_sata(hwif) || !is_dev_seagate_sata(&hwif->drives[0]))
+ hwif->rqsize = 128;
+}
+
+/**
* init_iops_siimage - set up iops
* @hwif: interface to set up
*
@@ -974,9 +990,8 @@ static void __devinit init_iops_siimage(ide_hwif_t *hwif)
hwif->hwif_data = NULL;
- hwif->rqsize = 128;
- if (is_sata(hwif) && is_dev_seagate_sata(&hwif->drives[0]))
- hwif->rqsize = 15;
+ /* Pessimal until we finish probing */
+ hwif->rqsize = 15;
if (pci_get_drvdata(dev) == NULL)
return;
@@ -1064,6 +1079,7 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
.init_chipset = init_chipset_siimage, \
.init_iops = init_iops_siimage, \
.init_hwif = init_hwif_siimage, \
+ .fixup = siimage_fixup, \
.channels = 2, \
.autodma = AUTODMA, \
.bootable = ON_BOARD, \
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index 126c51dc2925..5ccb60e40839 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -707,9 +707,9 @@ void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d)
ata_index_t index_list = do_ide_setup_pci_device(dev, d, 1);
if ((index_list.b.low & 0xf0) != 0xf0)
- probe_hwif_init(&ide_hwifs[index_list.b.low]);
+ probe_hwif_init_with_fixup(&ide_hwifs[index_list.b.low], d->fixup);
if ((index_list.b.high & 0xf0) != 0xf0)
- probe_hwif_init(&ide_hwifs[index_list.b.high]);
+ probe_hwif_init_with_fixup(&ide_hwifs[index_list.b.high], d->fixup);
create_proc_ide_interfaces();
}
diff --git a/include/linux/ide.h b/include/linux/ide.h
index b7bfa3f233ea..ec81a19ec550 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1428,6 +1428,7 @@ typedef struct ide_pci_device_s {
void (*init_iops)(ide_hwif_t *);
void (*init_hwif)(ide_hwif_t *);
void (*init_dma)(ide_hwif_t *, unsigned long);
+ void (*fixup)(ide_hwif_t *);
u8 channels;
u8 autodma;
ide_pci_enablebit_t enablebits[2];