コード例 #1
0
ファイル: aircable.c プロジェクト: Mr-Aloof/wl500g
static void aircable_read_bulk_callback(struct urb *urb)
{
	struct usb_serial_port *port = urb->context;
	struct aircable_private *priv = usb_get_serial_port_data(port);
	struct tty_struct *tty;
	unsigned long no_packages, remaining, package_length, i;
	int result, shift = 0;
	unsigned char *temp;
	int status = urb->status;

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

	if (status) {
		dbg("%s - urb status = %d", __FUNCTION__, status);
		if (!port->open_count) {
			dbg("%s - port is closed, exiting.", __FUNCTION__);
			return;
		}
		if (status == -EPROTO) {
			dbg("%s - caught -EPROTO, resubmitting the urb",
			    __FUNCTION__);
			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,
					  aircable_read_bulk_callback, port);

			result = usb_submit_urb(urb, GFP_ATOMIC);
			if (result)
				dev_err(&urb->dev->dev,
					"%s - failed resubmitting read urb, error %d\n",
					__FUNCTION__, result);
			return;
		}
		dbg("%s - unable to handle the error, exiting.", __FUNCTION__);
		return;
	}

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

	tty = port->tty;
	if (tty && urb->actual_length) {
		if (urb->actual_length <= 2) {
			/* This is an incomplete package */
			serial_buf_put(priv->rx_buf, urb->transfer_buffer,
				       urb->actual_length);
		} else {
			temp = urb->transfer_buffer;
			if (temp[0] == RX_HEADER_0)
				shift = HCI_HEADER_LENGTH;

			remaining = urb->actual_length;
			no_packages = urb->actual_length / (HCI_COMPLETE_FRAME);

			if (urb->actual_length % HCI_COMPLETE_FRAME != 0)
				no_packages+=1;

			for (i = 0; i < no_packages ;i++) {
				if (remaining > (HCI_COMPLETE_FRAME))
					package_length = HCI_COMPLETE_FRAME;
				else
					package_length = remaining;
				remaining -= package_length;

				serial_buf_put(priv->rx_buf,
					urb->transfer_buffer + shift +
					(HCI_COMPLETE_FRAME) * (i),
					package_length - shift);
			}
		}
		aircable_read(&priv->rx_work);
	}

	/* Schedule the next read _if_ we are still open */
	if (port->open_count) {
		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,
				  aircable_read_bulk_callback, port);

		result = usb_submit_urb(urb, GFP_ATOMIC);
		if (result)
			dev_err(&urb->dev->dev,
				"%s - failed resubmitting read urb, error %d\n",
				__FUNCTION__, result);
	}

	return;
}
コード例 #2
0
static int garmin_write_bulk(struct usb_serial_port *port,
			      const unsigned char *buf, int count,
			      int dismiss_ack)
{
	unsigned long flags;
	struct usb_serial *serial = port->serial;
	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
	struct urb *urb;
	unsigned char *buffer;
	int status;

	spin_lock_irqsave(&garmin_data_p->lock, flags);
	garmin_data_p->flags &= ~FLAGS_DROP_DATA;
	spin_unlock_irqrestore(&garmin_data_p->lock, flags);

	buffer = kmalloc(count, GFP_ATOMIC);
	if (!buffer)
		return -ENOMEM;

	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!urb) {
		kfree(buffer);
		return -ENOMEM;
	}

	memcpy(buffer, buf, count);

	usb_serial_debug_data(&port->dev, __func__, count, buffer);

	usb_fill_bulk_urb(urb, serial->dev,
				usb_sndbulkpipe(serial->dev,
					port->bulk_out_endpointAddress),
				buffer, count,
				garmin_write_bulk_callback,
				dismiss_ack ? NULL : port);
	urb->transfer_flags |= URB_ZERO_PACKET;

	if (GARMIN_LAYERID_APPL == getLayerId(buffer)) {

		spin_lock_irqsave(&garmin_data_p->lock, flags);
		garmin_data_p->flags |= APP_REQ_SEEN;
		spin_unlock_irqrestore(&garmin_data_p->lock, flags);

		if (garmin_data_p->mode == MODE_GARMIN_SERIAL)  {
			pkt_clear(garmin_data_p);
			garmin_data_p->state = STATE_GSP_WAIT_DATA;
		}
	}

	/* send it down the pipe */
	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status) {
		dev_err(&port->dev,
		   "%s - usb_submit_urb(write bulk) failed with status = %d\n",
				__func__, status);
		count = status;
		kfree(buffer);
	}

	/* we are done with this urb, so let the host driver
	 * really free it when it is finished with it */
	usb_free_urb(urb);

	return count;
}
コード例 #3
0
static void belkin_sa_read_int_callback(struct urb *urb)
{
    struct usb_serial_port *port = urb->context;
    struct belkin_sa_private *priv;
    unsigned char *data = urb->transfer_buffer;
    int retval;
    int status = urb->status;
    unsigned long flags;

    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);

    /* Handle known interrupt data */
    /* ignore data[0] and data[1] */

    priv = usb_get_serial_port_data(port);
    spin_lock_irqsave(&priv->lock, flags);
    priv->last_msr = data[BELKIN_SA_MSR_INDEX];

    /* Record Control Line states */
    if (priv->last_msr & BELKIN_SA_MSR_DSR)
        priv->control_state |= TIOCM_DSR;
    else
        priv->control_state &= ~TIOCM_DSR;

    if (priv->last_msr & BELKIN_SA_MSR_CTS)
        priv->control_state |= TIOCM_CTS;
    else
        priv->control_state &= ~TIOCM_CTS;

    if (priv->last_msr & BELKIN_SA_MSR_RI)
        priv->control_state |= TIOCM_RI;
    else
        priv->control_state &= ~TIOCM_RI;

    if (priv->last_msr & BELKIN_SA_MSR_CD)
        priv->control_state |= TIOCM_CD;
    else
        priv->control_state &= ~TIOCM_CD;

    priv->last_lsr = data[BELKIN_SA_LSR_INDEX];
    spin_unlock_irqrestore(&priv->lock, flags);
