diff options
| author | Bartlomiej Zolnierkiewicz <bzolnier@trik.(none)> | 2004-11-06 02:31:02 +0100 |
|---|---|---|
| committer | Bartlomiej Zolnierkiewicz <bzolnier@trik.(none)> | 2004-11-06 02:31:02 +0100 |
| commit | dc3f1bf75e1d7c37b1e7ed49294fc6753f81e2ab (patch) | |
| tree | a15925d727c27bf83e40e35474e8ec0dd58db41e | |
| parent | 4d81fe20ebfef6a993dda2f496c3141442f96142 (diff) | |
[ide] apply undecoded slave fixup only for ide-cs
From: Alan Cox <alan@lxorguk.ukuu.org.uk>
(some changes by me - bart)
We add probe_hwif_init_with_fixup (seperate naming as requested by
Bartlomiej). This runs a fixup on present interfaces before attaching
the drives. In order to be useful we need also an _with_fixup version
of ide_register_hw function.
The sometimes troublesome undecoded slave detector is moved to its own
function and exported so that ide-cs and the upcoming delkin_cb can both
use it (along with any arch specific cf/pcmcia drivers I don't know
about). The non-relevant checks for this scenario are removed.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
| -rw-r--r-- | drivers/ide/ide-probe.c | 63 | ||||
| -rw-r--r-- | drivers/ide/ide.c | 14 | ||||
| -rw-r--r-- | drivers/ide/legacy/ide-cs.c | 2 | ||||
| -rw-r--r-- | include/linux/ide.h | 4 |
4 files changed, 64 insertions, 19 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index ca53e05a88ed..7b6d9c991ca2 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -652,6 +652,43 @@ static int wait_hwif_ready(ide_hwif_t *hwif) return rc; } +/** + * ide_undecoded_slave - look for bad CF adapters + * @hwif: interface + * + * Analyse the drives on the interface and attempt to decide if we + * have the same drive viewed twice. This occurs with crap CF adapters + * and PCMCIA sometimes. + */ + +void ide_undecoded_slave(ide_hwif_t *hwif) +{ + ide_drive_t *drive0 = &hwif->drives[0]; + ide_drive_t *drive1 = &hwif->drives[1]; + + if (drive0->present == 0 || drive1->present == 0) + return; + + /* If the models don't match they are not the same product */ + if (strcmp(drive0->id->model, drive1->id->model)) + return; + + /* Serial numbers do not match */ + if (strncmp(drive0->id->serial_no, drive1->id->serial_no, 20)) + return; + + /* No serial number, thankfully very rare for CF */ + if (drive0->id->serial_no[0] == 0) + return; + + /* Appears to be an IDE flash adapter with decode bugs */ + printk(KERN_WARNING "ide-probe: ignoring undecoded slave\n"); + + drive1->present = 0; +} + +EXPORT_SYMBOL_GPL(ide_undecoded_slave); + /* * This routine only knows how to look for drive units 0 and 1 * on an interface, so any setting of MAX_DRIVES > 2 won't work here. @@ -723,20 +760,6 @@ static void probe_hwif(ide_hwif_t *hwif) ide_drive_t *drive = &hwif->drives[unit]; drive->dn = (hwif->channel ? 2 : 0) + unit; (void) probe_for_drive(drive); - if (drive->present && hwif->present && unit == 1) { - if (strcmp(hwif->drives[0].id->model, drive->id->model) == 0 && - /* Don't do this for noprobe or non ATA */ - strcmp(drive->id->model, "UNKNOWN") && - /* And beware of confused Maxtor drives that go "M0000000000" - "The SN# is garbage in the ID block..." [Eric] */ - strncmp(drive->id->serial_no, "M0000000000000000000", 20) && - /* Same goes for another set of Maxtor drives that say "D3000000" */ - strncmp(drive->id->serial_no, "D3000000", 8) && - strncmp(hwif->drives[0].id->serial_no, drive->id->serial_no, 20) == 0) { - printk(KERN_WARNING "ide-probe: ignoring undecoded slave\n"); - drive->present = 0; - } - } if (drive->present && !hwif->present) { hwif->present = 1; if (hwif->chipset != ide_4drives || @@ -810,9 +833,14 @@ static void probe_hwif(ide_hwif_t *hwif) } static int hwif_init(ide_hwif_t *hwif); -int probe_hwif_init (ide_hwif_t *hwif) + +int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif)) { probe_hwif(hwif); + + if (fixup) + fixup(hwif); + hwif_init(hwif); if (hwif->present) { @@ -830,6 +858,11 @@ int probe_hwif_init (ide_hwif_t *hwif) return 0; } +int probe_hwif_init(ide_hwif_t *hwif) +{ + return probe_hwif_init_with_fixup(hwif, NULL); +} + EXPORT_SYMBOL(probe_hwif_init); #if MAX_HWIFS > 1 diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 427f633dc441..1dd413ae439b 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -985,9 +985,10 @@ void ide_setup_ports ( hw_regs_t *hw, } /** - * ide_register_hw - register IDE interface + * ide_register_hw_with_fixup - register IDE interface * @hw: hardware registers * @hwifp: pointer to returned hwif + * @fixup: fixup function * * Register an IDE interface, specifying exactly the registers etc. * Set init=1 iff calling before probes have taken place. @@ -995,7 +996,7 @@ void ide_setup_ports ( hw_regs_t *hw, * Returns -1 on error. */ -int ide_register_hw (hw_regs_t *hw, ide_hwif_t **hwifp) +int ide_register_hw_with_fixup(hw_regs_t *hw, ide_hwif_t **hwifp, void(*fixup)(ide_hwif_t *hwif)) { int index, retry = 1; ide_hwif_t *hwif; @@ -1034,7 +1035,7 @@ found: hwif->chipset = hw->chipset; if (!initializing) { - probe_hwif_init(hwif); + probe_hwif_init_with_fixup(hwif, fixup); create_proc_ide_interfaces(); } @@ -1044,6 +1045,13 @@ found: return (initializing || hwif->present) ? index : -1; } +EXPORT_SYMBOL(ide_register_hw_with_fixup); + +int ide_register_hw(hw_regs_t *hw, ide_hwif_t **hwifp) +{ + return ide_register_hw_with_fixup(hw, hwifp, NULL); +} + EXPORT_SYMBOL(ide_register_hw); /* diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index dda2a17e0c6e..36426f72cb3f 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c @@ -206,7 +206,7 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq ide_init_hwif_ports(&hw, io, ctl, NULL); hw.irq = irq; hw.chipset = ide_pci; - return ide_register_hw(&hw, NULL); + return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave); } /*====================================================================== diff --git a/include/linux/ide.h b/include/linux/ide.h index e619f8247483..b7bfa3f233ea 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -240,6 +240,7 @@ typedef struct hw_regs_s { * Register new hardware with ide */ int ide_register_hw(hw_regs_t *hw, struct hwif_s **hwifp); +int ide_register_hw_with_fixup(hw_regs_t *, struct hwif_s **, void (*)(struct hwif_s *)); /* * Set up hw_regs_t structure before calling ide_register_hw (optional) @@ -1487,6 +1488,9 @@ extern int ide_hwif_request_regions(ide_hwif_t *hwif); extern void ide_hwif_release_regions(ide_hwif_t* hwif); extern void ide_unregister (unsigned int index); +void ide_undecoded_slave(ide_hwif_t *); + +int probe_hwif_init_with_fixup(ide_hwif_t *, void (*)(ide_hwif_t *)); extern int probe_hwif_init(ide_hwif_t *); static inline void *ide_get_hwifdata (ide_hwif_t * hwif) |
