Ignore:
Timestamp:
Jan 23, 2008, 7:05:10 AM (18 years ago)
Author:
Brendan Oakley
Message:

Merged to ALSA 1.0.1

File:
1 edited

Legend:

Unmodified
Added
Removed
  • GPL/branches/alsa-resync1/alsa-kernel/drivers/serial-u16550.c

    r277 r281  
    6464};
    6565
     66#define SNDRV_SERIAL_NORMALBUFF 0 /* Normal blocking buffer operation */
     67#define SNDRV_SERIAL_DROPBUFF   1 /* Non-blocking discard operation */
     68
    6669static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;      /* Index 0-MAX */
    6770static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;       /* ID for this card */
     
    7578static int ins[SNDRV_CARDS] = {REPEAT_SNDRV(1)};        /* 1 to 16 */
    7679static int adaptor[SNDRV_CARDS] = {REPEAT_SNDRV(SNDRV_SERIAL_SOUNDCANVAS)};
     80static int droponfull[SNDRV_CARDS] = {REPEAT_SNDRV(SNDRV_SERIAL_NORMALBUFF)};
    7781#else
    7882static int speed[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 38400}; /* 9600,19200,38400,57600,115200 */
     
    8185static int ins[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};  /* 1 to 16 */
    8286static int adaptor[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = SNDRV_SERIAL_SOUNDCANVAS};
     87static int droponfull[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS -1)] = SNDRV_SERIAL_NORMALBUFF };
    8388#endif
    8489
     
    108113MODULE_PARM(ins, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
    109114MODULE_PARM_DESC(ins, "Number of MIDI inputs.");
     115MODULE_PARM(droponfull, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
     116MODULE_PARM_DESC(droponfull, "Flag to enable drop-on-full buffer mode");
     117MODULE_PARM_SYNTAX(droponfull, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC);
    110118
    111119MODULE_PARM_SYNTAX(outs, SNDRV_ENABLED ",allows:{{1,16}},dialog:list");
     
    172180    int buff_in;
    173181    int buff_out;
     182        int drop_on_full;
    174183
    175184    // wait timer
     
    203212{
    204213    unsigned short buff_out = uart->buff_out;
     214        if( uart->buff_in_count > 0 ) {
    205215    outb(uart->tx_buff[buff_out], uart->base + UART_TX);
    206216    uart->fifo_count++;
     
    209219    uart->buff_out = buff_out;
    210220    uart->buff_in_count--;
     221        }
    211222}
    212223
     
    266277        /* Can't use FIFO, must send only when CTS is true */
    267278        status = inb(uart->base + UART_MSR);
    268         if (uart->fifo_count == 0 && (status & UART_MSR_CTS)
    269             && uart->buff_in_count > 0)
     279                while( (uart->fifo_count == 0) && (status & UART_MSR_CTS) &&
     280                      (uart->buff_in_count > 0) ) {
    270281            snd_uart16550_buffer_output(uart);
     282                       status = inb( uart->base + UART_MSR );
     283                }
    271284    } else {
    272285        /* Write loop */
     
    585598};
    586599
    587 inline static void snd_uart16550_write_buffer(snd_uart16550_t *uart, unsigned char byte)
     600inline static int snd_uart16550_buffer_can_write( snd_uart16550_t *uart, int Num )
     601{
     602        if( uart->buff_in_count + Num < TX_BUFF_SIZE )
     603                return 1;
     604        else
     605                return 0;
     606}
     607
     608inline static int snd_uart16550_write_buffer(snd_uart16550_t *uart, unsigned char byte)
    588609{
    589610    unsigned short buff_in = uart->buff_in;
     611        if( uart->buff_in_count < TX_BUFF_SIZE ) {
    590612    uart->tx_buff[buff_in] = byte;
    591613    buff_in++;
     
    594616    uart->buff_in_count++;
    595617    if (uart->irq < 0) /* polling mode */
    596         snd_uart16550_add_timer(uart);
    597 }
    598 
    599 static void snd_uart16550_output_byte(snd_uart16550_t *uart, snd_rawmidi_substream_t * substream, unsigned char midi_byte)
     618                        snd_uart16550_add_timer(uart);
     619                return 1;
     620        } else
     621                return 0;
     622}
     623
     624static int snd_uart16550_output_byte(snd_uart16550_t *uart, snd_rawmidi_substream_t * substream, unsigned char midi_byte)
    600625{
    601626    if (uart->buff_in_count == 0                            /* Buffer empty? */
     
    620645        }
    621646    } else {
    622         if (uart->buff_in_count >= TX_BUFF_SIZE) {
     647                if( !snd_uart16550_write_buffer(uart, midi_byte) ) {
    623648            snd_printk("%s: Buffer overrun on device at 0x%lx\n",
    624649                       uart->rmidi->name, uart->base);
    625             return;
    626         }
    627         snd_uart16550_write_buffer(uart, midi_byte);
    628     }
     650                        return 0;
     651                }
     652        }
     653
     654        return 1;
    629655}
    630656
     
    670696    } else {
    671697        first = 0;
    672         while (1) {
    673             if (snd_rawmidi_transmit(substream, &midi_byte, 1) != 1)
    674                 break;
     698                while( 1 == snd_rawmidi_transmit_peek(substream, &midi_byte, 1) ) {
    675699                        /* Also send F5 after 3 seconds with no data to handle device disconnect */
    676700                        if (first == 0 && (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS ||
     
    678702                           (uart->prev_out != substream->number || jiffies-lasttime > 3*HZ)) {
    679703
    680                                 /* We will need three bytes of data here (worst case). */
    681                                 if (uart->buff_in_count >= TX_BUFF_SIZE - 3)
    682                                         break;
    683 
     704                                if( snd_uart16550_buffer_can_write( uart, 3 ) ) {
    684705                /* Roland Soundcanvas part selection */
    685706                /* If this substream of the data is different previous
     
    693714                                if ((midi_byte < 0x80) && (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS))
    694715                    snd_uart16550_output_byte(uart, substream, uart->prev_status[uart->prev_out]);
    695             }
    696 
    697                         /* buffer full? */
    698                         if (uart->buff_in_count >= TX_BUFF_SIZE)
     716                                } else if( !uart->drop_on_full )
     717                                        break;
     718
     719                        }
     720
     721            /* send midi byte */
     722                        if( !snd_uart16550_output_byte(uart, substream, midi_byte) && !uart->drop_on_full )
    699723                                break;
    700724
    701             /* send midi byte */
    702             snd_uart16550_output_byte(uart, substream, midi_byte);
    703725            if (midi_byte >= 0x80 && midi_byte < 0xf0)
    704726                uart->prev_status[uart->prev_out] = midi_byte;
    705727            first = 1;
     728
     729                        snd_rawmidi_transmit_ack( substream, 1 );
    706730        }
    707731                lasttime = jiffies;
     
    780804                                       unsigned int base,
    781805                                       int adaptor,
     806                                       int droponfull,
    782807                                       snd_uart16550_t **ruart)
    783808{
     
    796821    uart->irq = -1;
    797822    uart->base = iobase;
     823        uart->drop_on_full = droponfull;
    798824
    799825        if ((err = snd_uart16550_detect(uart)) <= 0) {
     
    925951                                        base[dev],
    926952                                        adaptor[dev],
     953                                        droponfull[dev],
    927954                                    &uart)) < 0) {
    928955        snd_card_free(card);
     
    935962    }
    936963
    937         sprintf(card->longname, "%s at 0x%lx, irq %d speed %d div %d outs %d ins %d adaptor %s",
     964        sprintf(card->longname, "%s at 0x%lx, irq %d speed %d div %d outs %d ins %d adaptor %s droponfull %d",
    938965            card->shortname,
    939966            uart->base,
     
    943970                outs[dev],
    944971                ins[dev],
    945             adaptor_names[uart->adaptor]);
     972                adaptor_names[uart->adaptor],
     973                uart->drop_on_full);
    946974
    947975    if ((err = snd_card_register(card)) < 0) {
     
    9891017/* format is: snd-serial=enable,index,id,
    9901018                         port,irq,speed,base,outs,
    991                          ins,adaptor */
     1019                         ins,adaptor,droponfull */
    9921020
    9931021static int __init alsa_card_serial_setup(char *str)
     
    10061034               get_option(&str,&outs[nr_dev]) == 2 &&
    10071035               get_option(&str,&ins[nr_dev]) == 2 &&
    1008                get_option(&str,&adaptor[nr_dev]) == 2);
     1036               get_option(&str,&adaptor[nr_dev]) == 2 &&
     1037               get_option(&str,&droponfull[nr_dev]) == 2 );
    10091038    nr_dev++;
    10101039    return 1;
Note: See TracChangeset for help on using the changeset viewer.