exit:
    retval = usb_submit_urb(urb, GFP_ATOMIC);
    if (retval)
        dev_err(&port->dev, "%s - usb_submit_urb failed with "
                "result %d\n", __func__, retval);
}
コード例 #4
0
static void garmin_read_int_callback(struct urb *urb)
{
	unsigned long flags;
	int retval;
	struct usb_serial_port *port = urb->context;
	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
	unsigned char *data = urb->transfer_buffer;
	int status = urb->status;

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

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

	if (urb->actual_length == sizeof(GARMIN_BULK_IN_AVAIL_REPLY) &&
	    0 == memcmp(data, GARMIN_BULK_IN_AVAIL_REPLY,
				sizeof(GARMIN_BULK_IN_AVAIL_REPLY))) {

		dev_dbg(&port->dev, "%s - bulk data available.\n", __func__);

		if (0 == (garmin_data_p->flags & FLAGS_BULK_IN_ACTIVE)) {

			/* bulk data available */
			retval = usb_submit_urb(port->read_urb, GFP_ATOMIC);
			if (retval) {
				dev_err(&port->dev,
				 "%s - failed submitting read urb, error %d\n",
							__func__, retval);
			} else {
				spin_lock_irqsave(&garmin_data_p->lock, flags);
				garmin_data_p->flags |= FLAGS_BULK_IN_ACTIVE;
				spin_unlock_irqrestore(&garmin_data_p->lock,
									flags);
			}
		} else {
			/* bulk-in transfer still active */
			spin_lock_irqsave(&garmin_data_p->lock, flags);
			garmin_data_p->flags |= FLAGS_BULK_IN_RESTART;
			spin_unlock_irqrestore(&garmin_data_p->lock, flags);
		}

	} else if (urb->actual_length == (4+sizeof(GARMIN_START_SESSION_REPLY))
			 && 0 == memcmp(data, GARMIN_START_SESSION_REPLY,
					sizeof(GARMIN_START_SESSION_REPLY))) {

		spin_lock_irqsave(&garmin_data_p->lock, flags);
		garmin_data_p->flags |= FLAGS_SESSION_REPLY1_SEEN;
		spin_unlock_irqrestore(&garmin_data_p->lock, flags);

		/* save the serial number */
		garmin_data_p->serial_num = __le32_to_cpup(
					(__le32 *)(data+GARMIN_PKTHDR_LENGTH));

		dev_dbg(&port->dev, "%s - start-of-session reply seen - serial %u.\n",
			__func__, garmin_data_p->serial_num);
	}

	garmin_read_process(garmin_data_p, data, urb->actual_length, 0);

	retval = usb_submit_urb(urb, GFP_ATOMIC);
	if (retval)
		dev_err(&urb->dev->dev,
			"%s - Error %d submitting interrupt urb\n",
			__func__, retval);
}
コード例 #5
0
/*
 * Sends a usb packet to the tty
 *
 * Assumes, that all packages and at an usb-packet boundary.
 *
 * return <0 on error, 0 if packet is incomplete or > 0 if packet was sent
 */
static int gsp_send(struct garmin_data *garmin_data_p,
		    const unsigned char *buf, int count)
{
	struct device *dev = &garmin_data_p->port->dev;
	const unsigned char *src;
	unsigned char *dst;
	int pktid = 0;
	int datalen = 0;
	int cksum = 0;
	int i = 0;
	int k;

	dev_dbg(dev, "%s - state %d - %d bytes.\n", __func__,
		garmin_data_p->state, count);

	k = garmin_data_p->outsize;
	if ((k+count) > GPS_OUT_BUFSIZ) {
		dev_dbg(dev, "packet too large\n");
		garmin_data_p->outsize = 0;
		return -4;
	}

	memcpy(garmin_data_p->outbuffer+k, buf, count);
	k += count;
	garmin_data_p->outsize = k;

	if (k >= GARMIN_PKTHDR_LENGTH) {
		pktid  = getPacketId(garmin_data_p->outbuffer);
		datalen = getDataLength(garmin_data_p->outbuffer);
		i = GARMIN_PKTHDR_LENGTH + datalen;
		if (k < i)
			return 0;
	} else {
		return 0;
	}

	dev_dbg(dev, "%s - %d bytes in buffer, %d bytes in pkt.\n", __func__, k, i);

	/* garmin_data_p->outbuffer now contains a complete packet */

	usb_serial_debug_data(&garmin_data_p->port->dev, __func__, k,
			      garmin_data_p->outbuffer);

	garmin_data_p->outsize = 0;

	if (GARMIN_LAYERID_APPL != getLayerId(garmin_data_p->outbuffer)) {
		dev_dbg(dev, "not an application packet (%d)\n",
				getLayerId(garmin_data_p->outbuffer));
		return -1;
	}

	if (pktid > 255) {
		dev_dbg(dev, "packet-id %d too large\n", pktid);
		return -2;
	}

	if (datalen > 255) {
		dev_dbg(dev, "packet-size %d too large\n", datalen);
		return -3;
	}

	/* the serial protocol should be able to handle this packet */

	k = 0;
	src = garmin_data_p->outbuffer+GARMIN_PKTHDR_LENGTH;
	for (i = 0; i < datalen; i++) {
		if (*src++ == DLE)
			k++;
	}

	src = garmin_data_p->outbuffer+GARMIN_PKTHDR_LENGTH;
	if (k > (GARMIN_PKTHDR_LENGTH-2)) {
		/* can't add stuffing DLEs in place, move data to end
		   of buffer ... */
		dst = garmin_data_p->outbuffer+GPS_OUT_BUFSIZ-datalen;
		memcpy(dst, src, datalen);
		src = dst;
	}

	dst = garmin_data_p->outbuffer;

	*dst++ = DLE;
	*dst++ = pktid;
	cksum += pktid;
	*dst++ = datalen;
	cksum += datalen;
	if (datalen == DLE)
		*dst++ = DLE;

	for (i = 0; i < datalen; i++) {
		__u8 c = *src++;
		*dst++ = c;
		cksum += c;
		if (c == DLE)
			*dst++ = DLE;
	}

	cksum = 0xFF & -cksum;
	*dst++ = cksum;
	if (cksum == DLE)
		*dst++ = DLE;
	*dst++ = DLE;
	*dst++ = ETX;

	i = dst-garmin_data_p->outbuffer;

	send_to_tty(garmin_data_p->port, garmin_data_p->outbuffer, i);

	garmin_data_p->pkt_id = pktid;
	garmin_data_p->state  = STATE_WAIT_TTY_ACK;

	return i;
}
コード例 #6
0
ファイル: opticon.c プロジェクト: 119-org/hi3518-osdrv
static void opticon_read_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 data_length;
	unsigned long flags;

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

	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);

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

		/*
		 * Data from the device comes with a 2 byte header:
		 *
		 * <0x00><0x00>data...
		 *	This is real data to be sent to the tty layer
		 * <0x00><0x01)level
		 *	This is a CTS level change, the third byte is the CTS
		 *	value (0 for low, 1 for high).
		 */
		if ((data[0] == 0x00) && (data[1] == 0x00)) {
			/* real data, send it to the tty layer */
			tty = tty_port_tty_get(&port->port);
			if (tty) {
				tty_insert_flip_string(tty, data + 2,
						       data_length);
				tty_flip_buffer_push(tty);
				tty_kref_put(tty);
			}
		} else {
			if ((data[0] == 0x00) && (data[1] == 0x01)) {
				spin_lock_irqsave(&priv->lock, flags);
				/* CTS status information package */
				if (data[2] == 0x00)
					priv->cts = false;
				else
					priv->cts = true;
				spin_unlock_irqrestore(&priv->lock, flags);
			} 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 amount of data received from the device, "
			"%d bytes", urb->actual_length);
	}

exit:
	spin_lock(&priv->lock);

	/* Continue trying to always read if we should */
	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_read_bulk_callback, priv);
		result = usb_submit_urb(priv->bulk_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);
}
コード例 #7
0
ファイル: kobil_sct.c プロジェクト: 3null/linux
static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
			const unsigned char *buf, int count)
{
	int length = 0;
	int result = 0;
	int todo = 0;
	struct kobil_private *priv;

	if (count == 0) {
		dev_dbg(&port->dev, "%s - write request of 0 bytes\n", __func__);
		return 0;
	}

	priv = usb_get_serial_port_data(port);

	if (count > (KOBIL_BUF_LENGTH - priv->filled)) {
		dev_dbg(&port->dev, "%s - Error: write request bigger than buffer size\n", __func__);
		return -ENOMEM;
	}

	/* Copy data to buffer */
	memcpy(priv->buf + priv->filled, buf, count);
	usb_serial_debug_data(&port->dev, __func__, count, priv->buf + priv->filled);
	priv->filled = priv->filled + count;

	/* only send complete block. TWIN, KAAN SIM and adapter K
	   use the same protocol. */
	if (((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) ||
	     ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4)))) {
		/* stop reading (except TWIN and KAAN SIM) */
		if ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID)
			|| (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID))
			usb_kill_urb(port->interrupt_in_urb);

		todo = priv->filled - priv->cur_pos;

		while (todo > 0) {
			/* max 8 byte in one urb (endpoint size) */
			length = min(todo, port->interrupt_out_size);
			/* copy data to transfer buffer */
			memcpy(port->interrupt_out_buffer,
					priv->buf + priv->cur_pos, length);
			port->interrupt_out_urb->transfer_buffer_length = length;

			priv->cur_pos = priv->cur_pos + length;
			result = usb_submit_urb(port->interrupt_out_urb, GFP_NOIO);
			dev_dbg(&port->dev, "%s - Send write URB returns: %i\n", __func__, result);
			todo = priv->filled - priv->cur_pos;

			if (todo > 0)
				msleep(24);
		}

		priv->filled = 0;
		priv->cur_pos = 0;

		/* start reading (except TWIN and KAAN SIM) */
		if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
			priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) {
			result = usb_submit_urb(port->interrupt_in_urb,
								GFP_NOIO);
			dev_dbg(&port->dev, "%s - Send read URB returns: %i\n", __func__, result);
		}
	}
	return count;
}
コード例 #8
0
int usb_serial_generic_write(struct tty_struct *tty,
	struct usb_serial_port *port, const unsigned char *buf, int count)
{
	struct usb_serial *serial = port->serial;
	int result;
	unsigned char *data;

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

	if (count == 0) {
		dbg("%s - write request of 0 bytes", __func__);
		return 0;
	}

	/* only do something if we have a bulk out endpoint */
	if (serial->num_bulk_out) {
		unsigned long flags;
		spin_lock_irqsave(&port->lock, flags);
		if (port->write_urb_busy) {
			spin_unlock_irqrestore(&port->lock, flags);
			dbg("%s - already writing", __func__);
			return 0;
		}
		port->write_urb_busy = 1;
		spin_unlock_irqrestore(&port->lock, flags);

		count = (count > port->bulk_out_size) ?
					port->bulk_out_size : count;

		memcpy(port->write_urb->transfer_buffer, buf, count);
		data = port->write_urb->transfer_buffer;
		usb_serial_debug_data(debug, &port->dev, __func__, count, data);

		/* set up our urb */
		usb_fill_bulk_urb(port->write_urb, serial->dev,
				   usb_sndbulkpipe(serial->dev,
					port->bulk_out_endpointAddress),
				   port->write_urb->transfer_buffer, count,
				   ((serial->type->write_bulk_callback) ?
				     serial->type->write_bulk_callback :
				     usb_serial_generic_write_bulk_callback),
				   port);

		/* send the data out the bulk port */
		port->write_urb_busy = 1;
		result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
		if (result) {
			dev_err(&port->dev,
				"%s - failed submitting write urb, error %d\n",
							__func__, result);
			/* don't have to grab the lock here, as we will
			   retry if != 0 */
			port->write_urb_busy = 0;
		} else
			result = count;

		return result;
	}

	/* no bulk out, so return 0 bytes written */
	return 0;
}
コード例 #9
0
ファイル: kobil_sct.c プロジェクト: BackupTheBerlios/arp2-svn
static int kobil_write (struct usb_serial_port *port, 
			const unsigned char *buf, int count)
{
	int length = 0;
	int result = 0;
	int todo = 0;
	struct kobil_private * priv;

	if (count == 0) {
		dbg("%s - port %d write request of 0 bytes", __FUNCTION__, port->number);
		return 0;
	}

	priv = usb_get_serial_port_data(port);

	if (count > (KOBIL_BUF_LENGTH - priv->filled)) {
		dbg("%s - port %d Error: write request bigger than buffer size", __FUNCTION__, port->number);
		return -ENOMEM;
	}

	// Copy data to buffer
	memcpy (priv->buf + priv->filled, buf, count);

	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, priv->buf + priv->filled);

	priv->filled = priv->filled + count;


	// only send complete block. TWIN, KAAN SIM and adapter K use the same protocol.
	if ( ((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) || 
	     ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4))) ) {
		
		// stop reading (except TWIN and KAAN SIM)
		if ( (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) )
			usb_kill_urb(port->interrupt_in_urb);

		todo = priv->filled - priv->cur_pos;

		while(todo > 0) {
			// max 8 byte in one urb (endpoint size)
			length = (todo < 8) ? todo : 8;
			// copy data to transfer buffer
			memcpy(port->write_urb->transfer_buffer, priv->buf + priv->cur_pos, length );
			usb_fill_int_urb( port->write_urb,
					  port->serial->dev,
					  usb_sndintpipe(port->serial->dev, priv->write_int_endpoint_address),
					  port->write_urb->transfer_buffer,
					  length,
					  kobil_write_callback,
					  port,
					  8
				);

			priv->cur_pos = priv->cur_pos + length;
			result = usb_submit_urb( port->write_urb, GFP_NOIO );
			dbg("%s - port %d Send write URB returns: %i", __FUNCTION__, port->number, result);
			todo = priv->filled - priv->cur_pos;

			if (todo > 0) {
				msleep(24);
			}

		} // end while
		
		priv->filled = 0;
		priv->cur_pos = 0;

		// someone sets the dev to 0 if the close method has been called
		port->interrupt_in_urb->dev = port->serial->dev;
		
		// start reading (except TWIN and KAAN SIM)
		if ( (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) ) {
			// 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_NOIO ); 
			dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);
		}
	}
	return count;
}
コード例 #10
0
ファイル: sierra.c プロジェクト: xf739645524/kernel-rhel5
/* Write */
static int sierra_write(struct usb_serial_port *port,
			const unsigned char *buf, int count)
{
	struct sierra_port_private *portdata = usb_get_serial_port_data(port);
	struct usb_serial *serial = port->serial;
	unsigned long flags;
	unsigned char *buffer;
	struct urb *urb;
	int status;

	portdata = usb_get_serial_port_data(port);

	dbg("%s: write (%d chars)", __FUNCTION__, count);

	spin_lock_irqsave(&portdata->lock, flags);
	if (portdata->outstanding_urbs > N_OUT_URB) {
		spin_unlock_irqrestore(&portdata->lock, flags);
		dbg("%s - write limit hit\n", __FUNCTION__);
		return 0;
	}
	portdata->outstanding_urbs++;
	spin_unlock_irqrestore(&portdata->lock, flags);

	buffer = kmalloc(count, GFP_ATOMIC);
	if (!buffer) {
		dev_err(&port->dev, "out of memory\n");
		count = -ENOMEM;
		goto error_no_buffer;
	}

	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!urb) {
		dev_err(&port->dev, "no more free urbs\n");
		count = -ENOMEM;
		goto error_no_urb;
	}

	memcpy(buffer, buf, count);

	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer);

	usb_fill_bulk_urb(urb, serial->dev,
			  usb_sndbulkpipe(serial->dev,
					  port->bulk_out_endpointAddress),
			  buffer, count, sierra_outdat_callback, port);

	/* send it down the pipe */
	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status) {
		dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed "
			"with status = %d\n", __FUNCTION__, status);
		count = status;
		goto error;
	}

	/* we are done with this urb, so let the host driver
	 * really free it when it is finished with it */
	usb_free_urb(urb);

	return count;
error:
	usb_free_urb(urb);
error_no_urb:
	kfree(buffer);
