Commit e67c4298 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[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: default avatarAl Viro <viro@parcelfarce.linux.org.uk>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 4022b887
...@@ -1538,7 +1538,7 @@ static void ad1848_init_hw(ad1848_info * devc) ...@@ -1538,7 +1538,7 @@ static void ad1848_init_hw(ad1848_info * devc)
ad1848_mixer_reset(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; unsigned char tmp;
ad1848_info *devc = &adev_info[nr_ad1848_devs]; ad1848_info *devc = &adev_info[nr_ad1848_devs];
...@@ -1548,6 +1548,7 @@ int ad1848_detect(int io_base, int *ad_flags, int *osp) ...@@ -1548,6 +1548,7 @@ int ad1848_detect(int io_base, int *ad_flags, int *osp)
int ad1847_flag = 0; int ad1847_flag = 0;
int cs4248_flag = 0; int cs4248_flag = 0;
int sscape_flag = 0; int sscape_flag = 0;
int io_base = ports->start;
int i; int i;
...@@ -1578,11 +1579,6 @@ int ad1848_detect(int io_base, int *ad_flags, int *osp) ...@@ -1578,11 +1579,6 @@ int ad1848_detect(int io_base, int *ad_flags, int *osp)
printk(KERN_ERR "ad1848 - Too many audio devices\n"); printk(KERN_ERR "ad1848 - Too many audio devices\n");
return 0; 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); spin_lock_init(&devc->lock);
devc->base = io_base; devc->base = io_base;
devc->irq_ok = 0; devc->irq_ok = 0;
...@@ -1951,7 +1947,7 @@ int ad1848_detect(int io_base, int *ad_flags, int *osp) ...@@ -1951,7 +1947,7 @@ int ad1848_detect(int io_base, int *ad_flags, int *osp)
return 1; 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) 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, ...@@ -1986,8 +1982,7 @@ int ad1848_init (char *name, int io_base, int irq, int dma_playback,
sprintf(dev_name, sprintf(dev_name,
"Generic audio codec (%s)", devc->chip_name); "Generic audio codec (%s)", devc->chip_name);
if (!request_region(devc->base, 4, devc->name)) rename_region(ports, devc->name);
return -1;
conf_printf2(dev_name, devc->base, devc->irq, dma_playback, dma_capture); 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) ...@@ -2522,21 +2517,16 @@ static int init_deskpro(struct address_info *hw_config)
return 1; 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; unsigned char tmp;
DDB(printk("Entered probe_ms_sound(%x, %d)\n", hw_config->io_base, hw_config->card_subtype)); 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 */ if (hw_config->card_subtype == 1) /* Has no IRQ/DMA registers */
{ {
/* check_opl3(0x388, hw_config); */ /* 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 */ if (deskpro_xl && hw_config->card_subtype == 2) /* Compaq Deskpro XL */
...@@ -2562,7 +2552,7 @@ int probe_ms_sound(struct address_info *hw_config) ...@@ -2562,7 +2552,7 @@ int probe_ms_sound(struct address_info *hw_config)
int ret; int ret;
DDB(printk("I/O address is inactive (%x)\n", tmp)); 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 0;
return 1; return 1;
} }
...@@ -2575,7 +2565,7 @@ int probe_ms_sound(struct address_info *hw_config) ...@@ -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))); 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")); 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; return 0;
hw_config->card_subtype = 1; hw_config->card_subtype = 1;
...@@ -2610,10 +2600,10 @@ int probe_ms_sound(struct address_info *hw_config) ...@@ -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); printk(KERN_ERR "MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
return 0; 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] = static signed char interrupt_bits[12] =
{ {
...@@ -2634,13 +2624,12 @@ void attach_ms_sound(struct address_info *hw_config, struct module *owner) ...@@ -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 */ 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->irq,
hw_config->dma, hw_config->dma,
hw_config->dma2, 0, hw_config->dma2, 0,
hw_config->osp, hw_config->osp,
owner); owner);
request_region(hw_config->io_base, 4, "WSS config");
return; return;
} }
/* /*
...@@ -2651,6 +2640,8 @@ void attach_ms_sound(struct address_info *hw_config, struct module *owner) ...@@ -2651,6 +2640,8 @@ void attach_ms_sound(struct address_info *hw_config, struct module *owner)
if (bits == -1) if (bits == -1)
{ {
printk(KERN_ERR "MSS: Bad IRQ %d\n", hw_config->irq); printk(KERN_ERR "MSS: Bad IRQ %d\n", hw_config->irq);
release_region(ports->start, 4);
release_region(ports->start - 4, 4);
return; return;
} }
outb((bits | 0x40), config_port); outb((bits | 0x40), config_port);
...@@ -2694,12 +2685,11 @@ void attach_ms_sound(struct address_info *hw_config, struct module *owner) ...@@ -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 */ 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, hw_config->irq,
dma, dma2, 0, dma, dma2, 0,
hw_config->osp, hw_config->osp,
THIS_MODULE); THIS_MODULE);
request_region(hw_config->io_base, 4, "WSS config");
} }
void unload_ms_sound(struct address_info *hw_config) void unload_ms_sound(struct address_info *hw_config)
...@@ -3095,6 +3085,7 @@ static int __init init_ad1848(void) ...@@ -3095,6 +3085,7 @@ static int __init init_ad1848(void)
#endif #endif
if(io != -1) { if(io != -1) {
struct resource *ports;
if( isapnp == 0 ) if( isapnp == 0 )
{ {
if(irq == -1 || dma == -1) { if(irq == -1 || dma == -1) {
...@@ -3109,9 +3100,22 @@ static int __init init_ad1848(void) ...@@ -3109,9 +3100,22 @@ static int __init init_ad1848(void)
cfg.card_subtype = type; 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; return -ENODEV;
attach_ms_sound(&cfg, THIS_MODULE); }
attach_ms_sound(&cfg, ports, THIS_MODULE);
loaded = 1; loaded = 1;
} }
return 0; return 0;
......
...@@ -11,15 +11,15 @@ ...@@ -11,15 +11,15 @@
ad1848_control(AD1848_MIXER_REROUTE, ((oldctl)<<8)|(newctl)) 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); 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); 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); int ad1848_control(int cmd, int arg);
irqreturn_t adintr(int irq, void *dev_id, struct pt_regs * dummy); 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); void unload_ms_sound(struct address_info *hw_info);
...@@ -128,27 +128,33 @@ static void enable_xctrl(int baseio) ...@@ -128,27 +128,33 @@ static void enable_xctrl(int baseio)
outb(((unsigned char) (ENABLE_PINS | regd)), baseio + INDEX_DATA ); 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 i, n;
int base = hw_config->io_base, irq = hw_config->irq; int base = hw_config->io_base, irq = hw_config->irq;
int dma1 = hw_config->dma, dma2 = hw_config->dma2; 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. * 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); printk(KERN_ERR "cs4232.c: I/O port 0x%03x not free\n", base);
return 0; return 0;
} }
if (ad1848_detect(hw_config->io_base, NULL, hw_config->osp)) { if (ad1848_detect(ports, NULL, hw_config->osp)) {
return 1; /* The card is already active */ goto got_it; /* The card is already active */
} }
if (isapnp_configured) { if (isapnp_configured) {
printk(KERN_ERR "cs4232.c: ISA PnP configured, but not detected?\n"); 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) ...@@ -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 * Then try to detect the codec part of the chip
*/ */
if (ad1848_detect(hw_config->io_base, NULL, hw_config->osp)) if (ad1848_detect(ports, NULL, hw_config->osp))
return 1; goto got_it;
sleep(HZ); sleep(HZ);
} }
fail:
release_region(base, 4);
return 0; 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) if (dma2 == -1)
dma2 = dma1; dma2 = dma1;
hw_config->slots[0] = ad1848_init("Crystal audio controller", base, hw_config->slots[0] = ad1848_init("Crystal audio controller", ports,
irq, irq,
dma1, /* Playback DMA */ dma1, /* Playback DMA */
dma2, /* Capture DMA */ dma2, /* Capture DMA */
...@@ -308,9 +304,9 @@ void __init attach_cs4232(struct address_info *hw_config) ...@@ -308,9 +304,9 @@ void __init attach_cs4232(struct address_info *hw_config)
} }
if (bss) if (bss)
{
enable_xctrl(base); enable_xctrl(base);
}
return 1;
} }
static void __devexit unload_cs4232(struct address_info *hw_config) 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 ...@@ -423,7 +419,6 @@ static int cs4232_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev
kfree(isapnpcfg); kfree(isapnpcfg);
return -ENODEV; return -ENODEV;
} }
attach_cs4232(isapnpcfg);
pnp_set_drvdata(dev,isapnpcfg); pnp_set_drvdata(dev,isapnpcfg);
return 0; return 0;
} }
...@@ -486,7 +481,6 @@ static int __init init_cs4232(void) ...@@ -486,7 +481,6 @@ static int __init init_cs4232(void)
if (probe_cs4232(&cfg,FALSE) == 0) if (probe_cs4232(&cfg,FALSE) == 0)
return -ENODEV; return -ENODEV;
attach_cs4232(&cfg);
return 0; return 0;
} }
......
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); int probe_cs4232_mpu (struct address_info *hw_config);
void attach_cs4232_mpu (struct address_info *hw_config); void attach_cs4232_mpu (struct address_info *hw_config);
...@@ -160,22 +160,29 @@ irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs *dummy) ...@@ -160,22 +160,29 @@ irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs *dummy)
#ifdef CONFIG_SOUND_GUS16 #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_pcm_volume = 100;
gus_wave_volume = 90; 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->irq,
hw_config->dma, hw_config->dma,
hw_config->dma, 0, hw_config->dma, 0,
hw_config->osp, hw_config->osp,
THIS_MODULE); THIS_MODULE);
return 1;
} }
static void __exit unload_gus_db16(struct address_info *hw_config) static void __exit unload_gus_db16(struct address_info *hw_config)
...@@ -244,11 +251,8 @@ static int __init init_gus(void) ...@@ -244,11 +251,8 @@ static int __init init_gus(void)
} }
#ifdef CONFIG_SOUND_GUS16 #ifdef CONFIG_SOUND_GUS16
if (probe_gus_db16(&cfg) && gus16) { if (gus16 && init_gus_db16(&cfg))
/* FIXME: This can't work, can it ? -- Christoph */
attach_gus_db16(&cfg);
db16 = 1; db16 = 1;
}
#endif #endif
if (!probe_gus(&cfg)) if (!probe_gus(&cfg))
return -ENODEV; return -ENODEV;
......
...@@ -2942,6 +2942,8 @@ void __init gus_wave_init(struct address_info *hw_config) ...@@ -2942,6 +2942,8 @@ void __init gus_wave_init(struct address_info *hw_config)
} }
else else
{ {
struct resource *ports;
ports = request_region(gus_base + 0x10c, 4, "ad1848");
model_num = "MAX"; model_num = "MAX";
gus_type = 0x40; gus_type = 0x40;
mixer_type = CS4231; mixer_type = CS4231;
...@@ -2963,7 +2965,10 @@ void __init gus_wave_init(struct address_info *hw_config) ...@@ -2963,7 +2965,10 @@ void __init gus_wave_init(struct address_info *hw_config)
outb((max_config), gus_base + 0x106); /* UltraMax control */ 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"; char *name = "GUS MAX";
int old_num_mixers = num_mixers; int old_num_mixers = num_mixers;
...@@ -2977,7 +2982,7 @@ void __init gus_wave_init(struct address_info *hw_config) ...@@ -2977,7 +2982,7 @@ void __init gus_wave_init(struct address_info *hw_config)
if (hw_config->name) if (hw_config->name)
name = 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 */ -irq, gus_dma2, /* Playback DMA */
gus_dma, /* Capture DMA */ gus_dma, /* Capture DMA */
1, /* Share DMA channels with GF1 */ 1, /* Share DMA channels with GF1 */
...@@ -2992,8 +2997,11 @@ void __init gus_wave_init(struct address_info *hw_config) ...@@ -2992,8 +2997,11 @@ void __init gus_wave_init(struct address_info *hw_config)
AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE); AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
} }
} }
else else {
release_region(gus_base + 0x10c, 4);
no_cs4231:
printk(KERN_WARNING "GUS: No CS4231 ??"); printk(KERN_WARNING "GUS: No CS4231 ??");
}
#else #else
printk(KERN_ERR "GUS MAX found, but not compiled in\n"); printk(KERN_ERR "GUS MAX found, but not compiled in\n");
#endif #endif
......
...@@ -478,6 +478,7 @@ static int __init probe_mad16(struct address_info *hw_config) ...@@ -478,6 +478,7 @@ static int __init probe_mad16(struct address_info *hw_config)
int dma = hw_config->dma, dma2 = hw_config->dma2; int dma = hw_config->dma, dma2 = hw_config->dma2;
unsigned char dma2_bit = 0; unsigned char dma2_bit = 0;
int base; int base;
struct resource *ports;
mad16_osp = hw_config->osp; mad16_osp = hw_config->osp;
...@@ -536,11 +537,13 @@ static int __init probe_mad16(struct address_info *hw_config) ...@@ -536,11 +537,13 @@ static int __init probe_mad16(struct address_info *hw_config)
return 0; 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"); printk(KERN_ERR "MSS: I/O port conflict\n");
return 0; return 0;
} }
if (!request_region(hw_config->io_base, 4, "mad16 WSS config")) { 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"); printk(KERN_ERR "MSS: I/O port conflict\n");
return 0; return 0;
} }
...@@ -582,7 +585,7 @@ static int __init probe_mad16(struct address_info *hw_config) ...@@ -582,7 +585,7 @@ static int __init probe_mad16(struct address_info *hw_config)
mad_write(MC5_PORT, 0x05); mad_write(MC5_PORT, 0x05);
mad_write(MC6_PORT, 0x03); 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; goto fail;
if (ad_flags & (AD_F_CS4231 | AD_F_CS4248)) if (ad_flags & (AD_F_CS4231 | AD_F_CS4248))
...@@ -609,7 +612,7 @@ static int __init probe_mad16(struct address_info *hw_config) ...@@ -609,7 +612,7 @@ static int __init probe_mad16(struct address_info *hw_config)
got_it: got_it:
ad_flags = 0; 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; goto fail;
if (!wss_init(hw_config)) if (!wss_init(hw_config))
...@@ -653,7 +656,7 @@ static int __init probe_mad16(struct address_info *hw_config) ...@@ -653,7 +656,7 @@ static int __init probe_mad16(struct address_info *hw_config)
outb((bits | dma_bits[dma] | dma2_bit), config_port); /* Write IRQ+DMA setup */ 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, hw_config->irq,
dma, dma,
dma2, 0, dma2, 0,
...@@ -662,6 +665,7 @@ static int __init probe_mad16(struct address_info *hw_config) ...@@ -662,6 +665,7 @@ static int __init probe_mad16(struct address_info *hw_config)
return 1; return 1;
fail: fail:
release_region(hw_config->io_base + 4, 4);
release_region(hw_config->io_base, 4); release_region(hw_config->io_base, 4);
return 0; return 0;
} }
......
...@@ -103,7 +103,7 @@ static int __init opl3sa_detect(void) ...@@ -103,7 +103,7 @@ static int __init opl3sa_detect(void)
* OPL3-SA * 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 */ unsigned char tmp = 0x24; /* WSS enable */
...@@ -113,12 +113,6 @@ static int __init probe_opl3sa_wss(struct address_info *hw_config) ...@@ -113,12 +113,6 @@ static int __init probe_opl3sa_wss(struct address_info *hw_config)
* return 0x00. * 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()) if (!opl3sa_detect())
{ {
printk(KERN_ERR "OSS: OPL3-SA chip not found\n"); 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) ...@@ -146,15 +140,15 @@ static int __init probe_opl3sa_wss(struct address_info *hw_config)
opl3sa_write(0x01, tmp); /* WSS setup register */ 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; int nm = num_mixers;
/* FIXME */ /* FIXME */
attach_ms_sound(hw_config, THIS_MODULE); attach_ms_sound(hw_config, ports, THIS_MODULE);
if (num_mixers > nm) /* A mixer was installed */ if (num_mixers > nm) /* A mixer was installed */
{ {
AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_CD); AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_CD);
...@@ -260,6 +254,7 @@ MODULE_PARM(mpu_irq,"i"); ...@@ -260,6 +254,7 @@ MODULE_PARM(mpu_irq,"i");
static int __init init_opl3sa(void) static int __init init_opl3sa(void)
{ {
struct resource *ports;
if (io == -1 || irq == -1 || dma == -1) { if (io == -1 || irq == -1 || dma == -1) {
printk(KERN_ERR "opl3sa: dma, irq and io must be set.\n"); printk(KERN_ERR "opl3sa: dma, irq and io must be set.\n");
return -EINVAL; return -EINVAL;
...@@ -273,17 +268,31 @@ static int __init init_opl3sa(void) ...@@ -273,17 +268,31 @@ static int __init init_opl3sa(void)
cfg_mpu.io_base = mpu_io; cfg_mpu.io_base = mpu_io;
cfg_mpu.irq = mpu_irq; 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; 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(0xf86, 2);
release_region(io, 4);
release_region(io + 4, 4);
return -ENODEV; return -ENODEV;
} }
found_mpu=probe_opl3sa_mpu(&cfg_mpu); found_mpu=probe_opl3sa_mpu(&cfg_mpu);
attach_opl3sa_wss(&cfg); attach_opl3sa_wss(&cfg, ports);
return 0; return 0;
} }
......
...@@ -556,19 +556,12 @@ static inline void __exit unload_opl3sa2_mpu(struct address_info *hw_config) ...@@ -556,19 +556,12 @@ static inline void __exit unload_opl3sa2_mpu(struct address_info *hw_config)
unload_mpu401(hw_config); unload_mpu401(hw_config);
} }
static void __init attach_opl3sa2_mss(struct address_info* hw_config, struct resource *ports)
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)
{ {
int initial_mixers; int initial_mixers;
initial_mixers = num_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) { if (hw_config->slots[0] != -1) {
/* Did the MSS driver install? */ /* Did the MSS driver install? */
if(num_mixers == (initial_mixers + 1)) { if(num_mixers == (initial_mixers + 1)) {
...@@ -957,6 +950,8 @@ static int __init init_opl3sa2(void) ...@@ -957,6 +950,8 @@ static int __init init_opl3sa2(void)
for (card = 0; card < max; card++) { for (card = 0; card < max; card++) {
/* If a user wants an I/O then assume they meant it */ /* If a user wants an I/O then assume they meant it */
struct resource *ports;
int base;
if (!isapnp) { if (!isapnp) {
if (io == -1 || irq == -1 || dma == -1 || if (io == -1 || irq == -1 || dma == -1 ||
...@@ -995,17 +990,30 @@ static int __init init_opl3sa2(void) ...@@ -995,17 +990,30 @@ static int __init init_opl3sa2(void)
opl3sa2_clear_slots(&opl3sa2_state[card].cfg_mpu); opl3sa2_clear_slots(&opl3sa2_state[card].cfg_mpu);
} }
/* FIXME: leak */
if (probe_opl3sa2(&opl3sa2_state[card].cfg, card)) if (probe_opl3sa2(&opl3sa2_state[card].cfg, card))
return -ENODEV; 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 * If one or more cards are already registered, don't
* return an error but print a warning. Note, this * return an error but print a warning. Note, this
* should never really happen unless the hardware or * should never really happen unless the hardware or
* ISA PnP screwed up. * ISA PnP screwed up.
*/ */
release_region(base + 4, 4);
failed2:
release_region(base, 4);
failed:
release_region(opl3sa2_state[card].cfg.io_base, 2); release_region(opl3sa2_state[card].cfg.io_base, 2);
if (opl3sa2_cards_num) { if (opl3sa2_cards_num) {
...@@ -1021,7 +1029,7 @@ static int __init init_opl3sa2(void) ...@@ -1021,7 +1029,7 @@ static int __init init_opl3sa2(void)
attach_opl3sa2(&opl3sa2_state[card].cfg, card); attach_opl3sa2(&opl3sa2_state[card].cfg, card);
conf_printf(opl3sa2_state[card].chipset_name, &opl3sa2_state[card].cfg); conf_printf(opl3sa2_state[card].chipset_name, &opl3sa2_state[card].cfg);
attach_opl3sa2_mixer(&opl3sa2_state[card].cfg, card); 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 =) */ /* ewww =) */
opl3sa2_state[card].card = card; opl3sa2_state[card].card = card;
......
...@@ -1039,14 +1039,20 @@ static coproc_operations pss_coproc_operations = ...@@ -1039,14 +1039,20 @@ static coproc_operations pss_coproc_operations =
static int __init probe_pss_mss(struct address_info *hw_config) static int __init probe_pss_mss(struct address_info *hw_config)
{ {
volatile int timeout; volatile int timeout;
struct resource *ports;
int my_mix = -999; /* gcc shut up */ int my_mix = -999; /* gcc shut up */
if (!pss_initialized) if (!pss_initialized)
return 0; 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"); printk(KERN_ERR "PSS: WSS I/O port conflicts.\n");
release_region(hw_config->io_base, 4);
return 0; return 0;
} }
if (!set_io_base(devc, CONF_WSS, hw_config->io_base)) { 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) ...@@ -1077,7 +1083,7 @@ static int __init probe_pss_mss(struct address_info *hw_config)
(timeout < 100000); timeout++) (timeout < 100000); timeout++)
; ;
if (!probe_ms_sound(hw_config)) if (!probe_ms_sound(hw_config, ports))
goto fail; goto fail;
devc->ad_mixer_dev = NO_WSS_MIXER; devc->ad_mixer_dev = NO_WSS_MIXER;
...@@ -1094,7 +1100,7 @@ static int __init probe_pss_mss(struct address_info *hw_config) ...@@ -1094,7 +1100,7 @@ static int __init probe_pss_mss(struct address_info *hw_config)
} }
} }
pss_mixer_reset(devc); 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) if (hw_config->slots[0] != -1)
{ {
...@@ -1108,6 +1114,8 @@ static int __init probe_pss_mss(struct address_info *hw_config) ...@@ -1108,6 +1114,8 @@ static int __init probe_pss_mss(struct address_info *hw_config)
} }
return 1; return 1;
fail: fail:
release_region(hw_config->io_base + 4, 4);
release_region(hw_config->io_base, 4);
return 0; return 0;
} }
......
...@@ -86,20 +86,30 @@ static int __init sb_cmd( int base, unsigned char val ) ...@@ -86,20 +86,30 @@ static int __init sb_cmd( int base, unsigned char val )
static int __init probe_sgalaxy( struct address_info *ai ) static int __init probe_sgalaxy( struct address_info *ai )
{ {
struct resource *ports;
int n; 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); printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base);
return 0; 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")) { if (!request_region( ai->ai_sgbase, 0x10, "SoundGalaxy SB")) {
printk(KERN_ERR "sgalaxy: SB IO port 0x%03x not available\n", ai->ai_sgbase); 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; return 0;
} }
if ( ad1848_detect( ai->io_base+4, NULL, ai->osp ) ) if (ad1848_detect(ports, NULL, ai->osp))
goto out; goto out; /* The card is already active, check irq etc... */
/* switch to MSS/WSS mode */ /* switch to MSS/WSS mode */
...@@ -111,12 +121,14 @@ static int __init probe_sgalaxy( struct address_info *ai ) ...@@ -111,12 +121,14 @@ static int __init probe_sgalaxy( struct address_info *ai )
sleep( HZ/10 ); sleep( HZ/10 );
out: 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); release_region(ai->ai_sgbase, 0x10);
return 0; return 0;
} }
attach_ms_sound(ai, THIS_MODULE); attach_ms_sound(ai, ports, THIS_MODULE);
n=ai->slots[0]; n=ai->slots[0];
if (n!=-1 && audio_devs[n]->mixer_dev != -1 ) { if (n!=-1 && audio_devs[n]->mixer_dev != -1 ) {
......
...@@ -1268,6 +1268,7 @@ static int __init init_ss_ms_sound(struct address_info *hw_config) ...@@ -1268,6 +1268,7 @@ static int __init init_ss_ms_sound(struct address_info *hw_config)
{ {
int i, irq_bits = 0xff; int i, irq_bits = 0xff;
int ad_flags = 0; int ad_flags = 0;
struct resource *ports;
if (devc->failed) if (devc->failed)
{ {
...@@ -1296,8 +1297,17 @@ static int __init init_ss_ms_sound(struct address_info *hw_config) ...@@ -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) */ ad_flags = 0x12345677; /* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */
else if (sscape_is_pnp) else if (sscape_is_pnp)
ad_flags = 0x87654321; /* Tell that we have a soundscape pnp with 1845 chip */ 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; 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*/ if (!sscape_is_pnp) /*pnp is already setup*/
{ {
...@@ -1322,7 +1332,7 @@ static int __init init_ss_ms_sound(struct address_info *hw_config) ...@@ -1322,7 +1332,7 @@ static int __init init_ss_ms_sound(struct address_info *hw_config)
hw_config->slots[0] = ad1848_init( hw_config->slots[0] = ad1848_init(
sscape_is_pnp ? "SoundScape" : "SoundScape PNP", sscape_is_pnp ? "SoundScape" : "SoundScape PNP",
hw_config->io_base, ports,
hw_config->irq, hw_config->irq,
hw_config->dma, hw_config->dma,
hw_config->dma, hw_config->dma,
......
...@@ -125,6 +125,7 @@ static int __init init_trix_wss(struct address_info *hw_config) ...@@ -125,6 +125,7 @@ static int __init init_trix_wss(struct address_info *hw_config)
static unsigned char dma_bits[4] = { static unsigned char dma_bits[4] = {
1, 2, 0, 3 1, 2, 0, 3
}; };
struct resource *ports;
int config_port = hw_config->io_base + 0; int config_port = hw_config->io_base + 0;
int dma1 = hw_config->dma, dma2 = hw_config->dma2; int dma1 = hw_config->dma, dma2 = hw_config->dma2;
int old_num_mixers = num_mixers; int old_num_mixers = num_mixers;
...@@ -175,14 +176,15 @@ static int __init init_trix_wss(struct address_info *hw_config) ...@@ -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) * system returns 0x04 while some cards (AudioTrix Pro for example)
* return 0x00. * 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); printk(KERN_ERR "AudioTrix: MSS I/O port conflict (%x)\n", hw_config->io_base);
return 0; return 0;
} }
if (!request_region(hw_config->io_base, 4, "MSS config")) { 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); 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; return 0;
} }
...@@ -212,7 +214,7 @@ static int __init init_trix_wss(struct address_info *hw_config) ...@@ -212,7 +214,7 @@ static int __init init_trix_wss(struct address_info *hw_config)
goto fail; goto fail;
} }
ret = ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp); ret = ad1848_detect(ports, NULL, hw_config->osp);
if (!ret) if (!ret)
goto fail; goto fail;
...@@ -243,7 +245,7 @@ static int __init init_trix_wss(struct address_info *hw_config) ...@@ -243,7 +245,7 @@ static int __init init_trix_wss(struct address_info *hw_config)
outb((bits), config_port); /* Write IRQ+DMA setup */ 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, hw_config->irq,
dma1, dma1,
dma2, dma2,
...@@ -262,6 +264,7 @@ static int __init init_trix_wss(struct address_info *hw_config) ...@@ -262,6 +264,7 @@ static int __init init_trix_wss(struct address_info *hw_config)
fail: fail:
release_region(hw_config->io_base, 4); release_region(hw_config->io_base, 4);
release_region(hw_config->io_base + 4, 4);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment