Ejemplo n.º 1
0
static void ipaq_read_bulk_callback(struct urb *urb)
{
	struct usb_serial_port	*port = (struct usb_serial_port *)urb->context;
	struct tty_struct	*tty;
	unsigned char		*data = urb->transfer_buffer;
	int			result;

	dbg("%s - port %d", __FUNCTION__, port->number);

	if (urb->status) {
		dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
		return;
	}

	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);

	tty = port->tty;
	if (tty && urb->actual_length) {
		tty_buffer_request_room(tty, urb->actual_length);
		tty_insert_flip_string(tty, data, urb->actual_length);
		tty_flip_buffer_push(tty);
		bytes_in += urb->actual_length;
	}

	/* Continue trying to always read  */
	usb_fill_bulk_urb(port->read_urb, port->serial->dev, 
		      usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress),
		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
		      ipaq_read_bulk_callback, port);
	result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
	if (result)
		err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
	return;
}
Ejemplo n.º 2
0
/*------------------------------------------------------------
  函数原型: void    send_msg_to_user_space(PNDIS_NODE pnode, struct tty_struct * tty, int count)
  描述: send_msg_to_user_space函数是在,当从USB底层成功读入NDIS消息
        时,并且经过判别是WDS类型的消息,需要交给WDS进程或其他用户
        进程进行处理的情况,调用tty核心的缓冲区流输入和流刷新函数
        把WDS消息送入用户进程空间。
  输入: PNDIS_NODE pnode 读入WDS消息的消息结点.
        struct tty_struct * tty 记录下的对应的用户进程打开的指向的
        tty_struct的指针
        int count 要刷新到用户进程空间的字节数。
  输出: 输出到用户空间的WDS消息。
  返回值: 无。
-------------------------------------------------------------*/
static void send_msg_to_user_space(PNDIS_NODE pnode, struct tty_struct * tty, int count)
{
    int i = 0;
    if (NULL == tty)
    {
        printk("%s - tty maybe null.\n", __FUNCTION__);
        return;
    }
    /*printk("%s - send msg_len(0x%0x) to user space.\n", __FUNCTION__, count-SDU_START_POSITION);*/    /* < DTS2011011305021: gkf34687 2011-03-02 DEL>*/
	tty_buffer_request_room(tty, count);
    for (i = 0; i < count; ++i)
    {
#ifdef NDIS_MSG_PRINT_DBG
        printk("%02x ", *(MEG_ROW(pnode->row_num)+i));
#endif
        tty_insert_flip_char(tty, *(unsigned char *)(MEG_ROW(pnode->row_num)+i),
         TTY_NORMAL);
    }
#ifdef NDIS_MSG_PRINT_DBG
	printk("\n ");
#endif
    tty_flip_buffer_push(tty);
#ifdef NDIS_MSG_PRINT_DBG
    printk("\n");
#endif
}
static void
vcons_rx_intr (NkPort* port)
{
    unsigned int		size;
    int				i;
    int				count = 0;

    while ((size = vcons_rxfifo_count(port))) {
        if (port->count == 0) {
            return;
        }

        if (port->stoprx) {
            break;
        }

        /* ask how many characters we can read */
        size = tty_buffer_request_room(port->tty, size);
        if (size == 0) {
            return;
        }

        size = os_ctx->cops.read(port->id, port->buf, size);
        count += size;
        for (i = 0; i < size; i++) {
            tty_insert_flip_char(port->tty, port->buf[i], TTY_NORMAL);
        }
    }

    if (count > 0) {
        tty_schedule_flip(port->tty);
    }
}
Ejemplo n.º 4
0
static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len)
{
	struct uart_port *port = &max->port;
	struct tty_struct *tty;
	int usable;

	/* If uart is not opened, just return */
	if (!port->state)
		return;

	tty = port->state->port.tty;
	if (!tty)
		return;	/* receive some char before the tty is opened */

	while (len) {
		usable = tty_buffer_request_room(tty, len);
		if (usable) {
			tty_insert_flip_string(tty, str, usable);
			str += usable;
			port->icount.rx += usable;
			tty_flip_buffer_push(tty);
		}
		len -= usable;
	}
}
int tty_insert_flip_string_flags(struct tty_struct *tty,
		const unsigned char *chars, const char *flags, size_t size)
{
	int copied = 0;
	do {
		int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
		int space = tty_buffer_request_room(tty, goal);
		/* If there is no space then tty->buf.tail may be NULL */
		if(tty->buf.tail == 0)
			break;
		else{
			struct tty_buffer *tb = tty->buf.tail;
			/* If there is no space then tb may be NULL */
			if (unlikely(space == 0))
				break;
			memcpy(tb->char_buf_ptr + tb->used, chars, space);
			memcpy(tb->flag_buf_ptr + tb->used, flags, space);
			tb->used += space;
			copied += space;
			chars += space;
			flags += space;
			/* There is a small chance that we need to split the data over
			   several buffers. If this is the case we must loop */
		}
	} while (unlikely(size > copied));
	return copied;
}
Ejemplo n.º 6
0
static void my_timer(unsigned long data)
{
    /* TODO Auto-generated Function */
    PINFO("my_uart_timer executing\n");
//------------------------------------------------------
    char bytes[] = {'A'};
    int data_size = 1;
    int i;
    //if (!tiny)
    //	return;

    //tty = tiny->tty;
    //port = tty->port;

    /* send the data to the tty layer for users to read.  This doesn't
     * actually push the data through unless tty->low_latency is set */
    for (i = 0; i < data_size; ++i) {
        if (!tty_buffer_request_room(&devices[0].port, 1))
            tty_flip_buffer_push(&devices[0].port);
        tty_insert_flip_char(&devices[0].port, bytes[i], TTY_NORMAL);
    }
    tty_flip_buffer_push(&devices[0].port);

//------------------------------------------------------
    my_uart_timer.expires = jiffies + MY_UART_DELAY_MS * HZ / 1000;
    add_timer(&my_uart_timer);

}
Ejemplo n.º 7
0
static void tiny_timer(unsigned long timer_data)
{
	struct tiny_serial *tiny = (struct tiny_serial *)timer_data;
	struct tty_struct *tty;
	struct tty_port *port;
	int i;
	char data[1] = {TINY_DATA_CHARACTER};
	int data_size = 1;

	if (!tiny)
		return;

	tty = tiny->tty;
	port = tty->port;

	/* send the data to the tty layer for users to read.  This doesn't
	 * actually push the data through unless tty->low_latency is set */
	for (i = 0; i < data_size; ++i) {
		if (!tty_buffer_request_room(port, 1))
			tty_flip_buffer_push(port);
		tty_insert_flip_char(port, data[i], TTY_NORMAL);
	}
	tty_flip_buffer_push(port);

	/* resubmit the timer again */
	tiny->timer->expires = jiffies + DELAY_TIME;
	add_timer(tiny->timer);
}
Ejemplo n.º 8
0
static int gdm_tty_recv_complete(void *data,
				 int len,
				 int index,
				 struct tty_dev *tty_dev,
				 int complete)
{
	struct gdm *gdm = tty_dev->gdm[index];

	if (!GDM_TTY_READY(gdm)) {
		if (complete == RECV_PACKET_PROCESS_COMPLETE)
			gdm_tty_recv(gdm, gdm_tty_recv_complete);
		return TO_HOST_PORT_CLOSE;
	}

	if (data && len) {
		if (tty_buffer_request_room(&gdm->port, len) == len) {
			tty_insert_flip_string(&gdm->port, data, len);
			tty_flip_buffer_push(&gdm->port);
		} else {
			return TO_HOST_BUFFER_REQUEST_FAIL;
		}
	}

	if (complete == RECV_PACKET_PROCESS_COMPLETE)
		gdm_tty_recv(gdm, gdm_tty_recv_complete);

	return 0;
}
Ejemplo n.º 9
0
/* Push data to tty layer and resubmit the bulk read URB */
static void flush_and_resubmit_read_urb (struct usb_serial_port *port)
{
	struct usb_serial *serial = port->serial;
	struct urb *urb = port->read_urb;
	struct tty_struct *tty = port->tty;
	int result;

	/* Push data to tty */
	if (tty && urb->actual_length) {
		tty_buffer_request_room(tty, urb->actual_length);
		tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length);
	  	tty_flip_buffer_push(tty); /* is this allowed from an URB callback ? */
	}

	/* Continue reading from device */
	usb_fill_bulk_urb (port->read_urb, serial->dev,
			   usb_rcvbulkpipe (serial->dev,
				   	    port->bulk_in_endpointAddress),
			   port->read_urb->transfer_buffer,
			   port->read_urb->transfer_buffer_length,
			   ((serial->type->read_bulk_callback) ? 
			     serial->type->read_bulk_callback : 
			     usb_serial_generic_read_bulk_callback), port);
	result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
	if (result)
		dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
}
Ejemplo n.º 10
0
static void cyberjack_read_bulk_callback(struct urb *urb)
{
	struct usb_serial_port *port = urb->context;
	struct cyberjack_private *priv = usb_get_serial_port_data(port);
	struct tty_struct *tty;
	unsigned char *data = urb->transfer_buffer;
	short todo;
	int result;
	int status = urb->status;

	dbg("%s - port %d", __func__, port->number);

	usb_serial_debug_data(debug, &port->dev, __func__,
						urb->actual_length, data);
	if (status) {
		dbg("%s - nonzero read bulk status received: %d",
		    __func__, status);
		return;
	}

	tty = tty_port_tty_get(&port->port);
	if (!tty) {
		dbg("%s - ignoring since device not open\n", __func__);
		return;
	}
	if (urb->actual_length) {
		tty_buffer_request_room(tty, urb->actual_length);
		tty_insert_flip_string(tty, data, urb->actual_length);
		tty_flip_buffer_push(tty);
	}
	tty_kref_put(tty);

	spin_lock(&priv->lock);

	
	priv->rdtodo -= urb->actual_length;
	
	if (priv->rdtodo < 0)
		priv->rdtodo = 0;
	todo = priv->rdtodo;

	spin_unlock(&priv->lock);

	dbg("%s - rdtodo: %d", __func__, todo);

	
	if (todo ) {
		port->read_urb->dev = port->serial->dev;
		result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
		if (result)
			dev_err(&port->dev, "%s - failed resubmitting read "
				"urb, error %d\n", __func__, result);
		dbg("%s - usb_submit_urb(read urb)", __func__);
	}
}
Ejemplo n.º 11
0
/*===========================================================================
METHOD:
   GobiReadBulkCallback (Free Method)

DESCRIPTION:
   Read data from USB, push to TTY and user space

PARAMETERS:
   pURB  [ I ] - USB Request Block (urb) that called us 

RETURN VALUE:
===========================================================================*/
static void GobiReadBulkCallback( struct urb * pURB )
{
   struct usb_serial_port * pPort = pURB->context;
   struct tty_struct * pTTY = pPort->tty;
   int nResult;
   int nRoom = 0;
   unsigned int pipeEP;
   
   DBG( "port %d\n", pPort->number );

   if (pURB->status != 0) 
   {
      DBG( "nonzero read bulk status received: %d\n", pURB->status );

      return;
   }

   usb_serial_debug_data( debug, 
                          &pPort->dev, 
                          __FUNCTION__, 
                          pURB->actual_length, 
                          pURB->transfer_buffer );

   // We do no port throttling

   // Push data to tty layer and user space read function
   if (pTTY != 0 && pURB->actual_length) 
   {
      nRoom = tty_buffer_request_room( pTTY, pURB->actual_length );
      DBG( "room size %d %d\n", nRoom, 512 );
      if (nRoom != 0)
      {
         tty_insert_flip_string( pTTY, pURB->transfer_buffer, nRoom );
         tty_flip_buffer_push( pTTY );
      }
   }

   pipeEP = usb_rcvbulkpipe( pPort->serial->dev, 
                             pPort->bulk_in_endpointAddress );

   // For continuous reading
   usb_fill_bulk_urb( pPort->read_urb, 
                      pPort->serial->dev,
                      pipeEP,
                      pPort->read_urb->transfer_buffer,
                      pPort->read_urb->transfer_buffer_length,
                      GobiReadBulkCallback, 
                      pPort );
   
   nResult = usb_submit_urb( pPort->read_urb, GFP_ATOMIC );
   if (nResult != 0)
   {
      DBG( "failed resubmitting read urb, error %d\n", nResult );
   }
}
Ejemplo n.º 12
0
/*
 * byte channel receive interupt handler
 *
 * This ISR is called whenever data is available on a byte channel.
 */
static irqreturn_t ehv_bc_tty_rx_isr(int irq, void *data)
{
	struct ehv_bc_data *bc = data;
	unsigned int rx_count, tx_count, len;
	int count;
	char buffer[EV_BYTE_CHANNEL_MAX_BYTES];
	int ret;

	/* Find out how much data needs to be read, and then ask the TTY layer
	 * if it can handle that much.  We want to ensure that every byte we
	 * read from the byte channel will be accepted by the TTY layer.
	 */
	ev_byte_channel_poll(bc->handle, &rx_count, &tx_count);
	count = tty_buffer_request_room(&bc->port, rx_count);

	/* 'count' is the maximum amount of data the TTY layer can accept at
	 * this time.  However, during testing, I was never able to get 'count'
	 * to be less than 'rx_count'.  I'm not sure whether I'm calling it
	 * correctly.
	 */

	while (count > 0) {
		len = min_t(unsigned int, count, sizeof(buffer));

		/* Read some data from the byte channel.  This function will
		 * never return more than EV_BYTE_CHANNEL_MAX_BYTES bytes.
		 */
		ev_byte_channel_receive(bc->handle, &len, buffer);

		/* 'len' is now the amount of data that's been received. 'len'
		 * can't be zero, and most likely it's equal to one.
		 */

		/* Pass the received data to the tty layer. */
		ret = tty_insert_flip_string(&bc->port, buffer, len);

		/* 'ret' is the number of bytes that the TTY layer accepted.
		 * If it's not equal to 'len', then it means the buffer is
		 * full, which should never happen.  If it does happen, we can
		 * exit gracefully, but we drop the last 'len - ret' characters
		 * that we read from the byte channel.
		 */
		if (ret != len)
			break;

		count -= len;
	}

	/* Tell the tty layer that we're done. */
	tty_flip_buffer_push(&bc->port);

	return IRQ_HANDLED;
}
Ejemplo n.º 13
0
int tty_prepare_flip_string(struct tty_port *port, unsigned char **chars,
		size_t size)
{
	int space = tty_buffer_request_room(port, size);
	if (likely(space)) {
		struct tty_buffer *tb = port->buf.tail;
		*chars = tb->char_buf_ptr + tb->used;
		memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
		tb->used += space;
	}
	return space;
}
int tty_prepare_flip_string_flags(struct tty_struct *tty,
			unsigned char **chars, char **flags, size_t size)
{
	int space = tty_buffer_request_room(tty, size);
	if (likely(space)) {
		struct tty_buffer *tb = tty->buf.tail;
		*chars = tb->char_buf_ptr + tb->used;
		*flags = tb->flag_buf_ptr + tb->used;
		tb->used += space;
	}
	return space;
}
Ejemplo n.º 15
0
void gigaset_if_receive(struct cardstate *cs,
			unsigned char *buffer, size_t len)
{
	unsigned long flags;
	struct tty_struct *tty;

	spin_lock_irqsave(&cs->lock, flags);
	if ((tty = cs->tty) == NULL)
		gig_dbg(DEBUG_ANY, "receive on closed device");
	else {
		tty_buffer_request_room(tty, len);
		tty_insert_flip_string(tty, buffer, len);
		tty_flip_buffer_push(tty);
	}
	spin_unlock_irqrestore(&cs->lock, flags);
}
Ejemplo n.º 16
0
static void kobil_read_int_callback(struct urb *urb)
{
    int result;
    struct usb_serial_port *port = urb->context;
    struct tty_struct *tty;
    unsigned char *data = urb->transfer_buffer;
    int status = urb->status;
    /*	char *dbg_data; */

    dbg("%s - port %d", __func__, port->number);

    if (status) {
        dbg("%s - port %d Read int status not zero: %d",
            __func__, port->number, status);
        return;
    }

    tty = tty_port_tty_get(&port->port);
    if (urb->actual_length) {

        /* BEGIN DEBUG */
        /*
          dbg_data = kzalloc((3 *  purb->actual_length + 10)
        				* sizeof(char), GFP_KERNEL);
          if (! dbg_data) {
        	  return;
          }
          for (i = 0; i < purb->actual_length; i++) {
        	  sprintf(dbg_data +3*i, "%02X ", data[i]);
          }
          dbg(" <-- %s", dbg_data);
          kfree(dbg_data);
        */
        /* END DEBUG */

        tty_buffer_request_room(tty, urb->actual_length);
        tty_insert_flip_string(tty, data, urb->actual_length);
        tty_flip_buffer_push(tty);
    }
    tty_kref_put(tty);
    /* someone sets the dev to 0 if the close method has been called */
    port->interrupt_in_urb->dev = port->serial->dev;

    result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
    dbg("%s - port %d Send read URB returns: %i",
        __func__, port->number, result);
}
Ejemplo n.º 17
0
/* Push data to tty layer and resubmit the bulk read URB */
static void flush_and_resubmit_read_urb(struct usb_serial_port *port)
{
	struct urb *urb = port->read_urb;
	struct tty_struct *tty = port->port.tty;
	int room;

	/* Push data to tty */
	if (tty && urb->actual_length) {
		room = tty_buffer_request_room(tty, urb->actual_length);
		if (room) {
			tty_insert_flip_string(tty, urb->transfer_buffer, room);
			tty_flip_buffer_push(tty);
		}
	}

	resubmit_read_urb(port, GFP_ATOMIC);
}
Ejemplo n.º 18
0
static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs)
{
	int result;
	struct usb_serial_port *port = (struct usb_serial_port *) purb->context;
	struct tty_struct *tty;
	unsigned char *data = purb->transfer_buffer;
//	char *dbg_data;

	dbg("%s - port %d", __FUNCTION__, port->number);

	if (purb->status) {
		dbg("%s - port %d Read int status not zero: %d", __FUNCTION__, port->number, purb->status);
		return;
	}
	
	tty = port->tty; 
	if (purb->actual_length) {
		
		// BEGIN DEBUG
		/*
		  dbg_data = (unsigned char *) kmalloc((3 *  purb->actual_length + 10) * sizeof(char), GFP_KERNEL);
		  if (! dbg_data) {
		  return;
		  }
		  memset(dbg_data, 0, (3 *  purb->actual_length + 10));
		  for (i = 0; i < purb->actual_length; i++) { 
		  sprintf(dbg_data +3*i, "%02X ", data[i]); 
		  }
		  dbg(" <-- %s", dbg_data );
		  kfree(dbg_data);
		*/
		// END DEBUG

		tty_buffer_request_room(tty, purb->actual_length);
		tty_insert_flip_string(tty, data, purb->actual_length);
		tty_flip_buffer_push(tty);
	}

	// someone sets the dev to 0 if the close method has been called
	port->interrupt_in_urb->dev = port->serial->dev;

	result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC ); 
	dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);
}
Ejemplo n.º 19
0
static void navman_read_int_callback(struct urb *urb)
{
	struct usb_serial_port *port = urb->context;
	unsigned char *data = urb->transfer_buffer;
	struct tty_struct *tty;
	int status = urb->status;
	int result;

	switch (status) {
	case 0:
		/* success */
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		/* this urb is terminated, clean up */
		dbg("%s - urb shutting down with status: %d",
		    __func__, status);
		return;
	default:
		dbg("%s - nonzero urb status received: %d",
		    __func__, status);
		goto exit;
	}

	usb_serial_debug_data(debug, &port->dev, __func__,
			      urb->actual_length, data);

	tty = tty_port_tty_get(&port->port);
	if (tty && urb->actual_length) {
		tty_buffer_request_room(tty, urb->actual_length);
		tty_insert_flip_string(tty, data, urb->actual_length);
		tty_flip_buffer_push(tty);
	}
	tty_kref_put(tty);

exit:
	result = usb_submit_urb(urb, GFP_ATOMIC);
	if (result)
		dev_err(&urb->dev->dev,
			"%s - Error %d submitting interrupt urb\n",
			__func__, result);
}
Ejemplo n.º 20
0
int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars,
				size_t size)
{
	int copied = 0;
	do {
		int space = tty_buffer_request_room(tty, size - copied);
		struct tty_buffer *tb = tty->buf.tail;
		/* If there is no space then tb may be NULL */
		if (unlikely(space == 0))
			break;
		memcpy(tb->char_buf_ptr + tb->used, chars, space);
		memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
		tb->used += space;
		copied += space;
		chars += space;
		/* There is a small chance that we need to split the data over
		   several buffers. If this is the case we must loop */
	} while (unlikely(size > copied));
	return copied;
}
Ejemplo n.º 21
0
static void spi_tty_handle_data(void *context, u8 *buf, u32 count)
{
	int cnt, crc, len;
	struct spi_tty_s *spi_tty;
	spi_msg_header header;

	SPI_IPC_INFO("%s, context=%p, buf=%p, count=%d\n", __func__, context, buf, count);

	if (!context || !buf || !count) {
		pr_err("%s - Invalid param!\n", __func__);
		return;
	}

	spi_ipc_buf_dump("rx header: ", buf, SPI_MSG_HEADER_LEN);

	spi_tty = (struct spi_tty_s *) context;
	spi_msg_get_header(buf, &header);
	crc = spi_msg_cal_crc(&header);

	// validate data
	if (header.type != 1 || header.len > SPI_MTU || header.fcs != crc) {
		pr_err("Invalid data receicved!\n");
		return;
	}

	if (spi_tty->open_count > 0 && header.len > 0) {
		len = header.len;
		spi_ipc_buf_dump_ascii("rx data: ", buf+SPI_MSG_HEADER_LEN, (len>16?16:len));
		SPI_IPC_INFO("insert data to tty\n");
		buf += SPI_MSG_HEADER_LEN;
		do {
			cnt = tty_buffer_request_room(spi_tty->tty, len);
			if (cnt == 0)
				break;
			cnt = tty_insert_flip_string(spi_tty->tty, buf, cnt);
			tty_flip_buffer_push(spi_tty->tty);
			len -= cnt;
			buf += cnt;
		}while(len > 0);
	}
}
static int
receive_chars(struct uart_max3110 *max, unsigned short *str, int len)
{
	struct uart_port *port = &max->port;
	struct tty_port *tport;
	char buf[M3110_RX_FIFO_DEPTH];
	int r, w, usable;

	/* If uart is not opened, just return */
	if (!port->state)
		return 0;

	tport = &port->state->port;

	for (r = 0, w = 0; r < len; r++) {
		if (str[r] & MAX3110_BREAK &&
		    uart_handle_break(port))
			continue;

		if (str[r] & MAX3110_READ_DATA_AVAILABLE) {
			if (uart_handle_sysrq_char(port, str[r] & 0xff))
				continue;

			buf[w++] = str[r] & 0xff;
		}
	}

	if (!w)
		return 0;

	for (r = 0; w; r += usable, w -= usable) {
		usable = tty_buffer_request_room(tport, w);
		if (usable) {
			tty_insert_flip_string(tport, buf + r, usable);
			port->icount.rx += usable;
		}
	}
	tty_flip_buffer_push(tport);

	return r;
}
Ejemplo n.º 23
0
static void sierra_indat_callback(struct urb *urb)
{
	int err;
	int endpoint;
	struct usb_serial_port *port;
	struct tty_struct *tty;
	unsigned char *data = urb->transfer_buffer;
	int status = urb->status;

	dbg("%s: %p", __func__, urb);

	endpoint = usb_pipeendpoint(urb->pipe);
	port =  urb->context;

	if (status) {
		dev_dbg(&port->dev, "%s: nonzero status: %d on"
		    " endpoint %02x.", __func__, status, endpoint);
	} else {
		tty = port->port.tty;
		if (urb->actual_length) {
			tty_buffer_request_room(tty, urb->actual_length);
			tty_insert_flip_string(tty, data, urb->actual_length);
			tty_flip_buffer_push(tty);
		} else {
			dev_dbg(&port->dev, "%s: empty read urb"
				" received", __func__);
		}

		/* Resubmit urb so we continue receiving */
		if (port->port.count && status != -ESHUTDOWN) {
			err = usb_submit_urb(urb, GFP_ATOMIC);
			if (err)
				dev_err(&port->dev, "resubmit read urb failed."
					"(%d)\n", err);
		}
	}
	return;
}
Ejemplo n.º 24
0
static void option_indat_callback(struct urb *urb)
{
	int err;
	int endpoint;
	struct usb_serial_port *port;
	struct tty_struct *tty;
	unsigned char *data = urb->transfer_buffer;
	int status = urb->status;

	dbg("%s: %p", __FUNCTION__, urb);

	endpoint = usb_pipeendpoint(urb->pipe);
	port = (struct usb_serial_port *) urb->context;

	if (status) {
		dbg("%s: nonzero status: %d on endpoint %02x.",
		    __FUNCTION__, status, endpoint);
	} else {
		tty = port->tty;
		if (urb->actual_length) {
			tty_buffer_request_room(tty, urb->actual_length);
			tty_insert_flip_string(tty, data, urb->actual_length);
			tty_flip_buffer_push(tty);
		} else {
			dbg("%s: empty read urb received", __FUNCTION__);
		}

		/* Resubmit urb so we continue receiving */
		if (port->open_count && status != -ESHUTDOWN) {
			err = usb_submit_urb(urb, GFP_ATOMIC);
			if (err)
				printk(KERN_ERR "%s: resubmit read urb failed. "
					"(%d)", __FUNCTION__, err);
		}
	}
	return;
}
Ejemplo n.º 25
0
static void acm_rx_tasklet(unsigned long _acm)
{
	struct acm *acm = (void *)_acm;
	struct acm_rb *buf;
	struct tty_struct *tty = acm->tty;
	struct acm_ru *rcv;
	unsigned long flags;
	unsigned char throttled;

	dbg("Entering acm_rx_tasklet");

	if (!ACM_READY(acm))
	{
		dbg("acm_rx_tasklet: ACM not ready");
		return;
	}

	spin_lock_irqsave(&acm->throttle_lock, flags);
	throttled = acm->throttle;
	spin_unlock_irqrestore(&acm->throttle_lock, flags);
	if (throttled)
	{
		dbg("acm_rx_tasklet: throttled");
		return;
	}

next_buffer:
	spin_lock_irqsave(&acm->read_lock, flags);
	if (list_empty(&acm->filled_read_bufs)) {
		spin_unlock_irqrestore(&acm->read_lock, flags);
		goto urbs;
	}
	buf = list_entry(acm->filled_read_bufs.next,
			 struct acm_rb, list);
	list_del(&buf->list);
	spin_unlock_irqrestore(&acm->read_lock, flags);

	dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size);

	tty_buffer_request_room(tty, buf->size);
	spin_lock_irqsave(&acm->throttle_lock, flags);
	throttled = acm->throttle;
	spin_unlock_irqrestore(&acm->throttle_lock, flags);
	if (!throttled)
		tty_insert_flip_string(tty, buf->base, buf->size);
	tty_flip_buffer_push(tty);

	if (throttled) {
		dbg("Throttling noticed");
		spin_lock_irqsave(&acm->read_lock, flags);
		list_add(&buf->list, &acm->filled_read_bufs);
		spin_unlock_irqrestore(&acm->read_lock, flags);
		return;
	}

	spin_lock_irqsave(&acm->read_lock, flags);
	list_add(&buf->list, &acm->spare_read_bufs);
	spin_unlock_irqrestore(&acm->read_lock, flags);
	goto next_buffer;

urbs:
	while (!list_empty(&acm->spare_read_bufs)) {
		spin_lock_irqsave(&acm->read_lock, flags);
		if (list_empty(&acm->spare_read_urbs)) {
			acm->processing = 0;
			spin_unlock_irqrestore(&acm->read_lock, flags);
			return;
		}
		rcv = list_entry(acm->spare_read_urbs.next,
				 struct acm_ru, list);
		list_del(&rcv->list);
		spin_unlock_irqrestore(&acm->read_lock, flags);

		buf = list_entry(acm->spare_read_bufs.next,
				 struct acm_rb, list);
		list_del(&buf->list);

		rcv->buffer = buf;

		usb_fill_bulk_urb(rcv->urb, acm->dev,
				  acm->rx_endpoint,
				  buf->base,
				  acm->readsize,
				  acm_read_bulk, rcv);
		rcv->urb->transfer_dma = buf->dma;
		rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

		/* This shouldn't kill the driver as unsuccessful URBs are returned to the
		   free-urbs-pool and resubmited ASAP */
		spin_lock_irqsave(&acm->read_lock, flags);
		if (acm->susp_count || usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) {
			list_add(&buf->list, &acm->spare_read_bufs);
			list_add(&rcv->list, &acm->spare_read_urbs);
			acm->processing = 0;
			spin_unlock_irqrestore(&acm->read_lock, flags);
			return;
		} else {
			spin_unlock_irqrestore(&acm->read_lock, flags);
			dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p", rcv->urb, rcv, buf);
		}
	}
	spin_lock_irqsave(&acm->read_lock, flags);
	acm->processing = 0;
	spin_unlock_irqrestore(&acm->read_lock, flags);
}
Ejemplo n.º 26
0
/*
 * Receive characters
 */