error_no_buffer:
	spin_lock_irqsave(&portdata->lock, flags);
	--portdata->outstanding_urbs;
	spin_unlock_irqrestore(&portdata->lock, flags);
	return count;
}
コード例 #11
0
ファイル: belkin_sa.c プロジェクト: OpenHMR/Open-HMR600
static void belkin_sa_read_int_callback (struct urb *urb, struct pt_regs *regs)
{
	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
	struct belkin_sa_private *priv;
	unsigned char *data = urb->transfer_buffer;
	int retval;
	unsigned long flags;

	switch (urb->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", __FUNCTION__, urb->status);
		return;
	default:
		dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
		goto exit;
	}

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

	/* Handle known interrupt data */
	/* ignore data[0] and data[1] */

	priv = usb_get_serial_port_data(port);
	spin_lock_irqsave(&priv->lock, flags);
	priv->last_msr = data[BELKIN_SA_MSR_INDEX];
	
	/* Record Control Line states */
	if (priv->last_msr & BELKIN_SA_MSR_DSR)
		priv->control_state |= TIOCM_DSR;
	else
		priv->control_state &= ~TIOCM_DSR;

	if (priv->last_msr & BELKIN_SA_MSR_CTS)
		priv->control_state |= TIOCM_CTS;
	else
		priv->control_state &= ~TIOCM_CTS;

	if (priv->last_msr & BELKIN_SA_MSR_RI)
		priv->control_state |= TIOCM_RI;
	else
		priv->control_state &= ~TIOCM_RI;

	if (priv->last_msr & BELKIN_SA_MSR_CD)
		priv->control_state |= TIOCM_CD;
	else
		priv->control_state &= ~TIOCM_CD;

	/* Now to report any errors */
	priv->last_lsr = data[BELKIN_SA_LSR_INDEX];
#if 0
	/*
	 * fill in the flip buffer here, but I do not know the relation
	 * to the current/next receive buffer or characters.  I need
	 * to look in to this before committing any code.
	 */
	if (priv->last_lsr & BELKIN_SA_LSR_ERR) {
		tty = port->tty;
		/* Overrun Error */
		if (priv->last_lsr & BELKIN_SA_LSR_OE) {
		}
		/* Parity Error */
		if (priv->last_lsr & BELKIN_SA_LSR_PE) {
		}
		/* Framing Error */
		if (priv->last_lsr & BELKIN_SA_LSR_FE) {
		}
		/* Break Indicator */
		if (priv->last_lsr & BELKIN_SA_LSR_BI) {
		}
	}
#endif
	spin_unlock_irqrestore(&priv->lock, flags);
exit:
	retval = usb_submit_urb (urb, GFP_ATOMIC);
	if (retval)
		err ("%s - usb_submit_urb failed with result %d",
		     __FUNCTION__, retval);
}
コード例 #12
0
ファイル: empeg.c プロジェクト: maraz/linux-2.6
static int empeg_write (struct usb_serial_port *port, const unsigned char *buf, int count)
{
	struct usb_serial *serial = port->serial;
	struct urb *urb;
	const unsigned char *current_position = buf;
	unsigned long flags;
	int status;
	int i;
	int bytes_sent = 0;
	int transfer_size;

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

	while (count > 0) {

		/* try to find a free urb in our list of them */
		urb = NULL;

		spin_lock_irqsave (&write_urb_pool_lock, flags);

		for (i = 0; i < NUM_URBS; ++i) {
			if (write_urb_pool[i]->status != -EINPROGRESS) {
				urb = write_urb_pool[i];
				break;
			}
		}

		spin_unlock_irqrestore (&write_urb_pool_lock, flags);

		if (urb == NULL) {
			dbg("%s - no more free urbs", __func__);
			goto exit;
		}

		if (urb->transfer_buffer == NULL) {
			urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC);
			if (urb->transfer_buffer == NULL) {
				dev_err(&port->dev, "%s no more kernel memory...\n", __func__);
				goto exit;
			}
		}

		transfer_size = min (count, URB_TRANSFER_BUFFER_SIZE);

		memcpy (urb->transfer_buffer, current_position, transfer_size);

		usb_serial_debug_data(debug, &port->dev, __func__, transfer_size, urb->transfer_buffer);

		/* build up our urb */
		usb_fill_bulk_urb (
			urb,
			serial->dev,
			usb_sndbulkpipe(serial->dev,
				port->bulk_out_endpointAddress), 
			urb->transfer_buffer,
			transfer_size,
			empeg_write_bulk_callback,
			port);

		/* send it down the pipe */
		status = usb_submit_urb(urb, GFP_ATOMIC);
		if (status) {
			dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", __func__, status);
			bytes_sent = status;
			break;
		}

		current_position += transfer_size;
		bytes_sent += transfer_size;
		count -= transfer_size;
		bytes_out += transfer_size;

	}

exit:
	return bytes_sent;

} 
コード例 #13
0
static int usb_serial_multi_urb_write(struct tty_struct *tty,
	struct usb_serial_port *port, const unsigned char *buf, int count)
{
	unsigned long flags;
	struct urb *urb;
	unsigned char *buffer;
	int status;
	int towrite;
	int bwrite = 0;

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

	if (count == 0)
		dbg("%s - write request of 0 bytes", __func__);

