patch-2.1.90 linux/drivers/sound/uart401.c
Next file: linux/drivers/sound/uart6850.c
Previous file: linux/drivers/sound/soundcard.c
Back to the patch index
Back to the overall index
- Lines: 555
- Date:
Thu Mar 12 10:52:09 1998
- Orig file:
v2.1.89/linux/drivers/sound/uart401.c
- Orig date:
Tue Dec 30 10:59:17 1997
diff -u --recursive --new-file v2.1.89/linux/drivers/sound/uart401.c linux/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 @@
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);
+ {
+ 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);
- }
+ 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov