From f1382dc4850bb459d24a81c6cb0ef93ea7bd4a79 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 18 Mar 1998 17:17:51 +0000 Subject: o Merge with Linux 2.1.90. o Divide L1 cache sizes by 1024 before printing, makes the numbers a bit more credible ... --- drivers/sound/uart401.c | 337 +++++++++++++++++++++++------------------------- 1 file changed, 158 insertions(+), 179 deletions(-) (limited to 'drivers/sound/uart401.c') 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 #include @@ -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; } -- cgit v1.2.3