Subject: [PATCH 00/18] ide: warm-plug support for IDE devices and other goodies


- couple of fixes and preparatory patches

- rework of PowerMac media-bay support ([un]register IDE devices instead of
[un]registering IDE interface) [ it is the main reason for spamming PPC ML ]

- IDE warm-plug support (though it is still experimental it should work fine,
unlike the older method), to warm-plug devices on a port 'idex':

# echo -n "1" > /sys/class/ide_port/idex/delete_devices

unplug old device(s) and plug new device(s)

# echo -n "1" > /sys/class/ide_port/idex/scan

done

- ability to add new interfaces for ide-generic host driver through
/sys/class/ide_generic/add, i.e.

echo -n "0x168:0x36e:10" > /sys/class/ide_generic/add

- because of the above changes some obsoleted/broken code can be removed
(thus the total effect of the patch series is -100 LOC)


diffstat:
Documentation/ide.txt | 31 --
Documentation/ide/warm-plug-howto.txt | 13 +
block/compat_ioctl.c | 1
drivers/ide/Kconfig | 25 --
drivers/ide/Makefile | 2
drivers/ide/arm/bast-ide.c | 4
drivers/ide/arm/palm_bk3710.c | 2
drivers/ide/arm/rapide.c | 2
drivers/ide/ide-acpi.c | 2
drivers/ide/ide-generic.c | 85 +++++++
drivers/ide/ide-pnp.c | 2
drivers/ide/ide-probe.c | 108 ++++++++-
drivers/ide/ide-proc.c | 3
drivers/ide/ide.c | 386 ++++++++--------------------------
drivers/ide/legacy/ide-cs.c | 6
drivers/ide/legacy/ide_platform.c | 2
drivers/ide/mips/au1xxx-ide.c | 5
drivers/ide/pci/cmd640.c | 2
drivers/ide/pci/delkin_cb.c | 6
drivers/ide/pci/scc_pata.c | 2
drivers/ide/ppc/pmac.c | 4
drivers/ide/setup-pci.c | 11
drivers/macintosh/mediabay.c | 17 -
include/asm-powerpc/mediabay.h | 4
include/linux/hdreg.h | 4
include/linux/ide.h | 51 ----
26 files changed, 339 insertions(+), 441 deletions(-)


Subject: [PATCH 01/18] ide-generic: set hwif->chipset

This hwif->chipset fixup is already present in ide_device_add_all()
but for warm-plug support we also need to reserve not currently present
interfaces.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-generic.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