static void cpm_uart_int_rx(struct uart_port *port)
{
	int i;
	unsigned char ch, *cp;
	struct tty_struct *tty = port->info->tty;
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
	volatile cbd_t *bdp;
	u16 status;
	unsigned int flg;

	pr_debug("CPM uart[%d]:RX INT\n", port->line);

	/* Just loop through the closed BDs and copy the characters into
	 * the buffer.
	 */
	bdp = pinfo->rx_cur;
	for (;;) {
		/* get status */
		status = bdp->cbd_sc;
		/* If this one is empty, return happy */
		if (status & BD_SC_EMPTY)
			break;

		/* get number of characters, and check spce in flip-buffer */
		i = bdp->cbd_datlen;

		/* If we have not enough room in tty flip buffer, then we try
		 * later, which will be the next rx-interrupt or a timeout
		 */
		if(tty_buffer_request_room(tty, i) < i) {
			printk(KERN_WARNING "No room in flip buffer\n");
			return;
		}

		/* get pointer */
		cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);

		/* loop through the buffer */
		while (i-- > 0) {
			ch = *cp++;
			port->icount.rx++;
			flg = TTY_NORMAL;

			if (status &
			    (BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV))
				goto handle_error;
			if (uart_handle_sysrq_char(port, ch))
				continue;

		      error_return:
			tty_insert_flip_char(tty, ch, flg);

		}		/* End while (i--) */

		/* This BD is ready to be used again. Clear status. get next */
		bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID);
		bdp->cbd_sc |= BD_SC_EMPTY;

		if (bdp->cbd_sc & BD_SC_WRAP)
			bdp = pinfo->rx_bd_base;
		else
			bdp++;

	} /* End for (;;) */

	/* Write back buffer pointer */
	pinfo->rx_cur = (volatile cbd_t *) bdp;

	/* activate BH processing */
	tty_flip_buffer_push(tty);

	return;

	/* Error processing */

      handle_error:
	/* Statistics */
	if (status & BD_SC_BR)
		port->icount.brk++;
	if (status & BD_SC_PR)
		port->icount.parity++;
	if (status & BD_SC_FR)
		port->icount.frame++;
	if (status & BD_SC_OV)
		port->icount.overrun++;

	/* Mask out ignored conditions */
	status &= port->read_status_mask;

	/* Handle the remaining ones */
	if (status & BD_SC_BR)
		flg = TTY_BREAK;
	else if (status & BD_SC_PR)
		flg = TTY_PARITY;
	else if (status & BD_SC_FR)
		flg = TTY_FRAME;

	/* overrun does not affect the current character ! */
	if (status & BD_SC_OV) {
		ch = 0;
		flg = TTY_OVERRUN;
		/* We skip this buffer */
		/* CHECK: Is really nothing senseful there */
		/* ASSUMPTION: it contains nothing valid */
		i = 0;
	}
