staticvoid metrousb_read_int_callback(struct urb *urb)
{ struct usb_serial_port *port = urb->context; struct metrousb_private *metro_priv = usb_get_serial_port_data(port); unsignedchar *data = urb->transfer_buffer; unsignedlong flags; int throttled = 0; int result = 0;
dev_dbg(&port->dev, "%s\n", __func__);
switch (urb->status) { case0: /* Success status, read from the port. */ break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: /* urb has been terminated. */
dev_dbg(&port->dev, "%s - urb shutting down, error code=%d\n",
__func__, urb->status); return; default:
dev_dbg(&port->dev, "%s - non-zero urb received, error code=%d\n",
__func__, urb->status); gotoexit;
}
/* Set the data read from the usb port into the serial port buffer. */ if (urb->actual_length) { /* Loop through the data copying each byte to the tty layer. */
tty_insert_flip_string(&port->port, data, urb->actual_length);
/* Force the data to the tty layer. */
tty_flip_buffer_push(&port->port);
}
/* Set any port variables. */
spin_lock_irqsave(&metro_priv->lock, flags);
throttled = metro_priv->throttled;
spin_unlock_irqrestore(&metro_priv->lock, flags);
if (throttled) return; exit: /* Try to resubmit the urb. */
result = usb_submit_urb(urb, GFP_ATOMIC); if (result)
dev_err(&port->dev, "%s - failed submitting interrupt in urb, error code=%d\n",
__func__, result);
}
/* Set the private data information for the port. */
spin_lock_irqsave(&metro_priv->lock, flags);
metro_priv->control_state = 0;
metro_priv->throttled = 0;
spin_unlock_irqrestore(&metro_priv->lock, flags);
/* Clear the urb pipe. */
usb_clear_halt(serial->dev, port->interrupt_in_urb->pipe);
/* Start reading from the device */
usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
port->interrupt_in_urb->transfer_buffer,
port->interrupt_in_urb->transfer_buffer_length,
metrousb_read_int_callback, port, 1);
result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (result) {
dev_err(&port->dev, "%s - failed submitting interrupt in urb, error code=%d\n",
__func__, result); return result;
}
/* Send activate cmd to device */
result = metrousb_send_unidirectional_cmd(UNI_CMD_OPEN, port); if (result) {
dev_err(&port->dev, "%s - failed to configure device, error code=%d\n",
__func__, result); goto err_kill_urb;
}
/* Set the private information for the port to stop reading data. */
spin_lock_irqsave(&metro_priv->lock, flags);
metro_priv->throttled = 1;
spin_unlock_irqrestore(&metro_priv->lock, flags);
}
/* Set the private information for the port to resume reading data. */
spin_lock_irqsave(&metro_priv->lock, flags);
metro_priv->throttled = 0;
spin_unlock_irqrestore(&metro_priv->lock, flags);
/* Submit the urb to read from the port. */
result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); if (result)
dev_err(&port->dev, "failed submitting interrupt in urb error code=%d\n",
result);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.