Index: b/drivers/ide/ide-generic.c
===================================================================
--- a/drivers/ide/ide-generic.c
+++ b/drivers/ide/ide-generic.c
@@ -23,7 +23,9 @@ static int __init ide_generic_init(void)
for (i = 0; i < MAX_HWIFS; i++) {
ide_hwif_t *hwif = &ide_hwifs[i];

- if (hwif->io_ports[IDE_DATA_OFFSET] && !hwif->present)
+ if (hwif->io_ports[IDE_DATA_OFFSET] &&
+ (hwif->chipset == ide_unknown ||
+ hwif->chipset == ide_forced))
idx[i] = i;
else
idx[i] = 0xff;

Subject: [PATCH 02/18] ide: fix ide_find_port()

* Instead of checking for '->io_ports[IDE_DATA_OFFSET] == 0' check for
'->chipset == ide_unknown' when looking for an empty ide_hwifs[] slot.

* Do ide-pnp initialization after ide-generic when IDE is built-in
(ide-pnp is the only user of ide_find_port() which needs such fixup).

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/Makefile | 2 +-
drivers/ide/ide.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

Index: b/drivers/ide/Makefile
===================================================================
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -36,9 +36,9 @@ ifeq ($(CONFIG_BLK_DEV_CMD640), y)
endif

obj-$(CONFIG_BLK_DEV_IDE) += cris/ ppc/
-obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o
obj-$(CONFIG_IDE_H8300) += h8300/
obj-$(CONFIG_IDE_GENERIC) += ide-generic.o
+obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o

ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o

Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -259,7 +259,7 @@ ide_hwif_t * ide_find_port(unsigned long

for (i = 0; i < MAX_HWIFS; i++) {
hwif = &ide_hwifs[i];
- if (hwif->io_ports[IDE_DATA_OFFSET] == 0)
+ if (hwif->chipset == ide_unknown)
goto found;
}

Subject: [PATCH 03/18] ide: use ide_find_port() instead of ide_deprecated_find_port()

* Use ide_find_port() instead of ide_deprecated_find_port() in bast-ide/
palm_bk3710/ide-cs/delkin_cb host drivers and in ide_register_hw().

* Remove no longer needed ide_deprecated_find_port().

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/arm/bast-ide.c | 2 +-
drivers/ide/arm/palm_bk3710.c | 2 +-
drivers/ide/ide.c | 27 +--------------------------
drivers/ide/legacy/ide-cs.c | 2 +-
drivers/ide/pci/delkin_cb.c | 2 +-
include/linux/ide.h | 1 -
6 files changed, 5 insertions(+), 31 deletions(-)

Index: b/drivers/ide/arm/bast-ide.c
===================================================================
--- a/drivers/ide/arm/bast-ide.c
+++ b/drivers/ide/arm/bast-ide.c
@@ -46,7 +46,7 @@ bastide_register(unsigned int base, unsi
hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20);
hw.irq = irq;

- hwif = ide_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+ hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
if (hwif == NULL)
goto out;

Index: b/drivers/ide/arm/palm_bk3710.c
===================================================================
--- a/drivers/ide/arm/palm_bk3710.c
+++ b/drivers/ide/arm/palm_bk3710.c
@@ -378,7 +378,7 @@ static int __devinit palm_bk3710_probe(s
hw.irq = irq->start;
hw.chipset = ide_palm3710;

- hwif = ide_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+ hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
if (hwif == NULL)
goto out;

Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -627,31 +627,6 @@ void ide_init_port_hw(ide_hwif_t *hwif,
}
EXPORT_SYMBOL_GPL(ide_init_port_hw);

-ide_hwif_t *ide_deprecated_find_port(unsigned long base)
-{
- ide_hwif_t *hwif;
- int i;
-
- for (i = 0; i < MAX_HWIFS; i++) {
- hwif = &ide_hwifs[i];
- if (hwif->io_ports[IDE_DATA_OFFSET] == base)
- goto found;
- }
-
- for (i = 0; i < MAX_HWIFS; i++) {
- hwif = &ide_hwifs[i];
- if (hwif->hold)
- continue;
- if (!hwif->present && hwif->mate == NULL)
- goto found;
- }
-
- hwif = NULL;
-found:
- return hwif;
-}
-EXPORT_SYMBOL_GPL(ide_deprecated_find_port);
-
/**
* ide_register_hw - register IDE interface
* @hw: hardware registers
@@ -671,7 +646,7 @@ int ide_register_hw(hw_regs_t *hw, void
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };

do {
- hwif = ide_deprecated_find_port(hw->io_ports[IDE_DATA_OFFSET]);
+ hwif = ide_find_port(hw->io_ports[IDE_DATA_OFFSET]);
index = hwif->index;
if (hwif)
goto found;
Index: b/drivers/ide/legacy/ide-cs.c
===================================================================
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -156,7 +156,7 @@ static int idecs_register(unsigned long
hw.chipset = ide_pci;
hw.dev = &handle->dev;

- hwif = ide_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+ hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
if (hwif == NULL)
return -1;

Index: b/drivers/ide/pci/delkin_cb.c
===================================================================
--- a/drivers/ide/pci/delkin_cb.c
+++ b/drivers/ide/pci/delkin_cb.c
@@ -78,7 +78,7 @@ delkin_cb_probe (struct pci_dev *dev, co
hw.irq = dev->irq;
hw.chipset = ide_pci; /* this enables IRQ sharing */

- hwif = ide_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+ hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
if (hwif == NULL)
goto out_disable;

Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -186,7 +186,6 @@ typedef struct hw_regs_s {
} hw_regs_t;

struct hwif_s * ide_find_port(unsigned long);
-struct hwif_s *ide_deprecated_find_port(unsigned long);
void ide_init_port_data(struct hwif_s *, unsigned int);
void ide_init_port_hw(struct hwif_s *, hw_regs_t *);

Subject: [PATCH 04/18] ide-acpi: add missing drive->acpidata zeroing

There should be no functionality changes caused by this patch.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-acpi.c | 2 ++
1 file changed, 2 insertions(+)

Index: b/drivers/ide/ide-acpi.c
===================================================================
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -710,6 +710,8 @@ void ide_acpi_port_init_devices(ide_hwif
for (i = 0; i < MAX_DRIVES; i++) {
drive = &hwif->drives[i];

+ memset(drive->acpidata, 0, sizeof(*drive->acpidata));
+
if (!drive->present)
continue;

Subject: [PATCH 05/18] ide: factor out cable detection from ide_init_port()

* Factor out cable detection from ide_init_port() to ide_port_cable_detect().

* Move ide_port_cable_detect() call to ide_device_add_all().

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-probe.c | 4 ++++
1 file changed, 4 insertions(+)

Index: b/drivers/ide/ide-probe.c
===================================================================
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1364,7 +1364,10 @@ static void ide_init_port(ide_hwif_t *hw
/* call chipset specific routine for each enabled port */
if (d->init_hwif)
d->init_hwif(hwif);
+}

+static void ide_port_cable_detect(ide_hwif_t *hwif)
+{
if (hwif->cable_detect && (hwif->ultra_mask & 0x78)) {
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
hwif->cbl = hwif->cable_detect(hwif);
@@ -1392,6 +1395,7 @@ int ide_device_add_all(u8 *idx, const st
mate = (i & 1) ? NULL : hwif;

ide_init_port(hwif, i & 1, d);
+ ide_port_cable_detect(hwif);
ide_port_init_devices(hwif);
}

Subject: [PATCH 06/18] ide: factor out code unregistering devices from ide_unregister()

Factor out code unregistering devices from ide_unregister() to
ide_port_unregister_devices().

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide.c | 30 +++++++++++++++++++-----------
1 file changed, 19 insertions(+), 11 deletions(-)

Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -494,6 +494,23 @@ void ide_remove_port_from_hwgroup(ide_hw
spin_unlock_irq(&ide_lock);
}

+/* Called with ide_lock held. */
+static void ide_port_unregister_devices(ide_hwif_t *hwif)
+{
+ int i;
+
+ for (i = 0; i < MAX_DRIVES; i++) {
+ ide_drive_t *drive = &hwif->drives[i];
+
+ if (drive->present) {
+ spin_unlock_irq(&ide_lock);
+ device_unregister(&drive->gendev);
+ wait_for_completion(&drive->gendev_rel_comp);
+ spin_lock_irq(&ide_lock);
+ }
+ }
+}
+
/**
* ide_unregister - free an IDE interface
* @index: index of interface (will change soon to a pointer)
@@ -520,11 +537,10 @@ void ide_remove_port_from_hwgroup(ide_hw

void ide_unregister(unsigned int index, int init_default, int restore)
{
- ide_drive_t *drive;
ide_hwif_t *hwif, *g;
static ide_hwif_t tmp_hwif; /* protected by ide_cfg_mtx */
ide_hwgroup_t *hwgroup;
- int irq_count = 0, unit;
+ int irq_count = 0;

BUG_ON(index >= MAX_HWIFS);

@@ -535,15 +551,7 @@ void ide_unregister(unsigned int index,
hwif = &ide_hwifs[index];
if (!hwif->present)
goto abort;
- for (unit = 0; unit < MAX_DRIVES; ++unit) {
- drive = &hwif->drives[unit];
- if (!drive->present)
- continue;
- spin_unlock_irq(&ide_lock);
- device_unregister(&drive->gendev);
- wait_for_completion(&drive->gendev_rel_comp);
- spin_lock_irq(&ide_lock);
- }
+ ide_port_unregister_devices(hwif);
hwif->present = 0;

spin_unlock_irq(&ide_lock);

Subject: [PATCH 07/18] ide: factor out devices init from ide_init_port_data()

* Factor out devices init from ide_init_port_data() to
ide_port_init_devices_data().

While at it:

* Add explicit clearing of IDE device structure.

There should be no functionality changes caused by this patch.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)

Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -109,13 +109,13 @@ ide_hwif_t ide_hwifs[MAX_HWIFS]; /* mast

EXPORT_SYMBOL(ide_hwifs);

+static void ide_port_init_devices_data(ide_hwif_t *);
+
/*
* Do not even *think* about calling this!
*/
void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
{
- unsigned int unit;
-
/* bulk initialize hwif & drive info with zeros */
memset(hwif, 0, sizeof(ide_hwif_t));

@@ -134,8 +134,20 @@ void ide_init_port_data(ide_hwif_t *hwif

default_hwif_iops(hwif);
default_hwif_transport(hwif);
+
+ ide_port_init_devices_data(hwif);
+}
+EXPORT_SYMBOL_GPL(ide_init_port_data);
+
+static void ide_port_init_devices_data(ide_hwif_t *hwif)
+{
+ int unit;
+
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];
+ u8 j = (hwif->index * MAX_DRIVES) + unit;
+
+ memset(drive, 0, sizeof(*drive));

drive->media = ide_disk;
drive->select.all = (unit<<4)|0xa0;
@@ -147,15 +159,14 @@ void ide_init_port_data(ide_hwif_t *hwif
drive->special.b.set_geometry = 1;
drive->name[0] = 'h';
drive->name[1] = 'd';
- drive->name[2] = 'a' + (index * MAX_DRIVES) + unit;
+ drive->name[2] = 'a' + j;
drive->max_failures = IDE_DEFAULT_MAX_FAILURES;
- drive->using_dma = 0;
- drive->vdma = 0;
+
INIT_LIST_HEAD(&drive->list);
init_completion(&drive->gendev_rel_comp);
}
}
-EXPORT_SYMBOL_GPL(ide_init_port_data);
+

static void init_hwif_default(ide_hwif_t *hwif, unsigned int index)
{

Subject: [PATCH 08/18] ide: move ide_port_setup_devices() call to ide_device_add_all()

Add ide_cfg_mtx lock/unlock to ide_port_setup_devices() and then move
ide_port_setup_devices() call from init_irq() to ide_device_add_all().

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-probe.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

Index: b/drivers/ide/ide-probe.c
===================================================================
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -947,6 +947,7 @@ static void ide_port_setup_devices(ide_h
{
int i;

+ mutex_lock(&ide_cfg_mtx);
for (i = 0; i < MAX_DRIVES; i++) {
ide_drive_t *drive = &hwif->drives[i];

@@ -961,6 +962,7 @@ static void ide_port_setup_devices(ide_h

ide_add_drive_to_hwgroup(drive);
}
+ mutex_unlock(&ide_cfg_mtx);
}

/*
@@ -1086,8 +1088,6 @@ static int init_irq (ide_hwif_t *hwif)
hwif->sharing_irq ? "shar" : "serializ", match->name);
printk("\n");

- ide_port_setup_devices(hwif);
-
mutex_unlock(&ide_cfg_mtx);
return 0;
out_unlink:
@@ -1443,6 +1443,8 @@ int ide_device_add_all(u8 *idx, const st
continue;
}

+ ide_port_setup_devices(hwif);
+
ide_acpi_init(hwif);
ide_acpi_port_init_devices(hwif);
}

Subject: [PATCH 09/18] ide: rework PowerMac media-bay support

Rework PowerMac media-bay support in such way that instead of
un/registering the IDE interface we un/register IDE devices:

* Add ide_port_scan() helper for probing+registerering devices on a port.

* Rename ide_port_unregister_devices() to __ide_port_unregister_devices().

* Add ide_port_unregister_devices() helper for unregistering devices on a port.

* Add 'ide_hwif_t *cd_port' to 'struct media_bay_info', pass 'hwif' instead
of hwif->index to media_bay_set_ide_infos() and use it to setup 'cd_port'.

* Use ide_port_unregister_devices() instead of ide_unregister()
and ide_port_scan() instead of ide_register_hw() in media_bay_step().

* Unexport ide_register_hw() and make it static.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-probe.c | 18 ++++++++++++++++++
drivers/ide/ide.c | 22 ++++++++++++++++------
drivers/ide/ppc/pmac.c | 3 ++-
drivers/macintosh/mediabay.c | 17 +++++++----------
include/asm-powerpc/mediabay.h | 4 +++-
include/linux/ide.h | 6 ++----
6 files changed, 48 insertions(+), 22 deletions(-)

Index: b/drivers/ide/ide-probe.c
===================================================================
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1490,3 +1490,21 @@ int ide_device_add(u8 idx[4], const stru
return ide_device_add_all(idx_all, d);
}
EXPORT_SYMBOL_GPL(ide_device_add);
+
+void ide_port_scan(ide_hwif_t *hwif)
+{
+ ide_port_cable_detect(hwif);
+ ide_port_init_devices(hwif);
+
+ if (ide_probe_port(hwif) < 0)
+ return;
+
+ hwif->present = 1;
+
+ ide_port_tune_devices(hwif);
+ ide_acpi_port_init_devices(hwif);
+ ide_port_setup_devices(hwif);
+ hwif_register_devices(hwif);
+ ide_proc_port_register_devices(hwif);
+}
+EXPORT_SYMBOL_GPL(ide_port_scan);
Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -506,7 +506,7 @@ void ide_remove_port_from_hwgroup(ide_hw
}

/* Called with ide_lock held. */
-static void ide_port_unregister_devices(ide_hwif_t *hwif)
+static void __ide_port_unregister_devices(ide_hwif_t *hwif)
{
int i;

@@ -522,6 +522,18 @@ static void ide_port_unregister_devices(
}
}

+void ide_port_unregister_devices(ide_hwif_t *hwif)
+{
+ mutex_lock(&ide_cfg_mtx);
+ spin_lock_irq(&ide_lock);
+ __ide_port_unregister_devices(hwif);
+ hwif->present = 0;
+ ide_port_init_devices_data(hwif);
+ spin_unlock_irq(&ide_lock);
+ mutex_unlock(&ide_cfg_mtx);
+}
+EXPORT_SYMBOL_GPL(ide_port_unregister_devices);
+
/**
* ide_unregister - free an IDE interface
* @index: index of interface (will change soon to a pointer)
@@ -562,7 +574,7 @@ void ide_unregister(unsigned int index,
hwif = &ide_hwifs[index];
if (!hwif->present)
goto abort;
- ide_port_unregister_devices(hwif);
+ __ide_port_unregister_devices(hwif);
hwif->present = 0;

spin_unlock_irq(&ide_lock);
@@ -657,8 +669,8 @@ EXPORT_SYMBOL_GPL(ide_init_port_hw);
* Returns -1 on error.
*/

-int ide_register_hw(hw_regs_t *hw, void (*quirkproc)(ide_drive_t *),
- ide_hwif_t **hwifp)
+static int ide_register_hw(hw_regs_t *hw, void (*quirkproc)(ide_drive_t *),
+ ide_hwif_t **hwifp)
{
int index, retry = 1;
ide_hwif_t *hwif;
@@ -692,8 +704,6 @@ found:
return hwif->present ? index : -1;
}

-EXPORT_SYMBOL(ide_register_hw);
-
/*
* Locks for IDE setting functionality
*/
Index: b/drivers/ide/ppc/pmac.c
===================================================================
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1088,7 +1088,8 @@ pmac_ide_setup_device(pmac_ide_hwif_t *p
if (np->parent && np->parent->name
&& strcasecmp(np->parent->name, "media-bay") == 0) {
#ifdef CONFIG_PMAC_MEDIABAY
- media_bay_set_ide_infos(np->parent, pmif->regbase, pmif->irq, hwif->index);
+ media_bay_set_ide_infos(np->parent, pmif->regbase, pmif->irq,
+ hwif);
#endif /* CONFIG_PMAC_MEDIABAY */
pmif->mediabay = 1;
if (!bidp)
Index: b/drivers/macintosh/mediabay.c
===================================================================
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -79,6 +79,7 @@ struct media_bay_info {
int sleeping;
struct semaphore lock;
#ifdef CONFIG_BLK_DEV_IDE_PMAC
+ ide_hwif_t *cd_port;
void __iomem *cd_base;
int cd_irq;
int cd_retry;
@@ -450,7 +451,7 @@ int check_media_bay_by_base(unsigned lon
}

int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
- int irq, int index)
+ int irq, ide_hwif_t *hwif)
{
int i;

@@ -458,10 +459,11 @@ int media_bay_set_ide_infos(struct devic
struct media_bay_info* bay = &media_bays[i];

if (bay->mdev && which_bay == bay->mdev->ofdev.node) {
- int timeout = 5000;
+ int timeout = 5000, index = hwif->index;

down(&bay->lock);

+ bay->cd_port = hwif;
bay->cd_base = (void __iomem *) base;
bay->cd_irq = irq;

@@ -553,15 +555,10 @@ static void media_bay_step(int i)
bay->timer = 0;
bay->state = mb_up;
if (bay->cd_index < 0) {
- hw_regs_t hw;
-
printk("mediabay %d, registering IDE...\n", i);
pmu_suspend();
- ide_init_hwif_ports(&hw, (unsigned long) bay->cd_base, (unsigned long) 0, NULL);
- hw.irq = bay->cd_irq;
- hw.chipset = ide_pmac;
- bay->cd_index =
- ide_register_hw(&hw, NULL, NULL);
+ ide_port_scan(bay->cd_port);
+ bay->cd_index = bay->cd_port->index;
pmu_resume();
}
if (bay->cd_index == -1) {
@@ -591,7 +588,7 @@ static void media_bay_step(int i)
if (bay->cd_index >= 0) {
printk(KERN_DEBUG "Unregistering mb %d ide, index:%d\n", i,
bay->cd_index);
- ide_unregister(bay->cd_index, 1, 1);
+ ide_port_unregister_devices(bay->cd_port);
bay->cd_index = -1;
}
if (bay->cd_retry) {
Index: b/include/asm-powerpc/mediabay.h
===================================================================
--- a/include/asm-powerpc/mediabay.h
+++ b/include/asm-powerpc/mediabay.h
@@ -22,10 +22,12 @@ int check_media_bay(struct device_node *
/* Number of bays in the machine or 0 */
extern int media_bay_count;

+#ifdef CONFIG_BLK_DEV_IDE_PMAC
int check_media_bay_by_base(unsigned long base, int what);
/* called by IDE PMAC host driver to register IDE controller for media bay */
int media_bay_set_ide_infos(struct device_node *which_bay, unsigned long base,
- int irq, int index);
+ int irq, ide_hwif_t *hwif);
+#endif

#endif /* __KERNEL__ */
#endif /* _PPC_MEDIABAY_H */
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -189,10 +189,6 @@ struct hwif_s * ide_find_port(unsigned l
void ide_init_port_data(struct hwif_s *, unsigned int);
void ide_init_port_hw(struct hwif_s *, hw_regs_t *);

-struct ide_drive_s;
-int ide_register_hw(hw_regs_t *, void (*)(struct ide_drive_s *),
- struct hwif_s **);
-
static inline void ide_std_init_ports(hw_regs_t *hw,
unsigned long io_addr,
unsigned long ctl_addr)
@@ -1202,6 +1198,8 @@ void ide_undecoded_slave(ide_drive_t *);

int ide_device_add_all(u8 *idx, const struct ide_port_info *);
int ide_device_add(u8 idx[4], const struct ide_port_info *);
+void ide_port_unregister_devices(ide_hwif_t *);
+void ide_port_scan(ide_hwif_t *);

static inline void *ide_get_hwifdata (ide_hwif_t * hwif)
{

Subject: [PATCH 10/18] ide: add warm-plug support for IDE devices

* Add 'struct class ide_port_class' ('ide_port' class) and embedd 'struct
class_device classdev' ('ide_port' class device) in ide_hwif_t.

* Register 'ide_port' class in ide_init() and unregister it in
cleanup_module().

* Add class_to_ide_port() macro and ide_port_class_release().

* Register ->classdev in ide_register_port () and unregister it in
ide_unregister().

* Add "delete_devices" class device attribute for unregistering IDE devices
on a port and "scan" one for probing+registering IDE devices on a port.

* Add ide_sysfs_register_port() helper for registering "delete_devices"
and "scan" attributes with ->classdev. Call it in ide_device_add_all().

* Document IDE warm-plug support in Documentation/ide/warm-plug-howto.txt.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
+540 bytes (x86-32)

After seeing some 'class device' conversion patches from Greg I tried to
recast this patch to just use 'device' but I couldn't figure out how to
use class_device_create() with *static* objects...

Documentation/ide/warm-plug-howto.txt | 13 ++++++
drivers/ide/ide-probe.c | 70 +++++++++++++++++++++++++++++++++-
drivers/ide/ide.c | 22 ++++++++++
include/linux/ide.h | 7 ++-
4 files changed, 109 insertions(+), 3 deletions(-)

Index: b/Documentation/ide/warm-plug-howto.txt
===================================================================
--- /dev/null
+++ b/Documentation/ide/warm-plug-howto.txt
@@ -0,0 +1,13 @@
+
+IDE warm-plug HOWTO
+===================
+
+To warm-plug devices on a port 'idex':
+
+# echo -n "1" > /sys/class/ide_port/idex/delete_devices
+
+unplug old device(s) and plug new device(s)
+
+# echo -n "1" > /sys/class/ide_port/idex/scan
+
+done
Index: b/drivers/ide/ide-probe.c
===================================================================
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -623,7 +623,7 @@ static void hwif_release_dev (struct dev
complete(&hwif->gendev_rel_comp);
}

-static void ide_register_port(ide_hwif_t *hwif)
+static int ide_register_port(ide_hwif_t *hwif)
{
int ret;

@@ -639,9 +639,23 @@ static void ide_register_port(ide_hwif_t
}
hwif->gendev.release = hwif_release_dev;
ret = device_register(&hwif->gendev);
- if (ret < 0)
+ if (ret < 0) {
printk(KERN_WARNING "IDE: %s: device_register error: %d\n",
__FUNCTION__, ret);
+ goto out;
+ }
+
+ get_device(&hwif->gendev);
+
+ strlcpy(hwif->classdev.class_id, hwif->name, BUS_ID_SIZE);
+ hwif->classdev.dev = &hwif->gendev;
+ hwif->classdev.class = &ide_port_class;
+
+ ret = class_device_register(&hwif->classdev);
+ if (ret < 0)
+ device_unregister(&hwif->gendev);
+out:
+ return ret;
}

/**
@@ -1374,6 +1388,57 @@ static void ide_port_cable_detect(ide_hw
}
}

+static ssize_t store_delete_devices(struct class_device *class_dev,
+ const char *buf, size_t n)
+{
+ ide_hwif_t *hwif = class_to_ide_port(class_dev);
+
+ if (strncmp(buf, "1", n))
+ return -EINVAL;
+
+ ide_port_unregister_devices(hwif);
+
+ return n;
+};
+
+static CLASS_DEVICE_ATTR(delete_devices, S_IWUSR, NULL, store_delete_devices);
+
+static ssize_t store_scan(struct class_device *class_dev, const char *buf,
+ size_t n)
+{
+ ide_hwif_t *hwif = class_to_ide_port(class_dev);
+
+ if (strncmp(buf, "1", n))
+ return -EINVAL;
+
+ ide_port_unregister_devices(hwif);
+ ide_port_scan(hwif);
+
+ return n;
+};
+
+static CLASS_DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan);
+
+static struct class_device_attribute *ide_port_attrs[] = {
+ &class_device_attr_delete_devices,
+ &class_device_attr_scan,
+ NULL
+};
+
+static int ide_sysfs_register_port(ide_hwif_t *hwif)
+{
+ int i, rc;
+
+ for (i = 0; ide_port_attrs[i]; i++) {
+ rc = class_device_create_file(&hwif->classdev,
+ ide_port_attrs[i]);
+ if (rc)
+ break;
+ }
+
+ return rc;
+}
+
int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
{
ide_hwif_t *hwif, *mate = NULL;
@@ -1470,6 +1535,7 @@ int ide_device_add_all(u8 *idx, const st
hwif = &ide_hwifs[idx[i]];

if (hwif->present) {
+ ide_sysfs_register_port(hwif);
ide_proc_register_port(hwif);
ide_proc_port_register_devices(hwif);
}
Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -596,6 +596,7 @@ void ide_unregister(unsigned int index,

ide_remove_port_from_hwgroup(hwif);

+ class_device_unregister(&hwif->classdev);
device_unregister(&hwif->gendev);
wait_for_completion(&hwif->gendev_rel_comp);

@@ -1613,6 +1614,16 @@ struct bus_type ide_bus_type = {

EXPORT_SYMBOL_GPL(ide_bus_type);

+static void ide_port_class_release(struct class_device *class_dev)
+{
+ put_device(&class_to_ide_port(class_dev)->gendev);
+}
+
+struct class ide_port_class = {
+ .name = "ide_port",
+ .release = ide_port_class_release,
+};
+
/*
* This is gets invoked once during initialization, to set *everything* up
*/
@@ -1633,11 +1644,20 @@ static int __init ide_init(void)
return ret;
}

+ ret = class_register(&ide_port_class);
+ if (ret)
+ goto out_port_class;
+
init_ide_data();

proc_ide_create();

return 0;
+
+out_port_class:
+ bus_unregister(&ide_bus_type);
+
+ return ret;
}

#ifdef MODULE
@@ -1674,6 +1694,8 @@ void __exit cleanup_module (void)

proc_ide_destroy();

+ class_unregister(&ide_port_class);
+
bus_unregister(&ide_bus_type);
}

Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -581,7 +581,9 @@ typedef struct hwif_s {
unsigned mmio : 1; /* host uses MMIO */
unsigned straight8 : 1; /* Alan's straight 8 check */

- struct device gendev;
+ struct device gendev;
+ struct class_device classdev;
+
struct completion gendev_rel_comp; /* To deal with device release() */

void *hwif_data; /* extra hwif data */
@@ -593,6 +595,8 @@ typedef struct hwif_s {
#endif
} ____cacheline_internodealigned_in_smp ide_hwif_t;

+#define class_to_ide_port(dev) container_of(dev, ide_hwif_t, classdev)
+
/*
* internal ide interrupt handler type
*/
@@ -1275,6 +1279,7 @@ extern struct mutex ide_cfg_mtx;
#define local_irq_set(flags) do { local_save_flags((flags)); local_irq_enable_in_hardirq(); } while (0)

extern struct bus_type ide_bus_type;
+extern struct class ide_port_class;

/* check if CACHE FLUSH (EXT) command is supported (bits defined in ATA-6) */
#define ide_id_has_flush_cache(id) ((id)->cfs_enable_2 & 0x3000)

Subject: [PATCH 11/18] ide-generic: add ide_generic class and attribute for adding new interfaces

* Add ide_generic_sysfs_init() helper registering 'ide_generic' class
(together with ide_generic_class_release() ->class_release method)
and use it in ide_generic_init().

* Add "add" class attribute to 'ide_generic' class for adding new interfaces
(it is intended to be a replacement for obsoleted "idex=base[,ctl[,irq]]"
kernel parameters).

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
+391 bytes (x86-32)

I also tried interface based on kernel parameters but it sucked
(more complex, bigger source code + resulting binary).

drivers/ide/ide-generic.c | 78 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 77 insertions(+), 1 deletion(-)

Index: b/drivers/ide/ide-generic.c
===================================================================
--- a/drivers/ide/ide-generic.c
+++ b/drivers/ide/ide-generic.c
@@ -1,17 +1,89 @@
/*
* generic/default IDE host driver
*
- * Copyright (C) 2004 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2004, 2008 Bartlomiej Zolnierkiewicz
* This code was split off from ide.c. See it for original copyrights.
*
* May be copied or modified under the terms of the GNU General Public License.
*/

+/*
+ * For special cases new interfaces may be added using sysfs, i.e.
+ *
+ * echo -n "0x168:0x36e:10" > /sys/class/ide_generic/add
+ *
+ * will add an interface using I/O ports 0x168-0x16f/0x36e and IRQ 10.
+ */
+
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ide.h>

+#define DRV_NAME "ide_generic"
+
+static ssize_t store_add(struct class *cls, const char *buf, size_t n)
+{
+ ide_hwif_t *hwif;
+ unsigned int base, ctl;
+ int irq;
+ hw_regs_t hw;
+ u8 idx[] = { 0xff, 0xff, 0xff, 0xff };
+
+ if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3)
+ return -EINVAL;
+
+ hwif = ide_find_port(base);
+ if (hwif == NULL)
+ return -ENOENT;
+
+ memset(&hw, 0, sizeof(hw));
+ ide_std_init_ports(&hw, base, ctl);
+ hw.irq = irq;
+ hw.chipset = ide_generic;
+
+ ide_init_port_hw(hwif, &hw);
+
+ idx[0] = hwif->index;
+
+ ide_device_add(idx, NULL);
+
+ return n;
+};
+
+static struct class_attribute ide_generic_class_attrs[] = {
+ __ATTR(add, S_IWUSR, NULL, store_add),
+ __ATTR_NULL
+};
+
+static void ide_generic_class_release(struct class *cls)
+{
+ kfree(cls);
+}
+
+static int __init ide_generic_sysfs_init(void)
+{
+ struct class *cls;
+ int rc;
+
+ cls = kzalloc(sizeof(*cls), GFP_KERNEL);
+ if (!cls)
+ return -ENOMEM;
+
+ cls->name = DRV_NAME;
+ cls->owner = THIS_MODULE;
+ cls->class_release = ide_generic_class_release;
+ cls->class_attrs = ide_generic_class_attrs;
+
+ rc = class_register(cls);
+ if (rc) {
+ kfree(cls);
+ return rc;
+ }
+
+ return 0;
+}
+
static int __init ide_generic_init(void)
{
u8 idx[MAX_HWIFS];
@@ -36,6 +108,10 @@ static int __init ide_generic_init(void)
if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET])
ide_release_lock(); /* for atari only */

+ if (ide_generic_sysfs_init())
+ printk(KERN_ERR DRV_NAME ": failed to create ide_generic "
+ "class\n");
+
return 0;
}

Subject: [PATCH 12/18] ide: remove needless CONFIG_BLK_DEV_HD hack from init_hwif()

request_irq() will fail if there is already another IRQ handler
registered and IRQ flags are mismatched.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-probe.c | 7 -------
1 file changed, 7 deletions(-)

Index: b/drivers/ide/ide-probe.c
===================================================================
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1237,13 +1237,6 @@ static int hwif_init(ide_hwif_t *hwif)
return 0;
}
}
-#ifdef CONFIG_BLK_DEV_HD
- if (hwif->irq == HD_IRQ && hwif->io_ports[IDE_DATA_OFFSET] != HD_DATA) {
- printk("%s: CANNOT SHARE IRQ WITH OLD "
- "HARDDISK DRIVER (hd.c)\n", hwif->name);
- return 0;
- }
-#endif /* CONFIG_BLK_DEV_HD */

if (register_blkdev(hwif->major, hwif->name))
return 0;

Subject: [PATCH 13/18] ide: remove CONFIG_BLK_DEV_HD_IDE config option

* Remove CONFIG_BLK_DEV_HD hack from init_hwif_default() ("ide0=noprobe"
kernel parameter should be used instead if somebody wishes to use the
old "hd" driver).

* Make CONFIG_BLK_DEV_HD_ONLY config option available also when IDE
subsystem is used and update help entry.

* Remove no longer needed CONFIG_BLK_DEV_HD_IDE config option.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/Kconfig | 25 +++++--------------------
drivers/ide/ide.c | 4 ----
2 files changed, 5 insertions(+), 24 deletions(-)

Index: b/drivers/ide/Kconfig
===================================================================
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -118,24 +118,6 @@ config BLK_DEV_IDE_SATA

If unsure, say N.

-config BLK_DEV_HD_IDE
- bool "Use old disk-only driver on primary interface"
- depends on (X86 || SH_MPC1211)
- ---help---
- There are two drivers for MFM/RLL/IDE disks. Most people use just
- the new enhanced driver by itself. This option however installs the
- old hard disk driver to control the primary IDE/disk interface in
- the system, leaving the new enhanced IDE driver to take care of only
- the 2nd/3rd/4th IDE interfaces. Doing this will prevent you from
- having an IDE/ATAPI CD-ROM or tape drive connected to the primary
- IDE interface. Choosing this option may be useful for older systems
- which have MFM/RLL/ESDI controller+drives at the primary port
- address (0x1f0), along with IDE drives at the secondary/3rd/4th port
- addresses.
-
- Normally, just say N here; you will then use the new driver for all
- 4 interfaces.
-
config BLK_DEV_IDEDISK
tristate "Include IDE/ATA-2 DISK support"
---help---
@@ -1112,7 +1094,6 @@ endif

config BLK_DEV_HD_ONLY
bool "Old hard disk (MFM/RLL/IDE) driver"
- depends on BLK_DEV_IDE=n
help
There are two drivers for MFM/RLL/IDE hard disks. Most people use
the newer enhanced driver, but this old one is still around for two
@@ -1124,12 +1105,16 @@ config BLK_DEV_HD_ONLY
for systems with only older MFM/RLL/ESDI drives. Choosing the old
driver can save 13 KB or so of kernel memory.

+ If you want to use this driver together with the new one you have
+ to use "ide0=noprobe" kernel parameter to prevent the new driver
+ from probing the primary interface.
+
If you are unsure, then just choose the Enhanced IDE/MFM/RLL driver
instead of this one. For more detailed information, read the
Disk-HOWTO, available from
<http://www.tldp.org/docs.html#howto>.

config BLK_DEV_HD
- def_bool BLK_DEV_HD_IDE || BLK_DEV_HD_ONLY
+ def_bool BLK_DEV_HD_ONLY

endif # IDE
Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -179,10 +179,6 @@ static void init_hwif_default(ide_hwif_t
memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports));

hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
-#ifdef CONFIG_BLK_DEV_HD
- if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA)
- hwif->noprobe = 1; /* may be overridden by ide_setup() */
-#endif
}

/*

Subject: [PATCH 14/18] ide: remove obsoleted "idex=base[,ctl[,irq]]" kernel parameters

* Remove obsoleted "idex=base[,ctl[,irq]]" kernel parameters
and update Documentation/ide.txt.

* Remove no longer needed ide_forced chipset type.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
-244 bytes (x86-32)

Documentation/ide.txt | 31 -------------------------------
drivers/ide/ide-generic.c | 3 +--
drivers/ide/ide-probe.c | 3 +--
drivers/ide/ide-proc.c | 3 ---
drivers/ide/ide.c | 22 +++++-----------------
drivers/ide/pci/cmd640.c | 2 +-
drivers/ide/setup-pci.c | 11 -----------
include/linux/ide.h | 2 +-
8 files changed, 9 insertions(+), 68 deletions(-)

Index: b/Documentation/ide.txt
===================================================================
--- a/Documentation/ide.txt
+++ b/Documentation/ide.txt
@@ -71,29 +71,6 @@ This driver automatically probes for mos
ones), for the drives/geometries attached to those interfaces, and for the IRQ
lines being used by the interfaces (normally 14, 15 for ide0/ide1).

-For special cases, interfaces may be specified using kernel "command line"
-options. For example,
-
- ide3=0x168,0x36e,10 /* ioports 0x168-0x16f,0x36e, irq 10 */
-
-Normally the irq number need not be specified, as ide.c will probe for it:
-
- ide3=0x168,0x36e /* ioports 0x168-0x16f,0x36e */
-
-The standard port, and irq values are these:
-
- ide0=0x1f0,0x3f6,14
- ide1=0x170,0x376,15
- ide2=0x1e8,0x3ee,11
- ide3=0x168,0x36e,10
-
-Note that the first parameter reserves 8 contiguous ioports, whereas the
-second value denotes a single ioport. If in doubt, do a 'cat /proc/ioports'.
-
-In all probability the device uses these ports and IRQs if it is attached
-to the appropriate ide channel. Pass the parameter for the correct ide
-channel to the kernel, as explained above.
-
Any number of interfaces may share a single IRQ if necessary, at a slight
performance penalty, whether on separate cards or a single VLB card.
The IDE driver automatically detects and handles this. However, this may
@@ -259,14 +236,6 @@ Summary of ide driver parameters for ker
Bigger values are safer than smaller ones.

"idex=noprobe" : do not attempt to access/use this interface
-
- "idex=base" : probe for an interface at the addr specified,
- where "base" is usually 0x1f0 or 0x170
- and "ctl" is assumed to be "base"+0x206
-
- "idex=base,ctl" : specify both base and ctl
-
- "idex=base,ctl,irq" : specify base, ctl, and irq number

"idex=serialize" : do not overlap operations on idex. Please note
that you will have to specify this option for
Index: b/drivers/ide/ide-generic.c
===================================================================
--- a/drivers/ide/ide-generic.c
+++ b/drivers/ide/ide-generic.c
@@ -96,8 +96,7 @@ static int __init ide_generic_init(void)
ide_hwif_t *hwif = &ide_hwifs[i];

if (hwif->io_ports[IDE_DATA_OFFSET] &&
- (hwif->chipset == ide_unknown ||
- hwif->chipset == ide_forced))
+ hwif->chipset == ide_unknown)
idx[i] = i;
else
idx[i] = 0xff;
Index: b/drivers/ide/ide-probe.c
===================================================================
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1514,8 +1514,7 @@ int ide_device_add_all(u8 *idx, const st
hwif = &ide_hwifs[idx[i]];

if (hwif->present) {
- if (hwif->chipset == ide_unknown ||
- hwif->chipset == ide_forced)
+ if (hwif->chipset == ide_unknown)
hwif->chipset = ide_generic;
hwif_register_devices(hwif);
}
Index: b/drivers/ide/ide-proc.c
===================================================================
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -46,9 +46,6 @@ static int proc_ide_read_imodel
int len;
const char *name;

- /*
- * Neither ide_unknown nor ide_forced should be set at this point.
- */
switch (hwif->chipset) {
case ide_generic: name = "generic"; break;
case ide_pci: name = "pci"; break;
Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1349,8 +1349,6 @@ static int __init ide_setup(char *s)
"minus10", "four", "qd65xx", "ht6560b", "cmd640_vlb",
"dtc2278", "umc8672", "ali14xx", NULL };

- hw_regs_t hwregs;
-
hw = s[3] - '0';
hwif = &ide_hwifs[hw];
i = match_parm(&s[4], ide_words, vals, 3);
@@ -1451,21 +1449,11 @@ static int __init ide_setup(char *s)
case -1: /* "noprobe" */
hwif->noprobe = 1;
goto done;
-
- case 1: /* base */
- vals[1] = vals[0] + 0x206; /* default ctl */
- case 2: /* base,ctl */
- vals[2] = 0; /* default irq = probe for it */
- case 3: /* base,ctl,irq */
- memset(&hwregs, 0, sizeof(hwregs));
- ide_init_hwif_ports(&hwregs, vals[0], vals[1], &hwif->irq);
- memcpy(hwif->io_ports, hwregs.io_ports, sizeof(hwif->io_ports));
- hwif->irq = vals[2];
- hwif->noprobe = 0;
- hwif->chipset = ide_forced;
- goto obsolete_option;
-
- case 0: goto bad_option;
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ goto bad_option;
default:
printk(" -- SUPPORT NOT CONFIGURED IN THIS KERNEL\n");
return 1;
Index: b/drivers/ide/pci/cmd640.c
===================================================================
--- a/drivers/ide/pci/cmd640.c
+++ b/drivers/ide/pci/cmd640.c
@@ -415,7 +415,7 @@ static void __init setup_device_ptrs (vo
cmd_hwif1 = &ide_hwifs[1]; /* default, if not found below */
for (i = 0; i < MAX_HWIFS; i++) {
ide_hwif_t *hwif = &ide_hwifs[i];
- if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced) {
+ if (hwif->chipset == ide_unknown) {
if (hwif->io_ports[IDE_DATA_OFFSET] == 0x1f0)
cmd_hwif0 = hwif;
else if (hwif->io_ports[IDE_DATA_OFFSET] == 0x170)
Index: b/drivers/ide/setup-pci.c
===================================================================
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -41,17 +41,6 @@ static ide_hwif_t *ide_match_hwif(unsign
ide_hwif_t *hwif;

/*
- * Look for a hwif with matching io_base specified using
- * parameters to ide_setup().
- */
- for (h = 0; h < MAX_HWIFS; ++h) {
- hwif = &ide_hwifs[h];
- if (hwif->io_ports[IDE_DATA_OFFSET] == io_base) {
- if (hwif->chipset == ide_forced)
- return hwif; /* a perfect match */
- }
- }
- /*
* Look for a hwif with matching io_base default value.
* If chipset is "ide_unknown", then claim that hwif slot.
* Otherwise, some other chipset has already claimed it.. :(
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -169,7 +169,7 @@ enum { ide_unknown, ide_generic, ide_pc
ide_rz1000, ide_trm290,
ide_cmd646, ide_cy82c693, ide_4drives,
ide_pmac, ide_etrax100, ide_acorn,
- ide_au1xxx, ide_palm3710, ide_forced
+ ide_au1xxx, ide_palm3710
};

typedef u8 hwif_chipset_t;

Subject: [PATCH 15/18] ide: remove broken/dangerous HDIO_[UNREGISTER,SCAN]_HWIF ioctls

hdparm explicitely marks HDIO_[UNREGISTER,SCAN]_HWIF ioctls as DANGEROUS
and given the number of bugs we can assume that there are no real users:

* DMA has no chance of working because DMA resources are released by
ide_unregister() and they are never allocated again.

* Since ide_init_hwif_ports() is used for ->io_ports[] setup the ioctls
don't work for almost all hosts with "non-standard" (== non ISA-like)
layout of IDE taskfile registers (there is a lot of such host drivers).

* ide_port_init_devices() is not called when probing IDE devices so:
- drive->autotune is never set and IDE host/devices are not programmed
for the correct PIO/DMA transfer modes (=> possible data corruption)
- host specific I/O 32-bit and IRQ unmasking settings are not applied
(=> possible data corruption)
- host specific ->port_init_devs method is not called (=> no luck with
ht6560b, qd65xx and opti621 host drivers)

* ->rw_disk method is not preserved (=> no HPT3xxN chipsets support).

* ->serialized flag is not preserved (=> possible data corruption when
using icside, aec62xx (ATP850UF chipset), cmd640, cs5530, hpt366
(HPT3xxN chipsets), rz1000, sc1200, dtc2278 and ht6560b host drivers).

* ->ack_intr method is not preserved (=> needed by ide-cris, buddha,
gayle and macide host drivers).

* ->sata_scr[] and sata_misc[] is cleared by ide_unregister() and it
isn't initialized again (SiI3112 support needs them).

* To issue an ioctl() there need to be at least one IDE device present
in the system.

* ->cable_detect method is not preserved + it is not called when probing
IDE devices so cable detection is broken (however since DMA support is
also broken it doesn't really matter ;-).

* Some objects which may have already been freed in ide_unregister()
are restored by ide_hwif_restore() (i.e. ->hwgroup).

* ide_register_hw() may unregister unrelated IDE ports if free ide_hwifs[]
slot cannot be found.

* When IDE host drivers are modular unregistered port may be re-used by
different host driver that owned it first causing subtle bugs.

Since we now have a proper warm-plug support remove these ioctls,
then remove no longer needed:
- ide_register_hw() and ide_hwif_restore() functions
- 'init_default' and 'restore' arguments of ide_unregister()
- zeroeing of hwif->{dma,extra}_* fields in ide_unregister()

As an added bonus IDE core code size shrinks by ~3kB (x86-32).

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
block/compat_ioctl.c | 1
drivers/ide/arm/bast-ide.c | 2
drivers/ide/arm/rapide.c | 2
drivers/ide/ide-pnp.c | 2
drivers/ide/ide.c | 198 --------------------------------------
drivers/ide/legacy/ide-cs.c | 4
drivers/ide/legacy/ide_platform.c | 2
drivers/ide/mips/au1xxx-ide.c | 2
drivers/ide/pci/delkin_cb.c | 4
drivers/ide/pci/scc_pata.c | 2
include/linux/hdreg.h | 4
include/linux/ide.h | 2
12 files changed, 17 insertions(+), 208 deletions(-)

Index: b/block/compat_ioctl.c
===================================================================
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -624,7 +624,6 @@ static int compat_blkdev_driver_ioctl(st
case HDIO_GET_IDENTITY:
case HDIO_DRIVE_TASK:
case HDIO_DRIVE_CMD:
- case HDIO_SCAN_HWIF:
/* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */
case 0x330:
/* 0x02 -- Floppy ioctls */
Index: b/drivers/ide/arm/bast-ide.c
===================================================================
--- a/drivers/ide/arm/bast-ide.c
+++ b/drivers/ide/arm/bast-ide.c
@@ -53,7 +53,7 @@ bastide_register(unsigned int base, unsi
i = hwif->index;

if (hwif->present)
- ide_unregister(i, 0, 0);
+ ide_unregister(i);
else if (!hwif->hold)
ide_init_port_data(hwif, i);

Index: b/drivers/ide/arm/rapide.c
===================================================================
--- a/drivers/ide/arm/rapide.c
+++ b/drivers/ide/arm/rapide.c
@@ -76,7 +76,7 @@ static void __devexit rapide_remove(stru

ecard_set_drvdata(ec, NULL);

- ide_unregister(hwif->index, 0, 0);
+ ide_unregister(hwif->index);

ecard_release_resources(ec);
}
Index: b/drivers/ide/ide-pnp.c
===================================================================
--- a/drivers/ide/ide-pnp.c
+++ b/drivers/ide/ide-pnp.c
@@ -62,7 +62,7 @@ static void idepnp_remove(struct pnp_dev
ide_hwif_t *hwif = pnp_get_drvdata(dev);

if (hwif)
- ide_unregister(hwif->index, 0, 0);
+ ide_unregister(hwif->index);
else
printk(KERN_ERR "idepnp: Unable to remove device, please report.\n");
}
Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -364,108 +364,6 @@ void ide_hwif_release_regions(ide_hwif_t
release_region(hwif->io_ports[i], 1);
}

-/**
- * ide_hwif_restore - restore hwif to template
- * @hwif: hwif to update
- * @tmp_hwif: template
- *
- * Restore hwif to a previous state by copying most settings
- * from the template.
- */
-
-static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
-{
- hwif->hwgroup = tmp_hwif->hwgroup;
-
- hwif->gendev.parent = tmp_hwif->gendev.parent;
-
- hwif->proc = tmp_hwif->proc;
-
- hwif->major = tmp_hwif->major;
- hwif->straight8 = tmp_hwif->straight8;
- hwif->bus_state = tmp_hwif->bus_state;
-
- hwif->host_flags = tmp_hwif->host_flags;
-
- hwif->pio_mask = tmp_hwif->pio_mask;
-
- hwif->ultra_mask = tmp_hwif->ultra_mask;
- hwif->mwdma_mask = tmp_hwif->mwdma_mask;
- hwif->swdma_mask = tmp_hwif->swdma_mask;
-
- hwif->cbl = tmp_hwif->cbl;
-
- hwif->chipset = tmp_hwif->chipset;
- hwif->hold = tmp_hwif->hold;
-
- hwif->dev = tmp_hwif->dev;
-
-#ifdef CONFIG_BLK_DEV_IDEPCI
- hwif->cds = tmp_hwif->cds;
-#endif
-
- hwif->set_pio_mode = tmp_hwif->set_pio_mode;
- hwif->set_dma_mode = tmp_hwif->set_dma_mode;
- hwif->mdma_filter = tmp_hwif->mdma_filter;
- hwif->udma_filter = tmp_hwif->udma_filter;
- hwif->selectproc = tmp_hwif->selectproc;
- hwif->reset_poll = tmp_hwif->reset_poll;
- hwif->pre_reset = tmp_hwif->pre_reset;
- hwif->resetproc = tmp_hwif->resetproc;
- hwif->maskproc = tmp_hwif->maskproc;
- hwif->quirkproc = tmp_hwif->quirkproc;
- hwif->busproc = tmp_hwif->busproc;
-
- hwif->ata_input_data = tmp_hwif->ata_input_data;
- hwif->ata_output_data = tmp_hwif->ata_output_data;
- hwif->atapi_input_bytes = tmp_hwif->atapi_input_bytes;
- hwif->atapi_output_bytes = tmp_hwif->atapi_output_bytes;
-
- hwif->dma_host_set = tmp_hwif->dma_host_set;
- hwif->dma_setup = tmp_hwif->dma_setup;
- hwif->dma_exec_cmd = tmp_hwif->dma_exec_cmd;
- hwif->dma_start = tmp_hwif->dma_start;
- hwif->ide_dma_end = tmp_hwif->ide_dma_end;
- hwif->ide_dma_test_irq = tmp_hwif->ide_dma_test_irq;
- hwif->ide_dma_clear_irq = tmp_hwif->ide_dma_clear_irq;
- hwif->dma_lost_irq = tmp_hwif->dma_lost_irq;
- hwif->dma_timeout = tmp_hwif->dma_timeout;
-
- hwif->OUTB = tmp_hwif->OUTB;
- hwif->OUTBSYNC = tmp_hwif->OUTBSYNC;
- hwif->OUTW = tmp_hwif->OUTW;
- hwif->OUTSW = tmp_hwif->OUTSW;
- hwif->OUTSL = tmp_hwif->OUTSL;
-
- hwif->INB = tmp_hwif->INB;
- hwif->INW = tmp_hwif->INW;
- hwif->INSW = tmp_hwif->INSW;
- hwif->INSL = tmp_hwif->INSL;
-
- hwif->sg_max_nents = tmp_hwif->sg_max_nents;
-
- hwif->mmio = tmp_hwif->mmio;
- hwif->rqsize = tmp_hwif->rqsize;
-
-#ifndef CONFIG_BLK_DEV_IDECS
- hwif->irq = tmp_hwif->irq;
-#endif
-
- hwif->dma_base = tmp_hwif->dma_base;
- hwif->dma_command = tmp_hwif->dma_command;
- hwif->dma_vendor1 = tmp_hwif->dma_vendor1;
- hwif->dma_status = tmp_hwif->dma_status;
- hwif->dma_vendor3 = tmp_hwif->dma_vendor3;
- hwif->dma_prdtable = tmp_hwif->dma_prdtable;
-
- hwif->config_data = tmp_hwif->config_data;
- hwif->select_data = tmp_hwif->select_data;
- hwif->extra_base = tmp_hwif->extra_base;
- hwif->extra_ports = tmp_hwif->extra_ports;
-
- hwif->hwif_data = tmp_hwif->hwif_data;
-}
-
void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
{
ide_hwgroup_t *hwgroup = hwif->hwgroup;
@@ -533,8 +431,6 @@ EXPORT_SYMBOL_GPL(ide_port_unregister_de
/**
* ide_unregister - free an IDE interface
* @index: index of interface (will change soon to a pointer)
- * @init_default: init default hwif flag
- * @restore: restore hwif flag
*
* Perform the final unregister of an IDE interface. At the moment
* we don't refcount interfaces so this will also get split up.
@@ -554,10 +450,9 @@ EXPORT_SYMBOL_GPL(ide_port_unregister_de
* This is raving bonkers.
*/

-void ide_unregister(unsigned int index, int init_default, int restore)
+void ide_unregister(unsigned int index)
{
ide_hwif_t *hwif, *g;
- static ide_hwif_t tmp_hwif; /* protected by ide_cfg_mtx */
ide_hwgroup_t *hwgroup;
int irq_count = 0;

@@ -604,19 +499,8 @@ void ide_unregister(unsigned int index,
unregister_blkdev(hwif->major, hwif->name);
spin_lock_irq(&ide_lock);

- if (hwif->dma_base) {
- (void) ide_release_dma(hwif);
-
- hwif->dma_base = 0;
- hwif->dma_command = 0;
- hwif->dma_vendor1 = 0;
- hwif->dma_status = 0;
- hwif->dma_vendor3 = 0;
- hwif->dma_prdtable = 0;
-
- hwif->extra_base = 0;
- hwif->extra_ports = 0;
- }
+ if (hwif->dma_base)
+ (void)ide_release_dma(hwif);

/*
* Note that we only release the standard ports,
@@ -625,18 +509,9 @@ void ide_unregister(unsigned int index,
*/
ide_hwif_release_regions(hwif);

- /* copy original settings */
- tmp_hwif = *hwif;
-
/* restore hwif data to pristine status */
ide_init_port_data(hwif, index);

- if (init_default)
- init_hwif_default(hwif, index);
-
- if (restore)
- ide_hwif_restore(hwif, &tmp_hwif);
-
abort:
spin_unlock_irq(&ide_lock);
mutex_unlock(&ide_cfg_mtx);
@@ -655,52 +530,6 @@ void ide_init_port_hw(ide_hwif_t *hwif,
}
EXPORT_SYMBOL_GPL(ide_init_port_hw);

-/**
- * ide_register_hw - register IDE interface
- * @hw: hardware registers
- * @quirkproc: quirkproc function
- * @hwifp: pointer to returned hwif
- *
- * Register an IDE interface, specifying exactly the registers etc.
- *
- * Returns -1 on error.
- */
-
-static int ide_register_hw(hw_regs_t *hw, void (*quirkproc)(ide_drive_t *),
- ide_hwif_t **hwifp)
-{
- int index, retry = 1;
- ide_hwif_t *hwif;
- u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-
- do {
- hwif = ide_find_port(hw->io_ports[IDE_DATA_OFFSET]);
- index = hwif->index;
- if (hwif)
- goto found;
- for (index = 0; index < MAX_HWIFS; index++)
- ide_unregister(index, 1, 1);
- } while (retry--);
- return -1;
-found:
- if (hwif->present)
- ide_unregister(index, 0, 1);
- else if (!hwif->hold)
- ide_init_port_data(hwif, index);
-
- ide_init_port_hw(hwif, hw);
- hwif->quirkproc = quirkproc;
-
- idx[0] = index;
-
- ide_device_add(idx, NULL);
-
- if (hwifp)
- *hwifp = hwif;
-
- return hwif->present ? index : -1;
-}
-
/*
* Locks for IDE setting functionality
*/
@@ -1003,27 +832,6 @@ int generic_ide_ioctl(ide_drive_t *drive
if (!capable(CAP_SYS_RAWIO))
return -EACCES;
return ide_task_ioctl(drive, cmd, arg);
-
- case HDIO_SCAN_HWIF:
- {
- hw_regs_t hw;
- int args[3];
- if (!capable(CAP_SYS_RAWIO)) return -EACCES;
- if (copy_from_user(args, p, 3 * sizeof(int)))
- return -EFAULT;
- memset(&hw, 0, sizeof(hw));
- ide_init_hwif_ports(&hw, (unsigned long) args[0],
- (unsigned long) args[1], NULL);
- hw.irq = args[2];
- if (ide_register_hw(&hw, NULL, NULL) == -1)
- return -EIO;
- return 0;
- }
- case HDIO_UNREGISTER_HWIF:
- if (!capable(CAP_SYS_RAWIO)) return -EACCES;
- /* (arg > MAX_HWIFS) checked in function */
- ide_unregister(arg, 1, 1);
- return 0;
case HDIO_SET_NICE:
if (!capable(CAP_SYS_ADMIN)) return -EACCES;
if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1))))
Index: b/drivers/ide/legacy/ide-cs.c
===================================================================
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -163,7 +163,7 @@ static int idecs_register(unsigned long
i = hwif->index;

if (hwif->present)
- ide_unregister(i, 0, 0);
+ ide_unregister(i);
else if (!hwif->hold)
ide_init_port_data(hwif, i);

@@ -360,7 +360,7 @@ void ide_release(struct pcmcia_device *l
if (info->ndev) {
/* FIXME: if this fails we need to queue the cleanup somehow
-- need to investigate the required PCMCIA magic */
- ide_unregister(info->hd, 0, 0);
+ ide_unregister(info->hd);
}
info->ndev = 0;

Index: b/drivers/ide/legacy/ide_platform.c
===================================================================
--- a/drivers/ide/legacy/ide_platform.c
+++ b/drivers/ide/legacy/ide_platform.c
@@ -122,7 +122,7 @@ static int __devexit plat_ide_remove(str
{
ide_hwif_t *hwif = pdev->dev.driver_data;

- ide_unregister(hwif->index, 0, 0);
+ ide_unregister(hwif->index);

return 0;
}
Index: b/drivers/ide/mips/au1xxx-ide.c
===================================================================
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -677,7 +677,7 @@ static int au_ide_remove(struct device *
ide_hwif_t *hwif = dev_get_drvdata(dev);
_auide_hwif *ahwif = &auide_hwif;

- ide_unregister(hwif->index, 0, 0);
+ ide_unregister(hwif->index);

iounmap((void *)ahwif->regbase);

Index: b/drivers/ide/pci/delkin_cb.c
===================================================================
--- a/drivers/ide/pci/delkin_cb.c
+++ b/drivers/ide/pci/delkin_cb.c
@@ -85,7 +85,7 @@ delkin_cb_probe (struct pci_dev *dev, co
i = hwif->index;

if (hwif->present)
- ide_unregister(i, 0, 0);
+ ide_unregister(i);
else if (!hwif->hold)
ide_init_port_data(hwif, i);

@@ -120,7 +120,7 @@ delkin_cb_remove (struct pci_dev *dev)
ide_hwif_t *hwif = pci_get_drvdata(dev);

if (hwif)
- ide_unregister(hwif->index, 0, 0);
+ ide_unregister(hwif->index);

pci_disable_device(dev);
}
Index: b/drivers/ide/pci/scc_pata.c
===================================================================
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -736,7 +736,7 @@ static void __devexit scc_remove(struct
hwif->dmatable_cpu = NULL;
}

- ide_unregister(hwif->index, 0, 0);
+ ide_unregister(hwif->index);

hwif->chipset = ide_unknown;
iounmap((void*)ports->dma);
Index: b/include/linux/hdreg.h
===================================================================
--- a/include/linux/hdreg.h
+++ b/include/linux/hdreg.h
@@ -422,9 +422,11 @@ struct hd_geometry {
#define HDIO_SET_NOWERR 0x0325 /* change ignore-write-error flag */
#define HDIO_SET_DMA 0x0326 /* change use-dma flag */
#define HDIO_SET_PIO_MODE 0x0327 /* reconfig interface to new speed */
+#ifndef __KERNEL__
#define HDIO_SCAN_HWIF 0x0328 /* register and (re)scan interface */
-#define HDIO_SET_NICE 0x0329 /* set nice flags */
#define HDIO_UNREGISTER_HWIF 0x032a /* unregister interface */
+#endif
+#define HDIO_SET_NICE 0x0329 /* set nice flags */
#define HDIO_SET_WCACHE 0x032b /* change write cache enable-disable */
#define HDIO_SET_ACOUSTIC 0x032c /* change acoustic behavior */
#define HDIO_SET_BUSSTATE 0x032d /* set the bus state of the hwif */
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1193,7 +1193,7 @@ static inline void ide_acpi_set_state(id
void ide_remove_port_from_hwgroup(ide_hwif_t *);
extern int ide_hwif_request_regions(ide_hwif_t *hwif);
extern void ide_hwif_release_regions(ide_hwif_t* hwif);
-void ide_unregister(unsigned int, int, int);
+void ide_unregister(unsigned int);

void ide_register_region(struct gendisk *);
void ide_unregister_region(struct gendisk *);

Subject: [PATCH 16/18] ide: remove ->hold field from ide_hwif_t

->hold is write-only now, remove it.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/mips/au1xxx-ide.c | 3 ---
drivers/ide/ppc/pmac.c | 1 -
include/linux/ide.h | 1 -
3 files changed, 5 deletions(-)

Index: b/drivers/ide/mips/au1xxx-ide.c
===================================================================
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -617,9 +617,6 @@ static int au_ide_probe(struct device *d

hwif->dev = dev;

- /* hold should be on in all cases */
- hwif->hold = 1;
-
hwif->mmio = 1;

/* If the user has selected DDMA assisted copies,
Index: b/drivers/ide/ppc/pmac.c
===================================================================
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1120,7 +1120,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *p
hwif->hwif_data = pmif;
ide_init_port_hw(hwif, hw);
hwif->noprobe = pmif->mediabay;
- hwif->hold = pmif->mediabay;
hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
hwif->set_pio_mode = pmac_ide_set_pio_mode;
if (pmif->kind == controller_un_ata6
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -573,7 +573,6 @@ typedef struct hwif_s {

unsigned noprobe : 1; /* don't probe for this interface */
unsigned present : 1; /* this interface exists */
- unsigned hold : 1; /* this interface is always present */
unsigned serialized : 1; /* serialized all channel operation */
unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */
unsigned reset : 1; /* reset after probe */

Subject: [PATCH 17/18] ide: remove init_hwif_default()

init_hwif_default() is only used by init_ide_data() now, inline it there.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)

Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -168,19 +168,6 @@ static void ide_port_init_devices_data(i
}


-static void init_hwif_default(ide_hwif_t *hwif, unsigned int index)
-{
- hw_regs_t hw;
-
- memset(&hw, 0, sizeof(hw_regs_t));
-
- ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, &hwif->irq);
-
- memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports));
-
- hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
-}
-
/*
* init_ide_data() sets reasonable default values into all fields
* of all instances of the hwifs and drives, but only on the first call.
@@ -201,9 +188,9 @@ static void init_hwif_default(ide_hwif_t
#define MAGIC_COOKIE 0x12345678
static void __init init_ide_data (void)
{
- ide_hwif_t *hwif;
unsigned int index;
static unsigned long magic_cookie = MAGIC_COOKIE;
+ hw_regs_t hw;

if (magic_cookie != MAGIC_COOKIE)
return; /* already initialized */
@@ -211,9 +198,15 @@ static void __init init_ide_data (void)

/* Initialise all interface structures */
for (index = 0; index < MAX_HWIFS; ++index) {
- hwif = &ide_hwifs[index];
+ ide_hwif_t *hwif = &ide_hwifs[index];
+
ide_init_port_data(hwif, index);
- init_hwif_default(hwif, index);
+
+ memset(&hw, 0, sizeof(hw));
+ ide_init_hwif_ports(&hw, ide_default_io_base(index), 0,
+ &hwif->irq);
+ memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports));
+ hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
#if !defined(CONFIG_PPC32) || !defined(CONFIG_PCI)
hwif->irq =
ide_init_default_irq(hwif->io_ports[IDE_DATA_OFFSET]);

Subject: [PATCH 18/18] ide: remove ide_init_hwif_ports()

ide_init_hwif_ports() is only used by init_ide_data() now, inline it there.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide.c | 11 +++++++++--
include/linux/ide.h | 32 --------------------------------
2 files changed, 9 insertions(+), 34 deletions(-)

Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -199,13 +199,20 @@ static void __init init_ide_data (void)
/* Initialise all interface structures */
for (index = 0; index < MAX_HWIFS; ++index) {
ide_hwif_t *hwif = &ide_hwifs[index];
+ unsigned long io_addr = ide_default_io_base(index);
+ unsigned long ctl_addr = ide_default_io_ctl(io_addr);

ide_init_port_data(hwif, index);

+#ifdef CONFIG_IDE_ARCH_OBSOLETE_INIT
memset(&hw, 0, sizeof(hw));
- ide_init_hwif_ports(&hw, ide_default_io_base(index), 0,
- &hwif->irq);
+ ide_std_init_ports(&hw, io_addr, ctl_addr);
+# ifdef CONFIG_PPC32
+ if (ppc_ide_md.ide_init_hwif)
+ ppc_ide_md.ide_init_hwif(&hw, io_addr, 0, &hwif->irq);
+# endif
memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports));
+#endif
hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
#if !defined(CONFIG_PPC32) || !defined(CONFIG_PCI)
hwif->irq =
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -215,38 +215,6 @@ static inline void ide_std_init_ports(hw
# define ide_init_default_irq(base) (0)
#endif

-#ifdef CONFIG_IDE_ARCH_OBSOLETE_INIT
-static inline void ide_init_hwif_ports(hw_regs_t *hw,
- unsigned long io_addr,
- unsigned long ctl_addr,
- int *irq)
-{
- if (!ctl_addr)
- ide_std_init_ports(hw, io_addr, ide_default_io_ctl(io_addr));
- else
- ide_std_init_ports(hw, io_addr, ctl_addr);
-
- if (irq)
- *irq = 0;
-
- hw->io_ports[IDE_IRQ_OFFSET] = 0;
-
-#ifdef CONFIG_PPC32
- if (ppc_ide_md.ide_init_hwif)
- ppc_ide_md.ide_init_hwif(hw, io_addr, ctl_addr, irq);
-#endif
-}
-#else
-static inline void ide_init_hwif_ports(hw_regs_t *hw,
- unsigned long io_addr,
- unsigned long ctl_addr,
- int *irq)
-{
- if (io_addr || ctl_addr)
- printk(KERN_WARNING "%s: must not be called\n", __FUNCTION__);
-}
-#endif /* CONFIG_IDE_ARCH_OBSOLETE_INIT */
-
/* Currently only m68k, apus and m8xx need it */
#ifndef IDE_ARCH_ACK_INTR
# define ide_ack_intr(hwif) (1)

2008-02-08 08:41:21

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [PATCH 00/18] ide: warm-plug support for IDE devices and other goodies


On Fri, 2008-02-08 at 01:44 +0100, Bartlomiej Zolnierkiewicz wrote:
> - couple of fixes and preparatory patches
>
> - rework of PowerMac media-bay support ([un]register IDE devices instead of
> [un]registering IDE interface) [ it is the main reason for spamming PPC ML ]

Interesting... I was thinking about doing a full remove of the device at
a higher level instead but I suppose what you propose is easier.

I'll have a look & test next week hopefully.

Ben.

2008-02-08 17:21:07

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 05/18] ide: factor out cable detection from ide_init_port()

Bartlomiej Zolnierkiewicz wrote:

> * Factor out cable detection from ide_init_port() to ide_port_cable_detect().

> * Move ide_port_cable_detect() call to ide_device_add_all().

> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>

Acked-by: Sergei Shtylyov <[email protected]>

MBR, Sergei

2008-02-08 17:21:34

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 08/18] ide: move ide_port_setup_devices() call to ide_device_add_all()

Bartlomiej Zolnierkiewicz wrote:

> Add ide_cfg_mtx lock/unlock to ide_port_setup_devices() and then move
> ide_port_setup_devices() call from init_irq() to ide_device_add_all().

> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>

Acked-by: Sergei Shtylyov <[email protected]>

MBR, Sergei

2008-02-08 17:22:39

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 02/18] ide: fix ide_find_port()

Bartlomiej Zolnierkiewicz wrote:

> * Instead of checking for '->io_ports[IDE_DATA_OFFSET] == 0' check for
> '->chipset == ide_unknown' when looking for an empty ide_hwifs[] slot.

> * Do ide-pnp initialization after ide-generic when IDE is built-in
> (ide-pnp is the only user of ide_find_port() which needs such fixup).

> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>

Acked-by: Sergei Shtylyov <[email protected]>

MBR, Sergei

2008-02-09 18:06:50

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 06/18] ide: factor out code unregistering devices from ide_unregister()

Bartlomiej Zolnierkiewicz wrote:

> Factor out code unregistering devices from ide_unregister() to
> ide_port_unregister_devices().

> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>

Acked-by: Sergei Shtylyov <[email protected]>

MBR, Sergei

2008-02-09 18:10:38

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 07/18] ide: factor out devices init from ide_init_port_data()

Bartlomiej Zolnierkiewicz wrote:

> * Factor out devices init from ide_init_port_data() to
> ide_port_init_devices_data().

> While at it:

> * Add explicit clearing of IDE device structure.

> There should be no functionality changes caused by this patch.

> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>

Acked-by: Sergei Shtylyov <[email protected]>

MBR, Sergei

2008-02-12 12:24:17

by Gabriel Paubert

[permalink] [raw]
Subject: Re: [PATCH 00/18] ide: warm-plug support for IDE devices and other goodies

On Fri, Feb 08, 2008 at 07:40:43PM +1100, Benjamin Herrenschmidt wrote:
>
> On Fri, 2008-02-08 at 01:44 +0100, Bartlomiej Zolnierkiewicz wrote:
> > - couple of fixes and preparatory patches
> >
> > - rework of PowerMac media-bay support ([un]register IDE devices instead of
> > [un]registering IDE interface) [ it is the main reason for spamming PPC ML ]
>
> Interesting... I was thinking about doing a full remove of the device at
> a higher level instead but I suppose what you propose is easier.

Well, I have serious problem on a Pegasos which appeared some time
between 2.6.24 and 2.6.25-rc1: at boot I get an infinite string of

hdb: empty DMA table?

I'm trying to bisect it right now.

Gabriel


>
> I'll have a look & test next week hopefully.
>
> Ben.
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> [email protected]
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

2008-02-12 12:30:23

by Gabriel Paubert

[permalink] [raw]
Subject: Re: [PATCH 00/18] ide: warm-plug support for IDE devices and other goodies

On Tue, Feb 12, 2008 at 12:49:05PM +0100, Gabriel Paubert wrote:
> On Fri, Feb 08, 2008 at 07:40:43PM +1100, Benjamin Herrenschmidt wrote:
> >
> > On Fri, 2008-02-08 at 01:44 +0100, Bartlomiej Zolnierkiewicz wrote:
> > > - couple of fixes and preparatory patches
> > >
> > > - rework of PowerMac media-bay support ([un]register IDE devices instead of
> > > [un]registering IDE interface) [ it is the main reason for spamming PPC ML ]
> >
> > Interesting... I was thinking about doing a full remove of the device at
> > a higher level instead but I suppose what you propose is easier.
>
> Well, I have serious problem on a Pegasos which appeared some time
> between 2.6.24 and 2.6.25-rc1: at boot I get an infinite string of
>
> hdb: empty DMA table?
>
> I'm trying to bisect it right now.

Argh, the first bisect point ended up with timeouts on hdb...

Flagged as bad, to try to see when the problems started, but
I suspect that there are several.

Gabriel

2008-02-12 21:00:40

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [PATCH 00/18] ide: warm-plug support for IDE devices and other goodies


On Tue, 2008-02-12 at 12:49 +0100, Gabriel Paubert wrote:
> On Fri, Feb 08, 2008 at 07:40:43PM +1100, Benjamin Herrenschmidt wrote:
> >
> > On Fri, 2008-02-08 at 01:44 +0100, Bartlomiej Zolnierkiewicz wrote:
> > > - couple of fixes and preparatory patches
> > >
> > > - rework of PowerMac media-bay support ([un]register IDE devices instead of
> > > [un]registering IDE interface) [ it is the main reason for spamming PPC ML ]
> >
> > Interesting... I was thinking about doing a full remove of the device at
> > a higher level instead but I suppose what you propose is easier.
>
> Well, I have serious problem on a Pegasos which appeared some time
> between 2.6.24 and 2.6.25-rc1: at boot I get an infinite string of
>
> hdb: empty DMA table?
>
> I'm trying to bisect it right now.

Pegasos doesn't use the pmac ide which is what we were discussing. It
uses a VIA IDE which uses a normal PRD table. So something else must
have broken...

Ben.

2008-02-12 21:04:49

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [PATCH 00/18] ide: warm-plug support for IDE devices and other goodies


On Fri, 2008-02-08 at 19:40 +1100, Benjamin Herrenschmidt wrote:
> On Fri, 2008-02-08 at 01:44 +0100, Bartlomiej Zolnierkiewicz wrote:
> > - couple of fixes and preparatory patches
> >
> > - rework of PowerMac media-bay support ([un]register IDE devices instead of
> > [un]registering IDE interface) [ it is the main reason for spamming PPC ML ]
>
> Interesting... I was thinking about doing a full remove of the device at
> a higher level instead but I suppose what you propose is easier.
>
> I'll have a look & test next week hopefully.

Also, the above would have the advantage of not relying on drivers/ide
infrastructure, and thus working with libata (once somebody has ported
pmac ide to libata).

Ben.

Subject: Re: [PATCH 00/18] ide: warm-plug support for IDE devices and other goodies

On Tuesday 12 February 2008, Benjamin Herrenschmidt wrote:
>
> On Fri, 2008-02-08 at 19:40 +1100, Benjamin Herrenschmidt wrote:
> > On Fri, 2008-02-08 at 01:44 +0100, Bartlomiej Zolnierkiewicz wrote:
> > > - couple of fixes and preparatory patches
> > >
> > > - rework of PowerMac media-bay support ([un]register IDE devices instead of
> > > [un]registering IDE interface) [ it is the main reason for spamming PPC ML ]
> >
> > Interesting... I was thinking about doing a full remove of the device at
> > a higher level instead but I suppose what you propose is easier.
> >
> > I'll have a look & test next week hopefully.
>
> Also, the above would have the advantage of not relying on drivers/ide
> infrastructure, and thus working with libata (once somebody has ported
> pmac ide to libata).

Neither of these things exist at the moment so lets stick to the existing
code which is scheduled for 2.6.26 and which finally allows removal of ppc
specific ide hacks from arch/{powerpc,ppc} (500 LOC gone, patches to be
posted this week), not to mention other nice changes in the future...

Thanks,
Bart

2008-02-12 21:49:21

by Alan

[permalink] [raw]
Subject: Re: [PATCH 00/18] ide: warm-plug support for IDE devices and other goodies

On Wed, 13 Feb 2008 08:04:07 +1100
Benjamin Herrenschmidt <[email protected]> wrote:

>
> On Fri, 2008-02-08 at 19:40 +1100, Benjamin Herrenschmidt wrote:
> > On Fri, 2008-02-08 at 01:44 +0100, Bartlomiej Zolnierkiewicz wrote:
> > > - couple of fixes and preparatory patches
> > >
> > > - rework of PowerMac media-bay support ([un]register IDE devices instead of
> > > [un]registering IDE interface) [ it is the main reason for spamming PPC ML ]
> >
> > Interesting... I was thinking about doing a full remove of the device at
> > a higher level instead but I suppose what you propose is easier.
> >
> > I'll have a look & test next week hopefully.
>
> Also, the above would have the advantage of not relying on drivers/ide
> infrastructure, and thus working with libata (once somebody has ported
> pmac ide to libata).

Unfortunately you need a degree in dentistry to open a Macintosh up and
fix it otherwise we would have support by now.

Alan

2008-02-12 22:01:28

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [PATCH 00/18] ide: warm-plug support for IDE devices and other goodies


On Tue, 2008-02-12 at 21:41 +0000, Alan Cox wrote:
> On Wed, 13 Feb 2008 08:04:07 +1100
> Benjamin Herrenschmidt <[email protected]> wrote:
>
> >
> > On Fri, 2008-02-08 at 19:40 +1100, Benjamin Herrenschmidt wrote:
> > > On Fri, 2008-02-08 at 01:44 +0100, Bartlomiej Zolnierkiewicz wrote:
> > > > - couple of fixes and preparatory patches
> > > >
> > > > - rework of PowerMac media-bay support ([un]register IDE devices instead of
> > > > [un]registering IDE interface) [ it is the main reason for spamming PPC ML ]
> > >
> > > Interesting... I was thinking about doing a full remove of the device at
> > > a higher level instead but I suppose what you propose is easier.
> > >
> > > I'll have a look & test next week hopefully.
> >
> > Also, the above would have the advantage of not relying on drivers/ide
> > infrastructure, and thus working with libata (once somebody has ported
> > pmac ide to libata).
>
> Unfortunately you need a degree in dentistry to open a Macintosh up and
> fix it otherwise we would have support by now.

Heh :-)

Recent powermacs are trivial to open ! But yeah, I do need to produce a
driver for libata one of these days. On my todo list ...

Cheers,
Ben.

2008-02-13 07:29:54

by Michael Ellerman

[permalink] [raw]
Subject: Re: [PATCH 09/18] ide: rework PowerMac media-bay support

On Fri, 2008-02-08 at 01:45 +0100, Bartlomiej Zolnierkiewicz wrote:
> Rework PowerMac media-bay support in such way that instead of
> un/registering the IDE interface we un/register IDE devices:
>
> * Add ide_port_scan() helper for probing+registerering devices on a port.
>
> * Rename ide_port_unregister_devices() to __ide_port_unregister_devices().
>
> * Add ide_port_unregister_devices() helper for unregistering devices on a port.
>
> * Add 'ide_hwif_t *cd_port' to 'struct media_bay_info', pass 'hwif' instead
> of hwif->index to media_bay_set_ide_infos() and use it to setup 'cd_port'.
>
> * Use ide_port_unregister_devices() instead of ide_unregister()
> and ide_port_scan() instead of ide_register_hw() in media_bay_step().
>
> * Unexport ide_register_hw() and make it static.
>
> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
> ---
> drivers/ide/ide-probe.c | 18 ++++++++++++++++++
> drivers/ide/ide.c | 22 ++++++++++++++++------
> drivers/ide/ppc/pmac.c | 3 ++-
> drivers/macintosh/mediabay.c | 17 +++++++----------
> include/asm-powerpc/mediabay.h | 4 +++-
> include/linux/ide.h | 6 ++----
> 6 files changed, 48 insertions(+), 22 deletions(-)

> Index: b/include/asm-powerpc/mediabay.h
> ===================================================================
> --- a/include/asm-powerpc/mediabay.h
> +++ b/include/asm-powerpc/mediabay.h
> @@ -22,10 +22,12 @@ int check_media_bay(struct device_node *
> /* Number of bays in the machine or 0 */
> extern int media_bay_count;
>
> +#ifdef CONFIG_BLK_DEV_IDE_PMAC
> int check_media_bay_by_base(unsigned long base, int what);
> /* called by IDE PMAC host driver to register IDE controller for media bay */
> int media_bay_set_ide_infos(struct device_node *which_bay, unsigned long base,
> - int irq, int index);
> + int irq, ide_hwif_t *hwif);
> +#endif
>
> #endif /* __KERNEL__ */
> #endif /* _PPC_MEDIABAY_H */

This hunk breaks pmac32_defconfig for me.

include2/asm/mediabay.h:29: error: syntax error before 'ide_hwif_t'
make[3]: *** [arch/powerpc/platforms/powermac/setup.o] Error 1
make[2]: *** [arch/powerpc/platforms/powermac] Error 2
make[1]: *** [arch/powerpc/platforms] Error 2
make: *** [sub-make] Error 2

cheers

--
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person


Attachments:
signature.asc (189.00 B)
This is a digitally signed message part

2008-02-13 10:08:33

by Gabriel Paubert

[permalink] [raw]
Subject: Re: [PATCH 00/18] ide: warm-plug support for IDE devices and other goodies

On Tue, Feb 12, 2008 at 01:30:03PM +0100, Gabriel Paubert wrote:
> On Tue, Feb 12, 2008 at 12:49:05PM +0100, Gabriel Paubert wrote:
> > On Fri, Feb 08, 2008 at 07:40:43PM +1100, Benjamin Herrenschmidt wrote:
> > >
> > > On Fri, 2008-02-08 at 01:44 +0100, Bartlomiej Zolnierkiewicz wrote:
> > > > - couple of fixes and preparatory patches
> > > >
> > > > - rework of PowerMac media-bay support ([un]register IDE devices instead of
> > > > [un]registering IDE interface) [ it is the main reason for spamming PPC ML ]
> > >
> > > Interesting... I was thinking about doing a full remove of the device at
> > > a higher level instead but I suppose what you propose is easier.
> >
> > Well, I have serious problem on a Pegasos which appeared some time
> > between 2.6.24 and 2.6.25-rc1: at boot I get an infinite string of
> >
> > hdb: empty DMA table?
> >
> > I'm trying to bisect it right now.
>
> Argh, the first bisect point ended up with timeouts on hdb...
>
> Flagged as bad, to try to see when the problems started, but
> I suspect that there are several.

Well, it's worse than this. After 7 or 8 bisections (all flagged
bad) the symptoms changed: the system boots up to the point where
it does not recognize LVM volumes. So there are at least 3 bugs:
1) the timeout on interrupts (only seen on hdb)
2) the empty DMA table messages (seen on hda and hdb)
3) the inability to see logical volumes ("pvs" does not find them,
they are back when rebooting into 2.6.24). This is the apparently
the earliest introduced bug (no problems with the disks with that
version).

I am away from that machine until next Tuesday. IIRC the last git
bisect was something like 160 revisions left.

Gabriel

>
> Gabriel
> _______________________________________________
> Linuxppc-dev mailing list
> [email protected]
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

Subject: Re: [PATCH 09/18] ide: rework PowerMac media-bay support


Hi,

On Wednesday 13 February 2008, Michael Ellerman wrote:
> On Fri, 2008-02-08 at 01:45 +0100, Bartlomiej Zolnierkiewicz wrote:
> > Rework PowerMac media-bay support in such way that instead of
> > un/registering the IDE interface we un/register IDE devices:
> >
> > * Add ide_port_scan() helper for probing+registerering devices on a port.
> >
> > * Rename ide_port_unregister_devices() to __ide_port_unregister_devices().
> >
> > * Add ide_port_unregister_devices() helper for unregistering devices on a port.
> >
> > * Add 'ide_hwif_t *cd_port' to 'struct media_bay_info', pass 'hwif' instead
> > of hwif->index to media_bay_set_ide_infos() and use it to setup 'cd_port'.
> >
> > * Use ide_port_unregister_devices() instead of ide_unregister()
> > and ide_port_scan() instead of ide_register_hw() in media_bay_step().
> >
> > * Unexport ide_register_hw() and make it static.
> >
> > Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
> > ---
> > drivers/ide/ide-probe.c | 18 ++++++++++++++++++
> > drivers/ide/ide.c | 22 ++++++++++++++++------
> > drivers/ide/ppc/pmac.c | 3 ++-
> > drivers/macintosh/mediabay.c | 17 +++++++----------
> > include/asm-powerpc/mediabay.h | 4 +++-
> > include/linux/ide.h | 6 ++----
> > 6 files changed, 48 insertions(+), 22 deletions(-)
>
> > Index: b/include/asm-powerpc/mediabay.h
> > ===================================================================
> > --- a/include/asm-powerpc/mediabay.h
> > +++ b/include/asm-powerpc/mediabay.h
> > @@ -22,10 +22,12 @@ int check_media_bay(struct device_node *
> > /* Number of bays in the machine or 0 */
> > extern int media_bay_count;
> >
> > +#ifdef CONFIG_BLK_DEV_IDE_PMAC

Does adding:

#include <linux/ide.h>

after ifdef help?

> > int check_media_bay_by_base(unsigned long base, int what);
> > /* called by IDE PMAC host driver to register IDE controller for media bay */
> > int media_bay_set_ide_infos(struct device_node *which_bay, unsigned long base,
> > - int irq, int index);
> > + int irq, ide_hwif_t *hwif);
> > +#endif
> >
> > #endif /* __KERNEL__ */
> > #endif /* _PPC_MEDIABAY_H */
>
> This hunk breaks pmac32_defconfig for me.
>
> include2/asm/mediabay.h:29: error: syntax error before 'ide_hwif_t'
> make[3]: *** [arch/powerpc/platforms/powermac/setup.o] Error 1
> make[2]: *** [arch/powerpc/platforms/powermac] Error 2
> make[1]: *** [arch/powerpc/platforms] Error 2
> make: *** [sub-make] Error 2
>
> cheers

2008-03-27 17:37:48

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 15/18] ide: remove broken/dangerous HDIO_[UNREGISTER,SCAN]_HWIF ioctls

Bartlomiej Zolnierkiewicz wrote:

> hdparm explicitely marks HDIO_[UNREGISTER,SCAN]_HWIF ioctls as DANGEROUS
> and given the number of bugs we can assume that there are no real users:

> * DMA has no chance of working because DMA resources are released by
> ide_unregister() and they are never allocated again.

> * Since ide_init_hwif_ports() is used for ->io_ports[] setup the ioctls
> don't work for almost all hosts with "non-standard" (== non ISA-like)
> layout of IDE taskfile registers (there is a lot of such host drivers).

> * ide_port_init_devices() is not called when probing IDE devices so:
> - drive->autotune is never set and IDE host/devices are not programmed
> for the correct PIO/DMA transfer modes (=> possible data corruption)
> - host specific I/O 32-bit and IRQ unmasking settings are not applied
> (=> possible data corruption)
> - host specific ->port_init_devs method is not called (=> no luck with
> ht6560b, qd65xx and opti621 host drivers)

> * ->rw_disk method is not preserved (=> no HPT3xxN chipsets support).

> * ->serialized flag is not preserved (=> possible data corruption when
> using icside, aec62xx (ATP850UF chipset), cmd640, cs5530, hpt366
> (HPT3xxN chipsets), rz1000, sc1200, dtc2278 and ht6560b host drivers).

> * ->ack_intr method is not preserved (=> needed by ide-cris, buddha,
> gayle and macide host drivers).

> * ->sata_scr[] and sata_misc[] is cleared by ide_unregister() and it
> isn't initialized again (SiI3112 support needs them).

> * To issue an ioctl() there need to be at least one IDE device present
> in the system.

> * ->cable_detect method is not preserved + it is not called when probing
> IDE devices so cable detection is broken (however since DMA support is
> also broken it doesn't really matter ;-).

> * Some objects which may have already been freed in ide_unregister()
> are restored by ide_hwif_restore() (i.e. ->hwgroup).

> * ide_register_hw() may unregister unrelated IDE ports if free ide_hwifs[]
> slot cannot be found.

> * When IDE host drivers are modular unregistered port may be re-used by
> different host driver that owned it first causing subtle bugs.

> Since we now have a proper warm-plug support remove these ioctls,
> then remove no longer needed:
> - ide_register_hw() and ide_hwif_restore() functions
> - 'init_default' and 'restore' arguments of ide_unregister()
> - zeroeing of hwif->{dma,extra}_* fields in ide_unregister()

> As an added bonus IDE core code size shrinks by ~3kB (x86-32).

> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>

Acked-by: Sergei Shtylyov <[email protected]>

> Index: b/drivers/ide/ide-pnp.c
> ===================================================================
> --- a/drivers/ide/ide-pnp.c
> +++ b/drivers/ide/ide-pnp.c
[...]
> @@ -655,52 +530,6 @@ void ide_init_port_hw(ide_hwif_t *hwif,
> }
> EXPORT_SYMBOL_GPL(ide_init_port_hw);
>
> -/**
> - * ide_register_hw - register IDE interface
> - * @hw: hardware registers
> - * @quirkproc: quirkproc function
> - * @hwifp: pointer to returned hwif
> - *
> - * Register an IDE interface, specifying exactly the registers etc.
> - *
> - * Returns -1 on error.
> - */
> -
> -static int ide_register_hw(hw_regs_t *hw, void (*quirkproc)(ide_drive_t *),
> - ide_hwif_t **hwifp)
> -{
> - int index, retry = 1;
> - ide_hwif_t *hwif;
> - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
> -
> - do {
> - hwif = ide_find_port(hw->io_ports[IDE_DATA_OFFSET]);
> - index = hwif->index;
> - if (hwif)
> - goto found;

Hm, I remember there was a patch that fixed the above bug where hwif is
dereferenced before being checked for NULL, I wonder how come it was lost?

WBR, Sergei

2008-03-28 19:14:53

by Mark Lord

[permalink] [raw]
Subject: Re: [PATCH 15/18] ide: remove broken/dangerous HDIO_[UNREGISTER,SCAN]_HWIF ioctls

Sergei Shtylyov wrote:
> Bartlomiej Zolnierkiewicz wrote:
>
>> hdparm explicitely marks HDIO_[UNREGISTER,SCAN]_HWIF ioctls as DANGEROUS
>> and given the number of bugs we can assume that there are no real users:
..

There is the odd user of these, actually.

But the most recent to email me (a few weeks ago),
reported that the SCAN function was no longer working on his kernel.

I'll remove the -R and -U flags completely from hdparm-8.7.

Cheers

Subject: Re: [PATCH 15/18] ide: remove broken/dangerous HDIO_[UNREGISTER,SCAN]_HWIF ioctls

On Thursday 27 March 2008, Sergei Shtylyov wrote:

[...]

> > Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
>
> Acked-by: Sergei Shtylyov <[email protected]>

Thanks for reviewing it.

> > Index: b/drivers/ide/ide-pnp.c
> > ===================================================================
> > --- a/drivers/ide/ide-pnp.c
> > +++ b/drivers/ide/ide-pnp.c
> [...]
> > @@ -655,52 +530,6 @@ void ide_init_port_hw(ide_hwif_t *hwif,
> > }
> > EXPORT_SYMBOL_GPL(ide_init_port_hw);
> >
> > -/**
> > - * ide_register_hw - register IDE interface
> > - * @hw: hardware registers
> > - * @quirkproc: quirkproc function
> > - * @hwifp: pointer to returned hwif
> > - *
> > - * Register an IDE interface, specifying exactly the registers etc.
> > - *
> > - * Returns -1 on error.
> > - */
> > -
> > -static int ide_register_hw(hw_regs_t *hw, void (*quirkproc)(ide_drive_t *),
> > - ide_hwif_t **hwifp)
> > -{
> > - int index, retry = 1;
> > - ide_hwif_t *hwif;
> > - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
> > -
> > - do {
> > - hwif = ide_find_port(hw->io_ports[IDE_DATA_OFFSET]);
> > - index = hwif->index;
> > - if (hwif)
> > - goto found;
>
> Hm, I remember there was a patch that fixed the above bug where hwif is
> dereferenced before being checked for NULL, I wonder how come it was lost?

It has been already merged into Linus' tree
(commit 0c6025d44448bd688dfd351a09bc620aafa4d1ff).

Thanks,
Bart

Subject: Re: [PATCH 15/18] ide: remove broken/dangerous HDIO_[UNREGISTER,SCAN]_HWIF ioctls

On Friday 28 March 2008, Mark Lord wrote:
> Sergei Shtylyov wrote:
> > Bartlomiej Zolnierkiewicz wrote:
> >
> >> hdparm explicitely marks HDIO_[UNREGISTER,SCAN]_HWIF ioctls as DANGEROUS
> >> and given the number of bugs we can assume that there are no real users:
> ..
>
> There is the odd user of these, actually.
>
> But the most recent to email me (a few weeks ago),
> reported that the SCAN function was no longer working on his kernel.
>
> I'll remove the -R and -U flags completely from hdparm-8.7.

This will be quite helpful, thanks!

Bart