static int nonstandard_microcode;
static int pss_cdrom_port = -1; /* Parameter for the PSS cdrom port */
static int pss_enable_joystick; /* Parameter for enabling the joystick */
+static coproc_operations pss_coproc_operations;
static void pss_write(pss_confdata *devc, int data)
{
printk(KERN_WARNING "PSS: DSP Command (%04x) Timeout.\n", data);
}
-int __init probe_pss(struct address_info *hw_config)
+static int __init probe_pss(struct address_info *hw_config)
{
unsigned short id;
int irq, dma;
if (devc->base != 0x230 && devc->base != 0x250) /* Some cards use these */
return 0;
- if (check_region(devc->base, 0x19 /*16*/)) {
+ if (!request_region(devc->base, 0x10, "PSS mixer, SB emulation")) {
printk(KERN_ERR "PSS: I/O port conflict\n");
return 0;
}
id = inw(REG(PSS_ID));
if ((id >> 8) != 'E') {
printk(KERN_ERR "No PSS signature detected at 0x%x (0x%x)\n", devc->base, id);
+ release_region(devc->base, 0x10);
+ return 0;
+ }
+ if (!request_region(devc->base + 0x10, 0x9, "PSS config")) {
+ printk(KERN_ERR "PSS: I/O port conflict\n");
+ release_region(devc->base, 0x10);
return 0;
}
return 1;
}
}
-void __init attach_pss(struct address_info *hw_config)
+static int __init attach_pss(struct address_info *hw_config)
{
unsigned short id;
char tmp[100];
devc->ad_mixer_dev = NO_WSS_MIXER;
if (!probe_pss(hw_config))
- return;
-
- request_region(hw_config->io_base, 0x10, "PSS mixer, SB emulation");
- request_region(hw_config->io_base + 0x10, 0x9, "PSS config");
+ return 0;
id = inw(REG(PSS_ID)) & 0x00ff;
if (sound_alloc_dma(hw_config->dma, "PSS"))
{
printk("pss.c: Can't allocate DMA channel.\n");
- return;
+ release_region(hw_config->io_base, 0x10);
+ release_region(hw_config->io_base+0x10, 0x9);
+ return 0;
}
if (!set_irq(devc, CONF_PSS, devc->irq))
{
printk("PSS: IRQ allocation error.\n");
- return;
+ release_region(hw_config->io_base, 0x10);
+ release_region(hw_config->io_base+0x10, 0x9);
+ return 0;
}
if (!set_dma(devc, CONF_PSS, devc->dma))
{
printk(KERN_ERR "PSS: DMA allocation error\n");
- return;
+ release_region(hw_config->io_base, 0x10);
+ release_region(hw_config->io_base+0x10, 0x9);
+ return 0;
}
#endif
pss_initialized = 1;
sprintf(tmp, "ECHO-PSS Rev. %d", id);
conf_printf(tmp, hw_config);
+ return 1;
}
-int __init probe_pss_mpu(struct address_info *hw_config)
+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;
}
- if (!set_io_base(devc, CONF_MIDI, hw_config->io_base))
- {
- printk(KERN_ERR "PSS: MIDI base could not be set.\n");
- return 0;
+ if (!set_io_base(devc, CONF_MIDI, hw_config->io_base)) {
+ printk(KERN_ERR "PSS: MIDI base could not be set.\n");
+ goto fail;
}
- if (!set_irq(devc, CONF_MIDI, hw_config->irq))
- {
- printk(KERN_ERR "PSS: MIDI IRQ allocation error.\n");
- return 0;
+ if (!set_irq(devc, CONF_MIDI, hw_config->irq)) {
+ printk(KERN_ERR "PSS: MIDI IRQ allocation error.\n");
+ goto fail;
}
- if (!pss_synthLen)
- {
+ if (!pss_synthLen) {
printk(KERN_ERR "PSS: Can't enable MPU. MIDI synth microcode not available.\n");
- return 0;
+ goto fail;
}
- if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
- {
+ if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST)) {
printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
- return 0;
+ goto fail;
}
/*
break; /* No more input */
}
- return probe_mpu401(hw_config);
+ if (!probe_mpu401(hw_config, ports))
+ goto fail;
+
+ attach_mpu401(hw_config, THIS_MODULE); /* Slot 1 */
+ if (hw_config->slots[1] != -1) /* The MPU driver installed itself */
+ midi_devs[hw_config->slots[1]]->coproc = &pss_coproc_operations;
+ return 1;
+fail:
+ release_region(hw_config->io_base, 2);
+ return 0;
}
static int pss_coproc_open(void *dev_info, int sub_device)
&pss_data
};
-static void __init attach_pss_mpu(struct address_info *hw_config)
-{
- attach_mpu401(hw_config, THIS_MODULE); /* Slot 1 */
- if (hw_config->slots[1] != -1) /* The MPU driver installed itself */
- midi_devs[hw_config->slots[1]]->coproc = &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))
- {
- printk(KERN_ERR "PSS: WSS I/O port conflicts.\n");
- return 0;
+ if (!request_region(hw_config->io_base, 4, "WSS config")) {
+ printk(KERN_ERR "PSS: WSS I/O port conflicts.\n");
+ return 0;
}
- if (!set_io_base(devc, CONF_WSS, hw_config->io_base))
- {
- printk("PSS: WSS base not settable.\n");
+ 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_irq(devc, CONF_WSS, hw_config->irq))
- {
+ if (!set_io_base(devc, CONF_WSS, hw_config->io_base)) {
+ printk("PSS: WSS base not settable.\n");
+ goto fail;
+ }
+ if (!set_irq(devc, CONF_WSS, hw_config->irq)) {
printk("PSS: WSS IRQ allocation error.\n");
- return 0;
+ goto fail;
}
- if (!set_dma(devc, CONF_WSS, hw_config->dma))
- {
+ if (!set_dma(devc, CONF_WSS, hw_config->dma)) {
printk(KERN_ERR "PSS: WSS DMA allocation error\n");
- return 0;
+ goto fail;
}
/*
* For some reason the card returns 0xff in the WSS status register
(timeout < 100000); timeout++)
;
- return probe_ms_sound(hw_config);
-}
+ if (!probe_ms_sound(hw_config, ports))
+ goto fail;
-static void __init attach_pss_mss(struct address_info *hw_config)
-{
- int my_mix = -999; /* gcc shut up */
-
devc->ad_mixer_dev = NO_WSS_MIXER;
if (pss_mixer)
{
devc)) < 0)
{
printk(KERN_ERR "Could not install PSS mixer\n");
- return;
+ goto fail;
}
}
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)
{
devc->ad_mixer_dev = audio_devs[hw_config->slots[0]]->mixer_dev;
}
}
+ return 1;
+fail:
+ release_region(hw_config->io_base + 4, 4);
+ release_region(hw_config->io_base, 4);
+ return 0;
}
static inline void __exit unload_pss(struct address_info *hw_config)
printk(KERN_INFO "PSS: loading in no sound mode.\n");
disable_all_emulations();
configure_nonsound_components();
+ release_region(pss_io, 0x10);
+ release_region(pss_io + 0x10, 0x9);
return 0;
}
fw_load = 1;
pss_synthLen = mod_firmware_load(pss_firmware, (void *) &pss_synth);
}
- if (!probe_pss(&cfg))
+ if (!attach_pss(&cfg))
return -ENODEV;
- attach_pss(&cfg);
/*
* Attach stuff
*/
- if (probe_pss_mpu(&cfg_mpu)) {
+ if (probe_pss_mpu(&cfg_mpu))
pssmpu = 1;
- attach_pss_mpu(&cfg_mpu);
- }
- if (probe_pss_mss(&cfg2)) {
+
+ if (probe_pss_mss(&cfg2))
pssmss = 1;
- attach_pss_mss(&cfg2);
- }
return 0;
}