- Timestamp:
- Jan 23, 2008, 7:05:10 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GPL/branches/alsa-resync1/alsa-kernel/drivers/serial-u16550.c
r277 r281 64 64 }; 65 65 66 #define SNDRV_SERIAL_NORMALBUFF 0 /* Normal blocking buffer operation */ 67 #define SNDRV_SERIAL_DROPBUFF 1 /* Non-blocking discard operation */ 68 66 69 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 67 70 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ … … 75 78 static int ins[SNDRV_CARDS] = {REPEAT_SNDRV(1)}; /* 1 to 16 */ 76 79 static int adaptor[SNDRV_CARDS] = {REPEAT_SNDRV(SNDRV_SERIAL_SOUNDCANVAS)}; 80 static int droponfull[SNDRV_CARDS] = {REPEAT_SNDRV(SNDRV_SERIAL_NORMALBUFF)}; 77 81 #else 78 82 static int speed[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 38400}; /* 9600,19200,38400,57600,115200 */ … … 81 85 static int ins[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; /* 1 to 16 */ 82 86 static int adaptor[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = SNDRV_SERIAL_SOUNDCANVAS}; 87 static int droponfull[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS -1)] = SNDRV_SERIAL_NORMALBUFF }; 83 88 #endif 84 89 … … 108 113 MODULE_PARM(ins, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); 109 114 MODULE_PARM_DESC(ins, "Number of MIDI inputs."); 115 MODULE_PARM(droponfull, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); 116 MODULE_PARM_DESC(droponfull, "Flag to enable drop-on-full buffer mode"); 117 MODULE_PARM_SYNTAX(droponfull, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC); 110 118 111 119 MODULE_PARM_SYNTAX(outs, SNDRV_ENABLED ",allows:{{1,16}},dialog:list"); … … 172 180 int buff_in; 173 181 int buff_out; 182 int drop_on_full; 174 183 175 184 // wait timer … … 203 212 { 204 213 unsigned short buff_out = uart->buff_out; 214 if( uart->buff_in_count > 0 ) { 205 215 outb(uart->tx_buff[buff_out], uart->base + UART_TX); 206 216 uart->fifo_count++; … … 209 219 uart->buff_out = buff_out; 210 220 uart->buff_in_count--; 221 } 211 222 } 212 223 … … 266 277 /* Can't use FIFO, must send only when CTS is true */ 267 278 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) ) { 270 281 snd_uart16550_buffer_output(uart); 282 status = inb( uart->base + UART_MSR ); 283 } 271 284 } else { 272 285 /* Write loop */ … … 585 598 }; 586 599 587 inline static void snd_uart16550_write_buffer(snd_uart16550_t *uart, unsigned char byte) 600 inline 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 608 inline static int snd_uart16550_write_buffer(snd_uart16550_t *uart, unsigned char byte) 588 609 { 589 610 unsigned short buff_in = uart->buff_in; 611 if( uart->buff_in_count < TX_BUFF_SIZE ) { 590 612 uart->tx_buff[buff_in] = byte; 591 613 buff_in++; … … 594 616 uart->buff_in_count++; 595 617 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 624 static int snd_uart16550_output_byte(snd_uart16550_t *uart, snd_rawmidi_substream_t * substream, unsigned char midi_byte) 600 625 { 601 626 if (uart->buff_in_count == 0 /* Buffer empty? */ … … 620 645 } 621 646 } else { 622 if (uart->buff_in_count >= TX_BUFF_SIZE) {647 if( !snd_uart16550_write_buffer(uart, midi_byte) ) { 623 648 snd_printk("%s: Buffer overrun on device at 0x%lx\n", 624 649 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; 629 655 } 630 656 … … 670 696 } else { 671 697 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) ) { 675 699 /* Also send F5 after 3 seconds with no data to handle device disconnect */ 676 700 if (first == 0 && (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS || … … 678 702 (uart->prev_out != substream->number || jiffies-lasttime > 3*HZ)) { 679 703 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 ) ) { 684 705 /* Roland Soundcanvas part selection */ 685 706 /* If this substream of the data is different previous … … 693 714 if ((midi_byte < 0x80) && (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS)) 694 715 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 ) 699 723 break; 700 724 701 /* send midi byte */702 snd_uart16550_output_byte(uart, substream, midi_byte);703 725 if (midi_byte >= 0x80 && midi_byte < 0xf0) 704 726 uart->prev_status[uart->prev_out] = midi_byte; 705 727 first = 1; 728 729 snd_rawmidi_transmit_ack( substream, 1 ); 706 730 } 707 731 lasttime = jiffies; … … 780 804 unsigned int base, 781 805 int adaptor, 806 int droponfull, 782 807 snd_uart16550_t **ruart) 783 808 { … … 796 821 uart->irq = -1; 797 822 uart->base = iobase; 823 uart->drop_on_full = droponfull; 798 824 799 825 if ((err = snd_uart16550_detect(uart)) <= 0) { … … 925 951 base[dev], 926 952 adaptor[dev], 953 droponfull[dev], 927 954 &uart)) < 0) { 928 955 snd_card_free(card); … … 935 962 } 936 963 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", 938 965 card->shortname, 939 966 uart->base, … … 943 970 outs[dev], 944 971 ins[dev], 945 adaptor_names[uart->adaptor]); 972 adaptor_names[uart->adaptor], 973 uart->drop_on_full); 946 974 947 975 if ((err = snd_card_register(card)) < 0) { … … 989 1017 /* format is: snd-serial=enable,index,id, 990 1018 port,irq,speed,base,outs, 991 ins,adaptor */1019 ins,adaptor,droponfull */ 992 1020 993 1021 static int __init alsa_card_serial_setup(char *str) … … 1006 1034 get_option(&str,&outs[nr_dev]) == 2 && 1007 1035 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 ); 1009 1038 nr_dev++; 1010 1039 return 1;
Note:
See TracChangeset
for help on using the changeset viewer.
