Loading sound/drivers/serial-u16550.c +123 −98 Original line number Diff line number Diff line Loading @@ -117,13 +117,13 @@ MODULE_PARM_DESC(adaptor, "Type of adaptor."); #define SERIAL_MODE_INPUT_TRIGGERED (1 << 2) #define SERIAL_MODE_OUTPUT_TRIGGERED (1 << 3) typedef struct _snd_uart16550 { struct snd_uart16550 { struct snd_card *card; struct snd_rawmidi *rmidi; struct snd_rawmidi_substream *midi_output[SNDRV_SERIAL_MAX_OUTS]; struct snd_rawmidi_substream *midi_input[SNDRV_SERIAL_MAX_INS]; int filemode; //open status of file int filemode; /* open status of file */ spinlock_t open_lock; Loading @@ -140,37 +140,37 @@ typedef struct _snd_uart16550 { unsigned char old_divisor_msb; unsigned char old_line_ctrl_reg; // parameter for using of write loop short int fifo_limit; //used in uart16550 short int fifo_count; //used in uart16550 /* parameter for using of write loop */ short int fifo_limit; /* used in uart16550 */ short int fifo_count; /* used in uart16550 */ // type of adaptor /* type of adaptor */ int adaptor; // inputs /* inputs */ int prev_in; unsigned char rstatus; // outputs /* outputs */ int prev_out; unsigned char prev_status[SNDRV_SERIAL_MAX_OUTS]; // write buffer and its writing/reading position /* write buffer and its writing/reading position */ unsigned char tx_buff[TX_BUFF_SIZE]; int buff_in_count; int buff_in; int buff_out; int drop_on_full; // wait timer /* wait timer */ unsigned int timer_running:1; struct timer_list buffer_timer; } snd_uart16550_t; }; static struct platform_device *devices[SNDRV_CARDS]; static inline void snd_uart16550_add_timer(snd_uart16550_t *uart) static inline void snd_uart16550_add_timer(struct snd_uart16550 *uart) { if (!uart->timer_running) { /* timer 38600bps * 10bit * 16byte */ Loading @@ -180,7 +180,7 @@ static inline void snd_uart16550_add_timer(snd_uart16550_t *uart) } } static inline void snd_uart16550_del_timer(snd_uart16550_t *uart) static inline void snd_uart16550_del_timer(struct snd_uart16550 *uart) { if (uart->timer_running) { del_timer(&uart->buffer_timer); Loading @@ -189,7 +189,7 @@ static inline void snd_uart16550_del_timer(snd_uart16550_t *uart) } /* This macro is only used in snd_uart16550_io_loop */ static inline void snd_uart16550_buffer_output(snd_uart16550_t *uart) static inline void snd_uart16550_buffer_output(struct snd_uart16550 *uart) { unsigned short buff_out = uart->buff_out; if (uart->buff_in_count > 0) { Loading @@ -206,7 +206,7 @@ static inline void snd_uart16550_buffer_output(snd_uart16550_t *uart) * We don't want to interrupt this, * as we're already handling an interrupt */ static void snd_uart16550_io_loop(snd_uart16550_t * uart) static void snd_uart16550_io_loop(struct snd_uart16550 * uart) { unsigned char c, status; int substream; Loading @@ -220,9 +220,8 @@ static void snd_uart16550_io_loop(snd_uart16550_t * uart) c = inb(uart->base + UART_RX); /* keep track of last status byte */ if (c & 0x80) { if (c & 0x80) uart->rstatus = c; } /* handle stream switch */ if (uart->adaptor == SNDRV_SERIAL_GENERIC) { Loading @@ -230,14 +229,16 @@ static void snd_uart16550_io_loop(snd_uart16550_t * uart) if (c <= SNDRV_SERIAL_MAX_INS && c > 0) substream = c - 1; if (c != 0xf5) uart->rstatus = 0; /* prevent future bytes from being interpreted as streams */ } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) && (uart->midi_input[substream] != NULL)) { snd_rawmidi_receive(uart->midi_input[substream], &c, 1); } } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) && (uart->midi_input[substream] != NULL)) { /* prevent future bytes from being interpreted as streams */ uart->rstatus = 0; } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) && uart->midi_input[substream]) snd_rawmidi_receive(uart->midi_input[substream], &c, 1); } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) && uart->midi_input[substream]) snd_rawmidi_receive(uart->midi_input[substream], &c, 1); } if (status & UART_LSR_OE) snd_printk("%s: Overrun on device at 0x%lx\n", Loading @@ -250,15 +251,14 @@ static void snd_uart16550_io_loop(snd_uart16550_t * uart) /* no need of check SERIAL_MODE_OUTPUT_OPEN because if not, buffer is never filled. */ /* Check write status */ if (status & UART_LSR_THRE) { if (status & UART_LSR_THRE) uart->fifo_count = 0; } if (uart->adaptor == SNDRV_SERIAL_MS124W_SA || uart->adaptor == SNDRV_SERIAL_GENERIC) { /* Can't use FIFO, must send only when CTS is true */ status = inb(uart->base + UART_MSR); while( (uart->fifo_count == 0) && (status & UART_MSR_CTS) && (uart->buff_in_count > 0) ) { while (uart->fifo_count == 0 && (status & UART_MSR_CTS) && uart->buff_in_count > 0) { snd_uart16550_buffer_output(uart); status = inb(uart->base + UART_MSR); } Loading Loading @@ -294,15 +294,16 @@ static void snd_uart16550_io_loop(snd_uart16550_t * uart) */ static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id) { snd_uart16550_t *uart; struct snd_uart16550 *uart; uart = (snd_uart16550_t *) dev_id; uart = dev_id; spin_lock(&uart->open_lock); if (uart->filemode == SERIAL_MODE_NOT_OPENED) { spin_unlock(&uart->open_lock); return IRQ_NONE; } inb(uart->base + UART_IIR); /* indicate to the UART that the interrupt has been serviced */ /* indicate to the UART that the interrupt has been serviced */ inb(uart->base + UART_IIR); snd_uart16550_io_loop(uart); spin_unlock(&uart->open_lock); return IRQ_HANDLED; Loading @@ -312,9 +313,9 @@ static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id) static void snd_uart16550_buffer_timer(unsigned long data) { unsigned long flags; snd_uart16550_t *uart; struct snd_uart16550 *uart; uart = (snd_uart16550_t *)data; uart = (struct snd_uart16550 *)data; spin_lock_irqsave(&uart->open_lock, flags); snd_uart16550_del_timer(uart); snd_uart16550_io_loop(uart); Loading @@ -326,7 +327,7 @@ static void snd_uart16550_buffer_timer(unsigned long data) * return 0 if found * return negative error if not found */ static int __init snd_uart16550_detect(snd_uart16550_t *uart) static int __init snd_uart16550_detect(struct snd_uart16550 *uart) { unsigned long io_base = uart->base; int ok; Loading @@ -343,7 +344,8 @@ static int __init snd_uart16550_detect(snd_uart16550_t *uart) return -EBUSY; } ok = 1; /* uart detected unless one of the following tests should fail */ /* uart detected unless one of the following tests should fail */ ok = 1; /* 8 data-bits, 1 stop-bit, parity off, DLAB = 0 */ outb(UART_LCR_WLEN8, io_base + UART_LCR); /* Line Control Register */ c = inb(io_base + UART_IER); Loading @@ -368,7 +370,7 @@ static int __init snd_uart16550_detect(snd_uart16550_t *uart) return ok; } static void snd_uart16550_do_open(snd_uart16550_t * uart) static void snd_uart16550_do_open(struct snd_uart16550 * uart) { char byte; Loading Loading @@ -460,7 +462,7 @@ static void snd_uart16550_do_open(snd_uart16550_t * uart) inb(uart->base + UART_RX); /* Clear any pre-existing receive interrupt */ } static void snd_uart16550_do_close(snd_uart16550_t * uart) static void snd_uart16550_do_close(struct snd_uart16550 * uart) { if (uart->irq < 0) snd_uart16550_del_timer(uart); Loading Loading @@ -514,7 +516,7 @@ static void snd_uart16550_do_close(snd_uart16550_t * uart) static int snd_uart16550_input_open(struct snd_rawmidi_substream *substream) { unsigned long flags; snd_uart16550_t *uart = substream->rmidi->private_data; struct snd_uart16550 *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); if (uart->filemode == SERIAL_MODE_NOT_OPENED) Loading @@ -528,7 +530,7 @@ static int snd_uart16550_input_open(struct snd_rawmidi_substream *substream) static int snd_uart16550_input_close(struct snd_rawmidi_substream *substream) { unsigned long flags; snd_uart16550_t *uart = substream->rmidi->private_data; struct snd_uart16550 *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); uart->filemode &= ~SERIAL_MODE_INPUT_OPEN; Loading @@ -539,24 +541,24 @@ static int snd_uart16550_input_close(struct snd_rawmidi_substream *substream) return 0; } static void snd_uart16550_input_trigger(struct snd_rawmidi_substream *substream, int up) static void snd_uart16550_input_trigger(struct snd_rawmidi_substream *substream, int up) { unsigned long flags; snd_uart16550_t *uart = substream->rmidi->private_data; struct snd_uart16550 *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); if (up) { if (up) uart->filemode |= SERIAL_MODE_INPUT_TRIGGERED; } else { else uart->filemode &= ~SERIAL_MODE_INPUT_TRIGGERED; } spin_unlock_irqrestore(&uart->open_lock, flags); } static int snd_uart16550_output_open(struct snd_rawmidi_substream *substream) { unsigned long flags; snd_uart16550_t *uart = substream->rmidi->private_data; struct snd_uart16550 *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); if (uart->filemode == SERIAL_MODE_NOT_OPENED) Loading @@ -570,7 +572,7 @@ static int snd_uart16550_output_open(struct snd_rawmidi_substream *substream) static int snd_uart16550_output_close(struct snd_rawmidi_substream *substream) { unsigned long flags; snd_uart16550_t *uart = substream->rmidi->private_data; struct snd_uart16550 *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); uart->filemode &= ~SERIAL_MODE_OUTPUT_OPEN; Loading @@ -581,7 +583,8 @@ static int snd_uart16550_output_close(struct snd_rawmidi_substream *substream) return 0; }; static inline int snd_uart16550_buffer_can_write( snd_uart16550_t *uart, int Num ) static inline int snd_uart16550_buffer_can_write(struct snd_uart16550 *uart, int Num) { if (uart->buff_in_count + Num < TX_BUFF_SIZE) return 1; Loading @@ -589,7 +592,8 @@ static inline int snd_uart16550_buffer_can_write( snd_uart16550_t *uart, int Num return 0; } static inline int snd_uart16550_write_buffer(snd_uart16550_t *uart, unsigned char byte) static inline int snd_uart16550_write_buffer(struct snd_uart16550 *uart, unsigned char byte) { unsigned short buff_in = uart->buff_in; if (uart->buff_in_count < TX_BUFF_SIZE) { Loading @@ -605,7 +609,9 @@ static inline int snd_uart16550_write_buffer(snd_uart16550_t *uart, unsigned cha return 0; } static int snd_uart16550_output_byte(snd_uart16550_t *uart, struct snd_rawmidi_substream *substream, unsigned char midi_byte) static int snd_uart16550_output_byte(struct snd_uart16550 *uart, struct snd_rawmidi_substream *substream, unsigned char midi_byte) { if (uart->buff_in_count == 0 /* Buffer empty? */ && ((uart->adaptor != SNDRV_SERIAL_MS124W_SA && Loading @@ -623,7 +629,8 @@ static int snd_uart16550_output_byte(snd_uart16550_t *uart, struct snd_rawmidi_s uart->fifo_count++; outb(midi_byte, uart->base + UART_TX); } else { /* Cannot write (buffer empty) - put char in buffer */ /* Cannot write (buffer empty) - * put char in buffer */ snd_uart16550_write_buffer(uart, midi_byte); } } Loading @@ -642,7 +649,7 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) { unsigned long flags; unsigned char midi_byte, addr_byte; snd_uart16550_t *uart = substream->rmidi->private_data; struct snd_uart16550 *uart = substream->rmidi->private_data; char first; static unsigned long lasttime = 0; Loading @@ -653,7 +660,7 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) spin_lock_irqsave(&uart->open_lock, flags); if (uart->irq < 0) //polling if (uart->irq < 0) /* polling */ snd_uart16550_io_loop(uart); if (uart->adaptor == SNDRV_SERIAL_MS124W_MB) { Loading @@ -671,7 +678,8 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) /* select any combination of the four ports */ addr_byte = (substream->number << 4) | 0x08; /* ...except none */ if (addr_byte == 0x08) addr_byte = 0xf8; if (addr_byte == 0x08) addr_byte = 0xf8; #endif snd_uart16550_output_byte(uart, substream, addr_byte); /* send midi byte */ Loading @@ -679,23 +687,33 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) } } else { first = 0; while( 1 == snd_rawmidi_transmit_peek(substream, &midi_byte, 1) ) { /* Also send F5 after 3 seconds with no data to handle device disconnect */ if (first == 0 && (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS || while (snd_rawmidi_transmit_peek(substream, &midi_byte, 1) == 1) { /* Also send F5 after 3 seconds with no data * to handle device disconnect */ if (first == 0 && (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS || uart->adaptor == SNDRV_SERIAL_GENERIC) && (uart->prev_out != substream->number || jiffies-lasttime > 3*HZ)) { (uart->prev_out != substream->number || jiffies-lasttime > 3*HZ)) { if (snd_uart16550_buffer_can_write(uart, 3)) { /* Roland Soundcanvas part selection */ /* If this substream of the data is different previous substream in this uart, send the change part event */ /* If this substream of the data is * different previous substream * in this uart, send the change part * event */ uart->prev_out = substream->number; /* change part */ snd_uart16550_output_byte(uart, substream, 0xf5); snd_uart16550_output_byte(uart, substream, 0xf5); /* data */ snd_uart16550_output_byte(uart, substream, uart->prev_out + 1); /* If midi_byte is a data byte, send the previous status byte */ if ((midi_byte < 0x80) && (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS)) snd_uart16550_output_byte(uart, substream, uart->prev_out + 1); /* If midi_byte is a data byte, * send the previous status byte */ if (midi_byte < 0x80 && uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS) snd_uart16550_output_byte(uart, substream, uart->prev_status[uart->prev_out]); } else if (!uart->drop_on_full) break; Loading @@ -703,7 +721,8 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) } /* send midi byte */ if( !snd_uart16550_output_byte(uart, substream, midi_byte) && !uart->drop_on_full ) if (!snd_uart16550_output_byte(uart, substream, midi_byte) && !uart->drop_on_full ) break; if (midi_byte >= 0x80 && midi_byte < 0xf0) Loading @@ -717,17 +736,17 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) spin_unlock_irqrestore(&uart->open_lock, flags); } static void snd_uart16550_output_trigger(struct snd_rawmidi_substream *substream, int up) static void snd_uart16550_output_trigger(struct snd_rawmidi_substream *substream, int up) { unsigned long flags; snd_uart16550_t *uart = substream->rmidi->private_data; struct snd_uart16550 *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); if (up) { if (up) uart->filemode |= SERIAL_MODE_OUTPUT_TRIGGERED; } else { else uart->filemode &= ~SERIAL_MODE_OUTPUT_TRIGGERED; } spin_unlock_irqrestore(&uart->open_lock, flags); if (up) snd_uart16550_output_write(substream); Loading @@ -747,10 +766,10 @@ static struct snd_rawmidi_ops snd_uart16550_input = .trigger = snd_uart16550_input_trigger, }; static int snd_uart16550_free(snd_uart16550_t *uart) static int snd_uart16550_free(struct snd_uart16550 *uart) { if (uart->irq >= 0) free_irq(uart->irq, (void *)uart); free_irq(uart->irq, uart); release_and_free_resource(uart->res_base); kfree(uart); return 0; Loading @@ -758,7 +777,7 @@ static int snd_uart16550_free(snd_uart16550_t *uart) static int snd_uart16550_dev_free(struct snd_device *device) { snd_uart16550_t *uart = device->device_data; struct snd_uart16550 *uart = device->device_data; return snd_uart16550_free(uart); } Loading @@ -769,12 +788,12 @@ static int __init snd_uart16550_create(struct snd_card *card, unsigned int base, int adaptor, int droponfull, snd_uart16550_t **ruart) struct snd_uart16550 **ruart) { static struct snd_device_ops ops = { .dev_free = snd_uart16550_dev_free, }; snd_uart16550_t *uart; struct snd_uart16550 *uart; int err; Loading @@ -795,7 +814,7 @@ static int __init snd_uart16550_create(struct snd_card *card, if (irq >= 0 && irq != SNDRV_AUTO_IRQ) { if (request_irq(irq, snd_uart16550_interrupt, IRQF_DISABLED, "Serial MIDI", (void *) uart)) { IRQF_DISABLED, "Serial MIDI", uart)) { snd_printk("irq %d busy. Using Polling.\n", irq); } else { uart->irq = irq; Loading Loading @@ -843,23 +862,28 @@ static int __init snd_uart16550_create(struct snd_card *card, static void __init snd_uart16550_substreams(struct snd_rawmidi_str *stream) { struct list_head *list; struct snd_rawmidi_substream *substream; list_for_each(list, &stream->substreams) { struct snd_rawmidi_substream *substream = list_entry(list, struct snd_rawmidi_substream, list); list_for_each_entry(substream, &stream->substreams, list) { sprintf(substream->name, "Serial MIDI %d", substream->number + 1); } } static int __init snd_uart16550_rmidi(snd_uart16550_t *uart, int device, int outs, int ins, struct snd_rawmidi **rmidi) static int __init snd_uart16550_rmidi(struct snd_uart16550 *uart, int device, int outs, int ins, struct snd_rawmidi **rmidi) { struct snd_rawmidi *rrawmidi; int err; if ((err = snd_rawmidi_new(uart->card, "UART Serial MIDI", device, outs, ins, &rrawmidi)) < 0) err = snd_rawmidi_new(uart->card, "UART Serial MIDI", device, outs, ins, &rrawmidi); if (err < 0) return err; snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_uart16550_input); snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_uart16550_output); snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_uart16550_input); snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_uart16550_output); strcpy(rrawmidi->name, "Serial MIDI"); snd_uart16550_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]); snd_uart16550_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]); Loading @@ -875,7 +899,7 @@ static int __init snd_uart16550_rmidi(snd_uart16550_t *uart, int device, int out static int __init snd_serial_probe(struct platform_device *devptr) { struct snd_card *card; snd_uart16550_t *uart; struct snd_uart16550 *uart; int err; int dev = devptr->id; Loading Loading @@ -929,7 +953,8 @@ static int __init snd_serial_probe(struct platform_device *devptr) &uart)) < 0) goto _err; if ((err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi)) < 0) err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi); if (err < 0) goto _err; sprintf(card->longname, "%s at 0x%lx, irq %d speed %d div %d outs %d ins %d adaptor %s droponfull %d", Loading Loading
sound/drivers/serial-u16550.c +123 −98 Original line number Diff line number Diff line Loading @@ -117,13 +117,13 @@ MODULE_PARM_DESC(adaptor, "Type of adaptor."); #define SERIAL_MODE_INPUT_TRIGGERED (1 << 2) #define SERIAL_MODE_OUTPUT_TRIGGERED (1 << 3) typedef struct _snd_uart16550 { struct snd_uart16550 { struct snd_card *card; struct snd_rawmidi *rmidi; struct snd_rawmidi_substream *midi_output[SNDRV_SERIAL_MAX_OUTS]; struct snd_rawmidi_substream *midi_input[SNDRV_SERIAL_MAX_INS]; int filemode; //open status of file int filemode; /* open status of file */ spinlock_t open_lock; Loading @@ -140,37 +140,37 @@ typedef struct _snd_uart16550 { unsigned char old_divisor_msb; unsigned char old_line_ctrl_reg; // parameter for using of write loop short int fifo_limit; //used in uart16550 short int fifo_count; //used in uart16550 /* parameter for using of write loop */ short int fifo_limit; /* used in uart16550 */ short int fifo_count; /* used in uart16550 */ // type of adaptor /* type of adaptor */ int adaptor; // inputs /* inputs */ int prev_in; unsigned char rstatus; // outputs /* outputs */ int prev_out; unsigned char prev_status[SNDRV_SERIAL_MAX_OUTS]; // write buffer and its writing/reading position /* write buffer and its writing/reading position */ unsigned char tx_buff[TX_BUFF_SIZE]; int buff_in_count; int buff_in; int buff_out; int drop_on_full; // wait timer /* wait timer */ unsigned int timer_running:1; struct timer_list buffer_timer; } snd_uart16550_t; }; static struct platform_device *devices[SNDRV_CARDS]; static inline void snd_uart16550_add_timer(snd_uart16550_t *uart) static inline void snd_uart16550_add_timer(struct snd_uart16550 *uart) { if (!uart->timer_running) { /* timer 38600bps * 10bit * 16byte */ Loading @@ -180,7 +180,7 @@ static inline void snd_uart16550_add_timer(snd_uart16550_t *uart) } } static inline void snd_uart16550_del_timer(snd_uart16550_t *uart) static inline void snd_uart16550_del_timer(struct snd_uart16550 *uart) { if (uart->timer_running) { del_timer(&uart->buffer_timer); Loading @@ -189,7 +189,7 @@ static inline void snd_uart16550_del_timer(snd_uart16550_t *uart) } /* This macro is only used in snd_uart16550_io_loop */ static inline void snd_uart16550_buffer_output(snd_uart16550_t *uart) static inline void snd_uart16550_buffer_output(struct snd_uart16550 *uart) { unsigned short buff_out = uart->buff_out; if (uart->buff_in_count > 0) { Loading @@ -206,7 +206,7 @@ static inline void snd_uart16550_buffer_output(snd_uart16550_t *uart) * We don't want to interrupt this, * as we're already handling an interrupt */ static void snd_uart16550_io_loop(snd_uart16550_t * uart) static void snd_uart16550_io_loop(struct snd_uart16550 * uart) { unsigned char c, status; int substream; Loading @@ -220,9 +220,8 @@ static void snd_uart16550_io_loop(snd_uart16550_t * uart) c = inb(uart->base + UART_RX); /* keep track of last status byte */ if (c & 0x80) { if (c & 0x80) uart->rstatus = c; } /* handle stream switch */ if (uart->adaptor == SNDRV_SERIAL_GENERIC) { Loading @@ -230,14 +229,16 @@ static void snd_uart16550_io_loop(snd_uart16550_t * uart) if (c <= SNDRV_SERIAL_MAX_INS && c > 0) substream = c - 1; if (c != 0xf5) uart->rstatus = 0; /* prevent future bytes from being interpreted as streams */ } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) && (uart->midi_input[substream] != NULL)) { snd_rawmidi_receive(uart->midi_input[substream], &c, 1); } } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) && (uart->midi_input[substream] != NULL)) { /* prevent future bytes from being interpreted as streams */ uart->rstatus = 0; } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) && uart->midi_input[substream]) snd_rawmidi_receive(uart->midi_input[substream], &c, 1); } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) && uart->midi_input[substream]) snd_rawmidi_receive(uart->midi_input[substream], &c, 1); } if (status & UART_LSR_OE) snd_printk("%s: Overrun on device at 0x%lx\n", Loading @@ -250,15 +251,14 @@ static void snd_uart16550_io_loop(snd_uart16550_t * uart) /* no need of check SERIAL_MODE_OUTPUT_OPEN because if not, buffer is never filled. */ /* Check write status */ if (status & UART_LSR_THRE) { if (status & UART_LSR_THRE) uart->fifo_count = 0; } if (uart->adaptor == SNDRV_SERIAL_MS124W_SA || uart->adaptor == SNDRV_SERIAL_GENERIC) { /* Can't use FIFO, must send only when CTS is true */ status = inb(uart->base + UART_MSR); while( (uart->fifo_count == 0) && (status & UART_MSR_CTS) && (uart->buff_in_count > 0) ) { while (uart->fifo_count == 0 && (status & UART_MSR_CTS) && uart->buff_in_count > 0) { snd_uart16550_buffer_output(uart); status = inb(uart->base + UART_MSR); } Loading Loading @@ -294,15 +294,16 @@ static void snd_uart16550_io_loop(snd_uart16550_t * uart) */ static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id) { snd_uart16550_t *uart; struct snd_uart16550 *uart; uart = (snd_uart16550_t *) dev_id; uart = dev_id; spin_lock(&uart->open_lock); if (uart->filemode == SERIAL_MODE_NOT_OPENED) { spin_unlock(&uart->open_lock); return IRQ_NONE; } inb(uart->base + UART_IIR); /* indicate to the UART that the interrupt has been serviced */ /* indicate to the UART that the interrupt has been serviced */ inb(uart->base + UART_IIR); snd_uart16550_io_loop(uart); spin_unlock(&uart->open_lock); return IRQ_HANDLED; Loading @@ -312,9 +313,9 @@ static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id) static void snd_uart16550_buffer_timer(unsigned long data) { unsigned long flags; snd_uart16550_t *uart; struct snd_uart16550 *uart; uart = (snd_uart16550_t *)data; uart = (struct snd_uart16550 *)data; spin_lock_irqsave(&uart->open_lock, flags); snd_uart16550_del_timer(uart); snd_uart16550_io_loop(uart); Loading @@ -326,7 +327,7 @@ static void snd_uart16550_buffer_timer(unsigned long data) * return 0 if found * return negative error if not found */ static int __init snd_uart16550_detect(snd_uart16550_t *uart) static int __init snd_uart16550_detect(struct snd_uart16550 *uart) { unsigned long io_base = uart->base; int ok; Loading @@ -343,7 +344,8 @@ static int __init snd_uart16550_detect(snd_uart16550_t *uart) return -EBUSY; } ok = 1; /* uart detected unless one of the following tests should fail */ /* uart detected unless one of the following tests should fail */ ok = 1; /* 8 data-bits, 1 stop-bit, parity off, DLAB = 0 */ outb(UART_LCR_WLEN8, io_base + UART_LCR); /* Line Control Register */ c = inb(io_base + UART_IER); Loading @@ -368,7 +370,7 @@ static int __init snd_uart16550_detect(snd_uart16550_t *uart) return ok; } static void snd_uart16550_do_open(snd_uart16550_t * uart) static void snd_uart16550_do_open(struct snd_uart16550 * uart) { char byte; Loading Loading @@ -460,7 +462,7 @@ static void snd_uart16550_do_open(snd_uart16550_t * uart) inb(uart->base + UART_RX); /* Clear any pre-existing receive interrupt */ } static void snd_uart16550_do_close(snd_uart16550_t * uart) static void snd_uart16550_do_close(struct snd_uart16550 * uart) { if (uart->irq < 0) snd_uart16550_del_timer(uart); Loading Loading @@ -514,7 +516,7 @@ static void snd_uart16550_do_close(snd_uart16550_t * uart) static int snd_uart16550_input_open(struct snd_rawmidi_substream *substream) { unsigned long flags; snd_uart16550_t *uart = substream->rmidi->private_data; struct snd_uart16550 *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); if (uart->filemode == SERIAL_MODE_NOT_OPENED) Loading @@ -528,7 +530,7 @@ static int snd_uart16550_input_open(struct snd_rawmidi_substream *substream) static int snd_uart16550_input_close(struct snd_rawmidi_substream *substream) { unsigned long flags; snd_uart16550_t *uart = substream->rmidi->private_data; struct snd_uart16550 *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); uart->filemode &= ~SERIAL_MODE_INPUT_OPEN; Loading @@ -539,24 +541,24 @@ static int snd_uart16550_input_close(struct snd_rawmidi_substream *substream) return 0; } static void snd_uart16550_input_trigger(struct snd_rawmidi_substream *substream, int up) static void snd_uart16550_input_trigger(struct snd_rawmidi_substream *substream, int up) { unsigned long flags; snd_uart16550_t *uart = substream->rmidi->private_data; struct snd_uart16550 *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); if (up) { if (up) uart->filemode |= SERIAL_MODE_INPUT_TRIGGERED; } else { else uart->filemode &= ~SERIAL_MODE_INPUT_TRIGGERED; } spin_unlock_irqrestore(&uart->open_lock, flags); } static int snd_uart16550_output_open(struct snd_rawmidi_substream *substream) { unsigned long flags; snd_uart16550_t *uart = substream->rmidi->private_data; struct snd_uart16550 *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); if (uart->filemode == SERIAL_MODE_NOT_OPENED) Loading @@ -570,7 +572,7 @@ static int snd_uart16550_output_open(struct snd_rawmidi_substream *substream) static int snd_uart16550_output_close(struct snd_rawmidi_substream *substream) { unsigned long flags; snd_uart16550_t *uart = substream->rmidi->private_data; struct snd_uart16550 *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); uart->filemode &= ~SERIAL_MODE_OUTPUT_OPEN; Loading @@ -581,7 +583,8 @@ static int snd_uart16550_output_close(struct snd_rawmidi_substream *substream) return 0; }; static inline int snd_uart16550_buffer_can_write( snd_uart16550_t *uart, int Num ) static inline int snd_uart16550_buffer_can_write(struct snd_uart16550 *uart, int Num) { if (uart->buff_in_count + Num < TX_BUFF_SIZE) return 1; Loading @@ -589,7 +592,8 @@ static inline int snd_uart16550_buffer_can_write( snd_uart16550_t *uart, int Num return 0; } static inline int snd_uart16550_write_buffer(snd_uart16550_t *uart, unsigned char byte) static inline int snd_uart16550_write_buffer(struct snd_uart16550 *uart, unsigned char byte) { unsigned short buff_in = uart->buff_in; if (uart->buff_in_count < TX_BUFF_SIZE) { Loading @@ -605,7 +609,9 @@ static inline int snd_uart16550_write_buffer(snd_uart16550_t *uart, unsigned cha return 0; } static int snd_uart16550_output_byte(snd_uart16550_t *uart, struct snd_rawmidi_substream *substream, unsigned char midi_byte) static int snd_uart16550_output_byte(struct snd_uart16550 *uart, struct snd_rawmidi_substream *substream, unsigned char midi_byte) { if (uart->buff_in_count == 0 /* Buffer empty? */ && ((uart->adaptor != SNDRV_SERIAL_MS124W_SA && Loading @@ -623,7 +629,8 @@ static int snd_uart16550_output_byte(snd_uart16550_t *uart, struct snd_rawmidi_s uart->fifo_count++; outb(midi_byte, uart->base + UART_TX); } else { /* Cannot write (buffer empty) - put char in buffer */ /* Cannot write (buffer empty) - * put char in buffer */ snd_uart16550_write_buffer(uart, midi_byte); } } Loading @@ -642,7 +649,7 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) { unsigned long flags; unsigned char midi_byte, addr_byte; snd_uart16550_t *uart = substream->rmidi->private_data; struct snd_uart16550 *uart = substream->rmidi->private_data; char first; static unsigned long lasttime = 0; Loading @@ -653,7 +660,7 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) spin_lock_irqsave(&uart->open_lock, flags); if (uart->irq < 0) //polling if (uart->irq < 0) /* polling */ snd_uart16550_io_loop(uart); if (uart->adaptor == SNDRV_SERIAL_MS124W_MB) { Loading @@ -671,7 +678,8 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) /* select any combination of the four ports */ addr_byte = (substream->number << 4) | 0x08; /* ...except none */ if (addr_byte == 0x08) addr_byte = 0xf8; if (addr_byte == 0x08) addr_byte = 0xf8; #endif snd_uart16550_output_byte(uart, substream, addr_byte); /* send midi byte */ Loading @@ -679,23 +687,33 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) } } else { first = 0; while( 1 == snd_rawmidi_transmit_peek(substream, &midi_byte, 1) ) { /* Also send F5 after 3 seconds with no data to handle device disconnect */ if (first == 0 && (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS || while (snd_rawmidi_transmit_peek(substream, &midi_byte, 1) == 1) { /* Also send F5 after 3 seconds with no data * to handle device disconnect */ if (first == 0 && (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS || uart->adaptor == SNDRV_SERIAL_GENERIC) && (uart->prev_out != substream->number || jiffies-lasttime > 3*HZ)) { (uart->prev_out != substream->number || jiffies-lasttime > 3*HZ)) { if (snd_uart16550_buffer_can_write(uart, 3)) { /* Roland Soundcanvas part selection */ /* If this substream of the data is different previous substream in this uart, send the change part event */ /* If this substream of the data is * different previous substream * in this uart, send the change part * event */ uart->prev_out = substream->number; /* change part */ snd_uart16550_output_byte(uart, substream, 0xf5); snd_uart16550_output_byte(uart, substream, 0xf5); /* data */ snd_uart16550_output_byte(uart, substream, uart->prev_out + 1); /* If midi_byte is a data byte, send the previous status byte */ if ((midi_byte < 0x80) && (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS)) snd_uart16550_output_byte(uart, substream, uart->prev_out + 1); /* If midi_byte is a data byte, * send the previous status byte */ if (midi_byte < 0x80 && uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS) snd_uart16550_output_byte(uart, substream, uart->prev_status[uart->prev_out]); } else if (!uart->drop_on_full) break; Loading @@ -703,7 +721,8 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) } /* send midi byte */ if( !snd_uart16550_output_byte(uart, substream, midi_byte) && !uart->drop_on_full ) if (!snd_uart16550_output_byte(uart, substream, midi_byte) && !uart->drop_on_full ) break; if (midi_byte >= 0x80 && midi_byte < 0xf0) Loading @@ -717,17 +736,17 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) spin_unlock_irqrestore(&uart->open_lock, flags); } static void snd_uart16550_output_trigger(struct snd_rawmidi_substream *substream, int up) static void snd_uart16550_output_trigger(struct snd_rawmidi_substream *substream, int up) { unsigned long flags; snd_uart16550_t *uart = substream->rmidi->private_data; struct snd_uart16550 *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); if (up) { if (up) uart->filemode |= SERIAL_MODE_OUTPUT_TRIGGERED; } else { else uart->filemode &= ~SERIAL_MODE_OUTPUT_TRIGGERED; } spin_unlock_irqrestore(&uart->open_lock, flags); if (up) snd_uart16550_output_write(substream); Loading @@ -747,10 +766,10 @@ static struct snd_rawmidi_ops snd_uart16550_input = .trigger = snd_uart16550_input_trigger, }; static int snd_uart16550_free(snd_uart16550_t *uart) static int snd_uart16550_free(struct snd_uart16550 *uart) { if (uart->irq >= 0) free_irq(uart->irq, (void *)uart); free_irq(uart->irq, uart); release_and_free_resource(uart->res_base); kfree(uart); return 0; Loading @@ -758,7 +777,7 @@ static int snd_uart16550_free(snd_uart16550_t *uart) static int snd_uart16550_dev_free(struct snd_device *device) { snd_uart16550_t *uart = device->device_data; struct snd_uart16550 *uart = device->device_data; return snd_uart16550_free(uart); } Loading @@ -769,12 +788,12 @@ static int __init snd_uart16550_create(struct snd_card *card, unsigned int base, int adaptor, int droponfull, snd_uart16550_t **ruart) struct snd_uart16550 **ruart) { static struct snd_device_ops ops = { .dev_free = snd_uart16550_dev_free, }; snd_uart16550_t *uart; struct snd_uart16550 *uart; int err; Loading @@ -795,7 +814,7 @@ static int __init snd_uart16550_create(struct snd_card *card, if (irq >= 0 && irq != SNDRV_AUTO_IRQ) { if (request_irq(irq, snd_uart16550_interrupt, IRQF_DISABLED, "Serial MIDI", (void *) uart)) { IRQF_DISABLED, "Serial MIDI", uart)) { snd_printk("irq %d busy. Using Polling.\n", irq); } else { uart->irq = irq; Loading Loading @@ -843,23 +862,28 @@ static int __init snd_uart16550_create(struct snd_card *card, static void __init snd_uart16550_substreams(struct snd_rawmidi_str *stream) { struct list_head *list; struct snd_rawmidi_substream *substream; list_for_each(list, &stream->substreams) { struct snd_rawmidi_substream *substream = list_entry(list, struct snd_rawmidi_substream, list); list_for_each_entry(substream, &stream->substreams, list) { sprintf(substream->name, "Serial MIDI %d", substream->number + 1); } } static int __init snd_uart16550_rmidi(snd_uart16550_t *uart, int device, int outs, int ins, struct snd_rawmidi **rmidi) static int __init snd_uart16550_rmidi(struct snd_uart16550 *uart, int device, int outs, int ins, struct snd_rawmidi **rmidi) { struct snd_rawmidi *rrawmidi; int err; if ((err = snd_rawmidi_new(uart->card, "UART Serial MIDI", device, outs, ins, &rrawmidi)) < 0) err = snd_rawmidi_new(uart->card, "UART Serial MIDI", device, outs, ins, &rrawmidi); if (err < 0) return err; snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_uart16550_input); snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_uart16550_output); snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_uart16550_input); snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_uart16550_output); strcpy(rrawmidi->name, "Serial MIDI"); snd_uart16550_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]); snd_uart16550_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]); Loading @@ -875,7 +899,7 @@ static int __init snd_uart16550_rmidi(snd_uart16550_t *uart, int device, int out static int __init snd_serial_probe(struct platform_device *devptr) { struct snd_card *card; snd_uart16550_t *uart; struct snd_uart16550 *uart; int err; int dev = devptr->id; Loading Loading @@ -929,7 +953,8 @@ static int __init snd_serial_probe(struct platform_device *devptr) &uart)) < 0) goto _err; if ((err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi)) < 0) err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi); if (err < 0) goto _err; sprintf(card->longname, "%s at 0x%lx, irq %d speed %d div %d outs %d ins %d adaptor %s droponfull %d", Loading