ide: add ide_host_add() helper
PATCH 1/7 ide: add ide_host_add() helper
Add ide_host_add() helper which does ide_host_alloc()+ide_host_register(), then convert ide_setup_pci_device[s](), ide_legacy_device_add() and some host drivers to use it.
While at it:
* Fix ide_setup_pci_device[s](), ide_arm.c, gayle.c, ide-4drives.c, macide.c, q40ide.c, cmd640.c and cs5520.c to return correct error value.
* -ENOENT -> -ENOMEM in rapide.c, ide-h8300.c, ide-generic.c, au1xxx-ide.c and pmac.c
* -ENODEV -> -ENOMEM in palm_bk3710.c, ide_platform.c and delkin_cb.c
* -1 -> -ENOMEM in ide-pnp.c
--- drivers/ide/arm/ide_arm.c | 7 +------ drivers/ide/arm/palm_bk3710.c | 10 ++++------ drivers/ide/arm/rapide.c | 8 ++------ drivers/ide/h8300/ide-h8300.c | 9 +-------- drivers/ide/ide-generic.c | 11 ++++------- drivers/ide/ide-pnp.c | 16 ++++++++-------- drivers/ide/ide-probe.c | 27 +++++++++++++++++++-------- drivers/ide/legacy/buddha.c | 5 +---- drivers/ide/legacy/gayle.c | 7 +------ drivers/ide/legacy/ide-4drives.c | 7 +------ drivers/ide/legacy/ide-cs.c | 8 +++----- drivers/ide/legacy/ide_platform.c | 8 ++------ drivers/ide/legacy/macide.c | 7 +------ drivers/ide/legacy/q40ide.c | 7 +------ drivers/ide/mips/au1xxx-ide.c | 8 ++------ drivers/ide/mips/swarm.c | 10 ++++------ drivers/ide/pci/cmd640.c | 7 +------ drivers/ide/pci/cs5520.c | 7 +------ drivers/ide/pci/delkin_cb.c | 8 +++----- drivers/ide/pci/scc_pata.c | 10 ++++------ drivers/ide/ppc/pmac.c | 9 ++++----- drivers/ide/setup-pci.c | 10 ++-------- include/linux/ide.h | 2 ++ 23 files changed, 72 insertions(+), 136 deletions(-)
drivers/ide/arm/ide_arm.c +1 -6
@@ -28,7 +28,6 @@static int __init ide_arm_init (void ) { -struct ide_host *host;unsigned long base =IDE_ARM_IO , ctl =IDE_ARM_IO +0x206 ;hw_regs_t hw, *hws[] = { &hw,NULL ,NULL ,NULL };
@@ -50,11 +49,7 @@ static int __init ide_arm_init(void) hw.irq =IDE_ARM_IRQ ; hw.chipset = ide_generic; - host =ide_host_alloc (NULL , hws); -if (host) -ide_host_register (host,NULL , hws); - -return 0 ; +return ide_host_add (NULL , hws,NULL ); }module_init (ide_arm_init);
drivers/ide/arm/palm_bk3710.c +4 -6
@@ -351,7 +351,7 @@ static int __devinit palm_bk3710_probe(sstruct resource *mem, *irq;struct ide_host *host;unsigned long base; -int i; +int i, rc;hw_regs_t hw, *hws[] = { &hw,NULL ,NULL ,NULL }; clkp =clk_get (NULL ,"IDECLK" );
@@ -394,16 +394,14 @@ static int __devinit palm_bk3710_probe(s hw.irq = irq->start; hw.chipset = ide_palm3710; - host =ide_host_alloc (&palm_bk3710_port_info, hws); -if (host ==NULL ) + rc =ide_host_add (&palm_bk3710_port_info, hws,NULL ); +if (rc) goto out; -ide_host_register (host, &palm_bk3710_port_info, hws); -return 0 ; out:printk (KERN_WARNING "Palm Chip BK3710 IDE Register Fail\n" ); -return -ENODEV ; +return rc; }/* work with hotplug and coldplug */
drivers/ide/arm/rapide.c +2 -6
@@ -52,13 +52,9 @@ rapide_probe(struct expansion_card *ec, hw.chipset = ide_generic; hw.dev = &ec->dev; - host =ide_host_alloc (&rapide_port_info, hws); -if (host ==NULL ) { - ret = -ENOENT ; + ret =ide_host_add (&rapide_port_info, hws, &host); +if (ret) goto release; - } - -ide_host_register (host, &rapide_port_info, hws);ecard_set_drvdata (ec, host); goto out;
drivers/ide/h8300/ide-h8300.c +1 -8
@@ -191,7 +191,6 @@ static const struct ide_port_info h8300_static int __init h8300_ide_init (void ) { -struct ide_host *host;hw_regs_t hw, *hws[] = { &hw,NULL ,NULL ,NULL }; printk(KERN_INFO DRV_NAME ": H8/300 generic IDE interface\n");
@@ -205,13 +204,7 @@ static int __init h8300_ide_init(void)hw_setup (&hw); - host =ide_host_alloc (&h8300_port_info, hws); -if (host ==NULL ) -return -ENOENT ; - -ide_host_register (host, &h8300_port_info, hws); - -return 0 ; +return ide_host_add (&h8300_port_info, hws,NULL ); out_busy:printk (KERN_ERR "ide-h8300: IDE I/F resource already used.\n" );
drivers/ide/ide-generic.c +4 -7
@@ -28,9 +28,8 @@ MODULE_PARM_DESC(probe_mask, "probe maskstatic ssize_t store_add (struct class *cls,const char *buf,size_t n) { -struct ide_host *host;unsigned int base, ctl; -int irq; +int irq, rc;hw_regs_t hw, *hws[] = { &hw,NULL ,NULL ,NULL };if (sscanf (buf,"%x:%x:%d" , &base, &ctl, &irq) !=3 )
@@ -41,11 +40,9 @@ static ssize_t store_add(struct class *c hw.irq = irq; hw.chipset = ide_generic; - host =ide_host_alloc (NULL , hws); -if (host ==NULL ) -return -ENOENT ; - -ide_host_register (host,NULL , hws); + rc =ide_host_add (NULL , hws,NULL ); +if (rc) +return rc;return n; };
drivers/ide/ide-pnp.c +8 -8
@@ -31,6 +31,7 @@ static int idepnp_probe(struct pnp_dev * {struct ide_host *host;unsigned long base, ctl; +int rc;hw_regs_t hw, *hws[] = { &hw,NULL ,NULL ,NULL }; printk(KERN_INFO DRV_NAME ": generic PnP IDE interface\n");
@@ -59,19 +60,18 @@ static int idepnp_probe(struct pnp_dev * hw.irq =pnp_irq (dev,0 ); hw.chipset = ide_generic; - host =ide_host_alloc (NULL , hws); -if (host) { -pnp_set_drvdata (dev, host); + rc =ide_host_add (NULL , hws, &host); +if (rc) + goto out; -ide_host_register (host,NULL , hws); - -return 0 ; - } +pnp_set_drvdata (dev, host); +return 0 ; +out:release_region (ctl,1 );release_region (base,8 ); -return -1 ; +return rc; }static void idepnp_remove (struct pnp_dev *dev)
drivers/ide/ide-probe.c +19 -8
@@ -1683,6 +1683,24 @@ int ide_host_register(struct ide_host *h }EXPORT_SYMBOL_GPL (ide_host_register); +int ide_host_add (const struct ide_port_info *d,hw_regs_t **hws, +struct ide_host **hostp) +{ +struct ide_host *host; + + host =ide_host_alloc (d, hws); +if (host ==NULL ) +return -ENOMEM ; + +ide_host_register (host, d, hws); + +if (hostp) + *hostp = host; + +return 0 ; +} +EXPORT_SYMBOL_GPL (ide_host_add); +void ide_host_remove (struct ide_host *host) {int i;
@@ -1755,7 +1773,6 @@ static void ide_legacy_init_one(hw_regs_int ide_legacy_device_add (const struct ide_port_info *d,unsigned long config) { -struct ide_host *host;hw_regs_t hw[2 ], *hws[] = {NULL ,NULL ,NULL ,NULL };memset (&hw,0 ,sizeof (hw));
@@ -1768,12 +1785,6 @@ int ide_legacy_device_add(const struct i (d->host_flags & IDE_HFLAG_SINGLE))return -ENOENT ; - host =ide_host_alloc (d, hws); -if (host ==NULL ) -return -ENOMEM ; - -ide_host_register (host, d, hws); - -return 0 ; +return ide_host_add (d, hws,NULL ); }EXPORT_SYMBOL_GPL (ide_legacy_device_add);
drivers/ide/legacy/buddha.c +1 -4
@@ -151,7 +151,6 @@ static void __init buddha_setup_ports(hwstatic int __init buddha_init (void ) {struct zorro_dev *z =NULL ; -struct ide_host *host;u_long buddha_board =0 ;BuddhaType type;int buddha_num_hwifs, i;
@@ -226,9 +225,7 @@ fail_base2: hws[i] = &hw[i]; } - host =ide_host_alloc (NULL , hws); -if (host) -ide_host_register (host,NULL , hws); +ide_host_add (NULL , hws,NULL ); }return 0 ;
drivers/ide/legacy/gayle.c +1 -6
@@ -127,7 +127,6 @@ static int __init gayle_init(void)unsigned long phys_base, res_start, res_n;unsigned long base, ctrlport, irqport;ide_ack_intr_t *ack_intr; -struct ide_host *host;int a4000, i;hw_regs_t hw[GAYLE_NUM_HWIFS ], *hws[] = {NULL ,NULL ,NULL ,NULL };
@@ -180,11 +179,7 @@ found: hws[i] = &hw[i]; } - host =ide_host_alloc (NULL , hws); -if (host) -ide_host_register (host,NULL , hws); - -return 0 ; +return ide_host_add (NULL , hws,NULL ); }module_init (gayle_init);
drivers/ide/legacy/ide-4drives.c +1 -6
@@ -28,7 +28,6 @@ static const struct ide_port_info ide_4dstatic int __init ide_4drives_init (void ) { -struct ide_host *host;unsigned long base =0x1f0 , ctl =0x3f6 ;hw_regs_t hw, *hws[] = { &hw, &hw,NULL ,NULL };
@@ -54,11 +53,7 @@ static int __init ide_4drives_init(void) hw.irq =14 ; hw.chipset = ide_4drives; - host =ide_host_alloc (&ide_4drives_port_info, hws); -if (host) -ide_host_register (host, &ide_4drives_port_info, hws); - -return 0 ; +return ide_host_add (&ide_4drives_port_info, hws,NULL ); }module_init (ide_4drives_init);
drivers/ide/legacy/ide-cs.c +3 -5
@@ -164,7 +164,7 @@ static struct ide_host *idecs_register(u {struct ide_host *host;ide_hwif_t *hwif; -int i; +int i, rc;hw_regs_t hw, *hws[] = { &hw,NULL ,NULL ,NULL };if (!request_region (io,8 ,DRV_NAME )) {
@@ -186,12 +186,10 @@ static struct ide_host *idecs_register(u hw.chipset = ide_pci; hw.dev = &handle->dev; - host =ide_host_alloc (&idecs_port_info, hws); -if (host ==NULL ) + rc =ide_host_add (&idecs_port_info, hws, &host); +if (rc) goto out_release; -ide_host_register (host, &idecs_port_info, hws); - hwif = host->ports[0 ];if (hwif->present)
drivers/ide/legacy/ide_platform.c +2 -6
@@ -99,13 +99,9 @@ static int __devinit plat_ide_probe(struif (mmio) d.host_flags |=IDE_HFLAG_MMIO ; - host =ide_host_alloc (&d, hws); -if (host ==NULL ) { - ret = -ENODEV ; + ret =ide_host_add (&d, hws, &host); +if (ret) goto out; - } - -ide_host_register (host, &d, hws);platform_set_drvdata (pdev, host);
drivers/ide/legacy/macide.c +1 -6
@@ -92,7 +92,6 @@ static const char *mac_ide_name[] =static int __init macide_init (void ) {ide_ack_intr_t *ack_intr; -struct ide_host *host;unsigned long base;int irq;hw_regs_t hw, *hws[] = { &hw,NULL ,NULL ,NULL };
@@ -125,11 +124,7 @@ static int __init macide_init(void)macide_setup_ports (&hw, base, irq, ack_intr); - host =ide_host_alloc (NULL , hws); -if (host) -ide_host_register (host,NULL , hws); - -return 0 ; +return ide_host_add (NULL , hws,NULL ); }module_init (macide_init);
drivers/ide/legacy/q40ide.c +1 -6
@@ -131,7 +131,6 @@ static const char *q40_ide_names[Q40IDE_static int __init q40ide_init (void ) { -struct ide_host *host;int i;hw_regs_t hw[Q40IDE_NUM_HWIFS ], *hws[] = {NULL ,NULL ,NULL ,NULL };
@@ -160,11 +159,7 @@ static int __init q40ide_init(void) hws[i] = &hw[i]; } - host =ide_host_alloc (&q40ide_port_info, hws); -if (host) -ide_host_register (host, &q40ide_port_info, hws); - -return 0 ; +return ide_host_add (&q40ide_port_info, hws,NULL ); }module_init (q40ide_init);
drivers/ide/mips/au1xxx-ide.c +2 -6
@@ -609,13 +609,9 @@ static int au_ide_probe(struct device *d hw.dev = dev; hw.chipset = ide_au1xxx; - host =ide_host_alloc (&au1xxx_port_info, hws); -if (host ==NULL ) { - ret = -ENOENT ; + ret =ide_host_add (&au1xxx_port_info, hws, &host); +if (ret) goto out; - } - -ide_host_register (host, &au1xxx_port_info, hws); auide_hwif.hwif = host->ports[0 ];
drivers/ide/mips/swarm.c +4 -6
@@ -75,7 +75,7 @@ static int __devinit swarm_ide_probe(stru8 __iomem *base;struct ide_host *host;phys_t offset, size; -int i; +int i, rc;hw_regs_t hw, *hws[] = { &hw,NULL ,NULL ,NULL };if (!SIBYTE_HAVE_IDE )
@@ -115,19 +115,17 @@ static int __devinit swarm_ide_probe(str hw.irq =K_INT_GB_IDE ; hw.chipset = ide_generic; - host =ide_host_alloc (&swarm_port_info, hws); -if (host ==NULL ) + rc =ide_host_add (&swarm_port_info, hws, &host); +if (rc) goto err; -ide_host_register (host, &swarm_port_info, hws); -dev_set_drvdata (dev, host);return 0 ; err:release_resource (&swarm_ide_resource);iounmap (base); -return -ENOMEM ; +return rc; }static struct device_driver swarm_ide_driver = {
drivers/ide/pci/cmd640.c +1 -6
@@ -709,7 +709,6 @@ static int cmd640x_init_one(unsigned lon*/ static int __init cmd640x_init (void ) { -struct ide_host *host;int second_port_cmd640 =0 , rc;const char *bus_type, *port2;u8 b, cfr;
@@ -829,11 +828,7 @@ static int __init cmd640x_init(void)cmd640_dump_regs ();#endif - host =ide_host_alloc (&cmd640_port_info, hws); -if (host) -ide_host_register (host, &cmd640_port_info, hws); - -return 1 ; +return ide_host_add (&cmd640_port_info, hws,NULL ); }module_param_named (probe_vlb, cmd640_vlb, bool,0 );
drivers/ide/pci/cs5520.c +1 -6
@@ -114,7 +114,6 @@ static const struct ide_port_info cyrix_static int __devinit cs5520_init_one (struct pci_dev *dev,const struct pci_device_id *id) { -struct ide_host *host;const struct ide_port_info *d = &cyrix_chipsets[id->driver_data];hw_regs_t hw[4 ], *hws[] = {NULL ,NULL ,NULL ,NULL };
@@ -140,11 +139,7 @@ static int __devinit cs5520_init_one(stride_pci_setup_ports (dev, d,14 , &hw[0 ], &hws[0 ]); - host =ide_host_alloc (d, hws); -if (host) -ide_host_register (host, d, hws); - -return 0 ; +return ide_host_add (d, hws,NULL ); }static const struct pci_device_id cs5520_pci_tbl[] = {
drivers/ide/pci/delkin_cb.c +3 -5
@@ -86,12 +86,10 @@ delkin_cb_probe (struct pci_dev *dev, co hw.dev = &dev->dev; hw.chipset = ide_pci;/* this enables IRQ sharing */ - host =ide_host_alloc (&delkin_cb_port_info, hws); -if (host ==NULL ) + rc =ide_host_add (&delkin_cb_port_info, hws, &host); +if (rc) goto out_disable; -ide_host_register (host, &delkin_cb_port_info, hws); -pci_set_drvdata (dev, host);return 0 ;
@@ -99,7 +97,7 @@ delkin_cb_probe (struct pci_dev *dev, co out_disable:pci_release_regions (dev);pci_disable_device (dev); -return -ENODEV ; +return rc; } static void
drivers/ide/pci/scc_pata.c +4 -6
@@ -588,7 +588,7 @@ static int scc_ide_setup_pci_device(strustruct scc_ports *ports =pci_get_drvdata (dev);struct ide_host *host;hw_regs_t hw, *hws[] = { &hw,NULL ,NULL ,NULL }; -int i; +int i, rc;memset (&hw,0 ,sizeof (hw));for (i =0 ; i <=8 ; i++)
@@ -597,11 +597,9 @@ static int scc_ide_setup_pci_device(stru hw.dev = &dev->dev; hw.chipset = ide_pci; - host =ide_host_alloc (d, hws); -if (host ==NULL ) -return -ENOMEM ; - -ide_host_register (host, d, hws); + rc =ide_host_add (d, hws, &host); +if (rc) +return rc; ports->host = host;
drivers/ide/ppc/pmac.c +4 -5
@@ -1041,6 +1041,7 @@ static int __devinit pmac_ide_setup_deviide_hwif_t *hwif;hw_regs_t *hws[] = { hw,NULL ,NULL ,NULL };struct ide_port_info d = pmac_port_info; +int rc; pmif->broken_dma = pmif->broken_dma_warn =0 ;if (of_device_is_compatible (np,"shasta-ata" )) {
@@ -1112,11 +1113,9 @@ static int __devinit pmac_ide_setup_devi pmif->mdev ?"macio" :"PCI" , pmif->aapl_bus_id, pmif->mediabay ? " (mediabay)" : "", hw->irq); - host =ide_alloc_host (&d, hws); -if (host ==NULL ) -return -ENOENT ; - -ide_host_register (host, &d, hws); + rc =ide_host_add (&d, hws, &host); +if (rc) +return rc; hwif = host->ports[0 ];
drivers/ide/setup-pci.c +2 -8
@@ -540,7 +540,6 @@ out:int ide_setup_pci_device (struct pci_dev *dev,const struct ide_port_info *d) { -struct ide_host *host;hw_regs_t hw[4 ], *hws[] = {NULL ,NULL ,NULL ,NULL };int ret;
@@ -550,9 +549,7 @@ int ide_setup_pci_device(struct pci_dev/* FIXME: silent failure can happen */ ide_pci_setup_ports (dev, d, ret, &hw[0 ], &hws[0 ]); - host =ide_host_alloc (d, hws); -if (host) -ide_host_register (host, d, hws); + ret =ide_host_add (d, hws,NULL ); }return ret;
@@ -563,7 +560,6 @@ int ide_setup_pci_devices(struct pci_dev const struct ide_port_info *d) {struct pci_dev *pdev[] = { dev1, dev2 }; -struct ide_host *host;int ret, i;hw_regs_t hw[4 ], *hws[] = {NULL ,NULL ,NULL ,NULL };
@@ -581,9 +577,7 @@ int ide_setup_pci_devices(struct pci_devide_pci_setup_ports (pdev[i], d, ret, &hw[i*2 ], &hws[i*2 ]); } - host =ide_host_alloc (d, hws); -if (host) -ide_host_register (host, d, hws); + ret =ide_host_add (d, hws,NULL ); out:return ret; }
include/linux/ide.h +2 -0
@@ -1224,6 +1224,8 @@ struct ide_host *ide_host_alloc_all(consstruct ide_host *ide_host_alloc (const struct ide_port_info *,hw_regs_t **);int ide_host_register (struct ide_host *,const struct ide_port_info *,hw_regs_t **); +int ide_host_add (const struct ide_port_info *,hw_regs_t **, +struct ide_host **);void ide_host_remove (struct ide_host *);int ide_legacy_device_add (const struct ide_port_info *,unsigned long );void ide_port_unregister_devices (ide_hwif_t *);
PATCH 2/7 ide: fix ide_host_register() return value
Fix ide_host_register() to fail only if all ports cannot be registered.
While at it:
* Use host->ports[] instead of ide_hwifs[] and remove idx[].
There should be no functional changes caused by this patch.
--- drivers/ide/ide-probe.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-)
drivers/ide/ide-probe.c +18 -20
@@ -1580,19 +1580,16 @@ int ide_host_register(struct ide_host *h hw_regs_t **hws) {ide_hwif_t *hwif, *mate =NULL ; -u8 idx[MAX_HWIFS ]; -int i, rc =0 ; +int i, j =0 ;for (i =0 ; i <MAX_HWIFS ; i++) { - idx[i] = host->ports[i] ? host->ports[i]->index :0xff ; + hwif = host->ports[i]; -if (idx[i] ==0xff ) { +if (hwif ==NULL ) { mate =NULL ;continue ; } - hwif = &ide_hwifs[idx[i]]; -ide_init_port_hw (hwif, hws[i]);ide_port_apply_params (hwif);
@@ -1614,10 +1611,10 @@ int ide_host_register(struct ide_host *h }for (i =0 ; i <MAX_HWIFS ; i++) { -if (idx[i] ==0xff ) -continue ; + hwif = host->ports[i]; - hwif = &ide_hwifs[idx[i]]; +if (hwif ==NULL ) +continue ;if (ide_probe_port (hwif) ==0 ) hwif->present =1 ;
@@ -1631,19 +1628,20 @@ int ide_host_register(struct ide_host *h }for (i =0 ; i <MAX_HWIFS ; i++) { -if (idx[i] ==0xff ) -continue ; + hwif = host->ports[i]; - hwif = &ide_hwifs[idx[i]]; +if (hwif ==NULL ) +continue ;if (hwif_init (hwif) ==0 ) {printk (KERN_INFO "%s: failed to initialize IDE " "interface\n" , hwif->name); hwif->present =0 ; - rc =-1 ;continue ; } + j++; +if (hwif->present)ide_port_setup_devices (hwif);
@@ -1654,10 +1652,10 @@ int ide_host_register(struct ide_host *h }for (i =0 ; i <MAX_HWIFS ; i++) { -if (idx[i] ==0xff ) -continue ; + hwif = host->ports[i]; - hwif = &ide_hwifs[idx[i]]; +if (hwif ==NULL ) +continue ;if (hwif->chipset == ide_unknown) hwif->chipset = ide_generic;
@@ -1667,10 +1665,10 @@ int ide_host_register(struct ide_host *h }for (i =0 ; i <MAX_HWIFS ; i++) { -if (idx[i] ==0xff ) -continue ; + hwif = host->ports[i]; - hwif = &ide_hwifs[idx[i]]; +if (hwif ==NULL ) +continue ;ide_sysfs_register_port (hwif);ide_proc_register_port (hwif);
@@ -1679,7 +1677,7 @@ int ide_host_register(struct ide_host *hide_proc_port_register_devices (hwif); } -return rc; +return j ?0 :-1 ; }EXPORT_SYMBOL_GPL (ide_host_register);
PATCH 3/7 ide: fix IDE port slots reservation and freeing
In reply to Bartlomiej Zolnierkiewicz* Make ide_find_port_slot() return port slot index.
* Add ide_free_port_slot() helper.
* Move ide_init_port_data() call and error printk() from ide_find_port_slot() to ide_host_alloc_all().
* Make ide_{find,free}_port_slot() take ide_cfg_mtx mutex and convert them use ide_indexes bitmap to keep track of reserved port slots.
* Don't set hwif->chipset in ide_host_alloc_all() as it is no longer necessary.
--- drivers/ide/ide-probe.c | 87 +++++++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 37 deletions(-)
drivers/ide/ide-probe.c +50 -37
@@ -1476,18 +1476,20 @@ static int ide_sysfs_register_port(ide_hreturn rc; } +static unsigned int ide_indexes; +/** -* ide_find_port_slot - find free ide_hwifs[] slot +* ide_find_port_slot - find free port slot * @d: IDE port info * -* Return the new hwif. If we are out of free slots return NULL. +* Return the new port slot index or -ENOENT if we are out of free slots. */ -static ide_hwif_t *ide_find_port_slot (const struct ide_port_info *d) +static int ide_find_port_slot (const struct ide_port_info *d) { -ide_hwif_t *hwif; -int i; +int idx = -ENOENT ;u8 bootable = (d && (d->host_flags &IDE_HFLAG_NON_BOOTABLE )) ?0 :1 ; +u8 i = (d && (d->host_flags &IDE_HFLAG_QD_2ND_PORT )) ?1 :0 ;;/* * Claim an unassigned slot.
@@ -1499,35 +1501,33 @@ static ide_hwif_t *ide_find_port_slot(co* Unless there is a bootable card that does not use the standard * ports 0x1f0/0x170 (the ide0/ide1 defaults). */ -if (bootable) { - i = (d && (d->host_flags &IDE_HFLAG_QD_2ND_PORT )) ?1 :0 ; - -for (; i <MAX_HWIFS ; i++) { - hwif = &ide_hwifs[i]; -if (hwif->chipset == ide_unknown) - goto out_found; - } +mutex_lock (&ide_cfg_mtx); +if (MAX_HWIFS ==1 ) { +if (ide_indexes ==0 && i ==0 ) + idx =1 ; }else { -for (i =2 ; i <MAX_HWIFS ; i++) { - hwif = &ide_hwifs[i]; -if (hwif->chipset == ide_unknown) - goto out_found; - } -for (i =0 ; i <2 && i <MAX_HWIFS ; i++) { - hwif = &ide_hwifs[i]; -if (hwif->chipset == ide_unknown) - goto out_found; +if (bootable) { +if ((ide_indexes | i) != (1 <<MAX_HWIFS ) -1 ) + idx =ffz (ide_indexes | i); + }else { +if ((ide_indexes |3 ) != (1 <<MAX_HWIFS ) -1 ) + idx =ffz (ide_indexes |3 ); +else if ((ide_indexes &3 ) !=3 ) + idx =ffz (ide_indexes); } } +if (idx >=0 ) + ide_indexes |= (1 << idx); +mutex_unlock (&ide_cfg_mtx); -printk (KERN_ERR "%s: no free slot for interface\n" , - d ? d->name :"ide" ); - -return NULL ; +return idx; +} -out_found: -ide_init_port_data (hwif, i); -return hwif; +static void ide_free_port_slot (int idx) +{ +mutex_lock (&ide_cfg_mtx); + ide_indexes &= ~(1 << idx); +mutex_unlock (&ide_cfg_mtx); } struct ide_host *ide_host_alloc_all(const struct ide_port_info *d,
@@ -1542,17 +1542,24 @@ struct ide_host *ide_host_alloc_all(consfor (i =0 ; i <MAX_HWIFS ; i++) {ide_hwif_t *hwif; +int idx;if (hws[i] ==NULL )continue ; - hwif =ide_find_port_slot (d); -if (hwif) { - hwif->chipset = hws[i]->chipset; - - host->ports[i] = hwif; - host->n_ports++; + idx =ide_find_port_slot (d); +if (idx <0 ) { +printk (KERN_ERR "%s: no free slot for interface\n" , + d ? d->name :"ide" ); +continue ; } + + hwif = &ide_hwifs[idx]; + +ide_init_port_data (hwif, i); + + host->ports[i] = hwif; + host->n_ports++; }if (host->n_ports ==0 ) {
@@ -1701,11 +1708,17 @@ EXPORT_SYMBOL_GPL(ide_host_add);void ide_host_remove (struct ide_host *host) { +ide_hwif_t *hwif;int i;for (i =0 ; i <MAX_HWIFS ; i++) { -if (host->ports[i]) -ide_unregister (host->ports[i]); + hwif = host->ports[i]; + +if (hwif ==NULL ) +continue ; + +ide_unregister (hwif); +ide_free_port_slot (hwif->index); }kfree (host);
PATCH 4/7 ide: move ide_remove_port_from_hwgroup() to ide-probe.c
In reply to Bartlomiej Zolnierkiewicz--- drivers/ide/ide-probe.c | 35 +++++++++++++++++++++++++++++++++++ drivers/ide/ide.c | 35 ----------------------------------- 2 files changed, 35 insertions(+), 35 deletions(-)
drivers/ide/ide-probe.c +35 -0
@@ -994,6 +994,41 @@ static void ide_port_setup_devices(ide_hmutex_unlock (&ide_cfg_mtx); } +void ide_remove_port_from_hwgroup (ide_hwif_t *hwif) +{ +ide_hwgroup_t *hwgroup = hwif->hwgroup; + +spin_lock_irq (&ide_lock); +/* +* Remove us from the hwgroup, and free +* the hwgroup if we were the only member +*/ +if (hwif->next == hwif) { +BUG_ON (hwgroup->hwif != hwif); +kfree (hwgroup); + }else { +/* There is another interface in hwgroup. +* Unlink us, and set hwgroup->drive and ->hwif to +* something sane. +*/ +ide_hwif_t *g = hwgroup->hwif; + +while (g->next != hwif) + g = g->next; + g->next = hwif->next; +if (hwgroup->hwif == hwif) { +/* Chose a random hwif for hwgroup->hwif. +* It's guaranteed that there are no drives +* left in the hwgroup. +*/ +BUG_ON (hwgroup->drive !=NULL ); + hwgroup->hwif = g; + } +BUG_ON (hwgroup->hwif == hwif); + } +spin_unlock_irq (&ide_lock); +} +/* * This routine sets up the irq for an ide interface, and creates a new * hwgroup for the irq/hwif if none was previously assigned.
drivers/ide/ide.c +0 -35
@@ -133,41 +133,6 @@ static void ide_port_init_devices_data(i } } -void ide_remove_port_from_hwgroup (ide_hwif_t *hwif) -{ -ide_hwgroup_t *hwgroup = hwif->hwgroup; - -spin_lock_irq (&ide_lock); -/* -* Remove us from the hwgroup, and free -* the hwgroup if we were the only member -*/ -if (hwif->next == hwif) { -BUG_ON (hwgroup->hwif != hwif); -kfree (hwgroup); - }else { -/* There is another interface in hwgroup. -* Unlink us, and set hwgroup->drive and ->hwif to -* something sane. -*/ -ide_hwif_t *g = hwgroup->hwif; - -while (g->next != hwif) - g = g->next; - g->next = hwif->next; -if (hwgroup->hwif == hwif) { -/* Chose a random hwif for hwgroup->hwif. -* It's guaranteed that there are no drives -* left in the hwgroup. -*/ -BUG_ON (hwgroup->drive !=NULL ); - hwgroup->hwif = g; - } -BUG_ON (hwgroup->hwif == hwif); - } -spin_unlock_irq (&ide_lock); -} -/* Called with ide_lock held. */ static void __ide_port_unregister_devices (ide_hwif_t *hwif) {
PATCH 5/7 ide: add ide_ports[]
In reply to Bartlomiej Zolnierkiewicz* Add ide_ports[] table keeping pointers to all initialized ports.
* Set ide_ports[] entry for a given port in init_irq() and clear it ide_remove_port_from_hwgroup().
* Convert init_irq() to use ide_ports[] instead of ide_hwifs[] for grouping ports into hwgroup.
--- drivers/ide/ide-probe.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/ide/ide-probe.c +9 -2
@@ -994,10 +994,14 @@ static void ide_port_setup_devices(ide_hmutex_unlock (&ide_cfg_mtx); } +static ide_hwif_t *ide_ports[MAX_HWIFS ]; +void ide_remove_port_from_hwgroup (ide_hwif_t *hwif) {ide_hwgroup_t *hwgroup = hwif->hwgroup; + ide_ports[hwif->index] =NULL ; +spin_lock_irq (&ide_lock);/* * Remove us from the hwgroup, and free
@@ -1056,8 +1060,9 @@ static int init_irq (ide_hwif_t *hwif)* Group up with any other hwifs that share our irq(s). */ for (index =0 ; index <MAX_HWIFS ; index++) { -ide_hwif_t *h = &ide_hwifs[index]; -if (h->hwgroup) {/* scan only initialized hwif's */ +ide_hwif_t *h = ide_ports[index]; + +if (h && h->hwgroup) {/* scan only initialized ports */ if (hwif->irq == h->irq) { hwif->sharing_irq = h->sharing_irq =1 ; if (hwif->chipset != ide_pci ||
@@ -1111,6 +1116,8 @@ static int init_irq (ide_hwif_t *hwif) hwgroup->timer.data = (unsigned long ) hwgroup; } + ide_ports[hwif->index] = hwif; +/* * Allocate the irq, if not already obtained for another hwif */
PATCH 6/7 ide: allocate ide_hwif_t instances dynamically
In reply to Bartlomiej Zolnierkiewicz* Allocate ide_hwif_t instances dynamically and remove ide_hwifs[].
This cuts almost ~14kB from ide-probe.o (x86-32, MAX_HWIFS == 10):
text data bss dec hex filename
9140 40 14084 23264 5ae0 drivers/ide/ide-probe.o.before 9169 40 44 9253 2425 drivers/ide/ide-probe.o.after
* Remove no longer needed ide_init_port_data() call from ide_unregister().
--- drivers/ide/ide-probe.c | 10 ++++++---- drivers/ide/ide.c | 4 ---- 2 files changed, 6 insertions(+), 8 deletions(-)
drivers/ide/ide-probe.c +6 -4
@@ -39,8 +39,6 @@#include <asm/uaccess.h> #include <asm/io.h> -static ide_hwif_t ide_hwifs[MAX_HWIFS ];/* master data repository */ -/** * generic_id - add a generic drive id * @drive: drive to make an ID block for
@@ -1589,15 +1587,18 @@ struct ide_host *ide_host_alloc_all(consif (hws[i] ==NULL )continue ; + hwif =kzalloc (sizeof (*hwif),GFP_KERNEL ); +if (hwif ==NULL ) +continue ; + idx =ide_find_port_slot (d);if (idx <0 ) {printk (KERN_ERR "%s: no free slot for interface\n" , d ? d->name :"ide" ); +kfree (hwif);continue ; } - hwif = &ide_hwifs[idx]; -ide_init_port_data (hwif, i); host->ports[i] = hwif;
@@ -1761,6 +1762,7 @@ void ide_host_remove(struct ide_host *hoide_unregister (hwif);ide_free_port_slot (hwif->index); +kfree (hwif); }kfree (host);
drivers/ide/ide.c +0 -4
@@ -232,10 +232,6 @@ void ide_unregister(ide_hwif_t *hwif)if (hwif->dma_base)ide_release_dma_engine (hwif); - -/* restore hwif data to pristine status */ -ide_init_port_data (hwif, hwif->index); - abort:spin_unlock_irq (&ide_lock);mutex_unlock (&ide_cfg_mtx);
PATCH 7/7 ide: add ide_host_free() helper
In reply to Bartlomiej Zolnierkiewicz* Add ide_host_free() helper and convert ide_host_remove() to use it.
* Fix handling of ide_host_register() failure in ide_host_add(), icside.c, ide-generic.c, falconide.c and sgiioc4.c.
While at it:
* Fix handling of ide_host_alloc_all() failure in ide-generic.c.
* Fix handling of ide_host_alloc() failure in falconide.c (also return the correct error value if no device is found).
--- drivers/ide/arm/icside.c | 21 +++++++++++++++++---- drivers/ide/ide-generic.c | 27 +++++++++++++++++++++++---- drivers/ide/ide-probe.c | 23 ++++++++++++++++++++--- drivers/ide/legacy/falconide.c | 22 +++++++++++++++++----- drivers/ide/pci/sgiioc4.c | 14 ++++++++++---- include/linux/ide.h | 1 + 6 files changed, 88 insertions(+), 20 deletions(-)
drivers/ide/arm/icside.c +17 -4
@@ -445,6 +445,7 @@ icside_register_v5(struct icside_state *void __iomem *base;struct ide_host *host;hw_regs_t hw, *hws[] = { &hw,NULL ,NULL ,NULL }; +int ret; base =ecardm_iomap (ec,ECARD_RES_MEMC ,0 ,0 );if (!base)
@@ -472,9 +473,15 @@ icside_register_v5(struct icside_state *ecard_set_drvdata (ec, state); -ide_host_register (host,NULL , hws); + ret =ide_host_register (host,NULL , hws); +if (ret) + goto err_free;return 0 ; +err_free: +ide_host_free (host); +ecard_set_drvdata (ec,NULL ); +return ret; }static const struct ide_port_info icside_v6_port_info__initdata = {
@@ -547,11 +554,17 @@ icside_register_v6(struct icside_state * d.dma_ops =NULL ; } -ide_host_register (host, &d, hws); + ret =ide_host_register (host,NULL , hws); +if (ret) + goto err_free;return 0 ; - - out: +err_free: +ide_host_free (host); +if (d.dma_ops) +free_dma (ec->dma); +ecard_set_drvdata (ec,NULL ); +out:return ret; }
drivers/ide/ide-generic.c +23 -4
@@ -84,13 +84,14 @@ static int __init ide_generic_init(void) {hw_regs_t hw[MAX_HWIFS ], *hws[MAX_HWIFS ];struct ide_host *host; -int i; +unsigned long io_addr; +int i, rc; printk(KERN_INFO DRV_NAME ": please use \"probe_mask=0x3f\" module " "parameter for probing all legacy ISA IDE ports\n");for (i =0 ; i <MAX_HWIFS ; i++) { -unsigned long io_addr =ide_default_io_base (i); + io_addr =ide_default_io_base (i); hws[i] =NULL ;
@@ -120,14 +121,32 @@ static int __init ide_generic_init(void) } host =ide_host_alloc_all (NULL , hws); -if (host) -ide_host_register (host,NULL , hws); +if (host ==NULL ) { + rc = -ENOMEM ; + goto err; + } + + rc =ide_host_register (host,NULL , hws); +if (rc) + goto err_free;if (ide_generic_sysfs_init ()) printk(KERN_ERR DRV_NAME ": failed to create ide_generic ""class\n" );return 0 ; +err_free: +ide_host_free (host); +err: +for (i =0 ; i <MAX_HWIFS ; i++) { +if (hws[i] ==NULL ) +continue ; + + io_addr = hws[i]->io_ports.data_addr; +release_region (io_addr +0x206 ,1 ); +release_region (io_addr,8 ); + } +return rc; }module_init (ide_generic_init);
drivers/ide/ide-probe.c +20 -3
@@ -1735,12 +1735,17 @@ int ide_host_add(const struct ide_port_i struct ide_host **hostp) {struct ide_host *host; +int rc; host =ide_host_alloc (d, hws);if (host ==NULL )return -ENOMEM ; -ide_host_register (host, d, hws); + rc =ide_host_register (host, d, hws); +if (rc) { +ide_host_free (host); +return rc; + }if (hostp) *hostp = host;
@@ -1749,7 +1754,7 @@ int ide_host_add(const struct ide_port_i }EXPORT_SYMBOL_GPL (ide_host_add); -void ide_host_remove (struct ide_host *host) +void ide_host_free (struct ide_host *host) {ide_hwif_t *hwif;int i;
@@ -1760,13 +1765,25 @@ void ide_host_remove(struct ide_host *hoif (hwif ==NULL )continue ; -ide_unregister (hwif);ide_free_port_slot (hwif->index);kfree (hwif); }kfree (host); } +EXPORT_SYMBOL_GPL (ide_host_free); + +void ide_host_remove (struct ide_host *host) +{ +int i; + +for (i =0 ; i <MAX_HWIFS ; i++) { +if (host->ports[i]) +ide_unregister (host->ports[i]); + } + +ide_host_free (host); +}EXPORT_SYMBOL_GPL (ide_host_remove);void ide_port_scan (ide_hwif_t *hwif)
drivers/ide/legacy/falconide.c +17 -5
@@ -114,9 +114,10 @@ static int __init falconide_init(void) {struct ide_host *host;hw_regs_t hw, *hws[] = { &hw,NULL ,NULL ,NULL }; +int rc;if (!MACH_IS_ATARI || !ATARIHW_PRESENT (IDE )) -return 0 ; +return -NODEV ;printk (KERN_INFO "ide: Falcon IDE controller\n" );
@@ -128,13 +129,24 @@ static int __init falconide_init(void)falconide_setup_ports (&hw); host =ide_host_alloc (&falconide_port_info, hws); -if (host) { -ide_get_lock (NULL ,NULL ); -ide_host_register (host, &falconide_port_info, hws); -ide_release_lock (); +if (host ==NULL ) { + rc = -ENOMEM ; + goto err; } +ide_get_lock (NULL ,NULL ); + rc =ide_host_register (host, &falconide_port_info, hws); +ide_release_lock (); + +if (rc) + goto err_free; +return 0 ; +err_free: +ide_host_free (host); +err: +release_mem_region (ATA_HD_BASE ,0x40 ); +return rc; }module_init (falconide_init);
drivers/ide/pci/sgiioc4.c +10 -4
@@ -603,6 +603,7 @@ sgiioc4_ide_setup_pci_device(struct pci_struct ide_host *host;hw_regs_t hw, *hws[] = { &hw,NULL ,NULL ,NULL };struct ide_port_info d = sgiioc4_port_info; +int rc;/* Get the CmdBlk and CtrlBlk Base Registers */ bar0 =pci_resource_start (dev,0 );
@@ -638,17 +639,22 @@ sgiioc4_ide_setup_pci_device(struct pci_writel (0x03 , (void __iomem *)(irqport +IOC4_INTR_SET *4 )); host =ide_host_alloc (&d, hws); -if (host ==NULL ) +if (host ==NULL ) { + rc = -ENOMEM ; goto err; + } -if (ide_host_register (host, &d, hws)) -return -EIO ; + rc =ide_host_register (host, &d, hws); +if (rc) + goto err_free;return 0 ; +err_free: +ide_host_free (host); err:release_mem_region (cmd_phys_base,IOC4_CMD_CTL_BLK_SIZE );iounmap (virt_base); -return -ENOMEM ; +return rc; } static unsigned int __devinit
include/linux/ide.h +1 -0
@@ -1221,6 +1221,7 @@ void ide_port_apply_params(ide_hwif_t *)struct ide_host *ide_host_alloc_all (const struct ide_port_info *,hw_regs_t **);struct ide_host *ide_host_alloc (const struct ide_port_info *,hw_regs_t **); +void ide_host_free (struct ide_host *);int ide_host_register (struct ide_host *,const struct ide_port_info *,hw_regs_t **); int ide_host_add(const struct ide_port_info *, hw_regs_t **,
Quoted 22 lines · Bartlomiej Zolnierkiewicz
Add
ide_host_add()helper which does ide_host_alloc()+ide_host_register(), then convert ide_setup_pci_device[s](),ide_legacy_device_add()and some host drivers to use it.While at it:
* Fix ide_setup_pci_device[s](),
ide_arm.c,gayle.c,ide-4drives.c,macide.c,q40ide.c,cmd640.candcs5520.cto return correct error value.*
-ENOENT->-ENOMEMinrapide.c,ide-h8300.c,ide-generic.c,au1xxx-ide.candpmac.c*
-ENODEV->-ENOMEMinpalm_bk3710.c,ide_platform.canddelkin_cb.c* -1 ->
-ENOMEMinide-pnp.cSigned-off-by Bartlomiej Zolnierkiewicz <[email protected]>Index:
b/drivers/ide/arm/palm_bk3710.c
===================================================================
drivers/ide/arm/palm_bk3710.c static int __devinit palm_bk3710_probe(s · line 352
Quoted 2 lines
drivers/ide/arm/palm_bk3710.c +0
-0@@ -351,7 +351,7 @@ static int __devinit palm_bk3710_probe(sstruct resource *mem, *irq;struct ide_host *host;
You forgot to remove this variable which caused the warning:
drivers/ide/arm/palm_bk3710.c: In the fucntion ‘palm_bk3710_probe’ drivers/ide/arm/palm_bk3710.c:350: warning: unused variable ‘host’
Quoted 16 lines
drivers/ide/arm/palm_bk3710.c +3
-3unsigned long base; -int i; +int i, rc;hw_regs_t hw, *hws[] = { &hw,NULL ,NULL ,NULL }; clkp =clk_get (NULL ,"IDECLK" );@@ -394,16 +394,14 @@ static int __devinit palm_bk3710_probe(s hw.irq = irq->start; hw.chipset = ide_palm3710; - host =ide_host_alloc (&palm_bk3710_port_info, hws); -if (host ==NULL ) + rc =ide_host_add (&palm_bk3710_port_info, hws,NULL ); +if (rc) goto out;
drivers/ide/arm/palm_bk3710.c static int __devinit palm_bk3710_probe(s · line 407
Quoted 10 lines
drivers/ide/arm/palm_bk3710.c +1
-3-ide_host_register (host, &palm_bk3710_port_info, hws); -return 0 ; out:printk (KERN_WARNING "Palm Chip BK3710 IDE Register Fail\n" ); -return -ENODEV ; +return rc; }/* work with hotplug and coldplug */
MBR, Sergei