#ifdef SUPPORT_SYSRQ
	port->sysrq = 0;
#endif
	goto error_return;
}
Ejemplo n.º 27
0
static void opticon_bulk_callback(struct urb *urb)
{
	struct opticon_private *priv = urb->context;
	unsigned char *data = urb->transfer_buffer;
	struct usb_serial_port *port = priv->port;
	int status = urb->status;
	struct tty_struct *tty;
	int result;
	int available_room = 0;
	int data_length;

	dbg("%s - port %d", __func__, port->number);

	switch (status) {
	case 0:
		
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		
		dbg("%s - urb shutting down with status: %d",
		    __func__, status);
		return;
	default:
		dbg("%s - nonzero urb status received: %d",
		    __func__, status);
		goto exit;
	}

	usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length,
			      data);

	if (urb->actual_length > 2) {
		data_length = urb->actual_length - 2;

		
		if ((data[0] == 0x00) && (data[1] == 0x00)) {
			
			tty = tty_port_tty_get(&port->port);
			if (tty) {
				available_room = tty_buffer_request_room(tty,
								data_length);
				if (available_room) {
					tty_insert_flip_string(tty, data,
							       available_room);
					tty_flip_buffer_push(tty);
				}
				tty_kref_put(tty);
			}
		} else {
			if ((data[0] == 0x00) && (data[1] == 0x01)) {
				if (data[2] == 0x00)
					priv->rts = false;
				else
					priv->rts = true;
			} else {
			dev_dbg(&priv->udev->dev,
				"Unknown data packet received from the device:"
				" %2x %2x\n",
				data[0], data[1]);
			}
		}
	} else {
		dev_dbg(&priv->udev->dev,
			"Improper ammount of data received from the device, "
			"%d bytes", urb->actual_length);
	}