	while (count > 0) {
		towrite = (count > port->bulk_out_size) ?
			port->bulk_out_size : count;
		spin_lock_irqsave(&port->lock, flags);
		if (port->urbs_in_flight >
		    port->serial->type->max_in_flight_urbs) {
			spin_unlock_irqrestore(&port->lock, flags);
			dbg("%s - write limit hit\n", __func__);
			return bwrite;
		}
		port->tx_bytes_flight += towrite;
		port->urbs_in_flight++;
		spin_unlock_irqrestore(&port->lock, flags);

		buffer = kmalloc(towrite, GFP_ATOMIC);
		if (!buffer) {
			dev_err(&port->dev,
			"%s ran out of kernel memory for urb ...\n", __func__);
			goto error_no_buffer;
		}

		urb = usb_alloc_urb(0, GFP_ATOMIC);
		if (!urb) {
			dev_err(&port->dev, "%s - no more free urbs\n",
				__func__);
			goto error_no_urb;
		}

		/* Copy data */
		memcpy(buffer, buf + bwrite, towrite);
		usb_serial_debug_data(debug, &port->dev, __func__,
				      towrite, buffer);
		/* fill the buffer and send it */
		usb_fill_bulk_urb(urb, port->serial->dev,
			usb_sndbulkpipe(port->serial->dev,
					port->bulk_out_endpointAddress),
			buffer, towrite,
			usb_serial_generic_write_bulk_callback, port);

		status = usb_submit_urb(urb, GFP_ATOMIC);
		if (status) {
			dev_err(&port->dev,
				"%s - failed submitting write urb, error %d\n",
				__func__, status);
			goto error;
		}

		/* This urb is the responsibility of the host driver now */
		usb_free_urb(urb);
		dbg("%s write: %d", __func__, towrite);
		count -= towrite;
		bwrite += towrite;
	}
	return bwrite;

error:
	usb_free_urb(urb);
error_no_urb:
	kfree(buffer);
error_no_buffer:
	spin_lock_irqsave(&port->lock, flags);
	port->urbs_in_flight--;
	port->tx_bytes_flight -= towrite;
	spin_unlock_irqrestore(&port->lock, flags);
	return bwrite;
}
コード例 #14
0
ファイル: symbolserial.c プロジェクト: matsufan/linux
static void symbol_int_callback(struct urb *urb)
{
	struct symbol_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 data_length;

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

	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);

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

		/*
		 * Data from the device comes with a 1 byte header:
		 *
		 * <size of data>data...
		 * 	This is real data to be sent to the tty layer
		 * we pretty much just ignore the size and send everything
		 * else to the tty layer.
		 */
		tty = tty_port_tty_get(&port->port);
		if (tty) {
			tty_insert_flip_string(tty, &data[1], data_length);
			tty_flip_buffer_push(tty);
			tty_kref_put(tty);
		}
	} else {
		dev_dbg(&priv->udev->dev,
			"Improper amount of data received from the device, "
			"%d bytes", urb->actual_length);
	}

exit:
	spin_lock(&priv->lock);

	/* Continue trying to always read if we should */
	if (!priv->throttled) {
		usb_fill_int_urb(priv->int_urb, priv->udev,
				 usb_rcvintpipe(priv->udev,
				 		priv->int_address),
				 priv->int_buffer, priv->buffer_size,
				 symbol_int_callback, priv, priv->bInterval);
		result = usb_submit_urb(priv->int_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);
}
コード例 #15
0
static int cyberjack_write(struct tty_struct *tty,
	struct usb_serial_port *port, const unsigned char *buf, int count)
{
	struct cyberjack_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	int result;
	int wrexpected;

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

	if (count == 0) {
		dbg("%s - write request of 0 bytes", __func__);
		return 0;
	}

	if (!test_and_clear_bit(0, &port->write_urbs_free)) {
		dbg("%s - already writing", __func__);
		return 0;
	}

	spin_lock_irqsave(&priv->lock, flags);

	if (count+priv->wrfilled > sizeof(priv->wrbuf)) {
		/* To much data for buffer. Reset buffer. */
		priv->wrfilled = 0;
		spin_unlock_irqrestore(&priv->lock, flags);
		set_bit(0, &port->write_urbs_free);
		return 0;
	}

	/* Copy data */
	memcpy(priv->wrbuf + priv->wrfilled, buf, count);

	usb_serial_debug_data(debug, &port->dev, __func__, count,
		priv->wrbuf + priv->wrfilled);
	priv->wrfilled += count;

	if (priv->wrfilled >= 3) {
		wrexpected = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
		dbg("%s - expected data: %d", __func__, wrexpected);
	} else
		wrexpected = sizeof(priv->wrbuf);

	if (priv->wrfilled >= wrexpected) {
		/* We have enough data to begin transmission */
		int length;

		dbg("%s - transmitting data (frame 1)", __func__);
		length = (wrexpected > port->bulk_out_size) ?
					port->bulk_out_size : wrexpected;

		memcpy(port->write_urb->transfer_buffer, priv->wrbuf, length);
		priv->wrsent = length;

		/* set up our urb */
		port->write_urb->transfer_buffer_length = length;

		/* send the data out the bulk port */
		result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
		if (result) {
			dev_err(&port->dev,
				"%s - failed submitting write urb, error %d",
				__func__, result);
			/* Throw away data. No better idea what to do with it. */
			priv->wrfilled = 0;
			priv->wrsent = 0;
			spin_unlock_irqrestore(&priv->lock, flags);
			set_bit(0, &port->write_urbs_free);
			return 0;
		}

		dbg("%s - priv->wrsent=%d", __func__, priv->wrsent);
		dbg("%s - priv->wrfilled=%d", __func__, priv->wrfilled);

		if (priv->wrsent >= priv->wrfilled) {
			dbg("%s - buffer cleaned", __func__);
			memset(priv->wrbuf, 0, sizeof(priv->wrbuf));
			priv->wrfilled = 0;
			priv->wrsent = 0;
		}
	}

	spin_unlock_irqrestore(&priv->lock, flags);

