From e67c4298199b04d1e0deedb74b25ad5cc55aa974 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Fri, 27 Aug 2004 05:12:19 -0700 Subject: [PATCH] [PATCH] ad1848 check_region() removal * ports for ad1848 are now claimed by callers * ad1848_detect() gets pointer to struct resource in question * ad1848_init() gets the same pointer and consumes it * ports for mss are now claimed by callers (both config and ad1848 ones) * probe_ms_sound() gets pointer to ad1848 ports * attach_ms_sound() gets the same pointer and consumes both regions. * callers updated. That had killed a *lot* of check_region() and closed corresponding races. Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- sound/oss/ad1848.c | 56 ++++++++++++++++++++++++-------------------- sound/oss/ad1848.h | 8 +++---- sound/oss/cs4232.c | 46 ++++++++++++++++-------------------- sound/oss/cs4232.h | 2 -- sound/oss/gus_card.c | 24 +++++++++++-------- sound/oss/gus_wave.c | 14 ++++++++--- sound/oss/mad16.c | 12 ++++++---- sound/oss/opl3sa.c | 35 +++++++++++++++++---------- sound/oss/opl3sa2.c | 30 +++++++++++++++--------- sound/oss/pss.c | 16 +++++++++---- sound/oss/sgalaxy.c | 24 ++++++++++++++----- sound/oss/sscape.c | 14 +++++++++-- sound/oss/trix.c | 11 +++++---- 13 files changed, 177 insertions(+), 115 deletions(-) diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c index af1225d9fd4e1..c78a5a11d5c1c 100644 --- a/sound/oss/ad1848.c +++ b/sound/oss/ad1848.c @@ -1538,7 +1538,7 @@ static void ad1848_init_hw(ad1848_info * devc) ad1848_mixer_reset(devc); } -int ad1848_detect(int io_base, int *ad_flags, int *osp) +int ad1848_detect(struct resource *ports, int *ad_flags, int *osp) { unsigned char tmp; ad1848_info *devc = &adev_info[nr_ad1848_devs]; @@ -1548,6 +1548,7 @@ int ad1848_detect(int io_base, int *ad_flags, int *osp) int ad1847_flag = 0; int cs4248_flag = 0; int sscape_flag = 0; + int io_base = ports->start; int i; @@ -1578,11 +1579,6 @@ int ad1848_detect(int io_base, int *ad_flags, int *osp) printk(KERN_ERR "ad1848 - Too many audio devices\n"); return 0; } - if (check_region(io_base, 4)) - { - printk(KERN_ERR "ad1848.c: Port %x not free.\n", io_base); - return 0; - } spin_lock_init(&devc->lock); devc->base = io_base; devc->irq_ok = 0; @@ -1951,7 +1947,7 @@ int ad1848_detect(int io_base, int *ad_flags, int *osp) return 1; } -int ad1848_init (char *name, int io_base, int irq, int dma_playback, +int ad1848_init (char *name, struct resource *ports, int irq, int dma_playback, int dma_capture, int share_dma, int *osp, struct module *owner) { /* @@ -1986,8 +1982,7 @@ int ad1848_init (char *name, int io_base, int irq, int dma_playback, sprintf(dev_name, "Generic audio codec (%s)", devc->chip_name); - if (!request_region(devc->base, 4, devc->name)) - return -1; + rename_region(ports, devc->name); conf_printf2(dev_name, devc->base, devc->irq, dma_playback, dma_capture); @@ -2522,21 +2517,16 @@ static int init_deskpro(struct address_info *hw_config) return 1; } -int probe_ms_sound(struct address_info *hw_config) +int probe_ms_sound(struct address_info *hw_config, struct resource *ports) { unsigned char tmp; DDB(printk("Entered probe_ms_sound(%x, %d)\n", hw_config->io_base, hw_config->card_subtype)); - if (check_region(hw_config->io_base, 8)) - { - printk(KERN_ERR "MSS: I/O port conflict\n"); - return 0; - } if (hw_config->card_subtype == 1) /* Has no IRQ/DMA registers */ { /* check_opl3(0x388, hw_config); */ - return ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp); + return ad1848_detect(ports, NULL, hw_config->osp); } if (deskpro_xl && hw_config->card_subtype == 2) /* Compaq Deskpro XL */ @@ -2562,7 +2552,7 @@ int probe_ms_sound(struct address_info *hw_config) int ret; DDB(printk("I/O address is inactive (%x)\n", tmp)); - if (!(ret = ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp))) + if (!(ret = ad1848_detect(ports, NULL, hw_config->osp))) return 0; return 1; } @@ -2575,7 +2565,7 @@ int probe_ms_sound(struct address_info *hw_config) MDB(printk(KERN_ERR "No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, (int) inb(hw_config->io_base + 3))); DDB(printk("Trying to detect codec anyway but IRQ/DMA may not work\n")); - if (!(ret = ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp))) + if (!(ret = ad1848_detect(ports, NULL, hw_config->osp))) return 0; hw_config->card_subtype = 1; @@ -2610,10 +2600,10 @@ int probe_ms_sound(struct address_info *hw_config) printk(KERN_ERR "MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq); return 0; } - return ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp); + return ad1848_detect(ports, NULL, hw_config->osp); } -void attach_ms_sound(struct address_info *hw_config, struct module *owner) +void attach_ms_sound(struct address_info *hw_config, struct resource *ports, struct module *owner) { static signed char interrupt_bits[12] = { @@ -2634,13 +2624,12 @@ void attach_ms_sound(struct address_info *hw_config, struct module *owner) if (hw_config->card_subtype == 1) /* Has no IRQ/DMA registers */ { - hw_config->slots[0] = ad1848_init("MS Sound System", hw_config->io_base + 4, + hw_config->slots[0] = ad1848_init("MS Sound System", ports, hw_config->irq, hw_config->dma, hw_config->dma2, 0, hw_config->osp, owner); - request_region(hw_config->io_base, 4, "WSS config"); return; } /* @@ -2651,6 +2640,8 @@ void attach_ms_sound(struct address_info *hw_config, struct module *owner) if (bits == -1) { printk(KERN_ERR "MSS: Bad IRQ %d\n", hw_config->irq); + release_region(ports->start, 4); + release_region(ports->start - 4, 4); return; } outb((bits | 0x40), config_port); @@ -2694,12 +2685,11 @@ void attach_ms_sound(struct address_info *hw_config, struct module *owner) outb((bits | dma_bits[dma] | dma2_bit), config_port); /* Write IRQ+DMA setup */ - hw_config->slots[0] = ad1848_init("MS Sound System", hw_config->io_base + 4, + hw_config->slots[0] = ad1848_init("MS Sound System", ports, hw_config->irq, dma, dma2, 0, hw_config->osp, THIS_MODULE); - request_region(hw_config->io_base, 4, "WSS config"); } void unload_ms_sound(struct address_info *hw_config) @@ -3095,6 +3085,7 @@ static int __init init_ad1848(void) #endif if(io != -1) { + struct resource *ports; if( isapnp == 0 ) { if(irq == -1 || dma == -1) { @@ -3109,9 +3100,22 @@ static int __init init_ad1848(void) cfg.card_subtype = type; } - if(!probe_ms_sound(&cfg)) + ports = request_region(io + 4, 4, "ad1848"); + + if (!ports) + return -EBUSY; + + if (!request_region(io, 4, "WSS config")) { + release_region(io + 4, 4); + return -EBUSY; + } + + if (!probe_ms_sound(&cfg, ports)) { + release_region(io + 4, 4); + release_region(io, 4); return -ENODEV; - attach_ms_sound(&cfg, THIS_MODULE); + } + attach_ms_sound(&cfg, ports, THIS_MODULE); loaded = 1; } return 0; diff --git a/sound/oss/ad1848.h b/sound/oss/ad1848.h index 76e3c6a1dd073..d0573b0239732 100644 --- a/sound/oss/ad1848.h +++ b/sound/oss/ad1848.h @@ -11,15 +11,15 @@ ad1848_control(AD1848_MIXER_REROUTE, ((oldctl)<<8)|(newctl)) -int ad1848_init(char *name, int io_base, int irq, int dma_playback, +int ad1848_init(char *name, struct resource *ports, int irq, int dma_playback, int dma_capture, int share_dma, int *osp, struct module *owner); void ad1848_unload (int io_base, int irq, int dma_playback, int dma_capture, int share_dma); -int ad1848_detect (int io_base, int *flags, int *osp); +int ad1848_detect (struct resource *ports, int *flags, int *osp); int ad1848_control(int cmd, int arg); irqreturn_t adintr(int irq, void *dev_id, struct pt_regs * dummy); -void attach_ms_sound(struct address_info * hw_config, struct module * owner); +void attach_ms_sound(struct address_info * hw_config, struct resource *ports, struct module * owner); -int probe_ms_sound(struct address_info *hw_config); +int probe_ms_sound(struct address_info *hw_config, struct resource *ports); void unload_ms_sound(struct address_info *hw_info); diff --git a/sound/oss/cs4232.c b/sound/oss/cs4232.c index d05db7e969e34..1d0f6edc21ae1 100644 --- a/sound/oss/cs4232.c +++ b/sound/oss/cs4232.c @@ -128,27 +128,33 @@ static void enable_xctrl(int baseio) outb(((unsigned char) (ENABLE_PINS | regd)), baseio + INDEX_DATA ); } -int __init probe_cs4232(struct address_info *hw_config, int isapnp_configured) +static int __init probe_cs4232(struct address_info *hw_config, int isapnp_configured) { int i, n; int base = hw_config->io_base, irq = hw_config->irq; int dma1 = hw_config->dma, dma2 = hw_config->dma2; + struct resource *ports; + + if (base == -1 || irq == -1 || dma1 == -1) { + printk(KERN_ERR "cs4232: dma, irq and io must be set.\n"); + return 0; + } /* * Verify that the I/O port range is free. */ - if (check_region(base, 4)) - { + ports = request_region(base, 4, "ad1848"); + if (!ports) { printk(KERN_ERR "cs4232.c: I/O port 0x%03x not free\n", base); return 0; } - if (ad1848_detect(hw_config->io_base, NULL, hw_config->osp)) { - return 1; /* The card is already active */ + if (ad1848_detect(ports, NULL, hw_config->osp)) { + goto got_it; /* The card is already active */ } if (isapnp_configured) { printk(KERN_ERR "cs4232.c: ISA PnP configured, but not detected?\n"); - return 0; + goto fail; } /* @@ -241,30 +247,20 @@ int __init probe_cs4232(struct address_info *hw_config, int isapnp_configured) * Then try to detect the codec part of the chip */ - if (ad1848_detect(hw_config->io_base, NULL, hw_config->osp)) - return 1; + if (ad1848_detect(ports, NULL, hw_config->osp)) + goto got_it; sleep(HZ); } +fail: + release_region(base, 4); return 0; -} - -void __init attach_cs4232(struct address_info *hw_config) -{ - int base = hw_config->io_base, - irq = hw_config->irq, - dma1 = hw_config->dma, - dma2 = hw_config->dma2; - - if (base == -1 || irq == -1 || dma1 == -1) { - printk(KERN_ERR "cs4232: dma, irq and io must be set.\n"); - return; - } +got_it: if (dma2 == -1) dma2 = dma1; - hw_config->slots[0] = ad1848_init("Crystal audio controller", base, + hw_config->slots[0] = ad1848_init("Crystal audio controller", ports, irq, dma1, /* Playback DMA */ dma2, /* Capture DMA */ @@ -308,9 +304,9 @@ void __init attach_cs4232(struct address_info *hw_config) } if (bss) - { enable_xctrl(base); - } + + return 1; } static void __devexit unload_cs4232(struct address_info *hw_config) @@ -423,7 +419,6 @@ static int cs4232_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev kfree(isapnpcfg); return -ENODEV; } - attach_cs4232(isapnpcfg); pnp_set_drvdata(dev,isapnpcfg); return 0; } @@ -486,7 +481,6 @@ static int __init init_cs4232(void) if (probe_cs4232(&cfg,FALSE) == 0) return -ENODEV; - attach_cs4232(&cfg); return 0; } diff --git a/sound/oss/cs4232.h b/sound/oss/cs4232.h index 31c8d8b23c91e..a5a00292c5f32 100644 --- a/sound/oss/cs4232.h +++ b/sound/oss/cs4232.h @@ -1,5 +1,3 @@ -int probe_cs4232 (struct address_info *hw_config,int useisapnp); -void attach_cs4232 (struct address_info *hw_config); int probe_cs4232_mpu (struct address_info *hw_config); void attach_cs4232_mpu (struct address_info *hw_config); diff --git a/sound/oss/gus_card.c b/sound/oss/gus_card.c index 88f5ca1cf4577..e0111a7b6b4c9 100644 --- a/sound/oss/gus_card.c +++ b/sound/oss/gus_card.c @@ -160,22 +160,29 @@ irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs *dummy) #ifdef CONFIG_SOUND_GUS16 -static int __init probe_gus_db16(struct address_info *hw_config) +static int __init init_gus_db16(struct address_info *hw_config) { - return ad1848_detect(hw_config->io_base, NULL, hw_config->osp); -} + struct resource *ports; + + ports = request_region(hw_config->io_base, 4, "ad1848"); + if (!ports) + return 0; + + if (!ad1848_detect(ports, NULL, hw_config->osp)) { + release_region(hw_config->io_base, 4); + return 0; + } -static void __init attach_gus_db16(struct address_info *hw_config) -{ gus_pcm_volume = 100; gus_wave_volume = 90; - hw_config->slots[3] = ad1848_init("GUS 16 bit sampling", hw_config->io_base, + hw_config->slots[3] = ad1848_init("GUS 16 bit sampling", ports, hw_config->irq, hw_config->dma, hw_config->dma, 0, hw_config->osp, THIS_MODULE); + return 1; } static void __exit unload_gus_db16(struct address_info *hw_config) @@ -244,11 +251,8 @@ static int __init init_gus(void) } #ifdef CONFIG_SOUND_GUS16 - if (probe_gus_db16(&cfg) && gus16) { - /* FIXME: This can't work, can it ? -- Christoph */ - attach_gus_db16(&cfg); + if (gus16 && init_gus_db16(&cfg)) db16 = 1; - } #endif if (!probe_gus(&cfg)) return -ENODEV; diff --git a/sound/oss/gus_wave.c b/sound/oss/gus_wave.c index ed7333ca2bcff..2cc924d7b7f81 100644 --- a/sound/oss/gus_wave.c +++ b/sound/oss/gus_wave.c @@ -2942,6 +2942,8 @@ void __init gus_wave_init(struct address_info *hw_config) } else { + struct resource *ports; + ports = request_region(gus_base + 0x10c, 4, "ad1848"); model_num = "MAX"; gus_type = 0x40; mixer_type = CS4231; @@ -2963,7 +2965,10 @@ void __init gus_wave_init(struct address_info *hw_config) outb((max_config), gus_base + 0x106); /* UltraMax control */ } - if (ad1848_detect(gus_base + 0x10c, &ad_flags, hw_config->osp)) + if (!ports) + goto no_cs4231; + + if (ad1848_detect(ports, &ad_flags, hw_config->osp)) { char *name = "GUS MAX"; int old_num_mixers = num_mixers; @@ -2977,7 +2982,7 @@ void __init gus_wave_init(struct address_info *hw_config) if (hw_config->name) name = hw_config->name; - hw_config->slots[1] = ad1848_init(name, gus_base + 0x10c, + hw_config->slots[1] = ad1848_init(name, ports, -irq, gus_dma2, /* Playback DMA */ gus_dma, /* Capture DMA */ 1, /* Share DMA channels with GF1 */ @@ -2992,8 +2997,11 @@ void __init gus_wave_init(struct address_info *hw_config) AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE); } } - else + else { + release_region(gus_base + 0x10c, 4); + no_cs4231: printk(KERN_WARNING "GUS: No CS4231 ??"); + } #else printk(KERN_ERR "GUS MAX found, but not compiled in\n"); #endif diff --git a/sound/oss/mad16.c b/sound/oss/mad16.c index 516f9f79f793f..4c5db81ed3c14 100644 --- a/sound/oss/mad16.c +++ b/sound/oss/mad16.c @@ -478,6 +478,7 @@ static int __init probe_mad16(struct address_info *hw_config) int dma = hw_config->dma, dma2 = hw_config->dma2; unsigned char dma2_bit = 0; int base; + struct resource *ports; mad16_osp = hw_config->osp; @@ -536,11 +537,13 @@ static int __init probe_mad16(struct address_info *hw_config) return 0; } - if (check_region(hw_config->io_base + 4, 4) { + ports = request_region(hw_config->io_base + 4, 4, "ad1848"); + if (!ports) { printk(KERN_ERR "MSS: I/O port conflict\n"); return 0; } if (!request_region(hw_config->io_base, 4, "mad16 WSS config")) { + release_region(hw_config->io_base + 4, 4); printk(KERN_ERR "MSS: I/O port conflict\n"); return 0; } @@ -582,7 +585,7 @@ static int __init probe_mad16(struct address_info *hw_config) mad_write(MC5_PORT, 0x05); mad_write(MC6_PORT, 0x03); } - if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp)) + if (!ad1848_detect(ports, &ad_flags, mad16_osp)) goto fail; if (ad_flags & (AD_F_CS4231 | AD_F_CS4248)) @@ -609,7 +612,7 @@ static int __init probe_mad16(struct address_info *hw_config) got_it: ad_flags = 0; - if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp)) + if (!ad1848_detect(ports, &ad_flags, mad16_osp)) goto fail; if (!wss_init(hw_config)) @@ -653,7 +656,7 @@ got_it: outb((bits | dma_bits[dma] | dma2_bit), config_port); /* Write IRQ+DMA setup */ - hw_config->slots[0] = ad1848_init("mad16 WSS", hw_config->io_base + 4, + hw_config->slots[0] = ad1848_init("mad16 WSS", ports, hw_config->irq, dma, dma2, 0, @@ -662,6 +665,7 @@ got_it: return 1; fail: + release_region(hw_config->io_base + 4, 4); release_region(hw_config->io_base, 4); return 0; } diff --git a/sound/oss/opl3sa.c b/sound/oss/opl3sa.c index b8de4a4499c49..99f4ed66fd9f6 100644 --- a/sound/oss/opl3sa.c +++ b/sound/oss/opl3sa.c @@ -103,7 +103,7 @@ static int __init opl3sa_detect(void) * OPL3-SA */ -static int __init probe_opl3sa_wss(struct address_info *hw_config) +static int __init probe_opl3sa_wss(struct address_info *hw_config, struct resource *ports) { unsigned char tmp = 0x24; /* WSS enable */ @@ -113,12 +113,6 @@ static int __init probe_opl3sa_wss(struct address_info *hw_config) * return 0x00. */ - if (check_region(hw_config->io_base, 8)) - { - printk(KERN_ERR "OPL3-SA: MSS I/O port conflict (%x)\n", hw_config->io_base); - return 0; - } - if (!opl3sa_detect()) { printk(KERN_ERR "OSS: OPL3-SA chip not found\n"); @@ -146,15 +140,15 @@ static int __init probe_opl3sa_wss(struct address_info *hw_config) opl3sa_write(0x01, tmp); /* WSS setup register */ - return probe_ms_sound(hw_config); + return probe_ms_sound(hw_config, ports); } -static void __init attach_opl3sa_wss(struct address_info *hw_config) +static void __init attach_opl3sa_wss(struct address_info *hw_config, struct resource *ports) { int nm = num_mixers; /* FIXME */ - attach_ms_sound(hw_config, THIS_MODULE); + attach_ms_sound(hw_config, ports, THIS_MODULE); if (num_mixers > nm) /* A mixer was installed */ { AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_CD); @@ -260,6 +254,7 @@ MODULE_PARM(mpu_irq,"i"); static int __init init_opl3sa(void) { + struct resource *ports; if (io == -1 || irq == -1 || dma == -1) { printk(KERN_ERR "opl3sa: dma, irq and io must be set.\n"); return -EINVAL; @@ -273,17 +268,31 @@ static int __init init_opl3sa(void) cfg_mpu.io_base = mpu_io; cfg_mpu.irq = mpu_irq; - if (!request_region(0xf86, 2, "OPL3-SA"))/* Control port is busy */ + ports = request_region(io + 4, 4, "ad1848"); + if (!ports) + return -EBUSY; + + if (!request_region(0xf86, 2, "OPL3-SA"))/* Control port is busy */ { + release_region(io + 4, 4); return 0; + } + + if (!request_region(io, 4, "WSS config")) { + release_region(0x86, 2); + release_region(io + 4, 4); + return 0; + } - if (probe_opl3sa_wss(&cfg) == 0) { + if (probe_opl3sa_wss(&cfg, ports) == 0) { release_region(0xf86, 2); + release_region(io, 4); + release_region(io + 4, 4); return -ENODEV; } found_mpu=probe_opl3sa_mpu(&cfg_mpu); - attach_opl3sa_wss(&cfg); + attach_opl3sa_wss(&cfg, ports); return 0; } diff --git a/sound/oss/opl3sa2.c b/sound/oss/opl3sa2.c index 6daba626e2202..fb98c6ee60a90 100644 --- a/sound/oss/opl3sa2.c +++ b/sound/oss/opl3sa2.c @@ -556,19 +556,12 @@ static inline void __exit unload_opl3sa2_mpu(struct address_info *hw_config) unload_mpu401(hw_config); } - -static inline int __init probe_opl3sa2_mss(struct address_info* hw_config) -{ - return probe_ms_sound(hw_config); -} - - -static void __init attach_opl3sa2_mss(struct address_info* hw_config) +static void __init attach_opl3sa2_mss(struct address_info* hw_config, struct resource *ports) { int initial_mixers; initial_mixers = num_mixers; - attach_ms_sound(hw_config, THIS_MODULE); /* Slot 0 */ + attach_ms_sound(hw_config, ports, THIS_MODULE); /* Slot 0 */ if (hw_config->slots[0] != -1) { /* Did the MSS driver install? */ if(num_mixers == (initial_mixers + 1)) { @@ -957,6 +950,8 @@ static int __init init_opl3sa2(void) for (card = 0; card < max; card++) { /* If a user wants an I/O then assume they meant it */ + struct resource *ports; + int base; if (!isapnp) { if (io == -1 || irq == -1 || dma == -1 || @@ -995,17 +990,30 @@ static int __init init_opl3sa2(void) opl3sa2_clear_slots(&opl3sa2_state[card].cfg_mpu); } + /* FIXME: leak */ if (probe_opl3sa2(&opl3sa2_state[card].cfg, card)) return -ENODEV; + base = opl3sa2_state[card].cfg_mss.io_base; + + if (!request_region(base, 4, "WSS config")) + goto failed; + + ports = request_region(base + 4, 4, "ad1848"); + if (!ports) + goto failed2; - if (!probe_opl3sa2_mss(&opl3sa2_state[card].cfg_mss)) { + if (!probe_ms_sound(&opl3sa2_state[card].cfg_mss, ports)) { /* * If one or more cards are already registered, don't * return an error but print a warning. Note, this * should never really happen unless the hardware or * ISA PnP screwed up. */ + release_region(base + 4, 4); + failed2: + release_region(base, 4); + failed: release_region(opl3sa2_state[card].cfg.io_base, 2); if (opl3sa2_cards_num) { @@ -1021,7 +1029,7 @@ static int __init init_opl3sa2(void) attach_opl3sa2(&opl3sa2_state[card].cfg, card); conf_printf(opl3sa2_state[card].chipset_name, &opl3sa2_state[card].cfg); attach_opl3sa2_mixer(&opl3sa2_state[card].cfg, card); - attach_opl3sa2_mss(&opl3sa2_state[card].cfg_mss); + attach_opl3sa2_mss(&opl3sa2_state[card].cfg_mss, ports); /* ewww =) */ opl3sa2_state[card].card = card; diff --git a/sound/oss/pss.c b/sound/oss/pss.c index 7708271dfc56c..3e6ba68d09237 100644 --- a/sound/oss/pss.c +++ b/sound/oss/pss.c @@ -1039,14 +1039,20 @@ static coproc_operations pss_coproc_operations = static int __init probe_pss_mss(struct address_info *hw_config) { volatile int timeout; + struct resource *ports; int my_mix = -999; /* gcc shut up */ if (!pss_initialized) return 0; - if (check_region(hw_config->io_base, 8)) - { + if (!request_region(hw_config->io_base, 4, "WSS config")) { + printk(KERN_ERR "PSS: WSS I/O port conflicts.\n"); + return 0; + } + ports = request_region(hw_config->io_base + 4, 4, "ad1848"); + if (!ports) { printk(KERN_ERR "PSS: WSS I/O port conflicts.\n"); + release_region(hw_config->io_base, 4); return 0; } if (!set_io_base(devc, CONF_WSS, hw_config->io_base)) { @@ -1077,7 +1083,7 @@ static int __init probe_pss_mss(struct address_info *hw_config) (timeout < 100000); timeout++) ; - if (!probe_ms_sound(hw_config)) + if (!probe_ms_sound(hw_config, ports)) goto fail; devc->ad_mixer_dev = NO_WSS_MIXER; @@ -1094,7 +1100,7 @@ static int __init probe_pss_mss(struct address_info *hw_config) } } pss_mixer_reset(devc); - attach_ms_sound(hw_config, THIS_MODULE); /* Slot 0 */ + attach_ms_sound(hw_config, ports, THIS_MODULE); /* Slot 0 */ if (hw_config->slots[0] != -1) { @@ -1108,6 +1114,8 @@ static int __init probe_pss_mss(struct address_info *hw_config) } return 1; fail: + release_region(hw_config->io_base + 4, 4); + release_region(hw_config->io_base, 4); return 0; } diff --git a/sound/oss/sgalaxy.c b/sound/oss/sgalaxy.c index 78c9477204203..16cc9ab505b53 100644 --- a/sound/oss/sgalaxy.c +++ b/sound/oss/sgalaxy.c @@ -86,20 +86,30 @@ static int __init sb_cmd( int base, unsigned char val ) static int __init probe_sgalaxy( struct address_info *ai ) { + struct resource *ports; int n; - if ( check_region( ai->io_base, 8 ) ) { + if (!request_region(ai->io_base, 4, "WSS config")) { printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base); return 0; } + ports = request_region(ai->io_base + 4, 4, "ad1848"); + if (!ports) { + printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base); + release_region(ai->io_base, 4); + return 0; + } + if (!request_region( ai->ai_sgbase, 0x10, "SoundGalaxy SB")) { printk(KERN_ERR "sgalaxy: SB IO port 0x%03x not available\n", ai->ai_sgbase); + release_region(ai->io_base + 4, 4); + release_region(ai->io_base, 4); return 0; } - - if ( ad1848_detect( ai->io_base+4, NULL, ai->osp ) ) - goto out; + + if (ad1848_detect(ports, NULL, ai->osp)) + goto out; /* The card is already active, check irq etc... */ /* switch to MSS/WSS mode */ @@ -111,12 +121,14 @@ static int __init probe_sgalaxy( struct address_info *ai ) sleep( HZ/10 ); out: - if (!probe_ms_sound(ai)) { + if (!probe_ms_sound(ai, ports)) { + release_region(ai->io_base + 4, 4); + release_region(ai->io_base, 4); release_region(ai->ai_sgbase, 0x10); return 0; } - attach_ms_sound(ai, THIS_MODULE); + attach_ms_sound(ai, ports, THIS_MODULE); n=ai->slots[0]; if (n!=-1 && audio_devs[n]->mixer_dev != -1 ) { diff --git a/sound/oss/sscape.c b/sound/oss/sscape.c index bd94ca3cd8937..dfe02f1012641 100644 --- a/sound/oss/sscape.c +++ b/sound/oss/sscape.c @@ -1268,6 +1268,7 @@ static int __init init_ss_ms_sound(struct address_info *hw_config) { int i, irq_bits = 0xff; int ad_flags = 0; + struct resource *ports; if (devc->failed) { @@ -1296,8 +1297,17 @@ static int __init init_ss_ms_sound(struct address_info *hw_config) ad_flags = 0x12345677; /* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */ else if (sscape_is_pnp) ad_flags = 0x87654321; /* Tell that we have a soundscape pnp with 1845 chip */ - if (!ad1848_detect(hw_config->io_base, &ad_flags, hw_config->osp)) + + ports = request_region(hw_config->io_base, 4, "ad1848"); + if (!ports) { + printk(KERN_ERR "soundscape: ports busy\n"); return 0; + } + + if (!ad1848_detect(ports, &ad_flags, hw_config->osp)) { + release_region(hw_config->io_base, 4); + return 0; + } if (!sscape_is_pnp) /*pnp is already setup*/ { @@ -1322,7 +1332,7 @@ static int __init init_ss_ms_sound(struct address_info *hw_config) hw_config->slots[0] = ad1848_init( sscape_is_pnp ? "SoundScape" : "SoundScape PNP", - hw_config->io_base, + ports, hw_config->irq, hw_config->dma, hw_config->dma, diff --git a/sound/oss/trix.c b/sound/oss/trix.c index 0cc2b989054ac..13c3d79396a5f 100644 --- a/sound/oss/trix.c +++ b/sound/oss/trix.c @@ -125,6 +125,7 @@ static int __init init_trix_wss(struct address_info *hw_config) static unsigned char dma_bits[4] = { 1, 2, 0, 3 }; + struct resource *ports; int config_port = hw_config->io_base + 0; int dma1 = hw_config->dma, dma2 = hw_config->dma2; int old_num_mixers = num_mixers; @@ -175,14 +176,15 @@ static int __init init_trix_wss(struct address_info *hw_config) * system returns 0x04 while some cards (AudioTrix Pro for example) * return 0x00. */ - if (check_region(hw_config->io_base + 4, 4)) - { + ports = request_region(hw_config->io_base + 4, 4, "ad1848"); + if (!ports) { printk(KERN_ERR "AudioTrix: MSS I/O port conflict (%x)\n", hw_config->io_base); return 0; } if (!request_region(hw_config->io_base, 4, "MSS config")) { printk(KERN_ERR "AudioTrix: MSS I/O port conflict (%x)\n", hw_config->io_base); + release_region(hw_config->io_base + 4, 4); return 0; } @@ -212,7 +214,7 @@ static int __init init_trix_wss(struct address_info *hw_config) goto fail; } - ret = ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp); + ret = ad1848_detect(ports, NULL, hw_config->osp); if (!ret) goto fail; @@ -243,7 +245,7 @@ static int __init init_trix_wss(struct address_info *hw_config) outb((bits), config_port); /* Write IRQ+DMA setup */ - hw_config->slots[0] = ad1848_init("AudioTrix Pro", hw_config->io_base + 4, + hw_config->slots[0] = ad1848_init("AudioTrix Pro", ports, hw_config->irq, dma1, dma2, @@ -262,6 +264,7 @@ static int __init init_trix_wss(struct address_info *hw_config) fail: release_region(hw_config->io_base, 4); + release_region(hw_config->io_base + 4, 4); return 0; } -- 2.53.0