exit:
	spin_lock(&priv->lock);

	
	if (!priv->throttled) {
		usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev,
				  usb_rcvbulkpipe(priv->udev,
						  priv->bulk_address),
				  priv->bulk_in_buffer, priv->buffer_size,
				  opticon_bulk_callback, priv);
		result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
		if (result)
			dev_err(&port->dev,
			    "%s - failed resubmitting read urb, error %d\n",
							__func__, result);
	} else
		priv->actually_throttled = true;
	spin_unlock(&priv->lock);
}
Ejemplo n.º 28
0
static void acm_rx_tasklet(unsigned long _acm)
{
	struct acm *acm = (void *)_acm;
	struct acm_rb *buf;
	struct tty_struct *tty = acm->tty;
	struct acm_ru *rcv;
	//unsigned long flags;
	int i = 0;
	dbg("Entering acm_rx_tasklet");

	if (!ACM_READY(acm) || acm->throttle)
		return;

next_buffer:
	spin_lock(&acm->read_lock);
	if (list_empty(&acm->filled_read_bufs)) {
		spin_unlock(&acm->read_lock);
		goto urbs;
	}
	buf = list_entry(acm->filled_read_bufs.next,
			 struct acm_rb, list);
	list_del(&buf->list);
	spin_unlock(&acm->read_lock);

	dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size);

	tty_buffer_request_room(tty, buf->size);
	if (!acm->throttle)
		tty_insert_flip_string(tty, buf->base, buf->size);
	tty_flip_buffer_push(tty);

	spin_lock(&acm->throttle_lock);
	if (acm->throttle) {
		dbg("Throtteling noticed");
		memmove(buf->base, buf->base + i, buf->size - i);
		buf->size -= i;
		spin_unlock(&acm->throttle_lock);
		spin_lock(&acm->read_lock);
		list_add(&buf->list, &acm->filled_read_bufs);
		spin_unlock(&acm->read_lock);
		return;
	}
	spin_unlock(&acm->throttle_lock);

	spin_lock(&acm->read_lock);
	list_add(&buf->list, &acm->spare_read_bufs);
	spin_unlock(&acm->read_lock);
	goto next_buffer;