	return count;
}
コード例 #16
0
ファイル: opticon.c プロジェクト: 3sOx/asuswrt-merlin
static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port,
			 const unsigned char *buf, int count)
{
	struct opticon_private *priv = usb_get_serial_data(port->serial);
	struct usb_serial *serial = port->serial;
	struct urb *urb;
	unsigned char *buffer;
	unsigned long flags;
	int status;

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

	spin_lock_irqsave(&priv->lock, flags);
	if (priv->outstanding_urbs > URB_UPPER_LIMIT) {
		spin_unlock_irqrestore(&priv->lock, flags);
		dbg("%s - write limit hit", __func__);
		return 0;
	}
	priv->outstanding_urbs++;
	spin_unlock_irqrestore(&priv->lock, flags);

	buffer = kmalloc(count, GFP_ATOMIC);
	if (!buffer) {
		dev_err(&port->dev, "out of memory\n");
		count = -ENOMEM;
		goto error_no_buffer;
	}

	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!urb) {
		dev_err(&port->dev, "no more free urbs\n");
		count = -ENOMEM;
		goto error_no_urb;
	}

	memcpy(buffer, buf, count);

	usb_serial_debug_data(debug, &port->dev, __func__, count, buffer);

	usb_fill_bulk_urb(urb, serial->dev,
			  usb_sndbulkpipe(serial->dev,
					  port->bulk_out_endpointAddress),
			  buffer, count, opticon_write_bulk_callback, priv);

	/* send it down the pipe */
	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status) {
		dev_err(&port->dev,
		   "%s - usb_submit_urb(write bulk) failed with status = %d\n",
							__func__, status);
		count = status;
		goto error;
	}

	/* we are done with this urb, so let the host driver
	 * really free it when it is finished with it */
	usb_free_urb(urb);

	return count;
error:
	usb_free_urb(urb);
error_no_urb:
	kfree(buffer);
error_no_buffer:
	spin_lock_irqsave(&priv->lock, flags);
	--priv->outstanding_urbs;
	spin_unlock_irqrestore(&priv->lock, flags);
	return count;
}
コード例 #17
0
ファイル: opticon.c プロジェクト: 119-org/hi3518-osdrv
static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port,
			 const unsigned char *buf, int count)
{
	struct opticon_private *priv = usb_get_serial_data(port->serial);
	struct usb_serial *serial = port->serial;
	struct urb *urb;
	unsigned char *buffer;
	unsigned long flags;
	int status;
	struct usb_ctrlrequest *dr;

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

	spin_lock_irqsave(&priv->lock, flags);
	if (priv->outstanding_urbs > URB_UPPER_LIMIT) {
		spin_unlock_irqrestore(&priv->lock, flags);
		dbg("%s - write limit hit", __func__);
		return 0;
	}
	priv->outstanding_urbs++;
	spin_unlock_irqrestore(&priv->lock, flags);

	buffer = kmalloc(count, GFP_ATOMIC);
	if (!buffer) {
		dev_err(&port->dev, "out of memory\n");
		count = -ENOMEM;

		goto error_no_buffer;
	}

	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!urb) {
		dev_err(&port->dev, "no more free urbs\n");
		count = -ENOMEM;
		goto error_no_urb;
	}

	memcpy(buffer, buf, count);

	usb_serial_debug_data(debug, &port->dev, __func__, count, buffer);

	/* The conncected devices do not have a bulk write endpoint,
	 * to transmit data to de barcode device the control endpoint is used */
	dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
	if (!dr) {
		dev_err(&port->dev, "out of memory\n");
		count = -ENOMEM;
		goto error;
	}

	dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT;
	dr->bRequest = 0x01;
	dr->wValue = 0;
	dr->wIndex = 0;
	dr->wLength = cpu_to_le16(count);

	usb_fill_control_urb(urb, serial->dev,
		usb_sndctrlpipe(serial->dev, 0),
		(unsigned char *)dr, buffer, count,
		opticon_write_control_callback, priv);

	/* send it down the pipe */
	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status) {
		dev_err(&port->dev,
		"%s - usb_submit_urb(write endpoint) failed status = %d\n",
							__func__, status);
		count = status;
		goto error;
	}

	/* we are done with this urb, so let the host driver
	 * really free it when it is finished with it */
	usb_free_urb(urb);

	return count;
error:
	usb_free_urb(urb);
error_no_urb:
	kfree(buffer);
