int i, val, ret;
unsigned char reg_mask;
int timeout;
+ struct resource *ports;
struct {
unsigned short deviceid;
char *devicename;
s->iomidi = 0;
goto skip_mpu;
}
+ ports = request_region(s->iomidi, 2, "mpu401");
+ if (!ports)
+ goto skip_mpu;
/* disable MPU-401 */
maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x04, 0);
s->mpu_data.name = "cmpci mpu";
s->mpu_data.io_base = s->iomidi;
s->mpu_data.irq = -s->irq; // tell mpu401 to share irq
- if (probe_mpu401(&s->mpu_data)) {
+ if (probe_mpu401(&s->mpu_data, ports)) {
+ release_region(s->iomidi, 2);
s->iomidi = 0;
goto skip_mpu;
}
else
break;
}
- if (!probe_mpu401(&s->mpu_data)) {
+ if (!probe_mpu401(&s->mpu_data, ports)) {
+ release_region(s->iomidi, 2);
s->iomidi = 0;
maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x04);
} else {
static int __init probe_maui(struct address_info *hw_config)
{
+ struct resource *ports;
int this_dev;
int i;
int tmp1, tmp2, ret;
- if (check_region(hw_config->io_base, 2))
+ ports = request_region(hw_config->io_base, 2, "mpu401");
+ if (!ports)
return 0;
if (!request_region(hw_config->io_base + 2, 6, "Maui"))
printk(KERN_DEBUG "Available DRAM %dk\n", tmp1 / 1024);
for (i = 0; i < 1000; i++)
- if (probe_mpu401(hw_config))
+ if (probe_mpu401(hw_config, ports))
break;
- ret = probe_mpu401(hw_config);
+ ret = probe_mpu401(hw_config, ports);
if (!ret)
goto out3;
out2:
release_region(hw_config->io_base + 2, 6);
out:
+ release_region(hw_config->io_base, 2);
return 0;
}
spin_unlock_irqrestore(&devc->lock,flags);
}
- if (!request_region(hw_config->io_base, 2, "mpu401"))
- {
- ret = -ENOMEM;
- goto out_irq;
- }
-
if (devc->version != 0)
if (mpu_cmd(m, 0xC5, 0) >= 0) /* Set timebase OK */
if (mpu_cmd(m, 0xE0, 120) >= 0) /* Set tempo OK */
{
printk(KERN_ERR "mpu401: Can't allocate memory\n");
ret = -ENOMEM;
- goto out_resource;
+ goto out_irq;
}
if (!(devc->capabilities & MPU_CAP_INTLG)) /* No intelligent mode */
{
return 0;
-out_resource:
- release_region(hw_config->io_base, 2);
out_irq:
free_irq(devc->irq, (void *)m);
out_mididev:
sound_unload_mididev(m);
out_err:
+ release_region(hw_config->io_base, 2);
return ret;
}
}
-int probe_mpu401(struct address_info *hw_config)
+int probe_mpu401(struct address_info *hw_config, struct resource *ports)
{
int ok = 0;
struct mpu_config tmp_devc;
- if (check_region(hw_config->io_base, 2))
- {
- printk(KERN_ERR "mpu401: I/O port %x already in use\n\n", hw_config->io_base);
- return 0;
- }
tmp_devc.base = hw_config->io_base;
tmp_devc.irq = hw_config->irq;
tmp_devc.initialized = 0;
/* Can be loaded either for module use or to provide functions
to others */
if (io != -1 && irq != -1) {
+ struct resource *ports;
cfg.irq = irq;
cfg.io_base = io;
- if (probe_mpu401(&cfg) == 0)
+ ports = request_region(io, 2, "mpu401");
+ if (!ports)
+ return -EBUSY;
+ if (probe_mpu401(&cfg, ports) == 0) {
+ release_region(io, 2);
return -ENODEV;
+ }
if ((ret = attach_mpu401(&cfg, THIS_MODULE)))
return ret;
}
irqreturn_t uart401intr (int irq, void *dev_id, struct pt_regs * dummy);
/* From mpu401.c */
-int probe_mpu401(struct address_info *hw_config);
+int probe_mpu401(struct address_info *hw_config, struct resource *ports);
int attach_mpu401(struct address_info * hw_config, struct module *owner);
void unload_mpu401(struct address_info *hw_info);
* Component probe, attach, unload functions
*/
-static inline int __init probe_opl3sa2_mpu(struct address_info* hw_config)
-{
- return probe_mpu401(hw_config);
-}
-
-
-static inline int __init attach_opl3sa2_mpu(struct address_info* hw_config)
-{
- return attach_mpu401(hw_config, THIS_MODULE);
-}
-
-
static inline void __exit unload_opl3sa2_mpu(struct address_info *hw_config)
{
unload_mpu401(hw_config);
}
+
static void __init attach_opl3sa2_mss(struct address_info* hw_config, struct resource *ports)
{
int initial_mixers;
/* Attach MPU if we've been asked to do so, failure isn't fatal */
if (opl3sa2_state[card].cfg_mpu.io_base != -1) {
- if (probe_opl3sa2_mpu(&opl3sa2_state[card].cfg_mpu)) {
- if (attach_opl3sa2_mpu(&opl3sa2_state[card].cfg_mpu)) {
- printk(KERN_ERR PFX "failed to attach MPU401\n");
- opl3sa2_state[card].cfg_mpu.slots[1] = -1;
- }
+ int base = opl3sa2_state[card].cfg_mpu.io_base;
+ struct resource *ports;
+ ports = request_region(base, 2, "mpu401");
+ if (!ports)
+ goto out;
+ if (!probe_mpu401(&opl3sa2_state[card].cfg_mpu, ports)) {
+ release_region(base, 2);
+ goto out;
+ }
+ if (attach_mpu401(&opl3sa2_state[card].cfg_mpu, THIS_MODULE)) {
+ printk(KERN_ERR PFX "failed to attach MPU401\n");
+ opl3sa2_state[card].cfg_mpu.slots[1] = -1;
}
}
}
+out:
if (isapnp) {
printk(KERN_NOTICE PFX "%d PnP card(s) found.\n", opl3sa2_cards_num);
}
static int __init probe_pss_mpu(struct address_info *hw_config)
{
+ struct resource *ports;
int timeout;
if (!pss_initialized)
return 0;
- if (check_region(hw_config->io_base, 2))
- {
+ ports = request_region(hw_config->io_base, 2, "mpu401");
+
+ if (!ports) {
printk(KERN_ERR "PSS: MPU I/O port conflict\n");
return 0;
}
break; /* No more input */
}
- if (!probe_mpu401(hw_config))
+ if (!probe_mpu401(hw_config, ports))
goto fail;
attach_mpu401(hw_config, THIS_MODULE); /* Slot 1 */
midi_devs[hw_config->slots[1]]->coproc = &pss_coproc_operations;
return 1;
fail:
+ release_region(hw_config->io_base, 2);
return 0;
}
#if defined(CONFIG_SOUND_MPU401)
if (devc->model == MDL_ESS)
{
- if (check_region(hw_config->io_base, 2))
- {
+ struct resource *ports;
+ ports = request_region(hw_config->io_base, 2, "mpu401");
+ if (!ports) {
printk(KERN_ERR "sbmpu: I/O port conflict (%x)\n", hw_config->io_base);
return 0;
}
- if (!ess_midi_init(devc, hw_config))
+ if (!ess_midi_init(devc, hw_config)) {
+ release_region(hw_config->io_base, 2);
return 0;
+ }
hw_config->name = "ESS1xxx MPU";
devc->midi_irq_cookie = NULL;
- if (!probe_mpu401(hw_config))
+ if (!probe_mpu401(hw_config, ports)) {
+ release_region(hw_config->io_base, 2);
return 0;
+ }
attach_mpu401(hw_config, owner);
if (last_sb->irq == -hw_config->irq)
last_sb->midi_irq_cookie=(void *)hw_config->slots[1];
&adev_info
};
+static struct resource *sscape_ports;
static int sscape_is_pnp;
static void __init attach_sscape(struct address_info *hw_config)
int i, irq_bits = 0xff;
- request_region(devc->base + 2, 6, "SoundScape");
if (old_hardware)
{
valid_interrupts = valid_interrupts_old;
if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff))
{
printk(KERN_ERR "Invalid IRQ%d\n", hw_config->irq);
+ release_region(devc->base, 2);
+ release_region(devc->base + 2, 6);
if (sscape_is_pnp)
release_region(devc->codec, 2);
return;
}
#endif
- if (probe_mpu401(hw_config))
+ if (probe_mpu401(hw_config, sscape_ports))
hw_config->always_detect = 1;
hw_config->name = "SoundScape";
DDB(printk("Entered Soundscape detect_ga(%x)\n", devc->base));
- if (check_region(devc->base, 8))
- return 0;
-
/*
* First check that the address register of "ODIE" is
* there and that it has exactly 4 writable bits.
DDB(printk("Entered detect_sscape_pnp(%x)\n", devc->base));
- if (check_region(devc->base, 8)) {
- printk(KERN_ERR "detect_sscape_pnp: port %x is not free\n", devc->base);
- return 0;
- }
-
if (!request_region(devc->codec, 2, "sscape codec")) {
printk(KERN_ERR "detect_sscape_pnp: port %x is not free\n", devc->codec);
return 0;
#endif
devc->failed = 1;
+ sscape_ports = request_region(devc->base, 2, "mpu401");
+ if (!sscape_ports)
+ return 0;
+
+ if (!request_region(devc->base + 2, 6, "SoundScape")) {
+ release_region(devc->base, 2);
+ return 0;
+ }
+
if (!detect_ga(devc)) {
if (detect_sscape_pnp(devc))
return 1;
+ release_region(devc->base, 2);
+ release_region(devc->base + 2, 6);
return 0;
}