From 7662d046df09e80680b77b68de896beab45e675e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 10 May 2007 00:01:10 +0200 Subject: ide: move IDE settings handling to ide-proc.c * move __ide_add_setting() ide_add_setting() __ide_remove_setting() auto_remove_settings() ide_find_setting_by_name() ide_read_setting() ide_write_setting() set_xfer_rate() ide_add_generic_settings() ide_register_subdriver() ide_unregister_subdriver() from ide.c to ide-proc.c * set_{io_32bit,pio_mode,using_dma}() cannot be marked static now, fix it * rename ide_[un]register_subdriver() to ide_proc_[un]register_driver(), update device drivers to use new names * add CONFIG_IDE_PROC_FS=n versions of ide_proc_[un]register_driver() and ide_add_generic_settings() * make ide_find_setting_by_name(), ide_{read,write}_setting() and ide_{add,remove}_proc_entries() static * cover IDE settings code in device drivers with CONFIG_IDE_PROC_FS #ifdef, also while at it cover with CONFIG_IDE_PROC_FS #ifdef ide_driver_t.proc * remove bogus comment from ide.h * cover with CONFIG_IDE_PROC_FS #ifdef .proc and .settings in ide_drive_t Besides saner code this patch results in the IDE core smaller by ~2 kB (on x86-32) and IDE disk driver by ~1 kB (ditto) when CONFIG_IDE_PROC_FS=n. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-proc.c | 310 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 308 insertions(+), 2 deletions(-) (limited to 'drivers/ide/ide-proc.c') diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index a9e0b30fb1f..949a6f609d8 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -3,6 +3,8 @@ * * Copyright (C) 1997-1998 Mark Lord * Copyright (C) 2003 Red Hat + * + * Some code was moved here from ide.c, see it for original copyrights. */ /* @@ -121,6 +123,265 @@ static int proc_ide_read_identify PROC_IDE_READ_RETURN(page,start,off,count,eof,len); } +/** + * __ide_add_setting - add an ide setting option + * @drive: drive to use + * @name: setting name + * @rw: true if the function is read write + * @data_type: type of data + * @min: range minimum + * @max: range maximum + * @mul_factor: multiplication scale + * @div_factor: divison scale + * @data: private data field + * @set: setting + * @auto_remove: setting auto removal flag + * + * Removes the setting named from the device if it is present. + * The function takes the settings_lock to protect against + * parallel changes. This function must not be called from IRQ + * context. Returns 0 on success or -1 on failure. + * + * BUGS: This code is seriously over-engineered. There is also + * magic about how the driver specific features are setup. If + * a driver is attached we assume the driver settings are auto + * remove. + */ + +static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set, int auto_remove) +{ + ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL; + + down(&ide_setting_sem); + while ((*p) && strcmp((*p)->name, name) < 0) + p = &((*p)->next); + if ((setting = kzalloc(sizeof(*setting), GFP_KERNEL)) == NULL) + goto abort; + if ((setting->name = kmalloc(strlen(name) + 1, GFP_KERNEL)) == NULL) + goto abort; + strcpy(setting->name, name); + setting->rw = rw; + setting->data_type = data_type; + setting->min = min; + setting->max = max; + setting->mul_factor = mul_factor; + setting->div_factor = div_factor; + setting->data = data; + setting->set = set; + + setting->next = *p; + if (auto_remove) + setting->auto_remove = 1; + *p = setting; + up(&ide_setting_sem); + return 0; +abort: + up(&ide_setting_sem); + kfree(setting); + return -1; +} + +int ide_add_setting(ide_drive_t *drive, const char *name, int rw, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set) +{ + return __ide_add_setting(drive, name, rw, data_type, min, max, mul_factor, div_factor, data, set, 1); +} + +EXPORT_SYMBOL(ide_add_setting); + +/** + * __ide_remove_setting - remove an ide setting option + * @drive: drive to use + * @name: setting name + * + * Removes the setting named from the device if it is present. + * The caller must hold the setting semaphore. + */ + +static void __ide_remove_setting (ide_drive_t *drive, char *name) +{ + ide_settings_t **p, *setting; + + p = (ide_settings_t **) &drive->settings; + + while ((*p) && strcmp((*p)->name, name)) + p = &((*p)->next); + if ((setting = (*p)) == NULL) + return; + + (*p) = setting->next; + + kfree(setting->name); + kfree(setting); +} + +/** + * auto_remove_settings - remove driver specific settings + * @drive: drive + * + * Automatically remove all the driver specific settings for this + * drive. This function may not be called from IRQ context. The + * caller must hold ide_setting_sem. + */ + +static void auto_remove_settings (ide_drive_t *drive) +{ + ide_settings_t *setting; +repeat: + setting = drive->settings; + while (setting) { + if (setting->auto_remove) { + __ide_remove_setting(drive, setting->name); + goto repeat; + } + setting = setting->next; + } +} + +/** + * ide_find_setting_by_name - find a drive specific setting + * @drive: drive to scan + * @name: setting name + * + * Scan's the device setting table for a matching entry and returns + * this or NULL if no entry is found. The caller must hold the + * setting semaphore + */ + +static ide_settings_t *ide_find_setting_by_name(ide_drive_t *drive, char *name) +{ + ide_settings_t *setting = drive->settings; + + while (setting) { + if (strcmp(setting->name, name) == 0) + break; + setting = setting->next; + } + return setting; +} + +/** + * ide_read_setting - read an IDE setting + * @drive: drive to read from + * @setting: drive setting + * + * Read a drive setting and return the value. The caller + * must hold the ide_setting_sem when making this call. + * + * BUGS: the data return and error are the same return value + * so an error -EINVAL and true return of the same value cannot + * be told apart + */ + +static int ide_read_setting(ide_drive_t *drive, ide_settings_t *setting) +{ + int val = -EINVAL; + unsigned long flags; + + if ((setting->rw & SETTING_READ)) { + spin_lock_irqsave(&ide_lock, flags); + switch(setting->data_type) { + case TYPE_BYTE: + val = *((u8 *) setting->data); + break; + case TYPE_SHORT: + val = *((u16 *) setting->data); + break; + case TYPE_INT: + val = *((u32 *) setting->data); + break; + } + spin_unlock_irqrestore(&ide_lock, flags); + } + return val; +} + +/** + * ide_write_setting - read an IDE setting + * @drive: drive to read from + * @setting: drive setting + * @val: value + * + * Write a drive setting if it is possible. The caller + * must hold the ide_setting_sem when making this call. + * + * BUGS: the data return and error are the same return value + * so an error -EINVAL and true return of the same value cannot + * be told apart + * + * FIXME: This should be changed to enqueue a special request + * to the driver to change settings, and then wait on a sema for completion. + * The current scheme of polling is kludgy, though safe enough. + */ + +static int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int val) +{ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (setting->set) + return setting->set(drive, val); + if (!(setting->rw & SETTING_WRITE)) + return -EPERM; + if (val < setting->min || val > setting->max) + return -EINVAL; + if (ide_spin_wait_hwgroup(drive)) + return -EBUSY; + switch (setting->data_type) { + case TYPE_BYTE: + *((u8 *) setting->data) = val; + break; + case TYPE_SHORT: + *((u16 *) setting->data) = val; + break; + case TYPE_INT: + *((u32 *) setting->data) = val; + break; + } + spin_unlock_irq(&ide_lock); + return 0; +} + +static int set_xfer_rate (ide_drive_t *drive, int arg) +{ + int err; + + if (arg < 0 || arg > 70) + return -EINVAL; + + err = ide_wait_cmd(drive, + WIN_SETFEATURES, (u8) arg, + SETFEATURES_XFER, 0, NULL); + + if (!err && arg) { + ide_set_xfer_rate(drive, (u8) arg); + ide_driveid_update(drive); + } + return err; +} + +/** + * ide_add_generic_settings - generic ide settings + * @drive: drive being configured + * + * Add the generic parts of the system settings to the /proc files. + * The caller must not be holding the ide_setting_sem. + */ + +void ide_add_generic_settings (ide_drive_t *drive) +{ +/* + * drive setting name read/write access data type min max mul_factor div_factor data pointer set function + */ + __ide_add_setting(drive, "io_32bit", drive->no_io_32bit ? SETTING_READ : SETTING_RW, TYPE_BYTE, 0, 1 + (SUPPORT_VLB_SYNC << 1), 1, 1, &drive->io_32bit, set_io_32bit, 0); + __ide_add_setting(drive, "keepsettings", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->keep_settings, NULL, 0); + __ide_add_setting(drive, "nice1", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->nice1, NULL, 0); + __ide_add_setting(drive, "pio_mode", SETTING_WRITE, TYPE_BYTE, 0, 255, 1, 1, NULL, set_pio_mode, 0); + __ide_add_setting(drive, "unmaskirq", drive->no_unmask ? SETTING_READ : SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->unmask, NULL, 0); + __ide_add_setting(drive, "using_dma", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->using_dma, set_using_dma, 0); + __ide_add_setting(drive, "init_speed", SETTING_RW, TYPE_BYTE, 0, 70, 1, 1, &drive->init_speed, NULL, 0); + __ide_add_setting(drive, "current_speed", SETTING_RW, TYPE_BYTE, 0, 70, 1, 1, &drive->current_speed, set_xfer_rate, 0); + __ide_add_setting(drive, "number", SETTING_RW, TYPE_BYTE, 0, 3, 1, 1, &drive->dn, NULL, 0); +} + static void proc_ide_settings_warn(void) { static int warned = 0; @@ -399,7 +660,7 @@ static ide_proc_entry_t generic_drive_entries[] = { { NULL, 0, NULL, NULL } }; -void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void *data) +static void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void *data) { struct proc_dir_entry *ent; @@ -415,7 +676,7 @@ void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void } } -void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p) +static void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p) { if (!dir || !p) return; @@ -425,6 +686,51 @@ void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p) } } +void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver) +{ + ide_add_proc_entries(drive->proc, driver->proc, drive); +} + +EXPORT_SYMBOL(ide_proc_register_driver); + +/** + * ide_proc_unregister_driver - remove driver specific data + * @drive: drive + * @driver: driver + * + * Clean up the driver specific /proc files and IDE settings + * for a given drive. + * + * Takes ide_setting_sem and ide_lock. + * Caller must hold none of the locks. + */ + +void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) +{ + unsigned long flags; + + ide_remove_proc_entries(drive->proc, driver->proc); + + down(&ide_setting_sem); + spin_lock_irqsave(&ide_lock, flags); + /* + * ide_setting_sem protects the settings list + * ide_lock protects the use of settings + * + * so we need to hold both, ide_settings_sem because we want to + * modify the settings list, and ide_lock because we cannot take + * a setting out that is being used. + * + * OTOH both ide_{read,write}_setting are only ever used under + * ide_setting_sem. + */ + auto_remove_settings(drive); + spin_unlock_irqrestore(&ide_lock, flags); + up(&ide_setting_sem); +} + +EXPORT_SYMBOL(ide_proc_unregister_driver); + static void create_proc_ide_drives(ide_hwif_t *hwif) { int d; -- cgit v1.2.3 From 5cbf79cdb37be2aa2a1b4fa94144526b14557060 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 10 May 2007 00:01:11 +0200 Subject: ide: add ide_proc_register_port() * create_proc_ide_interfaces() tries to add /proc entries for every probed and initialized IDE port, replace it by ide_proc_register_port() which does it only for the given port (also rename destroy_proc_ide_interface() to ide_proc_unregister_port() for consistency) * convert {create,destroy}_proc_ide_interface[s]() users to use new functions * pmac driver depended on proc_ide_create() to add /proc port entries, fix it * au1xxx-ide, swarm and cs5520 drivers depended indirectly on ide-generic driver (CONFIG_IDE_GENERIC=y) to add port /proc entries, fix them * there is now no need to add /proc entries for IDE ports in proc_ide_create() so don't do it * proc_ide_create() needs now to be called before drivers are probed - fix it, while at it make proc_ide_create() create /proc "ide" directory Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/arm/icside.c | 7 +++++-- drivers/ide/arm/rapide.c | 2 +- drivers/ide/ide-generic.c | 2 -- drivers/ide/ide-probe.c | 3 +++ drivers/ide/ide-proc.c | 34 +++++++++++++++++----------------- drivers/ide/ide.c | 14 +++----------- drivers/ide/legacy/ali14xx.c | 3 ++- drivers/ide/legacy/dtc2278.c | 3 ++- drivers/ide/legacy/ht6560b.c | 3 ++- drivers/ide/legacy/qd65xx.c | 7 ++++--- drivers/ide/legacy/umc8672.c | 3 ++- drivers/ide/mips/au1xxx-ide.c | 3 +++ drivers/ide/mips/swarm.c | 3 +++ drivers/ide/pci/cs5520.c | 20 ++++++++++++++++---- drivers/ide/pci/sgiioc4.c | 2 +- drivers/ide/ppc/pmac.c | 2 ++ drivers/ide/setup-pci.c | 25 +++++++++++++++++++++---- include/linux/ide.h | 10 ++++------ 18 files changed, 91 insertions(+), 55 deletions(-) (limited to 'drivers/ide/ide-proc.c') diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index f383ace2a08..1fe0457243d 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -591,7 +591,8 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) state->hwif[0] = hwif; probe_hwif_init(hwif); - create_proc_ide_interfaces(); + + ide_proc_register_port(hwif); return 0; } @@ -679,7 +680,9 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) probe_hwif_init(hwif); probe_hwif_init(mate); - create_proc_ide_interfaces(); + + ide_proc_register_port(hwif); + ide_proc_register_port(mate); return 0; diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c index 9c6c49fdd2b..890ea3fac3c 100644 --- a/drivers/ide/arm/rapide.c +++ b/drivers/ide/arm/rapide.c @@ -76,7 +76,7 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id) hwif->gendev.parent = &ec->dev; hwif->noprobe = 0; probe_hwif_init(hwif); - create_proc_ide_interfaces(); + ide_proc_register_port(hwif); ecard_set_drvdata(ec, hwif); goto out; } diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c index 99fd5615113..0f72b98d727 100644 --- a/drivers/ide/ide-generic.c +++ b/drivers/ide/ide-generic.c @@ -22,8 +22,6 @@ static int __init ide_generic_init(void) if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) ide_release_lock(); /* for atari only */ - create_proc_ide_interfaces(); - return 0; } diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 8f15c23aa70..3cebed77f55 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1427,6 +1427,9 @@ int ideprobe_init (void) } } } + for (index = 0; index < MAX_HWIFS; ++index) + if (probe[index]) + ide_proc_register_port(&ide_hwifs[index]); return 0; } diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 949a6f609d8..d50bd996ff2 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -39,6 +39,8 @@ #include +static struct proc_dir_entry *proc_ide_root; + static int proc_ide_read_imodel (char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -783,26 +785,24 @@ static ide_proc_entry_t hwif_entries[] = { { NULL, 0, NULL, NULL } }; -void create_proc_ide_interfaces(void) +void ide_proc_register_port(ide_hwif_t *hwif) { - int h; + if (!hwif->present) + return; - for (h = 0; h < MAX_HWIFS; h++) { - ide_hwif_t *hwif = &ide_hwifs[h]; + if (!hwif->proc) { + hwif->proc = proc_mkdir(hwif->name, proc_ide_root); - if (!hwif->present) - continue; - if (!hwif->proc) { - hwif->proc = proc_mkdir(hwif->name, proc_ide_root); - if (!hwif->proc) - return; - ide_add_proc_entries(hwif->proc, hwif_entries, hwif); - } - create_proc_ide_drives(hwif); + if (!hwif->proc) + return; + + ide_add_proc_entries(hwif->proc, hwif_entries, hwif); } + + create_proc_ide_drives(hwif); } -EXPORT_SYMBOL(create_proc_ide_interfaces); +EXPORT_SYMBOL_GPL(ide_proc_register_port); #ifdef CONFIG_BLK_DEV_IDEPCI void ide_pci_create_host_proc(const char *name, get_info_t *get_info) @@ -813,7 +813,7 @@ void ide_pci_create_host_proc(const char *name, get_info_t *get_info) EXPORT_SYMBOL_GPL(ide_pci_create_host_proc); #endif -void destroy_proc_ide_interface(ide_hwif_t *hwif) +void ide_proc_unregister_port(ide_hwif_t *hwif) { if (hwif->proc) { destroy_proc_ide_drives(hwif); @@ -860,11 +860,11 @@ void proc_ide_create(void) { struct proc_dir_entry *entry; + proc_ide_root = proc_mkdir("ide", NULL); + if (!proc_ide_root) return; - create_proc_ide_interfaces(); - entry = create_proc_entry("drivers", 0, proc_ide_root); if (entry) entry->proc_fops = &ide_drivers_operations; diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 0fc532850bb..038f2610e73 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -347,10 +347,6 @@ static int ide_system_bus_speed(void) return system_bus_speed; } -#ifdef CONFIG_IDE_PROC_FS -struct proc_dir_entry *proc_ide_root; -#endif - static struct resource* hwif_request_region(ide_hwif_t *hwif, unsigned long addr, int num) { @@ -594,7 +590,7 @@ void ide_unregister(unsigned int index) spin_unlock_irq(&ide_lock); - destroy_proc_ide_interface(hwif); + ide_proc_unregister_port(hwif); hwgroup = hwif->hwgroup; /* @@ -799,7 +795,7 @@ found: if (!initializing) { probe_hwif_init_with_fixup(hwif, fixup); - create_proc_ide_interfaces(); + ide_proc_register_port(hwif); } if (hwifp) @@ -1794,9 +1790,7 @@ static int __init ide_init(void) init_ide_data(); -#ifdef CONFIG_IDE_PROC_FS - proc_ide_root = proc_mkdir("ide", NULL); -#endif + proc_ide_create(); #ifdef CONFIG_BLK_DEV_ALI14XX if (probe_ali14xx) @@ -1822,8 +1816,6 @@ static int __init ide_init(void) /* Probe for special PCI and other "known" interface chipsets. */ probe_for_hwifs(); - proc_ide_create(); - return 0; } diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c index 91961aa0304..df17ed68c0b 100644 --- a/drivers/ide/legacy/ali14xx.c +++ b/drivers/ide/legacy/ali14xx.c @@ -223,7 +223,8 @@ static int __init ali14xx_probe(void) probe_hwif_init(hwif); probe_hwif_init(mate); - create_proc_ide_interfaces(); + ide_proc_register_port(hwif); + ide_proc_register_port(mate); return 0; } diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c index 0219ffa64db..36a3f0ac616 100644 --- a/drivers/ide/legacy/dtc2278.c +++ b/drivers/ide/legacy/dtc2278.c @@ -138,7 +138,8 @@ static int __init dtc2278_probe(void) probe_hwif_init(hwif); probe_hwif_init(mate); - create_proc_ide_interfaces(); + ide_proc_register_port(hwif); + ide_proc_register_port(mate); return 0; } diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c index a2832643c52..c8f353b1296 100644 --- a/drivers/ide/legacy/ht6560b.c +++ b/drivers/ide/legacy/ht6560b.c @@ -357,7 +357,8 @@ int __init ht6560b_init(void) probe_hwif_init(hwif); probe_hwif_init(mate); - create_proc_ide_interfaces(); + ide_proc_register_port(hwif); + ide_proc_register_port(mate); return 0; diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c index 2fb8f50f129..d1414a75b52 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/legacy/qd65xx.c @@ -427,7 +427,7 @@ static int __init qd_probe(int base) qd_setup(hwif, base, config, QD6500_DEF_DATA, QD6500_DEF_DATA, &qd6500_tune_drive); - create_proc_ide_interfaces(); + ide_proc_register_port(hwif); return 1; } @@ -459,7 +459,7 @@ static int __init qd_probe(int base) &qd6580_tune_drive); qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT); - create_proc_ide_interfaces(); + ide_proc_register_port(hwif); return 1; } else { @@ -479,7 +479,8 @@ static int __init qd_probe(int base) &qd6580_tune_drive); qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT); - create_proc_ide_interfaces(); + ide_proc_register_port(hwif); + ide_proc_register_port(mate); return 0; /* no other qd65xx possible */ } diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c index ca797445557..ddc403a0bd8 100644 --- a/drivers/ide/legacy/umc8672.c +++ b/drivers/ide/legacy/umc8672.c @@ -160,7 +160,8 @@ static int __init umc8672_probe(void) probe_hwif_init(hwif); probe_hwif_init(mate); - create_proc_ide_interfaces(); + ide_proc_register_port(hwif); + ide_proc_register_port(mate); return 0; } diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index d54d9fe92a7..ca95e990862 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c @@ -760,6 +760,9 @@ static int au_ide_probe(struct device *dev) #endif probe_hwif_init(hwif); + + ide_proc_register_port(hwif); + dev_set_drvdata(dev, hwif); printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode ); diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c index 81fa06851b2..6e935d7c63f 100644 --- a/drivers/ide/mips/swarm.c +++ b/drivers/ide/mips/swarm.c @@ -129,6 +129,9 @@ static int __devinit swarm_ide_probe(struct device *dev) hwif->irq = hwif->hw.irq; probe_hwif_init(hwif); + + ide_proc_register_port(hwif); + dev_set_drvdata(dev, hwif); return 0; diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index 400859a839f..3b88a3a5611 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c @@ -213,6 +213,7 @@ static ide_pci_device_t cyrix_chipsets[] __devinitdata = { static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id) { + ide_hwif_t *hwif = NULL, *mate = NULL; ata_index_t index; ide_pci_device_t *d = &cyrix_chipsets[id->driver_data]; @@ -239,10 +240,21 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic ide_pci_setup_ports(dev, d, 14, &index); - if((index.b.low & 0xf0) != 0xf0) - probe_hwif_init(&ide_hwifs[index.b.low]); - if((index.b.high & 0xf0) != 0xf0) - probe_hwif_init(&ide_hwifs[index.b.high]); + if ((index.b.low & 0xf0) != 0xf0) + hwif = &ide_hwifs[index.b.low]; + if ((index.b.high & 0xf0) != 0xf0) + mate = &ide_hwifs[index.b.high]; + + if (hwif) + probe_hwif_init(hwif); + if (mate) + probe_hwif_init(mate); + + if (hwif) + ide_proc_register_port(hwif); + if (mate) + ide_proc_register_port(mate); + return 0; } diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index fd09b295a69..d3185e29a38 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -692,7 +692,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) return -EIO; /* Create /proc/ide entries */ - create_proc_ide_interfaces(); + ide_proc_register_port(hwif); return 0; } diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index a49ebe44bab..45fc36f0f21 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -1276,6 +1276,8 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) /* We probe the hwif now */ probe_hwif_init(hwif); + ide_proc_register_port(hwif); + return 0; } diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 118fb3205ca..892cda75578 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -702,6 +702,7 @@ out: int ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d) { + ide_hwif_t *hwif = NULL, *mate = NULL; ata_index_t index_list; int ret; @@ -710,11 +711,19 @@ int ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d) goto out; if ((index_list.b.low & 0xf0) != 0xf0) - probe_hwif_init_with_fixup(&ide_hwifs[index_list.b.low], d->fixup); + hwif = &ide_hwifs[index_list.b.low]; if ((index_list.b.high & 0xf0) != 0xf0) - probe_hwif_init_with_fixup(&ide_hwifs[index_list.b.high], d->fixup); + mate = &ide_hwifs[index_list.b.high]; - create_proc_ide_interfaces(); + if (hwif) + probe_hwif_init_with_fixup(hwif, d->fixup); + if (mate) + probe_hwif_init_with_fixup(mate, d->fixup); + + if (hwif) + ide_proc_register_port(hwif); + if (mate) + ide_proc_register_port(mate); out: return ret; } @@ -748,7 +757,15 @@ int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2, } } - create_proc_ide_interfaces(); + for (i = 0; i < 2; i++) { + u8 idx[2] = { index_list[i].b.low, index_list[i].b.high }; + int j; + + for (j = 0; j < 2; j++) { + if ((idx[j] & 0xf0) != 0xf0) + ide_proc_register_port(ide_hwifs + idx[j]); + } + } out: return ret; } diff --git a/include/linux/ide.h b/include/linux/ide.h index bdb97655ef6..52d482a16dd 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -909,12 +909,10 @@ typedef struct { write_proc_t *write_proc; } ide_proc_entry_t; -extern struct proc_dir_entry *proc_ide_root; - void proc_ide_create(void); void proc_ide_destroy(void); -void create_proc_ide_interfaces(void); -void destroy_proc_ide_interface(ide_hwif_t *); +void ide_proc_register_port(ide_hwif_t *); +void ide_proc_unregister_port(ide_hwif_t *); void ide_proc_register_driver(ide_drive_t *, ide_driver_t *); void ide_proc_unregister_driver(ide_drive_t *, ide_driver_t *); @@ -945,8 +943,8 @@ void ide_pci_create_host_proc(const char *, get_info_t *); #else static inline void proc_ide_create(void) { ; } static inline void proc_ide_destroy(void) { ; } -static inline void create_proc_ide_interfaces(void) { ; } -static inline void destroy_proc_ide_interface(ide_hwif_t *hwif) { ; } +static inline void ide_proc_register_port(ide_hwif_t *hwif) { ; } +static inline void ide_proc_unregister_port(ide_hwif_t *hwif) { ; } static inline void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver) { ; } static inline void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) { ; } static inline void ide_add_generic_settings(ide_drive_t *drive) { ; } -- cgit v1.2.3