summaryrefslogtreecommitdiffstats
path: root/drivers/sound
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-03-18 17:17:51 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-03-18 17:17:51 +0000
commitf1382dc4850bb459d24a81c6cb0ef93ea7bd4a79 (patch)
tree225271a3d5dcd4e9dea5ee393556abd754c964b1 /drivers/sound
parent135b00fc2e90e605ac2a96b20b0ebd93851a3f89 (diff)
o Merge with Linux 2.1.90.
o Divide L1 cache sizes by 1024 before printing, makes the numbers a bit more credible ...
Diffstat (limited to 'drivers/sound')
-rw-r--r--drivers/sound/Config.in2
-rw-r--r--drivers/sound/Makefile42
-rw-r--r--drivers/sound/ad1848.c113
-rw-r--r--drivers/sound/audio.c1
-rw-r--r--drivers/sound/bin2hex.c19
-rw-r--r--drivers/sound/cs4232.c17
-rw-r--r--drivers/sound/dev_table.c3
-rw-r--r--drivers/sound/dmabuf.c35
-rw-r--r--drivers/sound/gus_card.c11
-rw-r--r--drivers/sound/hex2hex.c17
-rw-r--r--drivers/sound/maui.c25
-rw-r--r--drivers/sound/midibuf.c1
-rw-r--r--drivers/sound/mpu401.c1778
-rw-r--r--drivers/sound/opl3.c78
-rw-r--r--drivers/sound/pas2_card.c4
-rw-r--r--drivers/sound/pss.c797
-rw-r--r--drivers/sound/sb_audio.c16
-rw-r--r--drivers/sound/sb_card.c22
-rw-r--r--drivers/sound/sb_common.c32
-rw-r--r--drivers/sound/sound_calls.h6
-rw-r--r--drivers/sound/sound_timer.c8
-rw-r--r--drivers/sound/soundcard.c22
-rw-r--r--drivers/sound/uart401.c337
-rw-r--r--drivers/sound/uart6850.c9
-rw-r--r--drivers/sound/v_midi.c11
25 files changed, 1652 insertions, 1754 deletions
diff --git a/drivers/sound/Config.in b/drivers/sound/Config.in
index 7ef5f8dd4..d4678da82 100644
--- a/drivers/sound/Config.in
+++ b/drivers/sound/Config.in
@@ -6,6 +6,8 @@ fi
dep_tristate '100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' CONFIG_SB $CONFIG_SOUND
if [ "$CONFIG_SB" = "y" ]; then
+ bool 'Is the card a Soundman Games ?' CONFIG_SM_GAMES
+ bool 'Are you using the IBM Mwave "emulation" of SB ?' CONFIG_SB_MWAVE
hex 'I/O base for SB Check from manual of the card' CONFIG_SB_BASE 220
int 'Sound Blaster IRQ Check from manual of the card' CONFIG_SB_IRQ 7
int 'Sound Blaster DMA 0, 1 or 3' CONFIG_SB_DMA 1
diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile
index e8ec0b12d..6b09e336b 100644
--- a/drivers/sound/Makefile
+++ b/drivers/sound/Makefile
@@ -117,22 +117,6 @@ else
endif
endif
-ifeq ($(CONFIG_MPU401),y)
-LX_OBJS += mpu401.o
-else
- ifeq ($(CONFIG_MPU401),m)
- MX_OBJS += mpu401.o
- else
- ifeq ($(CONFIG_MPU_EMU),y)
- LX_OBJS += mpu401.o
- else
- ifeq ($(CONFIG_MPU_EMU),m)
- MX_OBJS += mpu401.o
- endif
- endif
- endif
-endif
-
ifeq ($(CONFIG_UART401),y)
LX_OBJS += uart401.o
else
@@ -159,9 +143,31 @@ endif
ifeq ($(CONFIG_SSCAPE),y)
L_OBJS += sscape.o
+LX_OBJS += ad1848.o
+CONFIG_MPU401 = y
else
ifeq ($(CONFIG_SSCAPE),m)
M_OBJS += sscape.o
+ MX_OBJS += ad1848.o
+ ifneq ($(CONFIG_MPU401),y)
+ CONFIG_MPU401 = m
+ endif
+ endif
+endif
+
+ifeq ($(CONFIG_MPU401),y)
+LX_OBJS += mpu401.o
+else
+ ifeq ($(CONFIG_MPU401),m)
+ MX_OBJS += mpu401.o
+ else
+ ifeq ($(CONFIG_MPU_EMU),y)
+ LX_OBJS += mpu401.o
+ else
+ ifeq ($(CONFIG_MPU_EMU),m)
+ MX_OBJS += mpu401.o
+ endif
+ endif
endif
endif
@@ -265,7 +271,7 @@ CONFIG_MAUI_BOOT_FILE := $(patsubst "%", %, $(CONFIG_MAUI_BOOT_FILE))
maui.o: maui_boot.h
maui_boot.h: $(CONFIG_MAUI_BOOT_FILE) bin2hex
- bin2hex maui_os < "$(CONFIG_MAUI_BOOT_FILE)" > $@
+ bin2hex -i maui_os < "$(CONFIG_MAUI_BOOT_FILE)" > $@
@ ( \
echo 'ifeq ($(strip $(CONFIG_MAUI_BOOT_FILE)),$$(strip $$(CONFIG_MAUI_BOOT_FILE)))'; \
echo 'FILES_BOOT_UP_TO_DATE += $@'; \
@@ -297,7 +303,7 @@ CONFIG_TRIX_BOOT_FILE := $(patsubst "%", %, $(CONFIG_TRIX_BOOT_FILE))
trix.o: trix_boot.h
trix_boot.h: $(CONFIG_TRIX_BOOT_FILE) hex2hex
- hex2hex trix_boot < "$(CONFIG_TRIX_BOOT_FILE)" > $@
+ hex2hex -i trix_boot < "$(CONFIG_TRIX_BOOT_FILE)" > $@
@ ( \
echo 'ifeq ($(strip $(CONFIG_TRIX_BOOT_FILE)),$$(strip $$(CONFIG_TRIX_BOOT_FILE)))'; \
echo 'FILES_BOOT_UP_TO_DATE += $@'; \
diff --git a/drivers/sound/ad1848.c b/drivers/sound/ad1848.c
index 6fdec35ec..d839ed208 100644
--- a/drivers/sound/ad1848.c
+++ b/drivers/sound/ad1848.c
@@ -23,6 +23,12 @@
*/
/*
* Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ * general sleep/wakeup clean up.
+ * Alan Cox : reformatted. Fixed SMP bugs. Moved to kernel alloc/free
+ * of irqs. Use dev_id.
+ *
+ * Status:
+ * Tested. Believed fully functional.
*/
#include <linux/config.h>
@@ -144,9 +150,9 @@ static void ad1848_tmr_reprogram(int dev);
static int ad_read(ad1848_info * devc, int reg)
{
- unsigned long flags;
- int x;
- int timeout = 900000;
+ unsigned long flags;
+ int x;
+ int timeout = 900000;
while (timeout > 0 && inb(devc->base) == 0x80) /*Are we initializing */
timeout--;
@@ -163,11 +169,10 @@ static int ad_read(ad1848_info * devc, int reg)
static void ad_write(ad1848_info * devc, int reg, int data)
{
- unsigned long flags;
- int timeout = 900000;
+ unsigned long flags;
+ int timeout = 900000;
- while (timeout > 0 &&
- inb(devc->base) == 0x80) /*Are we initializing */
+ while (timeout > 0 && inb(devc->base) == 0x80) /* Are we initializing */
timeout--;
save_flags(flags);
@@ -180,7 +185,7 @@ static void ad_write(ad1848_info * devc, int reg, int data)
static void wait_for_calibration(ad1848_info * devc)
{
- int timeout = 0;
+ int timeout = 0;
/*
* Wait until the auto calibration process has finished.
@@ -1751,7 +1756,11 @@ int ad1848_init(char *name, int io_base, int irq, int dma_playback, int dma_capt
else
devc->audio_flags |= DMA_DUPLEX;
}
-
+
+ portc = (ad1848_port_info *) kmalloc(sizeof(ad1848_port_info), GFP_KERNEL);
+ if(portc==NULL)
+ return -1;
+
if ((my_dev = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
dev_name,
&ad1848_audio_driver,
@@ -1762,12 +1771,11 @@ int ad1848_init(char *name, int io_base, int irq, int dma_playback, int dma_capt
dma_playback,
dma_capture)) < 0)
{
+ kfree(portc);
+ portc=NULL;
return -1;
}
- portc = (ad1848_port_info *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(ad1848_port_info)));
- sound_mem_sizes[sound_nblocks] = sizeof(ad1848_port_info);
- if (sound_nblocks < 1024)
- sound_nblocks++;;
+
audio_devs[my_dev]->portc = portc;
memset((char *) portc, 0, sizeof(*portc));
@@ -1777,23 +1785,21 @@ int ad1848_init(char *name, int io_base, int irq, int dma_playback, int dma_capt
if (irq > 0)
{
- irq2dev[irq] = devc->dev_no = my_dev;
- if (snd_set_irq_handler(devc->irq, adintr,
- devc->name,
- NULL) < 0)
+ devc->dev_no = my_dev;
+ if (request_irq(devc->irq, adintr, 0, devc->name, (void *)my_dev) < 0)
{
- printk(KERN_WARNING "ad1848: IRQ in use\n");
+ printk(KERN_WARNING "ad1848: Unable to allocate IRQ\n");
}
if (devc->model != MD_1848 && devc->model != MD_C930)
{
- int x;
- unsigned char tmp = ad_read(devc, 16);
+ int x;
+ unsigned char tmp = ad_read(devc, 16);
devc->timer_ticks = 0;
ad_write(devc, 21, 0x00); /* Timer MSB */
ad_write(devc, 20, 0x10); /* Timer LSB */
-
+#ifndef __SMP__
ad_write(devc, 16, tmp | 0x40); /* Enable timer */
for (x = 0; x < 100000 && devc->timer_ticks == 0; x++);
ad_write(devc, 16, tmp & ~0x40); /* Disable timer */
@@ -1805,6 +1811,9 @@ int ad1848_init(char *name, int io_base, int irq, int dma_playback, int dma_capt
DDB(printk("Interrupt test OK\n"));
devc->irq_ok = 1;
}
+#else
+ devc->irq_ok=1;
+#endif
}
else
devc->irq_ok = 1; /* Couldn't test. assume it's OK */
@@ -1840,7 +1849,7 @@ int ad1848_init(char *name, int io_base, int irq, int dma_playback, int dma_capt
void ad1848_control(int cmd, int arg)
{
- ad1848_info *devc;
+ ad1848_info *devc;
if (nr_ad1848_devs < 1)
return;
@@ -1850,7 +1859,7 @@ void ad1848_control(int cmd, int arg)
switch (cmd)
{
case AD1848_SET_XTAL: /* Change clock frequency of AD1845 (only ) */
- if (devc->model != MD_1845)
+ if (devc->model != MD_1845)
return;
ad_enter_MCE(devc);
ad_write(devc, 29, (ad_read(devc, 29) & 0x1f) | (arg << 5));
@@ -1859,8 +1868,8 @@ void ad1848_control(int cmd, int arg)
case AD1848_MIXER_REROUTE:
{
- int o = (arg >> 8) & 0xff;
- int n = arg & 0xff;
+ int o = (arg >> 8) & 0xff;
+ int n = arg & 0xff;
if (n == SOUND_MIXER_NONE)
{ /* Just hide this control */
@@ -1906,12 +1915,14 @@ void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int
if (devc != NULL)
{
+ if(audio_devs[dev]->portc!=NULL)
+ kfree(audio_devs[dev]->portc);
release_region(devc->base, 4);
if (!share_dma)
{
if (irq > 0)
- snd_release_irq(devc->irq);
+ free_irq(devc->irq, NULL);
sound_free_dma(audio_devs[dev]->dmap_out->dma);
@@ -1926,35 +1937,15 @@ void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int
void adintr(int irq, void *dev_id, struct pt_regs *dummy)
{
- unsigned char status;
- ad1848_info *devc;
- int dev;
- int alt_stat = 0xff;
- unsigned char c930_stat = 0;
- int cnt = 0;
-
- if (irq < 0 || irq > 15)
- {
- dev = -1;
- }
- else
- dev = irq2dev[irq];
-
- if (dev < 0 || dev >= num_audiodevs)
- {
- for (irq = 0; irq < 17; irq++)
- if (irq2dev[irq] != -1)
- break;
-
- if (irq > 15)
- {
- /* printk("ad1848.c: Bogus interrupt %d\n", irq); */
- return;
- }
- dev = irq2dev[irq];
- devc = (ad1848_info *) audio_devs[dev]->devc;
- } else
- devc = (ad1848_info *) audio_devs[dev]->devc;
+ unsigned char status;
+ ad1848_info *devc;
+ int dev;
+ int alt_stat = 0xff;
+ unsigned char c930_stat = 0;
+ int cnt = 0;
+
+ dev = (int)dev_id;
+ devc = (ad1848_info *) audio_devs[dev]->devc;
interrupt_again: /* Jump back here if int status doesn't reset */
@@ -2542,12 +2533,12 @@ EXPORT_SYMBOL(unload_ms_sound);
#ifdef MODULE
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(dma, "i");
-MODULE_PARM(dma2, "i");
-MODULE_PARM(type, "i");
-MODULE_PARM(deskpro_xl, "i");
+MODULE_PARM(io, "i"); /* I/O for a raw AD1848 card */
+MODULE_PARM(irq, "i"); /* IRQ to use */
+MODULE_PARM(dma, "i"); /* First DMA channel */
+MODULE_PARM(dma2, "i"); /* Second DMA channel */
+MODULE_PARM(type, "i"); /* Card type */
+MODULE_PARM(deskpro_xl, "i"); /* Special magic for Deskpro XL boxen */
int io = -1;
int irq = -1;
diff --git a/drivers/sound/audio.c b/drivers/sound/audio.c
index b27b1999a..9c9ccf095 100644
--- a/drivers/sound/audio.c
+++ b/drivers/sound/audio.c
@@ -21,7 +21,6 @@
#include <linux/config.h>
#include <linux/stddef.h>
-#include <linux/kerneld.h>
#include "sound_config.h"
diff --git a/drivers/sound/bin2hex.c b/drivers/sound/bin2hex.c
index 351dd24e0..fc49c99d9 100644
--- a/drivers/sound/bin2hex.c
+++ b/drivers/sound/bin2hex.c
@@ -2,12 +2,27 @@
int main( int argc, const char * argv [] )
{
- const char * varname = argv[1];
+ const char * varname;
int i = 0;
int c;
+ int id = 0;
+ if(argv[1] && strcmp(argv[1],"-i")==0)
+ {
+ argv++;
+ argc--;
+ id=1;
+ }
+
+ if(argc==1)
+ {
+ fprintf(stderr, "bin2hex: [-i] firmware\n");
+ exit(1);
+ }
+
+ varname = argv[1];
printf( "/* automatically generated by bin2hex */\n" );
- printf( "static unsigned char %s [] =\n{\n", varname );
+ printf( "static unsigned char %s [] %s =\n{\n", varname , id?"__initdata":"");
while ( ( c = getchar( ) ) != EOF )
{
diff --git a/drivers/sound/cs4232.c b/drivers/sound/cs4232.c
index c8732dfe4..fdb5b738c 100644
--- a/drivers/sound/cs4232.c
+++ b/drivers/sound/cs4232.c
@@ -12,7 +12,14 @@
* CS4232
* CS4236
* CS4236B
+ *
+ * Note: You will need a PnP config setup to initialise some CS4232 boards
+ * anyway.
+ *
+ * Changes
+ * Alan Cox Modularisation, Basic cleanups.
*/
+
/*
* Copyright (C) by Hannu Savolainen 1993-1997
*
@@ -20,6 +27,7 @@
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
+
#include <linux/config.h>
#include <linux/module.h>
@@ -99,6 +107,8 @@ int probe_cs4232(struct address_info *hw_config)
* just one CS4232 compatible device can exist on the system. Also this
* method conflicts with possible PnP support in the OS. For this reason
* driver is just a temporary kludge.
+ *
+ * Also the Cirrus/Crystal method doesnt always work. Try ISAPnP first ;)
*/
/*
@@ -106,8 +116,8 @@ int probe_cs4232(struct address_info *hw_config)
* first time.
*/
- for (n = 0; n < 4; n++) {
-
+ for (n = 0; n < 4; n++)
+ {
/*
* Wake up the card by sending a 32 byte Crystal key to the key port.
*/
@@ -298,8 +308,7 @@ struct address_info cfg;
* loaded ready.
*/
-int
-init_module(void)
+int init_module(void)
{
if (io == -1 || irq == -1 || dma == -1 || dma2 == -1)
{
diff --git a/drivers/sound/dev_table.c b/drivers/sound/dev_table.c
index 666d7765e..7f3957bfd 100644
--- a/drivers/sound/dev_table.c
+++ b/drivers/sound/dev_table.c
@@ -148,9 +148,6 @@ void sound_unload_drivers(void)
}
}
- for (i=0;i<num_audiodevs;i++)
- DMAbuf_deinit(i);
-
if (trace_init)
printk(KERN_DEBUG "Sound unload complete\n");
}
diff --git a/drivers/sound/dmabuf.c b/drivers/sound/dmabuf.c
index 151e20449..db6a02d05 100644
--- a/drivers/sound/dmabuf.c
+++ b/drivers/sound/dmabuf.c
@@ -104,7 +104,7 @@ static int sound_alloc_dmap(struct dma_buffparms *dmap)
dmap->raw_buf_phys = virt_to_bus(start_addr);
for (i = MAP_NR(start_addr); i <= MAP_NR(end_addr); i++)
- set_bit(PG_reserved, &mem_map[i].flags);;
+ set_bit(PG_reserved, &mem_map[i].flags);
return 0;
}
@@ -115,8 +115,6 @@ static void sound_free_dmap(struct dma_buffparms *dmap)
if (dmap->raw_buf == NULL)
return;
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- return; /* Don't free mmapped buffer. Will use it next time */
for (sz = 0, size = PAGE_SIZE; size < dmap->buffsize; sz++, size <<= 1);
start_addr = (unsigned long) dmap->raw_buf;
@@ -127,6 +125,8 @@ static void sound_free_dmap(struct dma_buffparms *dmap)
free_pages((unsigned long) dmap->raw_buf, sz);
dmap->raw_buf = NULL;
+ /* Remember the buffer is deleted so we dont Oops later */
+ dmap->fragment_size = 0;
}
@@ -206,6 +206,7 @@ static void close_dmap(struct audio_operations *adev, struct dma_buffparms *dmap
dmap->dma_mode = DMODE_NONE;
dmap->flags &= ~DMA_BUSY;
disable_dma(dmap->dma);
+ sound_free_dmap(dmap);
}
@@ -832,12 +833,12 @@ int DMAbuf_move_wrpointer(int dev, int l)
dmap->user_counter += l;
dmap->flags |= DMA_DIRTY;
- if (dmap->user_counter >= dmap->max_byte_counter) {
+ if (dmap->byte_counter >= dmap->max_byte_counter) {
/* Wrap the byte counters */
- long decr = dmap->user_counter;
- dmap->user_counter = (dmap->user_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
- decr -= dmap->user_counter;
- dmap->byte_counter -= decr;
+ long decr = dmap->byte_counter;
+ dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use);
+ decr -= dmap->byte_counter;
+ dmap->user_counter -= decr;
}
end_ptr = (dmap->user_counter / dmap->fragment_size) * dmap->fragment_size;
@@ -928,7 +929,7 @@ static void do_outputintr(int dev, int dummy)
dmap->byte_counter += dmap->bytes_in_use;
if (dmap->byte_counter >= dmap->max_byte_counter) { /* Overflow */
long decr = dmap->byte_counter;
- dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
+ dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use);
decr -= dmap->byte_counter;
dmap->user_counter -= decr;
}
@@ -952,7 +953,7 @@ static void do_outputintr(int dev, int dummy)
dmap->byte_counter += dmap->bytes_in_use;
if (dmap->byte_counter >= dmap->max_byte_counter) { /* Overflow */
long decr = dmap->byte_counter;
- dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
+ dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use);
decr -= dmap->byte_counter;
dmap->user_counter -= decr;
}
@@ -1211,18 +1212,4 @@ unsigned int DMAbuf_poll(struct file * file, int dev, poll_table *wait)
return poll_input(file, dev, wait) | poll_output(file, dev, wait);
}
-void DMAbuf_deinit(int dev)
-{
- struct audio_operations *adev = audio_devs[dev];
- /* This routine is called when driver is being unloaded */
- if (!adev)
- return;
-#ifdef RUNTIME_DMA_ALLOC
- sound_free_dmap(adev->dmap_out);
-
- if (adev->flags & DMA_DUPLEX)
- sound_free_dmap(adev->dmap_in);
-#endif
-}
-
#endif
diff --git a/drivers/sound/gus_card.c b/drivers/sound/gus_card.c
index 0f4f769eb..92e6dbab6 100644
--- a/drivers/sound/gus_card.c
+++ b/drivers/sound/gus_card.c
@@ -30,7 +30,7 @@ int gus_pnp_flag = 0;
void attach_gus_card(struct address_info *hw_config)
{
- snd_set_irq_handler(hw_config->irq, gusintr, "Gravis Ultrasound", hw_config->osp);
+ snd_set_irq_handler(hw_config->irq, gusintr, "Gravis Ultrasound", hw_config->osp, hw_config);
gus_wave_init(hw_config);
@@ -101,7 +101,7 @@ void unload_gus(struct address_info *hw_config)
release_region(hw_config->io_base, 16);
release_region(hw_config->io_base + 0x100, 12); /* 0x10c-> is MAX */
- snd_release_irq(hw_config->irq);
+ snd_release_irq(hw_config->irq, hw_config);
sound_free_dma(hw_config->dma);
@@ -111,14 +111,15 @@ void unload_gus(struct address_info *hw_config)
void gusintr(int irq, void *dev_id, struct pt_regs *dummy)
{
- unsigned char src;
- extern int gus_timer_enabled;
+ unsigned char src;
+ extern int gus_timer_enabled;
+ struct address_info *hw_config=dev_id;
sti();
#ifdef CONFIG_GUSMAX
if (have_gus_max)
- adintr(irq, NULL, NULL);
+ adintr(irq, (void *)hw_config->slots[3], NULL);
#endif
while (1)
diff --git a/drivers/sound/hex2hex.c b/drivers/sound/hex2hex.c
index 19753bfc2..4b182625b 100644
--- a/drivers/sound/hex2hex.c
+++ b/drivers/sound/hex2hex.c
@@ -66,14 +66,27 @@ int loadhex(FILE *inf, unsigned char *buf)
int main( int argc, const char * argv [] )
{
- const char * varline = argv[1];
+ const char * varline;
int i,l;
+ int id=0;
+ if(argv[1] && strcmp(argv[1], "-i")==0)
+ {
+ argv++;
+ argc--;
+ id=1;
+ }
+ if(argv[1]==NULL)
+ {
+ fprintf(stderr,"hex2hex: [-i] filename\n");
+ exit(1);
+ }
+ varline = argv[1;
l = loadhex(stdin, buf);
printf("/*\n *\t Computer generated file. Do not edit.\n */\n");
printf("static int %s_len = %d;\n", varline, l);
- printf("static unsigned char %s[] = {\n", varline);
+ printf("static unsigned char %s[] %s = {\n", varline, id?"__initdata":"");
for (i=0;i<l;i++)
{
diff --git a/drivers/sound/maui.c b/drivers/sound/maui.c
index 5cd620dbf..a7d37039c 100644
--- a/drivers/sound/maui.c
+++ b/drivers/sound/maui.c
@@ -9,7 +9,15 @@
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
+ *
+ * Changes:
+ * Alan Cox General clean up, use kernel IRQ
+ * system
+ *
+ * Status:
+ * Untested
*/
+
#include <linux/config.h>
#include <linux/module.h>
@@ -327,7 +335,7 @@ int probe_maui(struct address_info *hw_config)
maui_base = hw_config->io_base;
maui_osp = hw_config->osp;
- if (snd_set_irq_handler(hw_config->irq, mauiintr, "Maui", maui_osp) < 0)
+ if (request_irq(hw_config->irq, mauiintr, 0, "Maui", NULL) < 0)
return 0;
/*
@@ -342,26 +350,26 @@ int probe_maui(struct address_info *hw_config)
maui_read() == -1 || maui_read() == -1)
if (!maui_init(hw_config->irq))
{
- snd_release_irq(hw_config->irq);
+ free_irq(hw_config->irq, NULL);
return 0;
}
}
if (!maui_write(0xCF)) /* Report hardware version */
{
printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n");
- snd_release_irq(hw_config->irq);
+ free_irq(hw_config->irq, NULL);
return 0;
}
if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1)
{
printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n");
- snd_release_irq(hw_config->irq);
+ free_irq(hw_config->irq, NULL);
return 0;
}
if (tmp1 == 0xff || tmp2 == 0xff)
{
- snd_release_irq(hw_config->irq);
- return 0;
+ free_irq(hw_config->irq, NULL);
+ return 0;
}
if (trace_init)
printk(KERN_DEBUG "WaveFront hardware version %d.%d\n", tmp1, tmp2);
@@ -439,7 +447,7 @@ void unload_maui(struct address_info *hw_config)
if (irq < 0)
irq = -irq;
if (irq > 0)
- snd_release_irq(irq);
+ free_irq(irq, NULL);
}
#ifdef MODULE
@@ -452,8 +460,7 @@ static int fw_load = 0;
struct address_info cfg;
/*
- * Install a CS4232 based card. Need to have ad1848 and mpu401
- * loaded ready.
+ * Install a Maui card. Needs mpu401 loaded already.
*/
int init_module(void)
diff --git a/drivers/sound/midibuf.c b/drivers/sound/midibuf.c
index 0c024a454..09dea3a34 100644
--- a/drivers/sound/midibuf.c
+++ b/drivers/sound/midibuf.c
@@ -15,7 +15,6 @@
*/
#include <linux/config.h>
#include <linux/stddef.h>
-#include <linux/kerneld.h>
#define MIDIBUF_C
diff --git a/drivers/sound/mpu401.c b/drivers/sound/mpu401.c
index 9ae597404..ce92010fc 100644
--- a/drivers/sound/mpu401.c
+++ b/drivers/sound/mpu401.c
@@ -9,10 +9,12 @@
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
+ *
+ *
+ * Thomas Sailer ioctl code reworked (vmalloc/vfree removed)
+ * Alan Cox modularisation, use normal request_irq, use dev_id
*/
-/*
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- */
+
#include <linux/config.h>
#include <linux/module.h>
@@ -32,30 +34,30 @@ static int timer_mode = TMR_INTERNAL, timer_caps = TMR_INTERNAL;
#endif
struct mpu_config
- {
- int base; /*
+{
+ int base; /*
* I/O base
*/
- int irq;
- int opened; /*
- * Open mode
- */
- int devno;
- int synthno;
- int uart_mode;
- int initialized;
- int mode;
+ int irq;
+ int opened; /*
+ * Open mode
+ */
+ int devno;
+ int synthno;
+ int uart_mode;
+ int initialized;
+ int mode;
#define MODE_MIDI 1
#define MODE_SYNTH 2
- unsigned char version, revision;
- unsigned int capabilities;
+ unsigned char version, revision;
+ unsigned int capabilities;
#define MPU_CAP_INTLG 0x10000000
#define MPU_CAP_SYNC 0x00000010
#define MPU_CAP_FSK 0x00000020
#define MPU_CAP_CLS 0x00000040
#define MPU_CAP_SMPTE 0x00000080
#define MPU_CAP_2PORT 0x00000001
- int timer_flag;
+ int timer_flag;
#define MBUF_MAX 10
#define BUFTEST(dc) if (dc->m_ptr >= MBUF_MAX || dc->m_ptr < 0) \
@@ -75,28 +77,27 @@ struct mpu_config
#define COMDPORT(base) (base+1)
#define STATPORT(base) (base+1)
-static int
-mpu401_status(struct mpu_config *devc)
+static int mpu401_status(struct mpu_config *devc)
{
return inb(STATPORT(devc->base));
}
+
#define input_avail(devc) (!(mpu401_status(devc)&INPUT_AVAIL))
#define output_ready(devc) (!(mpu401_status(devc)&OUTPUT_READY))
-static void
-write_command(struct mpu_config *devc, unsigned char cmd)
+
+static void write_command(struct mpu_config *devc, unsigned char cmd)
{
- outb((cmd), COMDPORT(devc->base));
+ outb(cmd, COMDPORT(devc->base));
}
-static int
-read_data(struct mpu_config *devc)
+
+static int read_data(struct mpu_config *devc)
{
return inb(DATAPORT(devc->base));
}
-static void
-write_data(struct mpu_config *devc, unsigned char byte)
+static void write_data(struct mpu_config *devc, unsigned char byte)
{
- outb((byte), DATAPORT(devc->base));
+ outb(byte, DATAPORT(devc->base));
}
#define OUTPUT_READY 0x40
@@ -107,22 +108,27 @@ write_data(struct mpu_config *devc, unsigned char byte)
static struct mpu_config dev_conf[MAX_MIDI_DEV] =
{
- {0}};
+ {0}
+};
-static int n_mpu_devs = 0;
-static volatile int irq2dev[17] =
-{-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1};
+static int n_mpu_devs = 0;
-static int reset_mpu401(struct mpu_config *devc);
-static void set_uart_mode(int dev, struct mpu_config *devc, int arg);
+static int reset_mpu401(struct mpu_config *devc);
+static void set_uart_mode(int dev, struct mpu_config *devc, int arg);
-static int mpu_timer_init(int midi_dev);
-static void mpu_timer_interrupt(void);
-static void timer_ext_event(struct mpu_config *devc, int event, int parm);
+static int mpu_timer_init(int midi_dev);
+static void mpu_timer_interrupt(void);
+static void timer_ext_event(struct mpu_config *devc, int event, int parm);
-static struct synth_info mpu_synth_info_proto =
-{"MPU-401 MIDI interface", 0, SYNTH_TYPE_MIDI, MIDI_TYPE_MPU401, 0, 128, 0, 128, SYNTH_CAP_INPUT};
+static struct synth_info mpu_synth_info_proto = {
+ "MPU-401 MIDI interface",
+ 0,
+ SYNTH_TYPE_MIDI,
+ MIDI_TYPE_MPU401,
+ 0, 128,
+ 0, 128,
+ SYNTH_CAP_INPUT
+};
static struct synth_info mpu_synth_info[MAX_MIDI_DEV];
@@ -158,10 +164,10 @@ static unsigned char len_tab[] = /* # of data bytes following a status
#else
#define STORE(cmd) \
{ \
- int len; \
- unsigned char obuf[8]; \
- cmd; \
- seq_input_event(obuf, len); \
+ int len; \
+ unsigned char obuf[8]; \
+ cmd; \
+ seq_input_event(obuf, len); \
}
#endif
@@ -169,242 +175,242 @@ static unsigned char len_tab[] = /* # of data bytes following a status
#define _seqbufptr 0
#define _SEQ_ADVBUF(x) len=x
-static int
-mpu_input_scanner(struct mpu_config *devc, unsigned char midic)
+static int mpu_input_scanner(struct mpu_config *devc, unsigned char midic)
{
switch (devc->m_state)
- {
- case ST_INIT:
- switch (midic)
- {
- case 0xf8:
- /* Timer overflow */
- break;
-
- case 0xfc:
- printk("<all end>");
- break;
-
- case 0xfd:
- if (devc->timer_flag)
- mpu_timer_interrupt();
- break;
-
- case 0xfe:
- return MPU_ACK;
- break;
-
- case 0xf0:
- case 0xf1:
- case 0xf2:
- case 0xf3:
- case 0xf4:
- case 0xf5:
- case 0xf6:
- case 0xf7:
- printk("<Trk data rq #%d>", midic & 0x0f);
- break;
-
- case 0xf9:
- printk("<conductor rq>");
- break;
-
- case 0xff:
- devc->m_state = ST_SYSMSG;
- break;
-
- default:
- if (midic <= 0xef)
- {
- /* printk( "mpu time: %d ", midic); */
- devc->m_state = ST_TIMED;
- } else
- printk("<MPU: Unknown event %02x> ", midic);
- }
- break;
-
- case ST_TIMED:
- {
- int msg = ((int) (midic & 0xf0) >> 4);
-
- devc->m_state = ST_DATABYTE;
-
- if (msg < 8) /* Data byte */
- {
- /* printk( "midi msg (running status) "); */
- msg = ((int) (devc->last_status & 0xf0) >> 4);
- msg -= 8;
- devc->m_left = len_tab[msg] - 1;
-
- devc->m_ptr = 2;
- devc->m_buf[0] = devc->last_status;
- devc->m_buf[1] = midic;
-
- if (devc->m_left <= 0)
- {
- devc->m_state = ST_INIT;
- do_midi_msg(devc->synthno, devc->m_buf, devc->m_ptr);
- devc->m_ptr = 0;
- }
- } else if (msg == 0xf) /* MPU MARK */
- {
- devc->m_state = ST_INIT;
-
- switch (midic)
- {
- case 0xf8:
- /* printk( "NOP "); */
- break;
-
- case 0xf9:
- /* printk( "meas end "); */
- break;
-
- case 0xfc:
- /* printk( "data end "); */
- break;
-
- default:
- printk("Unknown MPU mark %02x\n", midic);
- }
- } else
- {
- devc->last_status = midic;
- /* printk( "midi msg "); */
- msg -= 8;
- devc->m_left = len_tab[msg];
-
- devc->m_ptr = 1;
- devc->m_buf[0] = midic;
-
- if (devc->m_left <= 0)
- {
- devc->m_state = ST_INIT;
- do_midi_msg(devc->synthno, devc->m_buf, devc->m_ptr);
- devc->m_ptr = 0;
- }
- }
- }
- break;
-
- case ST_SYSMSG:
- switch (midic)
- {
- case 0xf0:
- printk("<SYX>");
- devc->m_state = ST_SYSEX;
- break;
-
- case 0xf1:
- devc->m_state = ST_MTC;
- break;
-
- case 0xf2:
- devc->m_state = ST_SONGPOS;
- devc->m_ptr = 0;
- break;
-
- case 0xf3:
- devc->m_state = ST_SONGSEL;
- break;
-
- case 0xf6:
- /* printk( "tune_request\n"); */
- devc->m_state = ST_INIT;
-
- /*
- * Real time messages
- */
- case 0xf8:
- /* midi clock */
- devc->m_state = ST_INIT;
- timer_ext_event(devc, TMR_CLOCK, 0);
- break;
-
- case 0xfA:
- devc->m_state = ST_INIT;
- timer_ext_event(devc, TMR_START, 0);
- break;
-
- case 0xFB:
- devc->m_state = ST_INIT;
- timer_ext_event(devc, TMR_CONTINUE, 0);
- break;
-
- case 0xFC:
- devc->m_state = ST_INIT;
- timer_ext_event(devc, TMR_STOP, 0);
- break;
-
- case 0xFE:
- /* active sensing */
- devc->m_state = ST_INIT;
- break;
-
- case 0xff:
- /* printk( "midi hard reset"); */
- devc->m_state = ST_INIT;
- break;
-
- default:
- printk("unknown MIDI sysmsg %0x\n", midic);
- devc->m_state = ST_INIT;
- }
- break;
-
- case ST_MTC:
- devc->m_state = ST_INIT;
- printk("MTC frame %x02\n", midic);
- break;
-
- case ST_SYSEX:
- if (midic == 0xf7)
- {
- printk("<EOX>");
- devc->m_state = ST_INIT;
- } else
- printk("%02x ", midic);
- break;
-
- case ST_SONGPOS:
- BUFTEST(devc);
- devc->m_buf[devc->m_ptr++] = midic;
- if (devc->m_ptr == 2)
- {
- devc->m_state = ST_INIT;
- devc->m_ptr = 0;
- timer_ext_event(devc, TMR_SPP,
- ((devc->m_buf[1] & 0x7f) << 7) |
- (devc->m_buf[0] & 0x7f));
- }
- break;
-
- case ST_DATABYTE:
- BUFTEST(devc);
- devc->m_buf[devc->m_ptr++] = midic;
- if ((--devc->m_left) <= 0)
- {
- devc->m_state = ST_INIT;
- do_midi_msg(devc->synthno, devc->m_buf, devc->m_ptr);
- devc->m_ptr = 0;
- }
- break;
-
- default:
- printk("Bad state %d ", devc->m_state);
- devc->m_state = ST_INIT;
- }
+ {
+ case ST_INIT:
+ switch (midic)
+ {
+ case 0xf8:
+ /* Timer overflow */
+ break;
+
+ case 0xfc:
+ printk("<all end>");
+ break;
+
+ case 0xfd:
+ if (devc->timer_flag)
+ mpu_timer_interrupt();
+ break;
+
+ case 0xfe:
+ return MPU_ACK;
+
+ case 0xf0:
+ case 0xf1:
+ case 0xf2:
+ case 0xf3:
+ case 0xf4:
+ case 0xf5:
+ case 0xf6:
+ case 0xf7:
+ printk("<Trk data rq #%d>", midic & 0x0f);
+ break;
+
+ case 0xf9:
+ printk("<conductor rq>");
+ break;
+
+ case 0xff:
+ devc->m_state = ST_SYSMSG;
+ break;
+
+ default:
+ if (midic <= 0xef)
+ {
+ /* printk( "mpu time: %d ", midic); */
+ devc->m_state = ST_TIMED;
+ }
+ else
+ printk("<MPU: Unknown event %02x> ", midic);
+ }
+ break;
+
+ case ST_TIMED:
+ {
+ int msg = ((int) (midic & 0xf0) >> 4);
+
+ devc->m_state = ST_DATABYTE;
+
+ if (msg < 8) /* Data byte */
+ {
+ /* printk( "midi msg (running status) "); */
+ msg = ((int) (devc->last_status & 0xf0) >> 4);
+ msg -= 8;
+ devc->m_left = len_tab[msg] - 1;
+
+ devc->m_ptr = 2;
+ devc->m_buf[0] = devc->last_status;
+ devc->m_buf[1] = midic;
+
+ if (devc->m_left <= 0)
+ {
+ devc->m_state = ST_INIT;
+ do_midi_msg(devc->synthno, devc->m_buf, devc->m_ptr);
+ devc->m_ptr = 0;
+ }
+ }
+ else if (msg == 0xf) /* MPU MARK */
+ {
+ devc->m_state = ST_INIT;
+
+ switch (midic)
+ {
+ case 0xf8:
+ /* printk( "NOP "); */
+ break;
+
+ case 0xf9:
+ /* printk( "meas end "); */
+ break;
+
+ case 0xfc:
+ /* printk( "data end "); */
+ break;
+
+ default:
+ printk("Unknown MPU mark %02x\n", midic);
+ }
+ }
+ else
+ {
+ devc->last_status = midic;
+ /* printk( "midi msg "); */
+ msg -= 8;
+ devc->m_left = len_tab[msg];
+
+ devc->m_ptr = 1;
+ devc->m_buf[0] = midic;
+
+ if (devc->m_left <= 0)
+ {
+ devc->m_state = ST_INIT;
+ do_midi_msg(devc->synthno, devc->m_buf, devc->m_ptr);
+ devc->m_ptr = 0;
+ }
+ }
+ }
+ break;
+
+ case ST_SYSMSG:
+ switch (midic)
+ {
+ case 0xf0:
+ printk("<SYX>");
+ devc->m_state = ST_SYSEX;
+ break;
+
+ case 0xf1:
+ devc->m_state = ST_MTC;
+ break;
+
+ case 0xf2:
+ devc->m_state = ST_SONGPOS;
+ devc->m_ptr = 0;
+ break;
+
+ case 0xf3:
+ devc->m_state = ST_SONGSEL;
+ break;
+
+ case 0xf6:
+ /* printk( "tune_request\n"); */
+ devc->m_state = ST_INIT;
+
+ /*
+ * Real time messages
+ */
+ case 0xf8:
+ /* midi clock */
+ devc->m_state = ST_INIT;
+ timer_ext_event(devc, TMR_CLOCK, 0);
+ break;
+
+ case 0xfA:
+ devc->m_state = ST_INIT;
+ timer_ext_event(devc, TMR_START, 0);
+ break;
+
+ case 0xFB:
+ devc->m_state = ST_INIT;
+ timer_ext_event(devc, TMR_CONTINUE, 0);
+ break;
+
+ case 0xFC:
+ devc->m_state = ST_INIT;
+ timer_ext_event(devc, TMR_STOP, 0);
+ break;
+
+ case 0xFE:
+ /* active sensing */
+ devc->m_state = ST_INIT;
+ break;
+
+ case 0xff:
+ /* printk( "midi hard reset"); */
+ devc->m_state = ST_INIT;
+ break;
+
+ default:
+ printk("unknown MIDI sysmsg %0x\n", midic);
+ devc->m_state = ST_INIT;
+ }
+ break;
+
+ case ST_MTC:
+ devc->m_state = ST_INIT;
+ printk("MTC frame %x02\n", midic);
+ break;
+
+ case ST_SYSEX:
+ if (midic == 0xf7)
+ {
+ printk("<EOX>");
+ devc->m_state = ST_INIT;
+ }
+ else
+ printk("%02x ", midic);
+ break;
+
+ case ST_SONGPOS:
+ BUFTEST(devc);
+ devc->m_buf[devc->m_ptr++] = midic;
+ if (devc->m_ptr == 2)
+ {
+ devc->m_state = ST_INIT;
+ devc->m_ptr = 0;
+ timer_ext_event(devc, TMR_SPP,
+ ((devc->m_buf[1] & 0x7f) << 7) |
+ (devc->m_buf[0] & 0x7f));
+ }
+ break;
+ case ST_DATABYTE:
+ BUFTEST(devc);
+ devc->m_buf[devc->m_ptr++] = midic;
+ if ((--devc->m_left) <= 0)
+ {
+ devc->m_state = ST_INIT;
+ do_midi_msg(devc->synthno, devc->m_buf, devc->m_ptr);
+ devc->m_ptr = 0;
+ }
+ break;
+
+ default:
+ printk("Bad state %d ", devc->m_state);
+ devc->m_state = ST_INIT;
+ }
return 1;
}
-static void
-mpu401_input_loop(struct mpu_config *devc)
+static void mpu401_input_loop(struct mpu_config *devc)
{
- unsigned long flags;
- int busy;
- int n;
+ unsigned long flags;
+ int busy;
+ int n;
save_flags(flags);
cli();
@@ -418,72 +424,45 @@ mpu401_input_loop(struct mpu_config *devc)
n = 50;
while (input_avail(devc) && n-- > 0)
- {
- unsigned char c = read_data(devc);
-
- if (devc->mode == MODE_SYNTH)
- {
- mpu_input_scanner(devc, c);
- } else if (devc->opened & OPEN_READ && devc->inputintr != NULL)
- devc->inputintr(devc->devno, c);
- }
+ {
+ unsigned char c = read_data(devc);
+ if (devc->mode == MODE_SYNTH)
+ {
+ mpu_input_scanner(devc, c);
+ }
+ else if (devc->opened & OPEN_READ && devc->inputintr != NULL)
+ devc->inputintr(devc->devno, c);
+ }
devc->m_busy = 0;
}
-void
-mpuintr(int irq, void *dev_id, struct pt_regs *dummy)
+void mpuintr(int irq, void *dev_id, struct pt_regs *dummy)
{
struct mpu_config *devc;
- int dev;
+ int dev = (int) dev_id;
sti();
-
-/*
- * FreeBSD (and some others) pass unit number to the interrupt handler.
- * In this case we have to scan the table for first handler.
- */
-
- if (irq < 1 || irq > 15)
- {
- dev = -1;
- } else
- dev = irq2dev[irq];
-
- if (dev == -1)
- {
- int origirq = irq;
-
- for (irq = 0; irq <= 16; irq++)
- if (irq2dev[irq] != -1)
- break;
- if (irq > 15)
- {
- printk("MPU-401: Bogus interrupt #%d?\n", origirq);
- return;
- }
- dev = irq2dev[irq];
- devc = &dev_conf[dev];
- } else
- devc = &dev_conf[dev];
+ devc = &dev_conf[dev];
if (input_avail(devc))
+ {
if (devc->base != 0 && (devc->opened & OPEN_READ || devc->mode == MODE_SYNTH))
mpu401_input_loop(devc);
else
- {
- /* Dummy read (just to acknowledge the interrupt) */
- read_data(devc);
- }
+ {
+ /* Dummy read (just to acknowledge the interrupt) */
+ read_data(devc);
+ }
+ }
}
-static int
-mpu401_open(int dev, int mode,
+static int mpu401_open(int dev, int mode,
void (*input) (int dev, unsigned char data),
void (*output) (int dev)
)
{
- int err;
+ int err;
struct mpu_config *devc;
if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
@@ -492,36 +471,34 @@ mpu401_open(int dev, int mode,
devc = &dev_conf[dev];
if (devc->opened)
- {
- printk("MPU-401: Midi busy\n");
return -EBUSY;
- }
/*
- * Verify that the device is really running.
- * Some devices (such as Ensoniq SoundScape don't
- * work before the on board processor (OBP) is initialized
- * by downloading its microcode.
+ * Verify that the device is really running.
+ * Some devices (such as Ensoniq SoundScape don't
+ * work before the on board processor (OBP) is initialized
+ * by downloading its microcode.
*/
if (!devc->initialized)
- {
- if (mpu401_status(devc) == 0xff) /* Bus float */
- {
- printk("MPU-401: Device not initialized properly\n");
- return -EIO;
- }
- reset_mpu401(devc);
- }
- irq2dev[devc->irq] = dev;
+ {
+ if (mpu401_status(devc) == 0xff) /* Bus float */
+ {
+ printk(KERN_ERR "mpu401: Device not initialized properly\n");
+ return -EIO;
+ }
+ reset_mpu401(devc);
+ }
if (midi_devs[dev]->coproc)
+ {
if ((err = midi_devs[dev]->coproc->
open(midi_devs[dev]->coproc->devc, COPR_MIDI)) < 0)
- {
- printk("MPU-401: Can't access coprocessor device\n");
-
- return err;
- }
+ {
+ printk("MPU-401: Can't access coprocessor device\n");
+ return err;
+ }
+ }
+
set_uart_mode(dev, devc, 1);
devc->mode = MODE_MIDI;
devc->synthno = 0;
@@ -534,19 +511,16 @@ mpu401_open(int dev, int mode,
return 0;
}
-static void
-mpu401_close(int dev)
+static void mpu401_close(int dev)
{
struct mpu_config *devc;
devc = &dev_conf[dev];
-
if (devc->uart_mode)
reset_mpu401(devc); /*
* This disables the UART mode
*/
devc->mode = 0;
-
devc->inputintr = NULL;
if (midi_devs[dev]->coproc)
@@ -554,11 +528,10 @@ mpu401_close(int dev)
devc->opened = 0;
}
-static int
-mpu401_out(int dev, unsigned char midi_byte)
+static int mpu401_out(int dev, unsigned char midi_byte)
{
- int timeout;
- unsigned long flags;
+ int timeout;
+ unsigned long flags;
struct mpu_config *devc;
@@ -574,21 +547,20 @@ mpu401_out(int dev, unsigned char midi_byte)
save_flags(flags);
cli();
if (!output_ready(devc))
- {
- printk("MPU-401: Send data timeout\n");
- restore_flags(flags);
- return 0;
- }
+ {
+ printk(KERN_WARNING "mpu401: Send data timeout\n");
+ restore_flags(flags);
+ return 0;
+ }
write_data(devc, midi_byte);
restore_flags(flags);
return 1;
}
-static int
-mpu401_command(int dev, mpu_command_rec * cmd)
+static int mpu401_command(int dev, mpu_command_rec * cmd)
{
- int i, timeout, ok;
- int ret = 0;
+ int i, timeout, ok;
+ int ret = 0;
unsigned long flags;
struct mpu_config *devc;
@@ -597,10 +569,10 @@ mpu401_command(int dev, mpu_command_rec * cmd)
if (devc->uart_mode) /*
* Not possible in UART mode
*/
- {
- printk("MPU-401 commands not possible in the UART mode\n");
- return -EINVAL;
- }
+ {
+ printk(KERN_WARNING "mpu401: commands not possible in the UART mode\n");
+ return -EINVAL;
+ }
/*
* Test for input since pending input seems to block the output.
*/
@@ -613,83 +585,87 @@ mpu401_command(int dev, mpu_command_rec * cmd)
*/
timeout = 50000;
- retry:
+retry:
if (timeout-- <= 0)
- {
- printk("MPU-401: Command (0x%x) timeout\n", (int) cmd->cmd);
- return -EIO;
- }
+ {
+ printk(KERN_WARNING "mpu401: Command (0x%x) timeout\n", (int) cmd->cmd);
+ return -EIO;
+ }
save_flags(flags);
cli();
if (!output_ready(devc))
- {
+ {
restore_flags(flags);
goto retry;
- }
+ }
write_command(devc, cmd->cmd);
ok = 0;
for (timeout = 50000; timeout > 0 && !ok; timeout--)
+ {
if (input_avail(devc))
- {
- if (devc->opened && devc->mode == MODE_SYNTH)
- {
- if (mpu_input_scanner(devc, read_data(devc)) == MPU_ACK)
- ok = 1;
- } else
- { /* Device is not currently open. Use simpler method */
- if (read_data(devc) == MPU_ACK)
- ok = 1;
- }
- }
+ {
+ if (devc->opened && devc->mode == MODE_SYNTH)
+ {
+ if (mpu_input_scanner(devc, read_data(devc)) == MPU_ACK)
+ ok = 1;
+ }
+ else
+ {
+ /* Device is not currently open. Use simpler method */
+ if (read_data(devc) == MPU_ACK)
+ ok = 1;
+ }
+ }
+ }
if (!ok)
- {
- restore_flags(flags);
- /* printk( "MPU: No ACK to command (0x%x)\n", (int) cmd->cmd); */
- return -EIO;
- }
+ {
+ restore_flags(flags);
+ return -EIO;
+ }
if (cmd->nr_args)
+ {
for (i = 0; i < cmd->nr_args; i++)
- {
- for (timeout = 3000; timeout > 0 && !output_ready(devc); timeout--);
-
- if (!mpu401_out(dev, cmd->data[i]))
- {
- restore_flags(flags);
- printk("MPU: Command (0x%x), parm send failed.\n", (int) cmd->cmd);
- return -EIO;
- }
- }
+ {
+ for (timeout = 3000; timeout > 0 && !output_ready(devc); timeout--);
+
+ if (!mpu401_out(dev, cmd->data[i]))
+ {
+ restore_flags(flags);
+ printk(KERN_WARNING "mpu401: Command (0x%x), parm send failed.\n", (int) cmd->cmd);
+ return -EIO;
+ }
+ }
+ }
ret = 0;
cmd->data[0] = 0;
if (cmd->nr_returns)
+ {
for (i = 0; i < cmd->nr_returns; i++)
- {
- ok = 0;
- for (timeout = 5000; timeout > 0 && !ok; timeout--)
- if (input_avail(devc))
- {
- cmd->data[i] = read_data(devc);
- ok = 1;
- }
- if (!ok)
- {
- restore_flags(flags);
- /* printk( "MPU: No response(%d) to command (0x%x)\n", i, (int) cmd->cmd); */
- return -EIO;
- }
- }
+ {
+ ok = 0;
+ for (timeout = 5000; timeout > 0 && !ok; timeout--)
+ if (input_avail(devc))
+ {
+ cmd->data[i] = read_data(devc);
+ ok = 1;
+ }
+ if (!ok)
+ {
+ restore_flags(flags);
+ return -EIO;
+ }
+ }
+ }
restore_flags(flags);
-
return ret;
}
-static int
-mpu_cmd(int dev, int cmd, int data)
+static int mpu_cmd(int dev, int cmd, int data)
{
- int ret;
+ int ret;
static mpu_command_rec rec;
@@ -699,14 +675,11 @@ mpu_cmd(int dev, int cmd, int data)
rec.data[0] = data & 0xff;
if ((ret = mpu401_command(dev, &rec)) < 0)
- {
- return ret;
- }
+ return ret;
return (unsigned char) rec.data[0];
}
-static int
-mpu401_prefix_cmd(int dev, unsigned char status)
+static int mpu401_prefix_cmd(int dev, unsigned char status)
{
struct mpu_config *devc = &dev_conf[dev];
@@ -714,37 +687,29 @@ mpu401_prefix_cmd(int dev, unsigned char status)
return 1;
if (status < 0xf0)
- {
- if (mpu_cmd(dev, 0xD0, 0) < 0)
- {
- return 0;
- }
- return 1;
- }
+ {
+ if (mpu_cmd(dev, 0xD0, 0) < 0)
+ return 0;
+ return 1;
+ }
switch (status)
- {
- case 0xF0:
- if (mpu_cmd(dev, 0xDF, 0) < 0)
- {
- return 0;
- }
- return 1;
- break;
-
- default:
- return 0;
- }
+ {
+ case 0xF0:
+ if (mpu_cmd(dev, 0xDF, 0) < 0)
+ return 0;
+ return 1;
+ default:
+ return 0;
+ }
}
-static int
-mpu401_start_read(int dev)
+static int mpu401_start_read(int dev)
{
return 0;
}
-static int
-mpu401_end_read(int dev)
+static int mpu401_end_read(int dev)
{
return 0;
}
@@ -756,49 +721,47 @@ static int mpu401_ioctl(int dev, unsigned cmd, caddr_t arg)
int val, ret;
devc = &dev_conf[dev];
- switch (cmd) {
- case SNDCTL_MIDI_MPUMODE:
- if (!(devc->capabilities & MPU_CAP_INTLG)) { /* No intelligent mode */
- printk("MPU-401: Intelligent mode not supported by the HW\n");
+ switch (cmd)
+ {
+ case SNDCTL_MIDI_MPUMODE:
+ if (!(devc->capabilities & MPU_CAP_INTLG)) { /* No intelligent mode */
+ printk(KERN_WARNING "mpu401: Intelligent mode not supported by the HW\n");
+ return -EINVAL;
+ }
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ set_uart_mode(dev, devc, !val);
+ return 0;
+
+ case SNDCTL_MIDI_MPUCMD:
+ if (copy_from_user(&rec, arg, sizeof(rec)))
+ return -EFAULT;
+ if ((ret = mpu401_command(dev, &rec)) < 0)
+ return ret;
+ if (copy_to_user(arg, &rec, sizeof(rec)))
+ return -EFAULT;
+ return 0;
+
+ default:
return -EINVAL;
- }
- if (__get_user(val, (int *)arg))
- return -EFAULT;
- set_uart_mode(dev, devc, !val);
- return 0;
-
- case SNDCTL_MIDI_MPUCMD:
- if (__copy_from_user(&rec, arg, sizeof(rec)))
- return -EFAULT;
- if ((ret = mpu401_command(dev, &rec)) < 0)
- return ret;
- if (__copy_to_user(arg, &rec, sizeof(rec)))
- return -EFAULT;
- return 0;
-
- default:
- return -EINVAL;
}
}
-static void
-mpu401_kick(int dev)
+static void mpu401_kick(int dev)
{
}
-static int
-mpu401_buffer_status(int dev)
+static int mpu401_buffer_status(int dev)
{
return 0; /*
* No data in buffers
*/
}
-static int
-mpu_synth_ioctl(int dev,
+static int mpu_synth_ioctl(int dev,
unsigned int cmd, caddr_t arg)
{
- int midi_dev;
+ int midi_dev;
struct mpu_config *devc;
midi_dev = synth_devs[dev]->midi_dev;
@@ -809,88 +772,77 @@ mpu_synth_ioctl(int dev,
devc = &dev_conf[midi_dev];
switch (cmd)
- {
-
- case SNDCTL_SYNTH_INFO:
- memcpy((&((char *) arg)[0]), (char *) &mpu_synth_info[midi_dev], sizeof(struct synth_info));
+ {
- return 0;
- break;
+ case SNDCTL_SYNTH_INFO:
+ memcpy((&((char *) arg)[0]), (char *) &mpu_synth_info[midi_dev], sizeof(struct synth_info));
+ return 0;
- case SNDCTL_SYNTH_MEMAVL:
- return 0x7fffffff;
- break;
+ case SNDCTL_SYNTH_MEMAVL:
+ return 0x7fffffff;
- default:
- return -EINVAL;
- }
+ default:
+ return -EINVAL;
+ }
}
-static int
-mpu_synth_open(int dev, int mode)
+static int mpu_synth_open(int dev, int mode)
{
- int midi_dev, err;
+ int midi_dev, err;
struct mpu_config *devc;
midi_dev = synth_devs[dev]->midi_dev;
if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev] == NULL)
- {
- return -ENXIO;
- }
+ return -ENXIO;
+
devc = &dev_conf[midi_dev];
/*
- * Verify that the device is really running.
- * Some devices (such as Ensoniq SoundScape don't
- * work before the on board processor (OBP) is initialized
- * by downloading its microcode.
+ * Verify that the device is really running.
+ * Some devices (such as Ensoniq SoundScape don't
+ * work before the on board processor (OBP) is initialized
+ * by downloading its microcode.
*/
if (!devc->initialized)
- {
- if (mpu401_status(devc) == 0xff) /* Bus float */
- {
- printk("MPU-401: Device not initialized properly\n");
- return -EIO;
- }
- reset_mpu401(devc);
- }
+ {
+ if (mpu401_status(devc) == 0xff) /* Bus float */
+ {
+ printk(KERN_ERR "mpu401: Device not initialized properly\n");
+ return -EIO;
+ }
+ reset_mpu401(devc);
+ }
if (devc->opened)
- {
- printk("MPU-401: Midi busy\n");
- return -EBUSY;
- }
+ return -EBUSY;
devc->mode = MODE_SYNTH;
devc->synthno = dev;
devc->inputintr = NULL;
- irq2dev[devc->irq] = midi_dev;
if (midi_devs[midi_dev]->coproc)
if ((err = midi_devs[midi_dev]->coproc->
open(midi_devs[midi_dev]->coproc->devc, COPR_MIDI)) < 0)
- {
- printk("MPU-401: Can't access coprocessor device\n");
-
- return err;
- }
+ {
+ printk(KERN_WARNING "mpu401: Can't access coprocessor device\n");
+ return err;
+ }
devc->opened = mode;
reset_mpu401(devc);
if (mode & OPEN_READ)
- {
- mpu_cmd(midi_dev, 0x8B, 0); /* Enable data in stop mode */
- mpu_cmd(midi_dev, 0x34, 0); /* Return timing bytes in stop mode */
- mpu_cmd(midi_dev, 0x87, 0); /* Enable pitch & controller */
- }
+ {
+ mpu_cmd(midi_dev, 0x8B, 0); /* Enable data in stop mode */
+ mpu_cmd(midi_dev, 0x34, 0); /* Return timing bytes in stop mode */
+ mpu_cmd(midi_dev, 0x87, 0); /* Enable pitch & controller */
+ }
return 0;
}
-static void
-mpu_synth_close(int dev)
-{
- int midi_dev;
+static void mpu_synth_close(int dev)
+{
+ int midi_dev;
struct mpu_config *devc;
midi_dev = synth_devs[dev]->midi_dev;
@@ -958,55 +910,52 @@ static struct midi_operations mpu401_midi_proto =
static struct midi_operations mpu401_midi_operations[MAX_MIDI_DEV];
-static void
-mpu401_chk_version(int n, struct mpu_config *devc)
+static void mpu401_chk_version(int n, struct mpu_config *devc)
{
- int tmp;
- unsigned long flags;
+ int tmp;
+ unsigned long flags;
devc->version = devc->revision = 0;
save_flags(flags);
cli();
if ((tmp = mpu_cmd(n, 0xAC, 0)) < 0)
- {
- restore_flags(flags);
- return;
- }
+ {
+ restore_flags(flags);
+ return;
+ }
if ((tmp & 0xf0) > 0x20) /* Why it's larger than 2.x ??? */
- {
- restore_flags(flags);
- return;
- }
+ {
+ restore_flags(flags);
+ return;
+ }
devc->version = tmp;
if ((tmp = mpu_cmd(n, 0xAD, 0)) < 0)
- {
- devc->version = 0;
- restore_flags(flags);
- return;
- }
+ {
+ devc->version = 0;
+ restore_flags(flags);
+ return;
+ }
devc->revision = tmp;
-
restore_flags(flags);
}
-void
-attach_mpu401(struct address_info *hw_config)
+void attach_mpu401(struct address_info *hw_config)
{
- unsigned long flags;
- char revision_char;
+ unsigned long flags;
+ char revision_char;
- int m;
+ int m;
struct mpu_config *devc;
hw_config->slots[1] = -1;
m = sound_alloc_mididev();
if (m == -1)
- {
- printk(KERN_WARNING "MPU-401: Too many midi devices detected\n");
- return;
- }
+ {
+ printk(KERN_WARNING "MPU-401: Too many midi devices detected\n");
+ return;
+ }
devc = &dev_conf[m];
devc->base = hw_config->io_base;
devc->osp = hw_config->osp;
@@ -1024,35 +973,36 @@ attach_mpu401(struct address_info *hw_config)
devc->irq = hw_config->irq;
if (devc->irq < 0)
- {
- devc->irq *= -1;
- devc->shared_irq = 1;
- }
- irq2dev[devc->irq] = m;
+ {
+ devc->irq *= -1;
+ devc->shared_irq = 1;
+ }
if (!hw_config->always_detect)
- {
- /* Verify the hardware again */
- if (!reset_mpu401(devc))
- {
- printk(KERN_WARNING "mpu401: Device didn't respond\n");
- sound_unload_mididev(m);
- return;
- }
- if (!devc->shared_irq)
- if (snd_set_irq_handler(devc->irq, mpuintr, "mpu401", devc->osp) < 0)
- {
- printk(KERN_WARNING "mpu401: Failed to allocate IRQ%d\n", devc->irq);
- sound_unload_mididev(m);
- return;
- }
- save_flags(flags);
- cli();
- mpu401_chk_version(m, devc);
- if (devc->version == 0)
- mpu401_chk_version(m, devc);
- restore_flags(flags);
- }
+ {
+ /* Verify the hardware again */
+ if (!reset_mpu401(devc))
+ {
+ printk(KERN_WARNING "mpu401: Device didn't respond\n");
+ sound_unload_mididev(m);
+ return;
+ }
+ if (!devc->shared_irq)
+ {
+ if (request_irq(devc->irq, mpuintr, 0, "mpu401", (void *)m) < 0)
+ {
+ printk(KERN_WARNING "mpu401: Failed to allocate IRQ%d\n", devc->irq);
+ sound_unload_mididev(m);
+ return;
+ }
+ }
+ save_flags(flags);
+ cli();
+ mpu401_chk_version(m, devc);
+ if (devc->version == 0)
+ mpu401_chk_version(m, devc);
+ restore_flags(flags);
+ }
request_region(hw_config->io_base, 2, "mpu401");
if (devc->version != 0)
@@ -1061,36 +1011,32 @@ attach_mpu401(struct address_info *hw_config)
devc->capabilities |= MPU_CAP_INTLG; /* Supports intelligent mode */
- mpu401_synth_operations[m] = (struct synth_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct synth_operations)));
- sound_mem_sizes[sound_nblocks] = sizeof(struct synth_operations);
-
- if (sound_nblocks < 1024)
- sound_nblocks++;;
+ mpu401_synth_operations[m] = (struct synth_operations *)kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
if (mpu401_synth_operations[m] == NULL)
- {
- sound_unload_mididev(m);
- printk(KERN_ERR "mpu401: Can't allocate memory\n");
- return;
- }
+ {
+ sound_unload_mididev(m);
+ printk(KERN_ERR "mpu401: Can't allocate memory\n");
+ return;
+ }
if (!(devc->capabilities & MPU_CAP_INTLG)) /* No intelligent mode */
- {
- memcpy((char *) mpu401_synth_operations[m],
- (char *) &std_midi_synth,
+ {
+ memcpy((char *) mpu401_synth_operations[m],
+ (char *) &std_midi_synth,
sizeof(struct synth_operations));
- } else
- {
- memcpy((char *) mpu401_synth_operations[m],
- (char *) &mpu401_synth_proto,
+ }
+ else
+ {
+ memcpy((char *) mpu401_synth_operations[m],
+ (char *) &mpu401_synth_proto,
sizeof(struct synth_operations));
- }
+ }
memcpy((char *) &mpu401_midi_operations[m],
(char *) &mpu401_midi_proto,
sizeof(struct midi_operations));
- mpu401_midi_operations[m].converter =
- mpu401_synth_operations[m];
+ mpu401_midi_operations[m].converter = mpu401_synth_operations[m];
memcpy((char *) &mpu_synth_info[m],
(char *) &mpu_synth_info_proto,
@@ -1099,37 +1045,36 @@ attach_mpu401(struct address_info *hw_config)
n_mpu_devs++;
if (devc->version == 0x20 && devc->revision >= 0x07) /* MusicQuest interface */
- {
- int ports = (devc->revision & 0x08) ? 32 : 16;
-
- devc->capabilities |= MPU_CAP_SYNC | MPU_CAP_SMPTE |
- MPU_CAP_CLS | MPU_CAP_2PORT;
-
- revision_char = (devc->revision == 0x7f) ? 'M' : ' ';
- sprintf(mpu_synth_info[m].name,
- "MQX-%d%c MIDI Interface #%d",
- ports,
- revision_char,
- n_mpu_devs);
- } else
- {
-
- revision_char = devc->revision ? devc->revision + '@' : ' ';
- if ((int) devc->revision > ('Z' - '@'))
- revision_char = '+';
-
- devc->capabilities |= MPU_CAP_SYNC | MPU_CAP_FSK;
-
- if (hw_config->name)
- sprintf(mpu_synth_info[m].name, "%s (MPU401)", hw_config->name);
- else
- sprintf(mpu_synth_info[m].name,
- "MPU-401 %d.%d%c Midi interface #%d",
- (int) (devc->version & 0xf0) >> 4,
- devc->version & 0x0f,
- revision_char,
- n_mpu_devs);
- }
+ {
+ int ports = (devc->revision & 0x08) ? 32 : 16;
+
+ devc->capabilities |= MPU_CAP_SYNC | MPU_CAP_SMPTE |
+ MPU_CAP_CLS | MPU_CAP_2PORT;
+
+ revision_char = (devc->revision == 0x7f) ? 'M' : ' ';
+ sprintf(mpu_synth_info[m].name, "MQX-%d%c MIDI Interface #%d",
+ ports,
+ revision_char,
+ n_mpu_devs);
+ }
+ else
+ {
+ revision_char = devc->revision ? devc->revision + '@' : ' ';
+ if ((int) devc->revision > ('Z' - '@'))
+ revision_char = '+';
+
+ devc->capabilities |= MPU_CAP_SYNC | MPU_CAP_FSK;
+
+ if (hw_config->name)
+ sprintf(mpu_synth_info[m].name, "%s (MPU401)", hw_config->name);
+ else
+ sprintf(mpu_synth_info[m].name,
+ "MPU-401 %d.%d%c Midi interface #%d",
+ (int) (devc->version & 0xf0) >> 4,
+ devc->version & 0x0f,
+ revision_char,
+ n_mpu_devs);
+ }
strcpy(mpu401_midi_operations[m].info.name,
mpu_synth_info[m].name);
@@ -1137,24 +1082,21 @@ attach_mpu401(struct address_info *hw_config)
conf_printf(mpu_synth_info[m].name, hw_config);
mpu401_synth_operations[m]->midi_dev = devc->devno = m;
- mpu401_synth_operations[devc->devno]->info =
- &mpu_synth_info[devc->devno];
+ mpu401_synth_operations[devc->devno]->info = &mpu_synth_info[devc->devno];
if (devc->capabilities & MPU_CAP_INTLG) /* Intelligent mode */
hw_config->slots[2] = mpu_timer_init(m);
- irq2dev[devc->irq] = m;
midi_devs[m] = &mpu401_midi_operations[devc->devno];
hw_config->slots[1] = m;
sequencer_init();
}
-static int
-reset_mpu401(struct mpu_config *devc)
+static int reset_mpu401(struct mpu_config *devc)
{
- unsigned long flags;
- int ok, timeout, n;
- int timeout_limit;
+ unsigned long flags;
+ int ok, timeout, n;
+ int timeout_limit;
/*
* Send the RESET command. Try again if no success at the first time.
@@ -1167,30 +1109,30 @@ reset_mpu401(struct mpu_config *devc)
devc->initialized = 1;
for (n = 0; n < 2 && !ok; n++)
- {
- for (timeout = timeout_limit; timeout > 0 && !ok; timeout--)
+ {
+ for (timeout = timeout_limit; timeout > 0 && !ok; timeout--)
ok = output_ready(devc);
- write_command(devc, MPU_RESET); /*
+ write_command(devc, MPU_RESET); /*
* Send MPU-401 RESET Command
*/
- /*
- * Wait at least 25 msec. This method is not accurate so let's make the
- * loop bit longer. Cannot sleep since this is called during boot.
- */
+ /*
+ * Wait at least 25 msec. This method is not accurate so let's make the
+ * loop bit longer. Cannot sleep since this is called during boot.
+ */
- for (timeout = timeout_limit * 2; timeout > 0 && !ok; timeout--)
- {
- save_flags(flags);
- cli();
- if (input_avail(devc))
- if (read_data(devc) == MPU_ACK)
- ok = 1;
- restore_flags(flags);
- }
+ for (timeout = timeout_limit * 2; timeout > 0 && !ok; timeout--)
+ {
+ save_flags(flags);
+ cli();
+ if (input_avail(devc))
+ if (read_data(devc) == MPU_ACK)
+ ok = 1;
+ restore_flags(flags);
+ }
- }
+ }
devc->m_state = ST_INIT;
devc->m_ptr = 0;
@@ -1201,43 +1143,37 @@ reset_mpu401(struct mpu_config *devc)
return ok;
}
-static void
-set_uart_mode(int dev, struct mpu_config *devc, int arg)
+static void set_uart_mode(int dev, struct mpu_config *devc, int arg)
{
if (!arg && (devc->capabilities & MPU_CAP_INTLG))
- {
- return;
- }
+ return;
if ((devc->uart_mode == 0) == (arg == 0))
- {
- return; /* Already set */
- }
+ return; /* Already set */
reset_mpu401(devc); /* This exits the uart mode */
if (arg)
- {
- if (mpu_cmd(dev, UART_MODE_ON, 0) < 0)
- {
- printk("MPU%d: Can't enter UART mode\n", devc->devno);
- devc->uart_mode = 0;
- return;
- }
- }
+ {
+ if (mpu_cmd(dev, UART_MODE_ON, 0) < 0)
+ {
+ printk(KERN_ERR "mpu401: Can't enter UART mode\n");
+ devc->uart_mode = 0;
+ return;
+ }
+ }
devc->uart_mode = arg;
}
-int
-probe_mpu401(struct address_info *hw_config)
+int probe_mpu401(struct address_info *hw_config)
{
- int ok = 0;
+ int ok = 0;
struct mpu_config tmp_devc;
if (check_region(hw_config->io_base, 2))
- {
- printk("\n\nmpu401.c: I/O port %x already in use\n\n", hw_config->io_base);
- return 0;
- }
+ {
+ 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;
@@ -1248,27 +1184,32 @@ probe_mpu401(struct address_info *hw_config)
return 1;
if (inb(hw_config->io_base + 1) == 0xff)
- {
- DDB(printk("MPU401: Port %x looks dead.\n", hw_config->io_base));
- return 0; /* Just bus float? */
- }
+ {
+ DDB(printk("MPU401: Port %x looks dead.\n", hw_config->io_base));
+ return 0; /* Just bus float? */
+ }
ok = reset_mpu401(&tmp_devc);
if (!ok)
- {
- DDB(printk("MPU401: Reset failed on port %x\n", hw_config->io_base));
- }
+ {
+ DDB(printk("MPU401: Reset failed on port %x\n", hw_config->io_base));
+ }
return ok;
}
-void
-unload_mpu401(struct address_info *hw_config)
+void unload_mpu401(struct address_info *hw_config)
{
+ void *p;
+ int n=hw_config->slots[1];
+
release_region(hw_config->io_base, 2);
if (hw_config->always_detect == 0 && hw_config->irq > 0)
- snd_release_irq(hw_config->irq);
- sound_unload_mididev(hw_config->slots[1]);
+ free_irq(hw_config->irq, (void *)n);
+ p=mpu401_synth_operations[n];
+ sound_unload_mididev(n);
sound_unload_timerdev(hw_config->slots[2]);
+ if(p)
+ kfree(p);
}
/*****************************************************
@@ -1285,23 +1226,20 @@ static volatile unsigned long curr_ticks, curr_clocks;
static unsigned long prev_event_time;
static int metronome_mode;
-static unsigned long
-clocks2ticks(unsigned long clocks)
+static unsigned long clocks2ticks(unsigned long clocks)
{
/*
- * The MPU-401 supports just a limited set of possible timebase values.
- * Since the applications require more choices, the driver has to
- * program the HW to do its best and to convert between the HW and
- * actual timebases.
+ * The MPU-401 supports just a limited set of possible timebase values.
+ * Since the applications require more choices, the driver has to
+ * program the HW to do its best and to convert between the HW and
+ * actual timebases.
*/
-
return ((clocks * curr_timebase) + (hw_timebase / 2)) / hw_timebase;
}
-static void
-set_timebase(int midi_dev, int val)
+static void set_timebase(int midi_dev, int val)
{
- int hw_val;
+ int hw_val;
if (val < 48)
val = 48;
@@ -1314,19 +1252,18 @@ set_timebase(int midi_dev, int val)
hw_val = max_timebase;
if (mpu_cmd(midi_dev, 0xC0 | (hw_val & 0x0f), 0) < 0)
- {
- printk("MPU: Can't set HW timebase to %d\n", hw_val * 24);
- return;
- }
+ {
+ printk(KERN_WARNING "mpu401: Can't set HW timebase to %d\n", hw_val * 24);
+ return;
+ }
hw_timebase = hw_val * 24;
curr_timebase = val;
}
-static void
-tmr_reset(void)
+static void tmr_reset(void)
{
- unsigned long flags;
+ unsigned long flags;
save_flags(flags);
cli();
@@ -1336,8 +1273,7 @@ tmr_reset(void)
restore_flags(flags);
}
-static void
-set_timer_mode(int midi_dev)
+static void set_timer_mode(int midi_dev)
{
if (timer_mode & TMR_MODE_CLS)
mpu_cmd(midi_dev, 0x3c, 0); /* Use CLS sync */
@@ -1345,31 +1281,31 @@ set_timer_mode(int midi_dev)
mpu_cmd(midi_dev, 0x3d, 0); /* Use SMPTE sync */
if (timer_mode & TMR_INTERNAL)
- {
+ {
mpu_cmd(midi_dev, 0x80, 0); /* Use MIDI sync */
- } else
- {
- if (timer_mode & (TMR_MODE_MIDI | TMR_MODE_CLS))
- {
- mpu_cmd(midi_dev, 0x82, 0); /* Use MIDI sync */
- mpu_cmd(midi_dev, 0x91, 0); /* Enable ext MIDI ctrl */
- } else if (timer_mode & TMR_MODE_FSK)
- mpu_cmd(midi_dev, 0x81, 0); /* Use FSK sync */
- }
+ }
+ else
+ {
+ if (timer_mode & (TMR_MODE_MIDI | TMR_MODE_CLS))
+ {
+ mpu_cmd(midi_dev, 0x82, 0); /* Use MIDI sync */
+ mpu_cmd(midi_dev, 0x91, 0); /* Enable ext MIDI ctrl */
+ }
+ else if (timer_mode & TMR_MODE_FSK)
+ mpu_cmd(midi_dev, 0x81, 0); /* Use FSK sync */
+ }
}
-static void
-stop_metronome(int midi_dev)
+static void stop_metronome(int midi_dev)
{
mpu_cmd(midi_dev, 0x84, 0); /* Disable metronome */
}
-static void
-setup_metronome(int midi_dev)
+static void setup_metronome(int midi_dev)
{
- int numerator, denominator;
- int clks_per_click, num_32nds_per_beat;
- int beats_per_measure;
+ int numerator, denominator;
+ int clks_per_click, num_32nds_per_beat;
+ int beats_per_measure;
numerator = ((unsigned) metronome_mode >> 24) & 0xff;
denominator = ((unsigned) metronome_mode >> 16) & 0xff;
@@ -1380,15 +1316,14 @@ setup_metronome(int midi_dev)
if (!metronome_mode)
mpu_cmd(midi_dev, 0x84, 0); /* Disable metronome */
else
- {
- mpu_cmd(midi_dev, 0xE4, clks_per_click);
- mpu_cmd(midi_dev, 0xE6, beats_per_measure);
- mpu_cmd(midi_dev, 0x83, 0); /* Enable metronome without accents */
- }
+ {
+ mpu_cmd(midi_dev, 0xE4, clks_per_click);
+ mpu_cmd(midi_dev, 0xE6, beats_per_measure);
+ mpu_cmd(midi_dev, 0x83, 0); /* Enable metronome without accents */
+ }
}
-static int
-mpu_start_timer(int midi_dev)
+static int mpu_start_timer(int midi_dev)
{
tmr_reset();
set_timer_mode(midi_dev);
@@ -1397,25 +1332,24 @@ mpu_start_timer(int midi_dev)
return TIMER_NOT_ARMED; /* Already running */
if (timer_mode & TMR_INTERNAL)
- {
- mpu_cmd(midi_dev, 0x02, 0); /* Send MIDI start */
- tmr_running = 1;
- return TIMER_NOT_ARMED;
- } else
- {
- mpu_cmd(midi_dev, 0x35, 0); /* Enable mode messages to PC */
- mpu_cmd(midi_dev, 0x38, 0); /* Enable sys common messages to PC */
- mpu_cmd(midi_dev, 0x39, 0); /* Enable real time messages to PC */
- mpu_cmd(midi_dev, 0x97, 0); /* Enable system exclusive messages to PC */
- }
-
+ {
+ mpu_cmd(midi_dev, 0x02, 0); /* Send MIDI start */
+ tmr_running = 1;
+ return TIMER_NOT_ARMED;
+ }
+ else
+ {
+ mpu_cmd(midi_dev, 0x35, 0); /* Enable mode messages to PC */
+ mpu_cmd(midi_dev, 0x38, 0); /* Enable sys common messages to PC */
+ mpu_cmd(midi_dev, 0x39, 0); /* Enable real time messages to PC */
+ mpu_cmd(midi_dev, 0x97, 0); /* Enable system exclusive messages to PC */
+ }
return TIMER_ARMED;
}
-static int
-mpu_timer_open(int dev, int mode)
+static int mpu_timer_open(int dev, int mode)
{
- int midi_dev = sound_timer_devs[dev]->devlink;
+ int midi_dev = sound_timer_devs[dev]->devlink;
if (timer_open)
return -EBUSY;
@@ -1435,10 +1369,9 @@ mpu_timer_open(int dev, int mode)
return 0;
}
-static void
-mpu_timer_close(int dev)
+static void mpu_timer_close(int dev)
{
- int midi_dev = sound_timer_devs[dev]->devlink;
+ int midi_dev = sound_timer_devs[dev]->devlink;
timer_open = tmr_running = 0;
mpu_cmd(midi_dev, 0x15, 0); /* Stop all */
@@ -1447,86 +1380,80 @@ mpu_timer_close(int dev)
stop_metronome(midi_dev);
}
-static int
-mpu_timer_event(int dev, unsigned char *event)
+static int mpu_timer_event(int dev, unsigned char *event)
{
- unsigned char command = event[1];
- unsigned long parm = *(unsigned int *) &event[4];
- int midi_dev = sound_timer_devs[dev]->devlink;
+ unsigned char command = event[1];
+ unsigned long parm = *(unsigned int *) &event[4];
+ int midi_dev = sound_timer_devs[dev]->devlink;
switch (command)
- {
- case TMR_WAIT_REL:
- parm += prev_event_time;
- case TMR_WAIT_ABS:
- if (parm > 0)
- {
- long time;
-
- if (parm <= curr_ticks) /* It's the time */
- return TIMER_NOT_ARMED;
-
- time = parm;
- next_event_time = prev_event_time = time;
-
- return TIMER_ARMED;
- }
- break;
-
- case TMR_START:
- if (tmr_running)
- break;
- return mpu_start_timer(midi_dev);
- break;
-
- case TMR_STOP:
- mpu_cmd(midi_dev, 0x01, 0); /* Send MIDI stop */
- stop_metronome(midi_dev);
- tmr_running = 0;
- break;
-
- case TMR_CONTINUE:
- if (tmr_running)
- break;
- mpu_cmd(midi_dev, 0x03, 0); /* Send MIDI continue */
- setup_metronome(midi_dev);
- tmr_running = 1;
- break;
-
- case TMR_TEMPO:
- if (parm)
- {
- if (parm < 8)
- parm = 8;
- if (parm > 250)
- parm = 250;
-
- if (mpu_cmd(midi_dev, 0xE0, parm) < 0)
- printk("MPU: Can't set tempo to %d\n", (int) parm);
- curr_tempo = parm;
- }
- break;
-
- case TMR_ECHO:
- seq_copy_to_input(event, 8);
- break;
-
- case TMR_TIMESIG:
- if (metronome_mode) /* Metronome enabled */
- {
- metronome_mode = parm;
- setup_metronome(midi_dev);
- }
- break;
-
- default:;
- }
+ {
+ case TMR_WAIT_REL:
+ parm += prev_event_time;
+ case TMR_WAIT_ABS:
+ if (parm > 0)
+ {
+ long time;
+
+ if (parm <= curr_ticks) /* It's the time */
+ return TIMER_NOT_ARMED;
+ time = parm;
+ next_event_time = prev_event_time = time;
+
+ return TIMER_ARMED;
+ }
+ break;
+
+ case TMR_START:
+ if (tmr_running)
+ break;
+ return mpu_start_timer(midi_dev);
+
+ case TMR_STOP:
+ mpu_cmd(midi_dev, 0x01, 0); /* Send MIDI stop */
+ stop_metronome(midi_dev);
+ tmr_running = 0;
+ break;
+ case TMR_CONTINUE:
+ if (tmr_running)
+ break;
+ mpu_cmd(midi_dev, 0x03, 0); /* Send MIDI continue */
+ setup_metronome(midi_dev);
+ tmr_running = 1;
+ break;
+
+ case TMR_TEMPO:
+ if (parm)
+ {
+ if (parm < 8)
+ parm = 8;
+ if (parm > 250)
+ parm = 250;
+ if (mpu_cmd(midi_dev, 0xE0, parm) < 0)
+ printk(KERN_WARNING "mpu401: Can't set tempo to %d\n", (int) parm);
+ curr_tempo = parm;
+ }
+ break;
+
+ case TMR_ECHO:
+ seq_copy_to_input(event, 8);
+ break;
+
+ case TMR_TIMESIG:
+ if (metronome_mode) /* Metronome enabled */
+ {
+ metronome_mode = parm;
+ setup_metronome(midi_dev);
+ }
+ break;
+
+ default:
+ }
return TIMER_NOT_ARMED;
}
-static unsigned long
-mpu_timer_get_time(int dev)
+static unsigned long mpu_timer_get_time(int dev)
{
if (!timer_open)
return 0;
@@ -1534,128 +1461,115 @@ mpu_timer_get_time(int dev)
return curr_ticks;
}
-static int
-mpu_timer_ioctl(int dev,
- unsigned int command, caddr_t arg)
+static int mpu_timer_ioctl(int dev, unsigned int command, caddr_t arg)
{
- int midi_dev = sound_timer_devs[dev]->devlink;
+ int midi_dev = sound_timer_devs[dev]->devlink;
switch (command)
- {
- case SNDCTL_TMR_SOURCE:
- {
- int parm;
-
- parm = *(int *) arg;
- parm &= timer_caps;
-
- if (parm != 0)
- {
- timer_mode = parm;
-
- if (timer_mode & TMR_MODE_CLS)
- mpu_cmd(midi_dev, 0x3c, 0); /* Use CLS sync */
- else if (timer_mode & TMR_MODE_SMPTE)
- mpu_cmd(midi_dev, 0x3d, 0); /* Use SMPTE sync */
- }
- return (*(int *) arg = timer_mode);
- }
- break;
-
- case SNDCTL_TMR_START:
- mpu_start_timer(midi_dev);
- return 0;
- break;
-
- case SNDCTL_TMR_STOP:
- tmr_running = 0;
- mpu_cmd(midi_dev, 0x01, 0); /* Send MIDI stop */
- stop_metronome(midi_dev);
- return 0;
- break;
-
- case SNDCTL_TMR_CONTINUE:
- if (tmr_running)
- return 0;
- tmr_running = 1;
- mpu_cmd(midi_dev, 0x03, 0); /* Send MIDI continue */
- return 0;
- break;
-
- case SNDCTL_TMR_TIMEBASE:
- {
- int val;
-
- val = *(int *) arg;
- if (val)
- set_timebase(midi_dev, val);
-
- return (*(int *) arg = curr_timebase);
- }
- break;
-
- case SNDCTL_TMR_TEMPO:
- {
- int val;
- int ret;
-
- val = *(int *) arg;
-
- if (val)
- {
- if (val < 8)
- val = 8;
- if (val > 250)
- val = 250;
- if ((ret = mpu_cmd(midi_dev, 0xE0, val)) < 0)
- {
- printk("MPU: Can't set tempo to %d\n", (int) val);
- return ret;
- }
- curr_tempo = val;
- }
- return (*(int *) arg = curr_tempo);
- }
- break;
-
- case SNDCTL_SEQ_CTRLRATE:
- {
- int val;
-
- val = *(int *) arg;
- if (val != 0) /* Can't change */
- return -EINVAL;
-
- return (*(int *) arg = ((curr_tempo * curr_timebase) + 30) / 60);
- }
- break;
-
- case SNDCTL_SEQ_GETTIME:
- return (*(int *) arg = curr_ticks);
- break;
-
- case SNDCTL_TMR_METRONOME:
- metronome_mode = *(int *) arg;
- setup_metronome(midi_dev);
- return 0;
- break;
-
- default:;
- }
+ {
+ case SNDCTL_TMR_SOURCE:
+ {
+ int parm;
+
+ parm = *(int *) arg;
+ parm &= timer_caps;
+ if (parm != 0)
+ {
+ timer_mode = parm;
+
+ if (timer_mode & TMR_MODE_CLS)
+ mpu_cmd(midi_dev, 0x3c, 0); /* Use CLS sync */
+ else if (timer_mode & TMR_MODE_SMPTE)
+ mpu_cmd(midi_dev, 0x3d, 0); /* Use SMPTE sync */
+ }
+ return (*(int *) arg = timer_mode);
+ }
+ break;
+
+ case SNDCTL_TMR_START:
+ mpu_start_timer(midi_dev);
+ return 0;
+
+ case SNDCTL_TMR_STOP:
+ tmr_running = 0;
+ mpu_cmd(midi_dev, 0x01, 0); /* Send MIDI stop */
+ stop_metronome(midi_dev);
+ return 0;
+
+ case SNDCTL_TMR_CONTINUE:
+ if (tmr_running)
+ return 0;
+ tmr_running = 1;
+ mpu_cmd(midi_dev, 0x03, 0); /* Send MIDI continue */
+ return 0;
+
+ case SNDCTL_TMR_TIMEBASE:
+ {
+ int val;
+
+ val = *(int *) arg;
+ if (val)
+ set_timebase(midi_dev, val);
+ return (*(int *) arg = curr_timebase);
+ }
+ break;
+
+ case SNDCTL_TMR_TEMPO:
+ {
+ int val;
+ int ret;
+
+ val = *(int *) arg;
+
+ if (val)
+ {
+ if (val < 8)
+ val = 8;
+ if (val > 250)
+ val = 250;
+ if ((ret = mpu_cmd(midi_dev, 0xE0, val)) < 0)
+ {
+ printk(KERN_WARNING "mpu401: Can't set tempo to %d\n", (int) val);
+ return ret;
+ }
+ curr_tempo = val;
+ }
+ return (*(int *) arg = curr_tempo);
+ }
+ break;
+
+ case SNDCTL_SEQ_CTRLRATE:
+ {
+ int val;
+
+ val = *(int *) arg;
+ if (val != 0) /* Can't change */
+ return -EINVAL;
+ return (*(int *) arg = ((curr_tempo * curr_timebase) + 30) / 60);
+ }
+ break;
+
+ case SNDCTL_SEQ_GETTIME:
+ return (*(int *) arg = curr_ticks);
+
+ case SNDCTL_TMR_METRONOME:
+ metronome_mode = *(int *) arg;
+ setup_metronome(midi_dev);
+ return 0;
+
+ default:
+ }
return -EINVAL;
}
-static void
-mpu_timer_arm(int dev, long time)
+static void mpu_timer_arm(int dev, long time)
{
if (time < 0)
time = curr_ticks + 1;
else if (time <= curr_ticks) /* It's the time */
return;
-
next_event_time = prev_event_time = time;
-
return;
}
@@ -1672,10 +1586,8 @@ static struct sound_timer_operations mpu_timer =
mpu_timer_arm
};
-static void
-mpu_timer_interrupt(void)
+static void mpu_timer_interrupt(void)
{
-
if (!timer_open)
return;
@@ -1686,10 +1598,10 @@ mpu_timer_interrupt(void)
curr_ticks = clocks2ticks(curr_clocks);
if (curr_ticks >= next_event_time)
- {
- next_event_time = (unsigned long) -1;
- sequencer_timer(0);
- }
+ {
+ next_event_time = (unsigned long) -1;
+ sequencer_timer(0);
+ }
}
static void timer_ext_event(struct mpu_config *devc, int event, int parm)
@@ -1706,8 +1618,9 @@ static void timer_ext_event(struct mpu_config *devc, int event, int parm)
break;
case TMR_START:
- printk("Ext MIDI start\n");
+ printk("Ext MIDI start\n");
if (!tmr_running)
+ {
if (timer_mode & TMR_EXTERNAL)
{
tmr_running = 1;
@@ -1715,6 +1628,7 @@ static void timer_ext_event(struct mpu_config *devc, int event, int parm)
next_event_time = 0;
STORE(SEQ_START_TIMER());
}
+ }
break;
case TMR_STOP:
diff --git a/drivers/sound/opl3.c b/drivers/sound/opl3.c
index 36734c2e7..cd768801f 100644
--- a/drivers/sound/opl3.c
+++ b/drivers/sound/opl3.c
@@ -2,25 +2,30 @@
* sound/opl3.c
*
* A low level driver for Yamaha YM3812 and OPL-3 -chips
- */
-/*
+ *
+*
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
+ *
+ *
+ * Changes
+ * Thomas Sailer ioctl code reworked (vmalloc/vfree removed)
+ * Alan Cox modularisation, fixed sound_mem allocs.
+ *
+ * Status
+ * Believed to work. Badly needs rewriting a bit to support multiple
+ * OPL3 devices.
*/
-/*
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- */
+
#include <linux/config.h>
#include <linux/module.h>
#include <linux/delay.h>
/*
* Major improvements to the FM handling 30AUG92 by Rob Hooft,
- */
-/*
* hooft@chem.ruu.nl
*/
@@ -109,32 +114,32 @@ static int opl3_ioctl(int dev, unsigned int cmd, caddr_t arg)
struct sbi_instrument ins;
switch (cmd) {
- case SNDCTL_FM_LOAD_INSTR:
- printk(KERN_WARNING "Warning: Obsolete ioctl(SNDCTL_FM_LOAD_INSTR) used. Fix the program.\n");
- if (__copy_from_user(&ins, arg, sizeof(ins)))
- return -EFAULT;
- if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR) {
- printk("FM Error: Invalid instrument number %d\n", ins.channel);
- return -EINVAL;
- }
- return store_instr(ins.channel, &ins);
+ case SNDCTL_FM_LOAD_INSTR:
+ printk(KERN_WARNING "Warning: Obsolete ioctl(SNDCTL_FM_LOAD_INSTR) used. Fix the program.\n");
+ if (copy_from_user(&ins, arg, sizeof(ins)))
+ return -EFAULT;
+ if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR) {
+ printk(KERN_WARNING "FM Error: Invalid instrument number %d\n", ins.channel);
+ return -EINVAL;
+ }
+ return store_instr(ins.channel, &ins);
- case SNDCTL_SYNTH_INFO:
- devc->fm_info.nr_voices = (devc->nr_voice == 12) ? 6 : devc->nr_voice;
- if (__copy_to_user(arg, &devc->fm_info, sizeof(devc->fm_info)))
- return -EFAULT;
- return 0;
+ case SNDCTL_SYNTH_INFO:
+ devc->fm_info.nr_voices = (devc->nr_voice == 12) ? 6 : devc->nr_voice;
+ if (copy_to_user(arg, &devc->fm_info, sizeof(devc->fm_info)))
+ return -EFAULT;
+ return 0;
- case SNDCTL_SYNTH_MEMAVL:
- return 0x7fffffff;
+ case SNDCTL_SYNTH_MEMAVL:
+ return 0x7fffffff;
- case SNDCTL_FM_4OP_ENABLE:
- if (devc->model == 2)
- enter_4op_mode();
- return 0;
+ case SNDCTL_FM_4OP_ENABLE:
+ if (devc->model == 2)
+ enter_4op_mode();
+ return 0;
- default:
- return -EINVAL;
+ default:
+ return -EINVAL;
}
}
@@ -151,8 +156,8 @@ int opl3_detect(int ioaddr, int *osp)
* Note2! The chip is initialized if detected.
*/
- unsigned char stat1, signature;
- int i;
+ unsigned char stat1, signature;
+ int i;
if (devc != NULL)
{
@@ -160,10 +165,7 @@ int opl3_detect(int ioaddr, int *osp)
return 0;
}
- devc = (struct opl_devinfo *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(*devc)));
- sound_mem_sizes[sound_nblocks] = sizeof(*devc);
- if (sound_nblocks < 1024)
- sound_nblocks++;;
+ devc = (struct opl_devinfo *)kmalloc(sizeof(*devc), GFP_KERNEL);
if (devc == NULL)
{
@@ -333,7 +335,7 @@ static char fm_volume_table[128] =
static void calc_vol(unsigned char *regbyte, int volume, int main_vol)
{
- int level = (~*regbyte & 0x3f);
+ int level = (~*regbyte & 0x3f);
if (main_vol > 127)
main_vol = 127;
@@ -814,7 +816,8 @@ static int opl3_load_patch(int dev, int format, const char *addr,
return -EINVAL;
}
- copy_from_user(&((char *) &ins)[offs], &(addr)[offs], sizeof(ins) - offs);
+ if(copy_from_user(&((char *) &ins)[offs], &(addr)[offs], sizeof(ins) - offs))
+ return -EFAULT;
if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR)
{
@@ -1199,6 +1202,7 @@ void cleanup_module(void)
{
if (devc)
{
+ kfree(devc);
devc = NULL;
sound_unload_synthdev(me);
}
diff --git a/drivers/sound/pas2_card.c b/drivers/sound/pas2_card.c
index 656034d54..bf95b84d5 100644
--- a/drivers/sound/pas2_card.c
+++ b/drivers/sound/pas2_card.c
@@ -164,7 +164,7 @@ static int config_pas_hw(struct address_info *hw_config)
}
else
{
- if (snd_set_irq_handler(pas_irq, pasintr, "PAS16", hw_config->osp) < 0)
+ if (request_irq(pas_irq, pasintr, "PAS16", 0, NULL) < 0)
ok = 0;
}
}
@@ -355,7 +355,7 @@ void
unload_pas(struct address_info *hw_config)
{
sound_free_dma(hw_config->dma);
- snd_release_irq(hw_config->irq);
+ free_irq(hw_config->irq, NULL);
}
#ifdef MODULE
diff --git a/drivers/sound/pss.c b/drivers/sound/pss.c
index 9d62dd485..7a0a2e66e 100644
--- a/drivers/sound/pss.c
+++ b/drivers/sound/pss.c
@@ -11,7 +11,8 @@
* for more info.
*/
/*
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ * Thomas Sailer ioctl code reworked (vmalloc/vfree removed)
+ * Alan Cox modularisation, clean up.
*/
#include <linux/config.h>
#include <linux/module.h>
@@ -62,12 +63,12 @@ static int pss_synthLen = 0;
#endif
typedef struct pss_confdata
- {
- int base;
- int irq;
- int dma;
- int *osp;
- }
+{
+ int base;
+ int irq;
+ int dma;
+ int *osp;
+}
pss_confdata;
@@ -77,12 +78,11 @@ static pss_confdata *devc = &pss_data;
static int pss_initialized = 0;
static int nonstandard_microcode = 0;
-static void
-pss_write(int data)
+static void pss_write(int data)
{
- int i, limit;
+ int i, limit;
- limit = jiffies + 10; /* The timeout is 0.1 seconds */
+ limit = jiffies + HZ/10; /* The timeout is 0.1 seconds */
/*
* Note! the i<5000000 is an emergency exit. The dsp_command() is sometimes
* called while interrupts are disabled. This means that the timer is
@@ -92,21 +92,20 @@ pss_write(int data)
*/
for (i = 0; i < 5000000 && jiffies < limit; i++)
- {
- if (inw(devc->base + PSS_STATUS) & PSS_WRITE_EMPTY)
- {
- outw(devc->base + PSS_DATA, data);
- return;
- }
- }
- printk("PSS: DSP Command (%04x) Timeout.\n", data);
+ {
+ if (inw(devc->base + PSS_STATUS) & PSS_WRITE_EMPTY)
+ {
+ outw(devc->base + PSS_DATA, data);
+ return;
+ }
+ }
+ printk(KERN_ERR "PSS: DSP Command (%04x) Timeout.\n", data);
}
-int
-probe_pss(struct address_info *hw_config)
+int probe_pss(struct address_info *hw_config)
{
- unsigned short id;
- int irq, dma;
+ unsigned short id;
+ int irq, dma;
devc->base = hw_config->io_base;
irq = devc->irq = hw_config->irq;
@@ -129,8 +128,7 @@ probe_pss(struct address_info *hw_config)
return 1;
}
-static int
-set_irq(pss_confdata * devc, int dev, int irq)
+static int set_irq(pss_confdata * devc, int dev, int irq)
{
static unsigned short irq_bits[16] =
{
@@ -148,16 +146,15 @@ set_irq(pss_confdata * devc, int dev, int irq)
tmp = inw(REG(dev)) & ~0x38; /* Load confreg, mask IRQ bits out */
if ((bits = irq_bits[irq]) == 0 && irq != 0)
- {
- printk("PSS: Invalid IRQ %d\n", irq);
- return 0;
- }
+ {
+ printk(KERN_ERR "PSS: Invalid IRQ %d\n", irq);
+ return 0;
+ }
outw(tmp | bits, REG(dev));
return 1;
}
-static int
-set_io_base(pss_confdata * devc, int dev, int base)
+static int set_io_base(pss_confdata * devc, int dev, int base)
{
unsigned short tmp = inw(REG(dev)) & 0x003f;
unsigned short bits = (base & 0x0ffc) << 4;
@@ -167,8 +164,7 @@ set_io_base(pss_confdata * devc, int dev, int base)
return 1;
}
-static int
-set_dma(pss_confdata * devc, int dev, int dma)
+static int set_dma(pss_confdata * devc, int dev, int dma)
{
static unsigned short dma_bits[8] =
{
@@ -184,150 +180,139 @@ set_dma(pss_confdata * devc, int dev, int dma)
tmp = inw(REG(dev)) & ~0x07; /* Load confreg, mask DMA bits out */
if ((bits = dma_bits[dma]) == 0 && dma != 4)
- {
- printk("PSS: Invalid DMA %d\n", dma);
+ {
+ printk(KERN_ERR "PSS: Invalid DMA %d\n", dma);
return 0;
- }
+ }
outw(tmp | bits, REG(dev));
return 1;
}
-static int
-pss_reset_dsp(pss_confdata * devc)
+static int pss_reset_dsp(pss_confdata * devc)
{
- unsigned long i, limit = jiffies + 10;
+ unsigned long i, limit = jiffies + HZ/10;
outw(0x2000, REG(PSS_CONTROL));
-
- for (i = 0; i < 32768 && jiffies < limit; i++)
+ for (i = 0; i < 32768 && (limit-jiffies >= 0); i++)
inw(REG(PSS_CONTROL));
-
outw(0x0000, REG(PSS_CONTROL));
-
return 1;
}
-static int
-pss_put_dspword(pss_confdata * devc, unsigned short word)
+static int pss_put_dspword(pss_confdata * devc, unsigned short word)
{
- int i, val;
+ int i, val;
for (i = 0; i < 327680; i++)
- {
- val = inw(REG(PSS_STATUS));
- if (val & PSS_WRITE_EMPTY)
- {
- outw(word, REG(PSS_DATA));
- return 1;
- }
- }
+ {
+ val = inw(REG(PSS_STATUS));
+ if (val & PSS_WRITE_EMPTY)
+ {
+ outw(word, REG(PSS_DATA));
+ return 1;
+ }
+ }
return 0;
}
-static int
-pss_get_dspword(pss_confdata * devc, unsigned short *word)
+static int pss_get_dspword(pss_confdata * devc, unsigned short *word)
{
- int i, val;
+ int i, val;
for (i = 0; i < 327680; i++)
- {
- val = inw(REG(PSS_STATUS));
- if (val & PSS_READ_FULL)
- {
- *word = inw(REG(PSS_DATA));
- return 1;
- }
- }
-
+ {
+ val = inw(REG(PSS_STATUS));
+ if (val & PSS_READ_FULL)
+ {
+ *word = inw(REG(PSS_DATA));
+ return 1;
+ }
+ }
return 0;
}
-static int
-pss_download_boot(pss_confdata * devc, unsigned char *block, int size, int flags)
+static int pss_download_boot(pss_confdata * devc, unsigned char *block, int size, int flags)
{
- int i, limit, val, count;
+ int i, limit, val, count;
if (flags & CPF_FIRST)
- {
+ {
/*_____ Warn DSP software that a boot is coming */
- outw(0x00fe, REG(PSS_DATA));
-
- limit = jiffies + 10;
+ outw(0x00fe, REG(PSS_DATA));
- for (i = 0; i < 32768 && jiffies < limit; i++)
- if (inw(REG(PSS_DATA)) == 0x5500)
- break;
-
- outw(*block++, REG(PSS_DATA));
+ limit = jiffies + HZ/10;
+ for (i = 0; i < 32768 && jiffies < limit; i++)
+ if (inw(REG(PSS_DATA)) == 0x5500)
+ break;
- pss_reset_dsp(devc);
- }
+ outw(*block++, REG(PSS_DATA));
+ pss_reset_dsp(devc);
+ }
count = 1;
while (1)
- {
- int j;
+ {
+ int j;
- for (j = 0; j < 327670; j++)
- {
+ for (j = 0; j < 327670; j++)
+ {
/*_____ Wait for BG to appear */
- if (inw(REG(PSS_STATUS)) & PSS_FLAG3)
- break;
- }
-
- if (j == 327670)
- {
- /* It's ok we timed out when the file was empty */
- if (count >= size && flags & CPF_LAST)
- break;
- else
- {
- printk("\nPSS: Download timeout problems, byte %d=%d\n", count, size);
- return 0;
- }
- }
+ if (inw(REG(PSS_STATUS)) & PSS_FLAG3)
+ break;
+ }
+
+ if (j == 327670)
+ {
+ /* It's ok we timed out when the file was empty */
+ if (count >= size && flags & CPF_LAST)
+ break;
+ else
+ {
+ printk("\nPSS: Download timeout problems, byte %d=%d\n", count, size);
+ return 0;
+ }
+ }
/*_____ Send the next byte */
- outw(*block++, REG(PSS_DATA));
- count++;
- }
+ outw(*block++, REG(PSS_DATA));
+ count++;
+ }
if (flags & CPF_LAST)
- {
+ {
/*_____ Why */
- outw(0, REG(PSS_DATA));
-
- limit = jiffies + 10;
- for (i = 0; i < 32768 && jiffies < limit; i++)
- val = inw(REG(PSS_STATUS));
-
- limit = jiffies + 10;
- for (i = 0; i < 32768 && jiffies < limit; i++)
- {
- val = inw(REG(PSS_STATUS));
- if (val & 0x4000)
- break;
- }
-
- /* now read the version */
- for (i = 0; i < 32000; i++)
- {
- val = inw(REG(PSS_STATUS));
- if (val & PSS_READ_FULL)
- break;
- }
- if (i == 32000)
- return 0;
-
- val = inw(REG(PSS_DATA));
- /* printk( "<PSS: microcode version %d.%d loaded>", val/16, val % 16); */
- }
+ outw(0, REG(PSS_DATA));
+
+ limit = jiffies + HZ/10;
+ for (i = 0; i < 32768 && (limit - jiffies >= 0); i++)
+ val = inw(REG(PSS_STATUS));
+
+ limit = jiffies + HZ/10;
+ for (i = 0; i < 32768 && (limit-jiffies >= 0); i++)
+ {
+ val = inw(REG(PSS_STATUS));
+ if (val & 0x4000)
+ break;
+ }
+
+ /* now read the version */
+ for (i = 0; i < 32000; i++)
+ {
+ val = inw(REG(PSS_STATUS));
+ if (val & PSS_READ_FULL)
+ break;
+ }
+ if (i == 32000)
+ return 0;
+
+ val = inw(REG(PSS_DATA));
+ /* printk( "<PSS: microcode version %d.%d loaded>", val/16, val % 16); */
+ }
return 1;
}
-void
-attach_pss(struct address_info *hw_config)
+void attach_pss(struct address_info *hw_config)
{
unsigned short id;
- char tmp[100];
+ char tmp[100];
devc->base = hw_config->io_base;
devc->irq = hw_config->irq;
@@ -350,20 +335,20 @@ attach_pss(struct address_info *hw_config)
#if YOU_REALLY_WANT_TO_ALLOCATE_THESE_RESOURCES
if (sound_alloc_dma(hw_config->dma, "PSS"))
- {
- printk("pss.c: Can't allocate DMA channel\n");
- return;
- }
+ {
+ printk("pss.c: Can't allocate DMA channel.\n");
+ return;
+ }
if (!set_irq(devc, CONF_PSS, devc->irq))
- {
- printk("PSS: IRQ error\n");
- return;
- }
+ {
+ printk("PSS: IRQ allocation error.\n");
+ return;
+ }
if (!set_dma(devc, CONF_PSS, devc->dma))
- {
- printk("PSS: DRQ error\n");
- return;
- }
+ {
+ printk(KERN_ERR "PSS: DMA allocation error\n");
+ return;
+ }
#endif
pss_initialized = 1;
@@ -371,8 +356,7 @@ attach_pss(struct address_info *hw_config)
conf_printf(tmp, hw_config);
}
-static void
-pss_init_speaker(void)
+static void pss_init_speaker(void)
{
/* Don't ask what are these commands. I really don't know */
pss_write(0x0010);
@@ -387,53 +371,52 @@ pss_init_speaker(void)
pss_write(0x0800 | 0x00ce); /* Stereo switch? */
}
-int
-probe_pss_mpu(struct address_info *hw_config)
+int probe_pss_mpu(struct address_info *hw_config)
{
- int timeout;
+ int timeout;
if (!pss_initialized)
return 0;
if (check_region(hw_config->io_base, 2))
- {
- printk("PSS: MPU I/O port conflict\n");
- return 0;
- }
+ {
+ printk("PSS: MPU I/O port conflict\n");
+ return 0;
+ }
if (!set_io_base(devc, CONF_MIDI, hw_config->io_base))
- {
- printk("PSS: MIDI base error.\n");
+ {
+ printk("PSS: MIDI base could not be set.\n");
return 0;
- }
+ }
if (!set_irq(devc, CONF_MIDI, hw_config->irq))
- {
- printk("PSS: MIDI IRQ error.\n");
+ {
+ printk("PSS: MIDI IRQ allocation error.\n");
return 0;
- }
+ }
if (!pss_synthLen)
- {
- printk("PSS: Can't enable MPU. MIDI synth microcode not available.\n");
- return 0;
- }
+ {
+ printk(KERN_ERR "PSS: Can't enable MPU. MIDI synth microcode not available.\n");
+ return 0;
+ }
if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
- {
- printk("PSS: Unable to load MIDI synth microcode to DSP.\n");
- return 0;
- }
+ {
+ printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
+ return 0;
+ }
pss_init_speaker();
-/*
- * Finally wait until the DSP algorithm has initialized itself and
- * deactivates receive interrupt.
- */
+ /*
+ * Finally wait until the DSP algorithm has initialized itself and
+ * deactivates receive interrupt.
+ */
for (timeout = 900000; timeout > 0; timeout--)
- {
- if ((inb(hw_config->io_base + 1) & 0x80) == 0) /* Input data avail */
- inb(hw_config->io_base); /* Discard it */
- else
- break; /* No more input */
- }
+ {
+ if ((inb(hw_config->io_base + 1) & 0x80) == 0) /* Input data avail */
+ inb(hw_config->io_base); /* Discard it */
+ else
+ break; /* No more input */
+ }
#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
return probe_mpu401(hw_config);
@@ -442,62 +425,56 @@ probe_pss_mpu(struct address_info *hw_config)
#endif
}
-static int
-pss_coproc_open(void *dev_info, int sub_device)
+static int pss_coproc_open(void *dev_info, int sub_device)
{
switch (sub_device)
- {
- case COPR_MIDI:
-
- if (pss_synthLen == 0)
- {
- printk("PSS: MIDI synth microcode not available.\n");
- return -EIO;
- }
- if (nonstandard_microcode)
- if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
- {
- printk("PSS: Unable to load MIDI synth microcode to DSP.\n");
- return -EIO;
- }
- nonstandard_microcode = 0;
- break;
-
- default:;
- }
+ {
+ case COPR_MIDI:
+ if (pss_synthLen == 0)
+ {
+ printk(KERN_ERR "PSS: MIDI synth microcode not available.\n");
+ return -EIO;
+ }
+ if (nonstandard_microcode)
+ 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 -EIO;
+ }
+ nonstandard_microcode = 0;
+ break;
+
+ default:
+ }
return 0;
}
-static void
-pss_coproc_close(void *dev_info, int sub_device)
+static void pss_coproc_close(void *dev_info, int sub_device)
{
return;
}
-static void
-pss_coproc_reset(void *dev_info)
+static void pss_coproc_reset(void *dev_info)
{
if (pss_synthLen)
if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
- {
- printk("PSS: Unable to load MIDI synth microcode to DSP.\n");
- }
+ {
+ printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
+ }
nonstandard_microcode = 0;
}
-static int
-download_boot_block(void *dev_info, copr_buffer * buf)
+static int download_boot_block(void *dev_info, copr_buffer * buf)
{
if (buf->len <= 0 || buf->len > sizeof(buf->data))
return -EINVAL;
if (!pss_download_boot(devc, buf->data, buf->len, buf->flags))
- {
- printk("PSS: Unable to load microcode block to DSP.\n");
- return -EIO;
- }
+ {
+ printk(KERN_ERR "PSS: Unable to load microcode block to DSP.\n");
+ return -EIO;
+ }
nonstandard_microcode = 1; /* The MIDI microcode has been overwritten */
-
return 0;
}
@@ -512,169 +489,170 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int l
int i, err;
/* printk( "PSS coproc ioctl %x %x %d\n", cmd, arg, local); */
- switch (cmd) {
- case SNDCTL_COPR_RESET:
- pss_coproc_reset(dev_info);
- return 0;
+ switch (cmd)
+ {
+ case SNDCTL_COPR_RESET:
+ pss_coproc_reset(dev_info);
+ return 0;
- case SNDCTL_COPR_LOAD:
- buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
- if (buf == NULL)
- return -ENOSPC;
- if (__copy_from_user(buf, arg, sizeof(copr_buffer))) {
+ case SNDCTL_COPR_LOAD:
+ buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
+ if (buf == NULL)
+ return -ENOSPC;
+ if (copy_from_user(buf, arg, sizeof(copr_buffer))) {
+ vfree(buf);
+ return -EFAULT;
+ }
+ err = download_boot_block(dev_info, buf);
vfree(buf);
- return -EFAULT;
- }
- err = download_boot_block(dev_info, buf);
- vfree(buf);
- return err;
+ return err;
- case SNDCTL_COPR_SENDMSG:
- mbuf = (copr_msg *)vmalloc(sizeof(copr_msg));
- if (mbuf == NULL)
- return -ENOSPC;
- if (__copy_from_user(mbuf, arg, sizeof(copr_msg))) {
- vfree(mbuf);
- return -EFAULT;
- }
- data = (unsigned short *)(mbuf->data);
- save_flags(flags);
- cli();
- for (i = 0; i < mbuf->len; i++) {
- if (!pss_put_dspword(devc, *data++)) {
- restore_flags(flags);
- mbuf->len = i; /* feed back number of WORDs sent */
- err = __copy_to_user(arg, mbuf, sizeof(copr_msg));
+ case SNDCTL_COPR_SENDMSG:
+ mbuf = (copr_msg *)vmalloc(sizeof(copr_msg));
+ if (mbuf == NULL)
+ return -ENOSPC;
+ if (copy_from_user(mbuf, arg, sizeof(copr_msg))) {
vfree(mbuf);
- return err ? -EFAULT : -EIO;
+ return -EFAULT;
}
- }
- restore_flags(flags);
- vfree(mbuf);
- return 0;
-
- case SNDCTL_COPR_RCVMSG:
- err = 0;
- mbuf = (copr_msg *)vmalloc(sizeof(copr_msg));
- if (mbuf == NULL)
- return -ENOSPC;
- data = (unsigned short *)mbuf->data;
- save_flags(flags);
- cli();
- for (i = 0; i < mbuf->len; i++) {
- mbuf->len = i; /* feed back number of WORDs read */
- if (!pss_get_dspword(devc, data++)) {
- if (i == 0)
- err = -EIO;
- break;
+ data = (unsigned short *)(mbuf->data);
+ save_flags(flags);
+ cli();
+ for (i = 0; i < mbuf->len; i++) {
+ if (!pss_put_dspword(devc, *data++)) {
+ restore_flags(flags);
+ mbuf->len = i; /* feed back number of WORDs sent */
+ err = copy_to_user(arg, mbuf, sizeof(copr_msg));
+ vfree(mbuf);
+ return err ? -EFAULT : -EIO;
+ }
}
- }
- restore_flags(flags);
- if (__copy_to_user(arg, mbuf, sizeof(copr_msg)))
- err = -EFAULT;
- vfree(mbuf);
- return err;
-
- case SNDCTL_COPR_RDATA:
- if (__copy_from_user(&dbuf, arg, sizeof(dbuf)))
- return -EFAULT;
- save_flags(flags);
- cli();
- if (!pss_put_dspword(devc, 0x00d0)) {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
restore_flags(flags);
- return -EIO;
- }
- if (!pss_get_dspword(devc, &tmp)) {
+ vfree(mbuf);
+ return 0;
+
+ case SNDCTL_COPR_RCVMSG:
+ err = 0;
+ mbuf = (copr_msg *)vmalloc(sizeof(copr_msg));
+ if (mbuf == NULL)
+ return -ENOSPC;
+ data = (unsigned short *)mbuf->data;
+ save_flags(flags);
+ cli();
+ for (i = 0; i < mbuf->len; i++) {
+ mbuf->len = i; /* feed back number of WORDs read */
+ if (!pss_get_dspword(devc, data++)) {
+ if (i == 0)
+ err = -EIO;
+ break;
+ }
+ }
restore_flags(flags);
- return -EIO;
- }
- dbuf.parm1 = tmp;
- restore_flags(flags);
- if (__copy_to_user(arg, &dbuf, sizeof(dbuf)))
- return -EFAULT;
- return 0;
+ if (copy_to_user(arg, mbuf, sizeof(copr_msg)))
+ err = -EFAULT;
+ vfree(mbuf);
+ return err;
- case SNDCTL_COPR_WDATA:
- if (__copy_from_user(&dbuf, arg, sizeof(dbuf)))
- return -EFAULT;
- save_flags(flags);
- cli();
- if (!pss_put_dspword(devc, 0x00d1)) {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_put_dspword(devc, (unsigned short) (dbuf.parm1 & 0xffff))) {
- restore_flags(flags);
- return -EIO;
- }
- tmp = (unsigned int)dbuf.parm2 & 0xffff;
- if (!pss_put_dspword(devc, tmp)) {
+ case SNDCTL_COPR_RDATA:
+ if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
+ return -EFAULT;
+ save_flags(flags);
+ cli();
+ if (!pss_put_dspword(devc, 0x00d0)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_get_dspword(devc, &tmp)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ dbuf.parm1 = tmp;
restore_flags(flags);
- return -EIO;
- }
- restore_flags(flags);
- return 0;
+ if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
+ return -EFAULT;
+ return 0;
- case SNDCTL_COPR_WCODE:
- if (__copy_from_user(&dbuf, arg, sizeof(dbuf)))
- return -EFAULT;
- save_flags(flags);
- cli();
- if (!pss_put_dspword(devc, 0x00d3)) {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
- restore_flags(flags);
- return -EIO;
- }
- tmp = (unsigned int)dbuf.parm2 & 0x00ff;
- if (!pss_put_dspword(devc, tmp)) {
- restore_flags(flags);
- return -EIO;
- }
- tmp = ((unsigned int)dbuf.parm2 >> 8) & 0xffff;
- if (!pss_put_dspword(devc, tmp)) {
+ case SNDCTL_COPR_WDATA:
+ if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
+ return -EFAULT;
+ save_flags(flags);
+ cli();
+ if (!pss_put_dspword(devc, 0x00d1)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_put_dspword(devc, (unsigned short) (dbuf.parm1 & 0xffff))) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ tmp = (unsigned int)dbuf.parm2 & 0xffff;
+ if (!pss_put_dspword(devc, tmp)) {
+ restore_flags(flags);
+ return -EIO;
+ }
restore_flags(flags);
- return -EIO;
- }
- restore_flags(flags);
- return 0;
+ return 0;
- case SNDCTL_COPR_RCODE:
- if (__copy_from_user(&dbuf, arg, sizeof(dbuf)))
- return -EFAULT;
- save_flags(flags);
- cli();
- if (!pss_put_dspword(devc, 0x00d2)) {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_get_dspword(devc, &tmp)) { /* Read MSB */
+ case SNDCTL_COPR_WCODE:
+ if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
+ return -EFAULT;
+ save_flags(flags);
+ cli();
+ if (!pss_put_dspword(devc, 0x00d3)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ tmp = (unsigned int)dbuf.parm2 & 0x00ff;
+ if (!pss_put_dspword(devc, tmp)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ tmp = ((unsigned int)dbuf.parm2 >> 8) & 0xffff;
+ if (!pss_put_dspword(devc, tmp)) {
+ restore_flags(flags);
+ return -EIO;
+ }
restore_flags(flags);
- return -EIO;
- }
- dbuf.parm1 = tmp << 8;
- if (!pss_get_dspword(devc, &tmp)) { /* Read LSB */
+ return 0;
+
+ case SNDCTL_COPR_RCODE:
+ if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
+ return -EFAULT;
+ save_flags(flags);
+ cli();
+ if (!pss_put_dspword(devc, 0x00d2)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_get_dspword(devc, &tmp)) { /* Read MSB */
+ restore_flags(flags);
+ return -EIO;
+ }
+ dbuf.parm1 = tmp << 8;
+ if (!pss_get_dspword(devc, &tmp)) { /* Read LSB */
+ restore_flags(flags);
+ return -EIO;
+ }
+ dbuf.parm1 |= tmp & 0x00ff;
restore_flags(flags);
- return -EIO;
- }
- dbuf.parm1 |= tmp & 0x00ff;
- restore_flags(flags);
- if (__copy_to_user(arg, &dbuf, sizeof(dbuf)))
- return -EFAULT;
- return 0;
+ if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
+ return -EFAULT;
+ return 0;
- default:
- return -EINVAL;
+ default:
+ return -EINVAL;
}
return -EINVAL;
}
@@ -689,52 +667,47 @@ static coproc_operations pss_coproc_operations =
&pss_data
};
-void
-attach_pss_mpu(struct address_info *hw_config)
+void attach_pss_mpu(struct address_info *hw_config)
{
#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
- {
- attach_mpu401(hw_config); /* Slot 1 */
-
- if (hw_config->slots[1] != -1) /* The MPU driver installed itself */
- midi_devs[hw_config->slots[1]]->coproc = &pss_coproc_operations;
- }
+ attach_mpu401(hw_config); /* Slot 1 */
+ if (hw_config->slots[1] != -1) /* The MPU driver installed itself */
+ midi_devs[hw_config->slots[1]]->coproc = &pss_coproc_operations;
#endif
}
-int
-probe_pss_mss(struct address_info *hw_config)
+int probe_pss_mss(struct address_info *hw_config)
{
- volatile int timeout;
+ volatile int timeout;
if (!pss_initialized)
return 0;
if (check_region(hw_config->io_base, 8))
- {
- printk("PSS: WSS I/O port conflict\n");
+ {
+ 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 error.\n");
- return 0;
- }
+ {
+ printk("PSS: WSS base not settable.\n");
+ return 0;
+ }
if (!set_irq(devc, CONF_WSS, hw_config->irq))
- {
- printk("PSS: WSS IRQ error.\n");
- return 0;
- }
+ {
+ printk("PSS: WSS IRQ allocation error.\n");
+ return 0;
+ }
if (!set_dma(devc, CONF_WSS, hw_config->dma))
- {
- printk("PSS: WSS DRQ error\n");
- return 0;
- }
+ {
+ printk(KERN_ERR "PSS: WSS DMA allocation error\n");
+ return 0;
+ }
/*
- * For some reason the card returns 0xff in the WSS status register
- * immediately after boot. Probably MIDI+SB emulation algorithm
- * downloaded to the ADSP2115 spends some time initializing the card.
- * Let's try to wait until it finishes this task.
+ * For some reason the card returns 0xff in the WSS status register
+ * immediately after boot. Probably MIDI+SB emulation algorithm
+ * downloaded to the ADSP2115 spends some time initializing the card.
+ * Let's try to wait until it finishes this task.
*/
for (timeout = 0;
timeout < 100000 && (inb(hw_config->io_base + 3) & 0x3f) != 0x04;
@@ -748,8 +721,7 @@ probe_pss_mss(struct address_info *hw_config)
return probe_ms_sound(hw_config);
}
-void
-attach_pss_mss(struct address_info *hw_config)
+void attach_pss_mss(struct address_info *hw_config)
{
attach_ms_sound(hw_config); /* Slot 0 */
@@ -757,34 +729,31 @@ attach_pss_mss(struct address_info *hw_config)
audio_devs[hw_config->slots[0]]->coproc = &pss_coproc_operations;
}
-void
-unload_pss(struct address_info *hw_config)
+void unload_pss(struct address_info *hw_config)
{
}
-void
-unload_pss_mpu(struct address_info *hw_config)
+void unload_pss_mpu(struct address_info *hw_config)
{
#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
unload_mpu401(hw_config);
#endif
}
-void
-unload_pss_mss(struct address_info *hw_config)
+void unload_pss_mss(struct address_info *hw_config)
{
unload_ms_sound(hw_config);
}
#ifdef MODULE
-int pss_io = 0x220;
+int pss_io = -1;
-int mss_io = 0x530;
-int mss_irq = 11;
-int mss_dma = 1;
+int mss_io = -1;
+int mss_irq = -1;
+int mss_dma = -1;
-int mpu_io = 0x330;
+int mpu_io = -1;
int mpu_irq = -1;
struct address_info cfgpss = { 0 /* pss_io */, 0, -1, -1 };
@@ -798,22 +767,20 @@ MODULE_PARM(mss_dma, "i");
MODULE_PARM(mpu_io, "i");
MODULE_PARM(mpu_irq, "i");
-static int fw_load = 0;
-static int pssmpu = 0, pssmss = 0;
+static int fw_load = 0;
+static int pssmpu = 0, pssmss = 0;
/*
* Load a PSS sound card module
*/
-int
-init_module(void)
+int init_module(void)
{
-#if 0
- if (pss_io == -1 || irq == -1 || dma == -1) {
- printk("pss: dma, irq and io must be set.\n");
- return -EINVAL;
+ if (pss_io == -1 || mss_io == -1 || mss_irq == -1 || mss_dma == -1) {
+ printk(KERN_INFO "pss: mss_io, mss_dma, mss_irq and pss_io must be set.\n");
+ return -EINVAL;
}
-#endif
+
cfgpss.io_base = pss_io;
cfgmss.io_base = mss_io;
@@ -823,7 +790,8 @@ init_module(void)
cfgmpu.io_base = mpu_io;
cfgmpu.irq = mpu_irq;
- if (!pss_synth) {
+ if (!pss_synth)
+ {
fw_load = 1;
pss_synthLen = mod_firmware_load("/etc/sound/pss_synth", (void *) &pss_synth);
}
@@ -845,8 +813,7 @@ init_module(void)
return 0;
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
if (fw_load && pss_synth)
kfree(pss_synth);
diff --git a/drivers/sound/sb_audio.c b/drivers/sound/sb_audio.c
index 9a0fe3c79..bf3a8dbef 100644
--- a/drivers/sound/sb_audio.c
+++ b/drivers/sound/sb_audio.c
@@ -1151,14 +1151,14 @@ void sb_audio_init(sb_devc * devc, char *name)
}
if ((devc->my_dev = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
- name,
- driver,
- sizeof(struct audio_driver),
- audio_flags,
- format_mask,
- devc,
- devc->dma8,
- devc->dma8)) < 0)
+ name,
+ driver,
+ sizeof(struct audio_driver),
+ audio_flags,
+ format_mask,
+ devc,
+ devc->dma8,
+ devc->dma8)) < 0)
{
printk(KERN_ERR "sb: unable to install audio.\n");
return;
diff --git a/drivers/sound/sb_card.c b/drivers/sound/sb_card.c
index fddf74b79..941422c3f 100644
--- a/drivers/sound/sb_card.c
+++ b/drivers/sound/sb_card.c
@@ -69,6 +69,7 @@ int trix = 0; /* Set trix=1 to load this as support for trix */
int pas2 = 0; /* Set pas2=1 to load this as support for pas2 */
int sm_games = 0; /* Mixer - see sb_mixer.c */
int acer = 0; /* Do acer notebook init */
+int mwave_bug = 0; /* Using the dreadful mwave sb emulation */
MODULE_PARM(io, "i");
MODULE_PARM(irq, "i");
@@ -80,10 +81,11 @@ MODULE_PARM(mad16, "i");
MODULE_PARM(trix, "i");
MODULE_PARM(pas2, "i");
MODULE_PARM(sm_games, "i");
+MODULE_PARM(mwave_bug, "i");
-static int sbmpu = 0;
+static int sbmpu = 0;
-void *smw_free = NULL;
+void *smw_free = NULL;
int init_module(void)
{
@@ -119,8 +121,7 @@ int init_module(void)
return 0;
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
if (smw_free)
kfree(smw_free);
@@ -133,19 +134,20 @@ cleanup_module(void)
#else
-#ifdef SM_GAMES
+#ifdef CONFIG_SM_GAMES
int sm_games = 1;
-
#else
int sm_games = 0;
-
#endif
-#ifdef SB_ACER
+#ifdef CONFIG_SB_ACER
int acer = 1;
-
#else
int acer = 0;
-
+#endif
+#ifdef CONFIG_SB_MWAVE
+int mwave_bug = 1;
+#else
+int mwave_bug = 0;
#endif
#endif
#endif
diff --git a/drivers/sound/sb_common.c b/drivers/sound/sb_common.c
index 0f3e1e6aa..fcdcfcf2c 100644
--- a/drivers/sound/sb_common.c
+++ b/drivers/sound/sb_common.c
@@ -28,7 +28,6 @@
static sb_devc *detected_devc = NULL; /* For communication from probe to init */
static sb_devc *last_devc = NULL; /* For MPU401 initialization */
-static sb_devc *irq2devc[16] = {NULL};
static unsigned char jazz_irq_bits[] = {
0, 0, 2, 3, 0, 1, 0, 4, 0, 2, 5, 0, 0, 0, 0, 6
};
@@ -123,15 +122,9 @@ static void sbintr(int irq, void *dev_id, struct pt_regs *dummy)
int status;
unsigned char src = 0xff;
- sb_devc *devc = irq2devc[irq];
+ sb_devc *devc = dev_id;
- if (devc == NULL || devc->irq != irq)
- {
- DEB(printk("sbintr: Bogus interrupt IRQ%d\n", irq));
- return;
- }
devc->irq_ok = 1;
-
if (devc->model == MDL_SB16)
{
src = sb_getmixer(devc, IRQ_STAT); /* Interrupt source register */
@@ -710,6 +703,7 @@ void sb_dsp_init(struct address_info *hw_config)
sb_devc *devc;
char name[100];
extern int sb_be_quiet;
+ extern int mwave_bug;
/*
* Check if we had detected a SB device earlier
@@ -743,21 +737,19 @@ void sb_dsp_init(struct address_info *hw_config)
if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI) && hw_config->irq > 0)
{ /* IRQ setup */
- if (snd_set_irq_handler(hw_config->irq, sbintr, "soundblaster", devc->osp) < 0)
+ if (request_irq(hw_config->irq, sbintr, 0, "soundblaster", devc) < 0)
{
printk(KERN_ERR "SB: Can't allocate IRQ%d\n", hw_config->irq);
sound_unload_audiodev(devc->dev);
return;
}
- irq2devc[hw_config->irq] = devc;
devc->irq_ok = 0;
if (devc->major == 4)
if (!sb16_set_irq_hw(devc, devc->irq)) /* Unsupported IRQ */
{
- snd_release_irq(devc->irq);
+ free_irq(devc->irq, devc);
sound_unload_audiodev(devc->dev);
- irq2devc[hw_config->irq] = NULL;
return;
}
if ((devc->type == 0 || devc->type == MDL_ESS) &&
@@ -777,7 +769,7 @@ void sb_dsp_init(struct address_info *hw_config)
/* Skip IRQ detection if SMP (doesn't work) */
devc->irq_ok = 1;
#else
- if (devc->major == 4 && devc->minor <= 11) /* Won't work */
+ if ((devc->major == 4 && devc->minor <= 11 ) || mwave_bug ) /* Won't work */
devc->irq_ok = 1;
else
{
@@ -883,6 +875,7 @@ void sb_dsp_init(struct address_info *hw_config)
}
}
hw_config->card_subtype = devc->model;
+ hw_config->slots[0]=devc->dev;
last_devc = devc; /* For SB MPU detection */
if (!(devc->caps & SB_NO_AUDIO) && devc->dma8 >= 0)
@@ -915,15 +908,8 @@ void sb_dsp_disable_recording(int io_base)
void sb_dsp_unload(struct address_info *hw_config)
{
sb_devc *devc;
- int irq = hw_config->irq;
- if (irq < 0)
- irq *= -1;
-
- if (irq > 2 && irq < 16)
- devc = irq2devc[irq];
- else
- devc = NULL;
+ devc = audio_devs[hw_config->slots[0]]->devc;
if (devc && devc->base == hw_config->io_base)
{
@@ -937,12 +923,12 @@ void sb_dsp_unload(struct address_info *hw_config)
}
if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI) && devc->irq > 0)
{
- snd_release_irq(devc->irq);
- irq2devc[devc->irq] = NULL;
+ free_irq(devc->irq, devc);
sound_unload_mixerdev(devc->my_mixerdev);
sound_unload_mididev(devc->my_mididev);
sound_unload_audiodev(devc->my_dev);
}
+ kfree(devc);
}
else
release_region(hw_config->io_base, 16);
diff --git a/drivers/sound/sound_calls.h b/drivers/sound/sound_calls.h
index aed677c89..416737f65 100644
--- a/drivers/sound/sound_calls.h
+++ b/drivers/sound/sound_calls.h
@@ -11,7 +11,6 @@ int DMAbuf_start_output(int dev, int buff_no, int l);
int DMAbuf_move_wrpointer(int dev, int l);
/* int DMAbuf_ioctl(int dev, unsigned int cmd, caddr_t arg, int local); */
void DMAbuf_init(int dev, int dma1, int dma2);
-void DMAbuf_deinit(int dev);
int DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode);
int DMAbuf_open_dma (int dev);
void DMAbuf_close_dma (int dev);
@@ -84,8 +83,9 @@ void MIDIbuf_init(void);
/* From soundcard.c */
void request_sound_timer (int count);
void sound_stop_timer(void);
-int snd_set_irq_handler (int interrupt_level, void(*iproc)(int, void*, struct pt_regs *), char *name, int *osp);
-void snd_release_irq(int vect);
+/* These two are about to die.. */
+int snd_set_irq_handler (int interrupt_level, void(*iproc)(int, void*, struct pt_regs *), char *name, int *osp, void *dev_id);
+void snd_release_irq(int vect, void *ptr);
void sound_dma_malloc(int dev);
void sound_dma_free(int dev);
void conf_printf(char *name, struct address_info *hw_config);
diff --git a/drivers/sound/sound_timer.c b/drivers/sound/sound_timer.c
index 8a519e7e2..986668316 100644
--- a/drivers/sound/sound_timer.c
+++ b/drivers/sound/sound_timer.c
@@ -47,6 +47,14 @@ void reprogram_timer(void)
{
unsigned long usecs_per_tick;
+ /*
+ * The user is changing the timer rate before setting a timer
+ * slap, bad bad not allowed.
+ */
+
+ if(!tmr)
+ return;
+
usecs_per_tick = (60 * 1000000) / (curr_tempo * curr_timebase);
/*
diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c
index e23e5486e..fe3622a73 100644
--- a/drivers/sound/soundcard.c
+++ b/drivers/sound/soundcard.c
@@ -26,7 +26,7 @@
#include <linux/fcntl.h>
#include <linux/ctype.h>
#include <linux/stddef.h>
-#include <linux/kerneld.h>
+#include <linux/kmod.h>
#ifdef __KERNEL__
#include <asm/io.h>
#include <asm/segment.h>
@@ -439,7 +439,7 @@ static int sound_open(struct inode *inode, struct file *file)
case SND_DEV_CTL:
dev >>= 4;
-#ifdef CONFIG_KERNELD
+#ifdef CONFIG_KMOD
if (dev >= 0 && dev < MAX_MIXER_DEV && mixer_devs[dev] == NULL) {
char modname[20];
sprintf(modname, "mixer%d", dev);
@@ -555,14 +555,14 @@ static int sound_mixer_ioctl(int mixdev, unsigned int cmd, caddr_t arg)
{
if (mixdev < 0 || mixdev >= MAX_MIXER_DEV)
return -ENXIO;
-#ifdef CONFIG_KERNELD
+#ifdef CONFIG_KMOD
/* Try to load the mixer... */
if (mixer_devs[mixdev] == NULL) {
char modname[20];
sprintf(modname, "mixer%d", mixdev);
request_module(modname);
}
-#endif /* CONFIG_KERNELD */
+#endif /* CONFIG_KMOD */
if (mixdev >= num_mixers || !mixer_devs[mixdev])
return -ENXIO;
if (cmd == SOUND_MIXER_INFO)
@@ -801,7 +801,7 @@ free_all_irqs(void)
if (irqs & (1ul << i))
{
printk(KERN_WARNING "Sound warning: IRQ%d was left allocated - fixed.\n", i);
- snd_release_irq(i);
+ snd_release_irq(i, NULL);
}
}
irqs = 0;
@@ -895,14 +895,14 @@ void cleanup_module(void)
}
#endif
-int snd_set_irq_handler(int interrupt_level, void (*iproc) (int, void *, struct pt_regs *), char *name, int *osp)
+int snd_set_irq_handler(int interrupt_level, void (*iproc) (int, void *, struct pt_regs *), char *name, int *osp, void *dev_id)
{
- int retcode;
- unsigned long flags;
+ int retcode;
+ unsigned long flags;
save_flags(flags);
cli();
- retcode = request_irq(interrupt_level, iproc, 0, name, NULL);
+ retcode = request_irq(interrupt_level, iproc, 0, name, dev_id);
if (retcode < 0)
{
@@ -915,13 +915,13 @@ int snd_set_irq_handler(int interrupt_level, void (*iproc) (int, void *, struct
return retcode;
}
-void snd_release_irq(int vect)
+void snd_release_irq(int vect, void *dev_id)
{
if (!(irqs & (1ul << vect)))
return;
irqs &= ~(1ul << vect);
- free_irq(vect, NULL);
+ free_irq(vect, dev_id);
}
int sound_alloc_dma(int chn, char *deviceID)
diff --git a/drivers/sound/uart401.c b/drivers/sound/uart401.c
index 7293e9047..2e7ed2a27 100644
--- a/drivers/sound/uart401.c
+++ b/drivers/sound/uart401.c
@@ -9,7 +9,15 @@
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
+ *
+ * Changes:
+ * Alan Cox Reformatted, removed sound_mem usage, use normal Linux
+ * interrupt allocation.
+ *
+ * Status:
+ * Untested
*/
+
#include <linux/config.h>
#include <linux/module.h>
@@ -19,45 +27,43 @@
#if (defined(CONFIG_UART401)||defined(CONFIG_MIDI)) || defined(MODULE)
typedef struct uart401_devc
- {
- int base;
- int irq;
- int *osp;
- void (*midi_input_intr) (int dev, unsigned char data);
- int opened, disabled;
- volatile unsigned char input_byte;
- int my_dev;
- int share_irq;
- }
+{
+ int base;
+ int irq;
+ int *osp;
+ void (*midi_input_intr) (int dev, unsigned char data);
+ int opened, disabled;
+ volatile unsigned char input_byte;
+ int my_dev;
+ int share_irq;
+}
uart401_devc;
static uart401_devc *detected_devc = NULL;
-static uart401_devc *irq2devc[16] =
-{NULL};
#define DATAPORT (devc->base)
#define COMDPORT (devc->base+1)
#define STATPORT (devc->base+1)
-static int
-uart401_status(uart401_devc * devc)
+static int uart401_status(uart401_devc * devc)
{
return inb(STATPORT);
}
+
#define input_avail(devc) (!(uart401_status(devc)&INPUT_AVAIL))
#define output_ready(devc) (!(uart401_status(devc)&OUTPUT_READY))
-static void
-uart401_cmd(uart401_devc * devc, unsigned char cmd)
+
+static void uart401_cmd(uart401_devc * devc, unsigned char cmd)
{
outb((cmd), COMDPORT);
}
-static int
-uart401_read(uart401_devc * devc)
+
+static int uart401_read(uart401_devc * devc)
{
return inb(DATAPORT);
}
-static void
-uart401_write(uart401_devc * devc, unsigned char byte)
+
+static void uart401_write(uart401_devc * devc, unsigned char byte)
{
outb((byte), DATAPORT);
}
@@ -71,30 +77,26 @@ uart401_write(uart401_devc * devc, unsigned char byte)
static int reset_uart401(uart401_devc * devc);
static void enter_uart_mode(uart401_devc * devc);
-static void
-uart401_input_loop(uart401_devc * devc)
+static void uart401_input_loop(uart401_devc * devc)
{
while (input_avail(devc))
- {
- unsigned char c = uart401_read(devc);
-
- if (c == MPU_ACK)
- devc->input_byte = c;
- else if (devc->opened & OPEN_READ && devc->midi_input_intr)
- devc->midi_input_intr(devc->my_dev, c);
- }
+ {
+ unsigned char c = uart401_read(devc);
+
+ if (c == MPU_ACK)
+ devc->input_byte = c;
+ else if (devc->opened & OPEN_READ && devc->midi_input_intr)
+ devc->midi_input_intr(devc->my_dev, c);
+ }
}
-void
-uart401intr(int irq, void *dev_id, struct pt_regs *dummy)
+void uart401intr(int irq, void *dev_id, struct pt_regs *dummy)
{
- uart401_devc *devc;
+ uart401_devc *devc = dev_id;
if (irq < 1 || irq > 15)
return;
- devc = irq2devc[irq];
-
if (devc == NULL)
return;
@@ -108,12 +110,12 @@ uart401_open(int dev, int mode,
void (*output) (int dev)
)
{
- uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
+ uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
if (devc->opened)
- {
- return -EBUSY;
- }
+ {
+ return -EBUSY;
+ }
while (input_avail(devc))
uart401_read(devc);
@@ -125,21 +127,19 @@ uart401_open(int dev, int mode,
return 0;
}
-static void
-uart401_close(int dev)
+static void uart401_close(int dev)
{
- uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
+ uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
reset_uart401(devc);
devc->opened = 0;
}
-static int
-uart401_out(int dev, unsigned char midi_byte)
+static int uart401_out(int dev, unsigned char midi_byte)
{
- int timeout;
- unsigned long flags;
- uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
+ int timeout;
+ unsigned long flags;
+ uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
if (devc->disabled)
return 1;
@@ -163,36 +163,32 @@ uart401_out(int dev, unsigned char midi_byte)
for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
if (!output_ready(devc))
- {
- printk("MPU-401: Timeout - Device not responding\n");
+ {
+ printk(KERN_WARNING "uart401: Timeout - Device not responding\n");
devc->disabled = 1;
reset_uart401(devc);
enter_uart_mode(devc);
return 1;
- }
+ }
uart401_write(devc, midi_byte);
return 1;
}
-static int
-uart401_start_read(int dev)
+static int uart401_start_read(int dev)
{
return 0;
}
-static int
-uart401_end_read(int dev)
+static int uart401_end_read(int dev)
{
return 0;
}
-static void
-uart401_kick(int dev)
+static void uart401_kick(int dev)
{
}
-static int
-uart401_buffer_status(int dev)
+static int uart401_buffer_status(int dev)
{
return 0;
}
@@ -203,7 +199,9 @@ uart401_buffer_status(int dev)
static struct midi_operations uart401_operations =
{
- {"MPU-401 (UART) MIDI", 0, 0, SNDCARD_MPU401},
+ {
+ "MPU-401 (UART) MIDI", 0, 0, SNDCARD_MPU401
+ },
&std_midi_synth,
{0},
uart401_open,
@@ -218,11 +216,10 @@ static struct midi_operations uart401_operations =
NULL
};
-static void
-enter_uart_mode(uart401_devc * devc)
+static void enter_uart_mode(uart401_devc * devc)
{
- int ok, timeout;
- unsigned long flags;
+ int ok, timeout;
+ unsigned long flags;
save_flags(flags);
cli();
@@ -242,11 +239,10 @@ enter_uart_mode(uart401_devc * devc)
restore_flags(flags);
}
-void
-attach_uart401(struct address_info *hw_config)
+void attach_uart401(struct address_info *hw_config)
{
- uart401_devc *devc;
- char *name = "MPU-401 (UART) MIDI";
+ uart401_devc *devc;
+ char *name = "MPU-401 (UART) MIDI";
if (hw_config->name)
name = hw_config->name;
@@ -255,80 +251,75 @@ attach_uart401(struct address_info *hw_config)
return;
- devc = (uart401_devc *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(uart401_devc)));
- sound_mem_sizes[sound_nblocks] = sizeof(uart401_devc);
- if (sound_nblocks < 1024)
- sound_nblocks++;;
+ devc = (uart401_devc *) kmalloc(sizeof(uart401_devc), GFP_KERNEL);
if (devc == NULL)
- {
- printk(KERN_WARNING "uart401: Can't allocate memory\n");
- return;
- }
+ {
+ printk(KERN_WARNING "uart401: Can't allocate memory\n");
+ return;
+ }
memcpy((char *) devc, (char *) detected_devc, sizeof(uart401_devc));
detected_devc = NULL;
devc->irq = hw_config->irq;
if (devc->irq < 0)
- {
- devc->share_irq = 1;
- devc->irq *= -1;
- } else
+ {
+ devc->share_irq = 1;
+ devc->irq *= -1;
+ }
+ else
devc->share_irq = 0;
if (devc->irq < 1 || devc->irq > 15)
+ {
+ kfree(devc);
return;
+ }
if (!devc->share_irq)
- if (snd_set_irq_handler(devc->irq, uart401intr, "MPU-401 UART", devc->osp) < 0)
- {
- printk(KERN_WARNING "uart401: Failed to allocate IRQ%d\n", devc->irq);
- devc->share_irq = 1;
- }
- irq2devc[devc->irq] = devc;
+ {
+ if (request_irq(devc->irq, uart401intr, 0, "MPU-401 UART", devc) < 0)
+ {
+ printk(KERN_WARNING "uart401: Failed to allocate IRQ%d\n", devc->irq);
+ devc->share_irq = 1;
+ }
+ }
devc->my_dev = sound_alloc_mididev();
request_region(hw_config->io_base, 4, "MPU-401 UART");
enter_uart_mode(devc);
if (devc->my_dev == -1)
- {
- printk(KERN_INFO "uart401: Too many midi devices detected\n");
- return;
- }
+ {
+ printk(KERN_INFO "uart401: Too many midi devices detected\n");
+ kfree(devc);
+ return;
+ }
conf_printf(name, hw_config);
std_midi_synth.midi_dev = devc->my_dev;
-
-
- midi_devs[devc->my_dev] = (struct midi_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct midi_operations)));
- sound_mem_sizes[sound_nblocks] = sizeof(struct midi_operations);
-
- if (sound_nblocks < 1024)
- sound_nblocks++;;
+ midi_devs[devc->my_dev] = (struct midi_operations *)kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
if (midi_devs[devc->my_dev] == NULL)
- {
- printk("uart401: Failed to allocate memory\n");
- sound_unload_mididev(devc->my_dev);
- return;
- }
+ {
+ printk(KERN_ERR "uart401: Failed to allocate memory\n");
+ sound_unload_mididev(devc->my_dev);
+ kfree(devc);
+ devc=NULL;
+ return;
+ }
memcpy((char *) midi_devs[devc->my_dev], (char *) &uart401_operations,
sizeof(struct midi_operations));
midi_devs[devc->my_dev]->devc = devc;
-
-
- midi_devs[devc->my_dev]->converter = (struct synth_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct synth_operations)));
- sound_mem_sizes[sound_nblocks] = sizeof(struct synth_operations);
-
- if (sound_nblocks < 1024)
- sound_nblocks++;
-
+ midi_devs[devc->my_dev]->converter = (struct synth_operations *)kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
if (midi_devs[devc->my_dev]->converter == NULL)
- {
- printk(KERN_WARNING "uart401: Failed to allocate memory\n");
- sound_unload_mididev(devc->my_dev);
- return;
- }
+ {
+ printk(KERN_WARNING "uart401: Failed to allocate memory\n");
+ sound_unload_mididev(devc->my_dev);
+ kfree(midi_devs[devc->my_dev]);
+ kfree(devc);
+ devc=NULL;
+ return;
+ }
memcpy((char *) midi_devs[devc->my_dev]->converter, (char *) &std_midi_synth,
sizeof(struct synth_operations));
@@ -339,10 +330,9 @@ attach_uart401(struct address_info *hw_config)
devc->opened = 0;
}
-static int
-reset_uart401(uart401_devc * devc)
+static int reset_uart401(uart401_devc * devc)
{
- int ok, timeout, n;
+ int ok, timeout, n;
/*
* Send the RESET command. Try again if no success at the first time.
@@ -351,31 +341,33 @@ reset_uart401(uart401_devc * devc)
ok = 0;
for (n = 0; n < 2 && !ok; n++)
- {
- for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
-
- devc->input_byte = 0;
- uart401_cmd(devc, MPU_RESET);
-
- /*
- * Wait at least 25 msec. This method is not accurate so let's make the
- * loop bit longer. Cannot sleep since this is called during boot.
- */
-
- for (timeout = 50000; timeout > 0 && !ok; timeout--)
- if (devc->input_byte == MPU_ACK) /* Interrupt */
- ok = 1;
- else if (input_avail(devc))
- if (uart401_read(devc) == MPU_ACK)
- ok = 1;
-
- }
+ {
+ for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
+ devc->input_byte = 0;
+ uart401_cmd(devc, MPU_RESET);
+ /*
+ * Wait at least 25 msec. This method is not accurate so let's make the
+ * loop bit longer. Cannot sleep since this is called during boot.
+ */
+
+ for (timeout = 50000; timeout > 0 && !ok; timeout--)
+ {
+ if (devc->input_byte == MPU_ACK) /* Interrupt */
+ ok = 1;
+ else if (input_avail(devc))
+ {
+ if (uart401_read(devc) == MPU_ACK)
+ ok = 1;
+ }
+ }
+ }
if (ok)
- {
- DEB(printk("Reset UART401 OK\n"));
- } else
+ {
+ DEB(printk("Reset UART401 OK\n"));
+ }
+ else
DDB(printk("Reset UART401 failed - No hardware detected.\n"));
if (ok)
@@ -386,14 +378,12 @@ reset_uart401(uart401_devc * devc)
return ok;
}
-int
-probe_uart401(struct address_info *hw_config)
+int probe_uart401(struct address_info *hw_config)
{
- int ok = 0;
- unsigned long flags;
-
+ int ok = 0;
+ unsigned long flags;
static uart401_devc hw_info;
- uart401_devc *devc = &hw_info;
+ uart401_devc *devc = &hw_info;
DDB(printk("Entered probe_uart401()\n"));
@@ -422,21 +412,10 @@ probe_uart401(struct address_info *hw_config)
return ok;
}
-void
-unload_uart401(struct address_info *hw_config)
+void unload_uart401(struct address_info *hw_config)
{
- uart401_devc *devc;
-
- int irq = hw_config->irq;
-
- if (irq < 0)
- {
- irq *= -1;
- }
- if (irq < 1 || irq > 15)
- return;
-
- devc = irq2devc[irq];
+ uart401_devc *devc;
+ devc = midi_devs[hw_config->slots[4]]->devc;
if (devc == NULL)
return;
@@ -444,47 +423,47 @@ unload_uart401(struct address_info *hw_config)
release_region(hw_config->io_base, 4);
if (!devc->share_irq)
- snd_release_irq(devc->irq);
-
+ free_irq(devc->irq, devc);
+ sound_unload_mididev(hw_config->slots[4]);
if (devc)
+ {
+ kfree(midi_devs[devc->my_dev]->converter);
+ kfree(midi_devs[devc->my_dev]);
+ kfree(devc);
devc = NULL;
- sound_unload_mididev(hw_config->slots[4]);
+ }
}
#ifdef MODULE
-int io = -1;
-int irq = -1;
+int io = -1;
+int irq = -1;
MODULE_PARM(io, "i");
MODULE_PARM(irq, "i");
struct address_info hw;
-int
-init_module(void)
+int init_module(void)
{
/* Can be loaded either for module use or to provide functions
to others */
if (io != -1 && irq != -1)
- {
- printk("MPU-401 UART driver Copyright (C) Hannu Savolainen 1993-1997");
- hw.irq = irq;
- hw.io_base = io;
- if (probe_uart401(&hw) == 0)
- return -ENODEV;
- attach_uart401(&hw);
- }
+ {
+ printk(KERN_INFO "MPU-401 UART driver Copyright (C) Hannu Savolainen 1993-1997");
+ hw.irq = irq;
+ hw.io_base = io;
+ if (probe_uart401(&hw) == 0)
+ return -ENODEV;
+ attach_uart401(&hw);
+ }
SOUND_LOCK;
return 0;
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
if (io != -1 && irq != -1)
- {
- unload_uart401(&hw);
- }
+ unload_uart401(&hw);
/* FREE SYMTAB */
SOUND_LOCK_END;
}
diff --git a/drivers/sound/uart6850.c b/drivers/sound/uart6850.c
index 932be1846..b26e75a89 100644
--- a/drivers/sound/uart6850.c
+++ b/drivers/sound/uart6850.c
@@ -10,6 +10,11 @@
* Extended by Alan Cox for Red Hat Software. Now a loadable MIDI driver.
* 28/4/97 - (C) Copyright Alan Cox. Released under the GPL version 2.
*
+ * Alan Cox: Updated for new modular code. Removed snd_* irq handling. Now
+ * uses native linux resources
+ *
+ * Status: Testing required
+ *
*/
#include <linux/config.h>
#include <linux/module.h>
@@ -297,7 +302,7 @@ int probe_uart6850(struct address_info *hw_config)
uart6850_base = hw_config->io_base;
uart6850_irq = hw_config->irq;
- if (snd_set_irq_handler(uart6850_irq, m6850intr, "MIDI6850", uart6850_osp) < 0)
+ if (request_irq(uart6850_irq, m6850intr, 0, "MIDI6850", NULL) < 0)
return 0;
ok = reset_uart6850();
@@ -307,7 +312,7 @@ int probe_uart6850(struct address_info *hw_config)
void unload_uart6850(struct address_info *hw_config)
{
- snd_release_irq(hw_config->irq);
+ free_irq(hw_config->irq, NULL);
sound_unload_mididev(hw_config->slots[4]);
}
diff --git a/drivers/sound/v_midi.c b/drivers/sound/v_midi.c
index 12c221a68..4820d5f36 100644
--- a/drivers/sound/v_midi.c
+++ b/drivers/sound/v_midi.c
@@ -2,15 +2,22 @@
* sound/v_midi.c
*
* The low level driver for the Sound Blaster DS chips.
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1996
*
* USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
* ??
+ *
+ * Changes
+ * Alan Cox Modularisation, changed memory allocations
+ *
+ * Status
+ * Untested
*/
+
#include <linux/config.h>
#include <linux/module.h>