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)
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;
......
......@@ -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);
......@@ -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;
}
......
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);
......@@ -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;
......
......@@ -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
......
......@@ -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 @@ static int __init probe_mad16(struct address_info *hw_config)
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 @@ static int __init probe_mad16(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;
}
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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 ) {
......
......@@ -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,
......
......@@ -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;
}
......
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