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; }
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; }
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); }
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); }
/* * 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; }
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); }
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; }
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; }
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; }
/* 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; }
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); }
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; }
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; }
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); }
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; }
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; }
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; }
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); } }
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 */
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); }