Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/sound/drivers/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 29 kB image not shown  

Quelle  serial-u16550.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *   serial.c
 *   Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
 *                    Isaku Yamahata <yamahata@private.email.ne.jp>,
 *       George Hansper <ghansper@apana.org.au>,
 *       Hannu Savolainen
 *
 *   This code is based on the code from ALSA 0.5.9, but heavily rewritten.
 *
 * Sat Mar 31 17:27:57 PST 2001 tim.mann@compaq.com 
 *      Added support for the Midiator MS-124T and for the MS-124W in
 *      Single Addressed (S/A) or Multiple Burst (M/B) mode, with
 *      power derived either parasitically from the serial port or
 *      from a separate power supply.
 *
 *      More documentation can be found in serial-u16550.txt.
 */

#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/io.h>
#include <sound/core.h>
#include <sound/rawmidi.h>
#include <sound/initval.h>

#include <linux/serial_reg.h>
#include <linux/jiffies.h>

MODULE_DESCRIPTION("MIDI serial u16550");
MODULE_LICENSE("GPL");

#define SNDRV_SERIAL_SOUNDCANVAS 0 /* Roland Soundcanvas; F5 NN selects part */
#define SNDRV_SERIAL_MS124T 1      /* Midiator MS-124T */
#define SNDRV_SERIAL_MS124W_SA 2   /* Midiator MS-124W in S/A mode */
#define SNDRV_SERIAL_MS124W_MB 3   /* Midiator MS-124W in M/B mode */
#define SNDRV_SERIAL_GENERIC 4     /* Generic Interface */
#define SNDRV_SERIAL_MAX_ADAPTOR SNDRV_SERIAL_GENERIC
static const char * const adaptor_names[] = {
"Soundcanvas",
        "MS-124T",
"MS-124W S/A",
"MS-124W M/B",
"Generic"
};

#define SNDRV_SERIAL_NORMALBUFF 0 /* Normal blocking buffer operation */
#define SNDRV_SERIAL_DROPBUFF   1 /* Non-blocking discard operation */

static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x3f8,0x2f8,0x3e8,0x2e8 */
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;  /* 3,4,5,7,9,10,11,14,15 */
static int speed[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 38400}; /* 9600,19200,38400,57600,115200 */
static int base[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 115200}; /* baud base */
static int outs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};  /* 1 to 16 */
static int ins[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; /* 1 to 16 */
static int adaptor[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = SNDRV_SERIAL_SOUNDCANVAS};
static bool droponfull[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS -1)] = SNDRV_SERIAL_NORMALBUFF };

module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Serial MIDI.");
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for Serial MIDI.");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable UART16550A chip.");
module_param_hw_array(port, long, ioport, NULL, 0444);
MODULE_PARM_DESC(port, "Port # for UART16550A chip.");
module_param_hw_array(irq, int, irq, NULL, 0444);
MODULE_PARM_DESC(irq, "IRQ # for UART16550A chip.");
module_param_array(speed, int, NULL, 0444);
MODULE_PARM_DESC(speed, "Speed in bauds.");
module_param_array(base, int, NULL, 0444);
MODULE_PARM_DESC(base, "Base for divisor in bauds.");
module_param_array(outs, int, NULL, 0444);
MODULE_PARM_DESC(outs, "Number of MIDI outputs.");
module_param_array(ins, int, NULL, 0444);
MODULE_PARM_DESC(ins, "Number of MIDI inputs.");
module_param_array(droponfull, bool, NULL, 0444);
MODULE_PARM_DESC(droponfull, "Flag to enable drop-on-full buffer mode");

module_param_array(adaptor, int, NULL, 0444);
MODULE_PARM_DESC(adaptor, "Type of adaptor.");

/*#define SNDRV_SERIAL_MS124W_MB_NOCOMBO 1*/  /* Address outs as 0-3 instead of bitmap */

#define SNDRV_SERIAL_MAX_OUTS 16 /* max 64, min 16 */
#define SNDRV_SERIAL_MAX_INS 16 /* max 64, min 16 */

#define TX_BUFF_SIZE (1<<15) /* Must be 2^n */
#define TX_BUFF_MASK (TX_BUFF_SIZE - 1)

#define SERIAL_MODE_NOT_OPENED  (0)
#define SERIAL_MODE_INPUT_OPEN (1 << 0)
#define SERIAL_MODE_OUTPUT_OPEN (1 << 1)
#define SERIAL_MODE_INPUT_TRIGGERED (1 << 2)
#define SERIAL_MODE_OUTPUT_TRIGGERED (1 << 3)

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 */

spinlock_t open_lock;

int irq;

unsigned long base;

unsigned int speed;
unsigned int speed_base;
unsigned char divisor;

unsigned char old_divisor_lsb;
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 */

/* type of adaptor */
int adaptor;

/* inputs */
int prev_in;
unsigned char rstatus;

/* outputs */
int prev_out;
unsigned char prev_status[SNDRV_SERIAL_MAX_OUTS];

/* 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 */
unsigned int timer_running:1;
struct timer_list buffer_timer;

};

static struct platform_device *devices[SNDRV_CARDS];

static inline void snd_uart16550_add_timer(struct snd_uart16550 *uart)
{
if (!uart->timer_running) {
/* timer 38600bps * 10bit * 16byte */
mod_timer(&uart->buffer_timer, jiffies + (HZ + 255) / 256);
uart->timer_running = 1;
}
}

static inline void snd_uart16550_del_timer(struct snd_uart16550 *uart)
{
if (uart->timer_running) {
timer_delete(&uart->buffer_timer);
uart->timer_running = 0;
}
}

/* This macro is only used in snd_uart16550_io_loop */
static inline void snd_uart16550_buffer_output(struct snd_uart16550 *uart)
{
unsigned short buff_out = uart->buff_out;
if (uart->buff_in_count > 0) {
outb(uart->tx_buff[buff_out], uart->base + UART_TX);
uart->fifo_count++;
buff_out++;
buff_out &= TX_BUFF_MASK;
uart->buff_out = buff_out;
uart->buff_in_count--;
}
}

/* This loop should be called with interrupts disabled
 * We don't want to interrupt this, 
 * as we're already handling an interrupt 
 */
static void snd_uart16550_io_loop(struct snd_uart16550 * uart)
{
unsigned char c, status;
int substream;

/* recall previous stream */
substream = uart->prev_in;

/* Read Loop */
while ((status = inb(uart->base + UART_LSR)) & UART_LSR_DR) {
/* while receive data ready */
c = inb(uart->base + UART_RX);

/* keep track of last status byte */
if (c & 0x80)
uart->rstatus = c;

/* handle stream switch */
if (uart->adaptor == SNDRV_SERIAL_GENERIC) {
if (uart->rstatus == 0xf5) {
if (c <= SNDRV_SERIAL_MAX_INS && c > 0)
substream = c - 1;
if (c != 0xf5)
/* prevent future bytes from being
   interpreted as streams */

     uart- * *                    Isaku Yamahata <yamahata@private *   *        Hannu *   This code is * Sat Mar 31 17:27:57 PST 2001 tim.mann *      Added support for the Midiator MS-124T and for the MS-124W in
include/h>
       && uart-[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)
   dev_warn(uart->card->dev,
     "%s: Overrun on device at 0x%lx\n",
     uart->rmidi->name, uart->base);
 }

 /* remember the last stream */
 >prev_insubstream

 /* no need of check SERIAL_MODE_OUTPUT_OPEN because if not,
   buffer is never filled. */

 /* Check write status */includesound.h>
 ifstatus UART_LSR_THRE)
  #include<soundinitvalh>
 if (uart->adaptor == SNDRV_SERIAL_MS124W_SA
    || >adaptor==S) {
  /* Can't use FIFO, must send only when CTS is true */("MIDI serial u16550";
   = (uart-> +UART_MSR);
  while (uart->fifo_count == 0 && (status & UART_MSR_CTSdefine 1      /* Midiator MS-124T */defineSNDRV_SERIAL_MS124W_SA2   *Midiator in SA  *java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
 uart-buff_in_count>0) java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
        (uart
         status = inb(uart->base + UART_MSR); longport[SNDRV_CARDS]  SNDRV_DEFAULT_PORT; /* 0x3f8,0x2f8,0x3e8,0x2e8 */
  }
 }else java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
 /* Write loop */
  while (>fifo_count < >fifo_limitjava.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
         && uart->buff_in_count > 0) /* Do we want to? */
  snd_uart16550_buffer_output(uart;
 }
 if (uart->irq < 0 && uart->buff_in_count > 0)
  snd_uart16550_add_timer(uart);
}

/* NOTES ON SERVICING INTERUPTS
 * ---------------------------
 * After receiving a interrupt, it is important to indicate to the UART that
 * this has been done. 
 * For a Rx interrupt, this is done by reading the received byte.
 * For a Tx interrupt this is done by either:
 * a) Writing a byte
 * b) Reading the IIR
 * It is particularly important to read the IIR if a Tx interrupt is received
 * when there is no data in tx_buff[], as in this case there no other
 * indication that the interrupt has been serviced, and it remains outstanding
 * indefinitely. This has the curious side effect that and no further interrupts
 * will be generated from this device AT ALL!!.
 * It is also desirable to clear outstanding interrupts when the device is
 * opened/closed.
 *
 *
 * Note that some devices need OUT2 to be set before they will generate
 * interrupts at all. (Possibly tied to an internal pull-up on CTS?)
 */

static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id)
{
 struct snd_uart16550 *uart;

= ;
 spin_lock(indexint,NULL,44;
 if (uart->filemode == SERIAL_MODE_NOT_OPENED) {
  spin_unlock(&uart->open_lock);
  return IRQ_NONE;
 }
 /* indicate to the UART that the interrupt has been serviced */
 inb(uart->base + UART_IIR(, charpNULL04)java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
 snd_uart16550_io_loopuart;
 spin_unlock&uart-open_lock;
 return IRQ_HANDLED;
}

/* When the polling mode, this function calls snd_uart16550_io_loop. */port,Portchip;
staticvoidsnd_uart16550_buffer_timer( timer_list*)
{
 unsigned MODULE_PARM_DESCirq "IRQ# ART16550A "java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
   *art

 module_param_array(,i,java.lang.StringIndexOutOfBoundsException: Range [34, 31) out of bounds for length 42
 spin_lock_irqsave&>open_lockflags)java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
 snd_uart16550_del_timeruart;
 snd_uart16550_io_loopuart;
 spin_unlock_irqrestore&>open_lock flags;
}

/*
 *  this method probes, if an uart sits on given port
 *  return 0 if found
 *  return negative error if not found
 */

static int snd_uart16550_detect(struct snd_uart16550 *uart)
{
 unsigned long io_base = uart-(adaptor, int NULL 44;
 int ok;
 unsignedchar;

 /* Do some vague tests for the presence of the uart */
 ifjava.lang.StringIndexOutOfBoundsException: Range [0, 4) out of bounds for length 0
  return define 1 
}

if (!devm_request_region(uart->card->dev, io_base, 8, "Serial MIDI")) {
dev_err(uart->card->dev,
"u16550: can't grab port 0x%lx\n", io_base);
return -EBUSY;
}

/* uart detected unless one of the following tests should fail */

 ok = 1;
 /* 8 data-bits, 1 stop-bit, parity off, DLAB = 0 */
 (UART_LCR_WLEN8 io_base  UART_LCR) /* Line Control Register */
 c =inbio_base UART_IER);
 /* The top four bits of the IER should always == 0 */
 if ( & xf0 != 0)
  ok = 0;  /* failed */

 outb(0xaa, io_base + UART_SCR);
 /* Write arbitrary data into the scratch reg */
  ( +UART_SCR;
 /* If it comes back, it's OK */
 ifc!=xaa
  ok = 0java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

(0,io_base +UART_SCR);
 
c = inb(io_base + UART_SCR);
/* If it comes back, it's OK */

 if ( !0)
  ok = 0;  /* failed */

 return ok;
}

staticshort  fifo_count 
{
char byte;

/* Initialize basic variables */

 uart->buff_in_count = 0;
 uart-buff_in=0java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
 
 uart-  ;
 uart->fifo_count = 0;
 uart->timer_running = 0;

 outb(UART_FCR_ENABLE_FIFO /* Enable FIFO's (if available) */
     | UART_FCR_CLEAR_RCVR /* Clear receiver FIFO */*  receiverFIFO *java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
      |UART_FCR_CLEAR_XMIT
      | UART_FCR_TRIGGER_4 /* Set FIFO trigger at 4-bytes */
intbuff_in
  *         int;
  */
      ,uart->base

 if(inbuart-base+ UART_IIR&xf0= 0java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
  uart->fifo_limit 
  uart-divisor ! 0 {
  uart->old_line_ctrl_reg = inb{
  outb(UART_LCR_DLAB /* Divisor latch access bit */
  if!>timer_running) {
  uart-o = inbbase +);
  uart->old_divisor_msb = inb mod_timer&>, jiffies +(HZ  5)/ 5)java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61

  outb(uart->divisorjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
      uart- +) 
outb(0
     ,uart->base + UART_DLM); /* Divisor Latch High */

  /* DLAB is reset to 0 in next outb() */
 }
 /* Set serial parameters (parity off, etc) */
 outbUART_LCR_WLEN8 /* 8 data-bits */
      | 0 i uart-buff_in_count  )java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
      |0 
     | 0 /* DLAB = 0 */

      ,uart-uart-fifo_count+;

 switchuart->adaptor 
 default
  outb( 
     | UART_MCR_DTR /* Set Data-Terminal-Ready line active */

         /* Set OUT2 - not always required, but when
 * it is, it is ESSENTIAL for enabling interrupts
 */

       ,uart->base + UART_MCR) */
  break;
caseSNDRV_SERIAL_MS124W_SA
 case unsignedchar c status
  /* MS-124W can draw power from RTS and DTR if they
   are in opposite states. */

  outb(UART_MCR_RTS | (0&UART_MCR_DTR) | UART_MCR_OUT2,
       uart-base+ UART_MCR;
  break;
 case SNDRV_SERIAL_MS124T:
  /* MS-124T can draw power from RTS and/or DTR (preferably
   both) if they are both asserted. */

  (UART_MCR_RTS| UART_MCR_DTR | UART_MCR_OUT2,
       uart->base + (( =inb(uart->base  ) &) java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
 reak
 }

 if ( java.lang.StringIndexOutOfBoundsException: Range [4, 3) out of bounds for length 15
 ifrstatus)java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
    (&UART_IER_THRI)/* Disable Transmitter    interrupt*/
      ;
 } else    if(! 0f5
  byte = UART_IER_RDI        
      |UART_IER_MSI /* Enable Modem status interrupt */
      ;
  lseif(art-> = ){
  byte = UART_IER_RDI    & >substream)
      | UART_IER_MSI /* Enable Modem status interrupt */
           &c );
  ;
 }   uart-midi_inputsubstream)
  byte = UART_IER_RDI /* Enable Receiver data interrupt */
       UART_IER_THRIjava.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
 ;
 }
 outb(byte, uart->base +   "s:Overrun on at 0java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 40

 inbuart-base+UART_LSR /* Clear any pre-existing overrun indication */
 inb>prev_in  substream;
  /* no need of check SERIAL_MODE_OUTPUT_OPEN because if not,
}

static void snd_uart16550_do_close(struct snd_uart16550 * uart)
{
if (uart->irq < 0)
snd_uart16550_del_timer(uart);

/* NOTE: may need to disable interrupts before de-registering out handler.
 * For now, the consequences are harmless.
 */


   /* Can't use FIFO, must send only when CTS is true */
      |(0 & UART_IER_THRI  status = inb(uart->base + UART_MSR);
      ,uart->base + UART_IER); /* Interrupt enable Register */

 switch (uart->adaptor) {
 default:
 outb((0&UART_MCR_RTS) /* Deactivate Request-To-Send line  */
       |(0 & UART_MCR_DTR)         status = inb(uart->base + UART_MSR)  }
       |(0 & UART_MCR_OUT2) /* Deactivate OUT2 */
       ,uart->base + UART_MCR); /* Modem Control Register */
 break
 case :
 case SNDRV_SERIAL_MS124W_MB(art
  /* MS-124W can draw power from RTS and DTR if they
   are in opposite states; leave it powered. */

  outb(UART_MCR_RTS | (snd_uart16550_add_timeruart)java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
       uart->base + UART_MCR);
  break * this has been done. * For a Rx interrupt, this is done by reading  * For a Tx interrupt this is done * a)  * b) Reading the * It is particularly important to read the IIR if  * when there is no data in tx_buff[], as  * indication that the interrupt has been serviced, and it * indefinitely. This has the curious side effect * will be generated * It is also desirable to * opened * *
 case :
  /* MS-124T can draw power from RTS and/or DTR (preferably(>+UART_IIR)java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
   both) if they are both asserted; leave it powered. */

  outb(UART_MCR_RTSstruct*uart;
       uart- =timer_container_of(uart t uffer_timer
  break;
 }

 inb(uart->base + UART_IIR); /* Clear any outstanding interrupts */

 /* Restore old divisor */
 if(>divisor! 0)java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
 outbUART_LCR_DLAB /* Divisor latch access bit */
       ,uart->base + UART_LCR); /* Line Control Register */
  outb(uart- *  this method probes, if an uart sits on given port
       ,uart->base + UART_DLL); /* Divisor Latch Low */
  outbuart-old_divisor_msb
       ,uart->java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 1
  /* Restore old LCR (data bits, stop bits, parity, DLAB) */
 outb>old_line_ctrl_reg
       java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
}

static int returnENODEV; 
{
 unsignedif (!(uart->>dev ,8 SerialMIDI){
 struct u = substream->rmidi-private_data

 spin_lock_irqsave(&uart->open_lock, flags);
 f(>filemode =SERIAL_MODE_NOT_OPENED)
  snd_uart16550_do_open
  /* uart detected unless one of the following tests should fail */
 uart-  1java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
 spin_unlock_irqrestore&uart-open_lock,flags;
 return0;
}

static int snd_uart16550_input_close(struct snd_rawmidi_substreamif (c& xf0 != )
{
 unsigned long flags;
 truct * =>>;

 spin_lock_irqsave(&uart->open_lock, flags);
 uart-filemode & ~SERIAL_MODE_INPUT_OPEN
 uart->midi_input[substream-> /* If it comes back, it's OK */
 if (uart->filemode == SERIAL_MODE_NOT_OPENED)
  snd_uart16550_do_close(uart if (c = 0xaa)
 pin_unlock_irqrestore&>open_lock flags);
 return 0;
}

static voidsnd_uart16550_input_trigger( snd_rawmidi_substreamsubstream,
    intup
{
 unsigned long flags;
 struct snd_uart16550 *uart = substream- /* If it comes back, it's OK */

 spin_lock_irqsave(&o = ; /* failed */
 if()
  uart->filemode
 else
  uart->filemode &= ~SERIAL_MODE_INPUT_TRIGGERED;
 spin_unlock_irqrestore(&uart- b;
}

staticintsnd_uart16550_output_openstructsnd_rawmidi_substream )
{
 unsigned flags
 struct snd_uart16550*uart=substream-rmidi-private_datajava.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61

 spin_lock_irqsave
 if  outb(UART_FCR_ENABLE_FIFO/* Enable FIFO's (if available) */
  snd_uart16550_do_open(uart);
 uart-     |UART_FCR_CLEAR_XMIT /* Clear transmitter FIFO */
 uart->midi_output[substream->number] = substream;
 spin_unlock_irqrestore(&uart->open_lock,  at 4- */
 return 0;
};

static int snd_uart16550_output_close( java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{
 unsigned
 tructsnd_uart16550* = >>private_data

 spin_lock_irqsave(&uart->open_lock, flags);
emode & SERIAL_MODE_OUTPUT_OPEN
  >old_line_ctrl_reg =inbuart-base+UART_LCR
 if(uart-filemode=SERIAL_MODE_NOT_OPENED)
  snd_uart16550_do_close(uart);
 spin_unlock_irqrestore&>, );
 return ;
};

 inline int snd_uart16550_buffer_can_write snd_uart16550uart,
       int Num)
{
 if (> +Num< )
  return1java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
 else
  return 0;
}

static  intsnd_uart16550_write_buffer(struct snd_uart16550 **,
          unsigned char byte)
{
 unsigned|0 /* 1 stop-bit */
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  uart->[buff_in] = byte
  buff_in++;
  buff_in &= TX_BUFF_MASK;
  uart-buff_in buff_in
  uart->buff_in_count++;
  if  (uart-adaptor java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
   snd_uart16550_add_timer(uart);
  return 1;
 }else
  return 0;
}

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- case SNDRV_SERIAL_MS124W_MB  /* MS-124W can draw power from RTS and DTR if they
    uart->adaptor != SNDRV_SERIAL_GENERIC) ||
(uart->fifo_count == 0                  /* FIFO empty? */

   && (inb(     >base+ UART_MCR;

         *Tx  Empty-try   *
  if ((inb(uart->base     java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 0

          uart-( ) 
outb(midi_byte, uart->base + UART_TX);
} else {
        if (uart->fifo_count < uart->fifo_limit) {
        uart->fifo_count++;
outb(midi_byte, uart->base + UART_TX);
} else {
        /* Cannot write (buffer empty) -
 * put char in buffer */

   | 
}
}
} else {
if (!snd_uart16550_write_buffer(uart, midi_byte)) {
dev_warn(uart->card->dev,
 "%s: Buffer overrun on device at 0x%lx\n",
 uart->rmidi->name, uart->base);
return 0;
}
}

return 1;
}

static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream)
{
unsigned long flags;
unsigned char midi_byte, addr_byte;
struct snd_uart16550 *uart = substream->rmidi->private_data;
char first;
static unsigned long lasttime = 0;

/* Interrupts are disabled during the updating of the tx_buff,
 * since it is 'bad' to have two processes updating the same
 * variables (ie buff_in & buff_out)
 */


 spin_lock_irqsave(&uart->open_lock, flags);

 if (uart->irq < 0) /* polling */
  snd_uart16550_io_loop(uart-old_divisor_msb

 if (uart->adaptor == SNDRV_SERIAL_MS124W_MB) {
  while (1) {
   /* buffer full? */
 /* in this mode we need two bytes of space */
   if (uart->buff_in_count >  /
    break;
     utbuart-old_line_ctrl_reg
    break;
#ifdefSNDRV_SERIAL_MS124W_MB_NOCOMBO
   /* select exactly one of the four ports */
 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
#else
   /* select any combination of the four ports */
  addr_byte= substream-number<4)|0x08;
   /* ...except none */
   iflock_irqsave(uart-open_lock );
    addr_byte = xf8
#endif
   (uart,substream, addr_byte);
   /* send midi byte */uart-midi_inputsubstream-number =substream
   nd_uart16550_output_byte, substreammidi_byte;
  }
 }else{
  java.lang.StringIndexOutOfBoundsException: Range [1, 7) out of bounds for length 1
  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- structsnd_uart16550*uart = substream->rmidi->private_data;
       (uart-spin_lock_irqsave(&uart->pen_lock flags);
        time_after(jiffies, lasttime + 3*HZ

  >midi_inputsubstream-number  NULL;
     /* Roland Soundcanvas part selection */
     /* If this substream of the data is
 * different previous substream
 * in this uart, send the change part
 * event
 */

     uart->prev_out = substream->number;
   java.lang.StringIndexOutOfBoundsException: Range [22, 6) out of bounds for length 22
     snd_uart16550_output_byte(uart
    static voidsnd_uart16550_input_trigger( snd_rawmidi_substream*ubstream
    /* data */
     snd_uart16550_output_byte(uart, substream,
          uart->
  unsignedl ;
      * send snd_uart16550 *uartsubstream-rmidi-private_data
   if(idi_byte &
         uart-filemode|SERIAL_MODE_INPUT_TRIGGERED
      snd_uart16550_output_byte( >filemode & ~;
    } else if (! spin_unlock_irqrestore(&art-, flags)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
     break;

  

   /* send midi byte */  * = substream->rmidi-private_data;
   java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
       !uart-if (>filemode ==)
    break;

   if  uart->filemode |= SERIAL_MODE_OUTPUT_OPEN;
    uart->prev_status[uart- >midi_output[substream-]= ;
   firstreturn0java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10

   snd_rawmidi_transmit_ack( java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
 }
  lasttime = jiffies;
 }
 spin_unlock_irqrestore(&uart->open_lock, flags);
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

staticvoid (structsnd_rawmidi_substream*ubstream
  i )
{
 unsigned long flags(uart-open_lock,)
 struct snd_uart16550 

 spin_lock_irqsave&uart->open_lock flags
 if    java.lang.StringIndexOutOfBoundsException: Range [10, 8) out of bounds for length 15
  uart->filemodereturn1;
 else
  uart->filemode &= java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
 spin_unlock_irqrestorestaticinlinesnd_uart16550_write_buffer( snd_uart16550 *,
 if (up)
  substream;
}

static const struct snd_rawmidi_ops java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
{
 .open =  snd_uart16550_output_open,
 c =,
  buff_in+;
}   =TX_BUFF_MASK

static >buff_in_count+
{
 .open =  snd_uart16550_input_open,
 .lose= ,
 . = snd_uart16550_input_trigger
};

static int snd_uart16550_create(struct snd_card *card,
    unsigned long iobasestatic int snd_uart16550_output_byte(struct snd_uart16550*uart,
    int irq,
    unsigned int speed,
    unsigned  base,
    int adaptor,
  int droponfull
    struct snd_uart16550if(uart-> =                    
{
struct snd_uart16550 *uart;
int err;


uart = devm_kzalloc(card->dev, sizeof(*uart), GFP_KERNEL);
if (!uart)
return -ENOMEM;
uart->adaptor = adaptor;
uart->card = card;
spin_lock_init(&uart->open_lock);
uart->irq = -1;
uart->base = iobase;
uart->drop_on_full = droponfull;

err = snd_uart16550_detect(uart);
if (err <= 0) {
dev_err(card->dev, "no UART detected at 0x%lx\n", iobase);
return -ENODEV;
}

if (irq >= 0 && irq != SNDRV_AUTO_IRQ) {
if (devm_request_irq(card->dev, irq, snd_uart16550_interrupt,
     0, "Serial MIDI", uart)) {
dev_warn(card->dev,
 "irq %d busy. Using Polling.\n", irq);
} else {
uart->irq = irq;
}
}
uart->divisor = base / speed;
uart->speed = base / (unsigned int)uart->divisor;
uart->speed_base = base;
uart->prev_out = -1;
uart->prev_in = 0;
uart->rstatus = 0;
memset(uart->prev_status, 0x80, sizeof(unsigned char) * SNDRV_SERIAL_MAX_OUTS);
timer_setup(&uart->buffer_timer, snd_uart16550_buffer_timer, 0);
uart->timer_running = 0;

switch (uart->adaptor) {
case SNDRV_SERIAL_MS124W_SA:
case SNDRV_SERIAL_MS124W_MB:
/* MS-124W can draw power from RTS and DTR if they
   are in opposite states. */

  outb }
  break;
 case } else {
  /* MS-124T can draw power from RTS and/or DTR (preferably  (!nd_uart16550_write_bufferuart,midi_byte)) {
   both) if they are asserted. */

MCR_DTRuart->base java.lang.StringIndexOutOfBoundsException: Range [59, 60) out of bounds for length 59
  break;
 default:
  break;
 }

 if (ruart)
  *ruart =uart

 return unsigned  flags
}

static voidsnd_uart16550_substreams( snd_rawmidi_str *stream
{
idi_substreamsubstream

 list_for_each_entry(substreamjava.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
  sprintf(substream->name,   * variables (ie buff_in & buff_out)
 }
}

static int snd_uart16550_rmidi(struct snd_uart16550 *uart, int device,
snd_uart16550_io_loop(uart
          struct snd_rawmidi **rmidi)
{
struct  rrawmidi
interr

 err = snd_rawmidi_new(uart->cardifuart-buff_in_count  -2)
         outs(,substreamaddr_byte;
   0
 return;
 snd_rawmidi_set_ops
  first;
 w substream midi_byte 1 = 1java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
       &snd_uart16550_output);
 strscpy(rrawmidi->name, "Serial MIDI");
 snd_uart16550_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]);
 snd_uart16550_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]);
 rrawmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
          SNDRV_RAWMIDI_INFO_INPUT |
      if(first== 0 &&
 rrawmidi->private_data = uart;
 if (rmidi)
  java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
 return 0;
}

static int snd_serial_probe(struct platform_device *devptr)
{
 struct snd_card  /* Roland Soundcanvas part selection */
 struct   * in this uart, send the change java.lang.StringIndexOutOfBoundsException: Range [0, 42) out of bounds for length 13
  (, ,
 int  >id

  (,substream
 caseSNDRV_SERIAL_SOUNDCANVAS
  ins[dev] = 1   /* If midi_byte is a data byte,
break;
case SNDRV_SERIAL_MS124T:
case SNDRV_SERIAL_MS124W_SA:
outs[dev] = 1;
ins[dev] = 1;
break;
case SNDRV_SERIAL_MS124W_MB:
outs[dev] = 16;
ins[dev] = 1;
break;
case SNDRV_SERIAL_GENERIC:
break;
default:
dev_err(&devptr->dev,
"Adaptor type is out of range 0-%d (%d)\n",
SNDRV_SERIAL_MAX_ADAPTOR, adaptor[dev]);
return -ENODEV;
}

if (outs[dev] < 1 || outs[dev] > SNDRV_SERIAL_MAX_OUTS) {
dev_err(&devptr->dev,
"Count of outputs is out of range 1-%d (%d)\n",
SNDRV_SERIAL_MAX_OUTS, outs[dev]);
return -ENODEV;
}

if (ins[dev] < 1 || ins[dev] > SNDRV_SERIAL_MAX_INS) {
dev_err(&devptr->dev,
"Count of inputs is out of range 1-%d (%d)\n",
SNDRV_SERIAL_MAX_INS, ins[dev]);
return -ENODEV;
}

err  = snd_devm_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
 0, &card);
if (err < 0)
return err;

strscpy(card->driver, "Serial");
strscpy(card->shortname, "Serial MIDI (UART16550A)");

err = snd_uart16550_create(card, port[dev], irq[dev], speed[dev],
   base[dev], adaptor[dev], droponfull[dev],
   &uart);
if (err < 0)
return err;

err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi);
if (err < 0)
return err;

sprintf(card->longname, "%s [%s] at %#lx, irq %d",
card->shortname,
adaptor_names[uart->adaptor],
uart->base,
uart->irq);

err = snd_card_register(card);
if (err < 0)
return err;

platform_set_drvdata(devptr, card);
return 0;
}

#define SND_SERIAL_DRIVER "snd_serial_u16550"

static struct platform_driver snd_serial_driver = {
.probe = snd_serial_probe,
.driver = {
.name = SND_SERIAL_DRIVER,
},
};

static void snd_serial_unregister_all(void)
{
int i;

for (i = 0; i < ARRAY_SIZE(devices); ++i)
platform_device_unregister(devices[i]);
platform_driver_unregister(&snd_serial_driver);
}

static int __init alsa_card_serial_init(void)
{
int i, cards, err;

err = platform_driver_register(&snd_serial_driver);
if (err < 0)
return err;

cards = 0;
for (i = 0; i < SNDRV_CARDS; i++) {
struct platform_device *device;
if (! enable[i])
continue;
device = platform_device_register_simple(SND_SERIAL_DRIVER,
 i, NULL, 0);
if (IS_ERR(device))
continue;
if (!platform_get_drvdata(device)) {
platform_device_unregister(device);
continue;
}
devices[i] = device;
cards++;
}
if (! cards) {
#ifdef MODULE
pr_err("serial midi soundcard not found or device busy\n");
#endif
snd_serial_unregister_all();
return -ENODEV;
}
return 0;
}

static void __exit alsa_card_serial_exit(void)
{
snd_serial_unregister_all();
}

module_init(alsa_card_serial_init)
module_exit(alsa_card_serial_exit)

Messung V0.5
C=96 H=95 G=95

¤ Dauer der Verarbeitung: 0.8 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.