urbs:
	while (!list_empty(&acm->spare_read_bufs)) {
		spin_lock(&acm->read_lock);
		if (list_empty(&acm->spare_read_urbs)) {
			spin_unlock(&acm->read_lock);
			return;
		}
		rcv = list_entry(acm->spare_read_urbs.next,
				 struct acm_ru, list);
		list_del(&rcv->list);
		spin_unlock(&acm->read_lock);

		buf = list_entry(acm->spare_read_bufs.next,
				 struct acm_rb, list);
		list_del(&buf->list);

		rcv->buffer = buf;

		usb_fill_bulk_urb(rcv->urb, acm->dev,
				  acm->rx_endpoint,
				  buf->base,
				  acm->readsize,
				  acm_read_bulk, rcv);
		rcv->urb->transfer_dma = buf->dma;
		rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

		dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p\n", rcv->urb, rcv, buf);

		/* This shouldn't kill the driver as unsuccessful URBs are returned to the
		   free-urbs-pool and resubmited ASAP */
		if (usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) {
			list_add(&buf->list, &acm->spare_read_bufs);
			spin_lock(&acm->read_lock);
			list_add(&rcv->list, &acm->spare_read_urbs);
			spin_unlock(&acm->read_lock);
			return;
		}
	}
}
Ejemplo n.º 29
0
/* bulk read call back function. check the status of the urb. if transfer
 * failed return. then update the status and the tty send data to tty subsys.
 * submit urb again.
 */