error_no_buffer:
	spin_lock_irqsave(&priv->lock, flags);
	--priv->outstanding_urbs;
	spin_unlock_irqrestore(&priv->lock, flags);
	return count;
}
コード例 #18
0
static int garmin_write(struct tty_struct *tty, struct usb_serial_port *port,
					 const unsigned char *buf, int count)
{
	struct device *dev = &port->dev;
	int pktid, pktsiz, len;
	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
	__le32 *privpkt = (__le32 *)garmin_data_p->privpkt;

	usb_serial_debug_data(dev, __func__, count, buf);

	if (garmin_data_p->state == STATE_RESET)
		return -EIO;

	/* check for our private packets */
	if (count >= GARMIN_PKTHDR_LENGTH) {
		len = PRIVPKTSIZ;
		if (count < len)
			len = count;

		memcpy(garmin_data_p->privpkt, buf, len);

		pktsiz = getDataLength(garmin_data_p->privpkt);
		pktid  = getPacketId(garmin_data_p->privpkt);

		if (count == (GARMIN_PKTHDR_LENGTH+pktsiz)
		    && GARMIN_LAYERID_PRIVATE ==
				getLayerId(garmin_data_p->privpkt)) {

			dev_dbg(dev, "%s - processing private request %d\n",
				__func__, pktid);

			/* drop all unfinished transfers */
			garmin_clear(garmin_data_p);

			switch (pktid) {
			case PRIV_PKTID_SET_MODE:
				if (pktsiz != 4)
					return -EINVPKT;
				garmin_data_p->mode = __le32_to_cpu(privpkt[3]);
				dev_dbg(dev, "%s - mode set to %d\n",
					__func__, garmin_data_p->mode);
				break;

			case PRIV_PKTID_INFO_REQ:
				priv_status_resp(port);
				break;

			case PRIV_PKTID_RESET_REQ:
				process_resetdev_request(port);
				break;

			case PRIV_PKTID_SET_DEF_MODE:
				if (pktsiz != 4)
					return -EINVPKT;
				initial_mode = __le32_to_cpu(privpkt[3]);
				dev_dbg(dev, "%s - initial_mode set to %d\n",
					__func__,
					garmin_data_p->mode);
				break;
			}
			return count;
		}
	}

	if (garmin_data_p->mode == MODE_GARMIN_SERIAL) {
		return gsp_receive(garmin_data_p, buf, count);
	} else {	/* MODE_NATIVE */
		return nat_receive(garmin_data_p, buf, count);
	}
}
コード例 #19
0
ファイル: mct_u232.c プロジェクト: PennPanda/linux-repo
static void mct_u232_read_int_callback (struct urb *urb)
{
	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
	struct mct_u232_private *priv = usb_get_serial_port_data(port);
	struct usb_serial *serial = port->serial;
	struct tty_struct *tty;
	unsigned char *data = urb->transfer_buffer;
	int retval;
	int status = urb->status;
	unsigned long flags;

	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",
		    __FUNCTION__, status);
		return;
	default:
		dbg("%s - nonzero urb status received: %d",
		    __FUNCTION__, status);
		goto exit;
	}

	if (!serial) {
		dbg("%s - bad serial pointer, exiting", __FUNCTION__);
		return;
	}

        dbg("%s - port %d", __FUNCTION__, port->number);
	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);

	/*
	 * Work-a-round: handle the 'usual' bulk-in pipe here
	 */
	if (urb->transfer_buffer_length > 2) {
		int i;
		tty = port->tty;
		if (urb->actual_length) {
			for (i = 0; i < urb->actual_length ; ++i) {
				tty_insert_flip_char(tty, data[i], 0);
			}
			tty_flip_buffer_push(tty);
		}
		goto exit;
	}
	
	/*
	 * The interrupt-in pipe signals exceptional conditions (modem line
	 * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
	 */
	spin_lock_irqsave(&priv->lock, flags);
	priv->last_msr = data[MCT_U232_MSR_INDEX];
	
	/* Record Control Line states */
	mct_u232_msr_to_state(&priv->control_state, priv->last_msr);

#if 0
	/* Not yet handled. See belin_sa.c for further information */
	/* Now to report any errors */
	priv->last_lsr = data[MCT_U232_LSR_INDEX];
	/*
	 * fill in the flip buffer here, but I do not know the relation
	 * to the current/next receive buffer or characters.  I need
	 * to look in to this before committing any code.
	 */
	if (priv->last_lsr & MCT_U232_LSR_ERR) {
		tty = port->tty;
		/* Overrun Error */
		if (priv->last_lsr & MCT_U232_LSR_OE) {
		}
		/* Parity Error */
		if (priv->last_lsr & MCT_U232_LSR_PE) {
		}
		/* Framing Error */
		if (priv->last_lsr & MCT_U232_LSR_FE) {
		}
		/* Break Indicator */
		if (priv->last_lsr & MCT_U232_LSR_BI) {
		}
	}
#endif
	spin_unlock_irqrestore(&priv->lock, flags);
exit:
	retval = usb_submit_urb (urb, GFP_ATOMIC);
	if (retval)
		err ("%s - usb_submit_urb failed with result %d",
		     __FUNCTION__, retval);
} /* mct_u232_read_int_callback */
コード例 #20
0
static void csvt_ctrl_int_cb(struct urb *urb)
{
	int				status;
	struct usb_cdc_notification	*ctrl;
	struct usb_serial_port		*port = urb->context;
	struct csvt_ctrl_dev		*dev;
	unsigned int			ctrl_bits;
	unsigned char			*data;

	switch (urb->status) {
	case 0:
		/*success*/
		break;
	case -ESHUTDOWN:
	case -ENOENT:
	case -ECONNRESET:
	case -EPROTO:
		 /* unplug */
		 return;
	case -EPIPE:
		dev_err(&port->dev, "%s: stall on int endpoint\n", __func__);
		/* TBD : halt to be cleared in work */
	case -EOVERFLOW:
	default:
		pr_debug_ratelimited("%s: non zero urb status = %d\n",
					__func__, urb->status);
		goto resubmit_int_urb;
	}

	dev = usb_get_serial_port_data(port);
	if (!dev)
		return;

	ctrl = urb->transfer_buffer;
	data = (unsigned char *)(ctrl + 1);

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

	switch (ctrl->bNotificationType) {
	case USB_CDC_NOTIFY_NETWORK_CONNECTION:
		dev_dbg(&port->dev, "%s network\n", ctrl->wValue ?
					"connected to" : "disconnected from");
		break;
	case USB_CDC_NOTIFY_SERIAL_STATE:
		ctrl_bits = get_unaligned_le16(data);
		dev_dbg(&port->dev, "serial state: %d\n", ctrl_bits);
		dev->cbits_tolocal = ctrl_bits;
		break;
	default:
		dev_err(&port->dev, "%s: unknown notification %d received:"
			"index %d len %d data0 %d data1 %d",
			__func__, ctrl->bNotificationType, ctrl->wIndex,
			ctrl->wLength, data[0], data[1]);
	}

resubmit_int_urb:
	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status)
		dev_err(&port->dev, "%s: Error re-submitting Int URB %d\n",
		__func__, status);

}