static void spcp8x5_read_bulk_callback(struct urb *urb)
{
	struct usb_serial_port *port = urb->context;
	struct spcp8x5_private *priv = usb_get_serial_port_data(port);
	struct tty_struct *tty;
	unsigned char *data = urb->transfer_buffer;
	unsigned long flags;
	int i;
	int result;
	u8 status = 0;
	char tty_flag;

	dev_dbg(&port->dev, "start, urb->status = %d, "
		"urb->actual_length = %d\n,", urb->status, urb->actual_length);

	/* check the urb status */
	if (urb->status) {
		if (!port->open_count)
			return;
		if (urb->status == -EPROTO) {
			/* spcp8x5 mysteriously fails with -EPROTO */
			/* reschedule the read */
			urb->status = 0;
			urb->dev = port->serial->dev;
			result = usb_submit_urb(urb , GFP_ATOMIC);
			if (result)
				dev_dbg(&port->dev,
					"failed submitting read urb %d\n",
					result);
			return;
		}
		dev_dbg(&port->dev, "unable to handle the error, exiting.\n");
		return;
	}

	/* get tty_flag from status */
	tty_flag = TTY_NORMAL;

	spin_lock_irqsave(&priv->lock, flags);
	status = priv->line_status;
	priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
	spin_unlock_irqrestore(&priv->lock, flags);
	/* wake up the wait for termios */
	wake_up_interruptible(&priv->delta_msr_wait);

	/* break takes precedence over parity, which takes precedence over
	 * framing errors */
	if (status & UART_BREAK_ERROR)
		tty_flag = TTY_BREAK;
	else if (status & UART_PARITY_ERROR)
		tty_flag = TTY_PARITY;
	else if (status & UART_FRAME_ERROR)
		tty_flag = TTY_FRAME;
	dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag);

	tty = port->tty;
	if (tty && urb->actual_length) {
		tty_buffer_request_room(tty, urb->actual_length + 1);
		/* overrun is special, not associated with a char */
		if (status & UART_OVERRUN_ERROR)
			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
		for (i = 0; i < urb->actual_length; ++i)
			tty_insert_flip_char(tty, data[i], tty_flag);
		tty_flip_buffer_push(tty);
	}

	/* Schedule the next read _if_ we are still open */
	if (port->open_count) {
		urb->dev = port->serial->dev;
		result = usb_submit_urb(urb , GFP_ATOMIC);
		if (result)
			dev_dbg(&port->dev, "failed submitting read urb %d\n",
				result);
	}

	return;
}
Ejemplo n.º 30
0
static void modem_rx_tasklet(unsigned long _modem_port)
{
	struct modem_port *modem_port_ptr = (void *)_modem_port;
	struct ap_rb *buf;
	struct tty_struct *tty;
	struct usb_serial_port *port;
	struct ap_ru *rcv;
	unsigned long flags;
	unsigned char throttled;
	int ret = -1;

	if (!modem_port_ptr)
		return;

	port = modem_port_ptr->port;
	if (!port)
		return;

	tty = port->port.tty;
	if (!tty)
		return;

	spin_lock_irqsave(&modem_port_ptr->port->lock, flags);
	throttled = modem_port_ptr->port->throttle_req;
	spin_unlock_irqrestore(&modem_port_ptr->port->lock, flags);
	if (throttled) {
		dev_err(&port->dev, "%s: throttled.\n", __func__);
		return;
	}

next_buffer:
	spin_lock_irqsave(&modem_port_ptr->read_lock, flags);
	if (list_empty(&modem_port_ptr->filled_read_bufs)) {
		spin_unlock_irqrestore(&modem_port_ptr->read_lock, flags);
		goto urbs;
	}
	buf = list_entry(modem_port_ptr->filled_read_bufs.next,
			 struct ap_rb, list);
	list_del(&buf->list);
	spin_unlock_irqrestore(&modem_port_ptr->read_lock, flags);

	tty_buffer_request_room(tty, buf->size);
	spin_lock_irqsave(&modem_port_ptr->port->lock, flags);
	throttled = modem_port_ptr->port->throttle_req;
	spin_unlock_irqrestore(&modem_port_ptr->port->lock, flags);
	if (!throttled)
		tty_insert_flip_string(tty, buf->base, buf->size);
	tty_flip_buffer_push(tty);

	if (throttled) {
		dev_err(&port->dev, "%s: Throttling noticed.\n", __func__);
		spin_lock_irqsave(&modem_port_ptr->read_lock, flags);
		list_add(&buf->list, &modem_port_ptr->filled_read_bufs);
		spin_unlock_irqrestore(&modem_port_ptr->read_lock, flags);
		return;
	}

	spin_lock_irqsave(&modem_port_ptr->read_lock, flags);
	list_add_tail(&buf->list, &modem_port_ptr->spare_read_bufs);
	spin_unlock_irqrestore(&modem_port_ptr->read_lock, flags);
	goto next_buffer;

urbs:
	while (1) {
		spin_lock_irqsave(&modem_port_ptr->read_lock, flags);
		if (list_empty(&modem_port_ptr->spare_read_bufs)) {
			spin_unlock_irqrestore(&modem_port_ptr->read_lock,
							flags);
			break;
		}
		if (list_empty(&modem_port_ptr->spare_read_urbs)) {
			modem_port_ptr->processing = 0;
			spin_unlock_irqrestore(&modem_port_ptr->read_lock,
					       flags);
			if (cdma_modem_debug)
				dev_info(&port->dev,
					 "%s: no urb to create.\n", __func__);
			return;
		}
		rcv = list_entry(modem_port_ptr->spare_read_urbs.next,
				 struct ap_ru, list);
		list_del(&rcv->list);

		buf = list_entry(modem_port_ptr->spare_read_bufs.next,
				 struct ap_rb, list);
		list_del(&buf->list);

		spin_unlock_irqrestore(&modem_port_ptr->read_lock, flags);

		rcv->buffer = buf;

		usb_fill_bulk_urb(rcv->urb, modem_port_ptr->port->serial->dev,
				  modem_port_ptr->rx_endpoint,
				  buf->base,
				  modem_port_ptr->readsize,
				  modem_read_bulk_callback, rcv);
		rcv->urb->transfer_dma = buf->dma;
		rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

		spin_lock_irqsave(&modem_port_ptr->read_lock, flags);
		if ((modem_port_ptr->susp_count > 0) ||
		    (ret = usb_submit_urb(rcv->urb, GFP_ATOMIC)) < 0) {
			if (cdma_modem_debug)
				dev_info(&port->dev,
					"%s():susp_count=%d ret=%d\n",
					__func__, modem_port_ptr->susp_count,
					ret);
			list_add_tail(&buf->list,
				 &modem_port_ptr->spare_read_bufs);
			list_add_tail(&rcv->list,
				 &modem_port_ptr->spare_read_urbs);
			modem_port_ptr->processing = 0;
			dev_err(&port->dev, "%s: submit bulk in  urb failed.\n",
				__func__);
			spin_unlock_irqrestore(&modem_port_ptr->read_lock,
						flags);
			return;
		} else {
			spin_unlock_irqrestore(&modem_port_ptr->read_lock,
						flags);
		}
	}
	spin_lock_irqsave(&modem_port_ptr->read_lock, flags);
	modem_port_ptr->processing = 0;
	spin_unlock_irqrestore(&modem_port_ptr->read_lock, flags);

}