|
@@ -65,7 +65,7 @@ static int kobil_tiocmget(struct tty_struct *tty);
|
|
|
static int kobil_tiocmset(struct tty_struct *tty,
|
|
|
unsigned int set, unsigned int clear);
|
|
|
static void kobil_read_int_callback(struct urb *urb);
|
|
|
-static void kobil_write_callback(struct urb *purb);
|
|
|
+static void kobil_write_int_callback(struct urb *urb);
|
|
|
static void kobil_set_termios(struct tty_struct *tty,
|
|
|
struct usb_serial_port *port, struct ktermios *old);
|
|
|
static void kobil_init_termios(struct tty_struct *tty);
|
|
@@ -99,6 +99,7 @@ static struct usb_serial_driver kobil_device = {
|
|
|
.write = kobil_write,
|
|
|
.write_room = kobil_write_room,
|
|
|
.read_int_callback = kobil_read_int_callback,
|
|
|
+ .write_int_callback = kobil_write_int_callback,
|
|
|
};
|
|
|
|
|
|
static struct usb_serial_driver * const serial_drivers[] = {
|
|
@@ -106,7 +107,6 @@ static struct usb_serial_driver * const serial_drivers[] = {
|
|
|
};
|
|
|
|
|
|
struct kobil_private {
|
|
|
- int write_int_endpoint_address;
|
|
|
unsigned char buf[KOBIL_BUF_LENGTH]; /* buffer for the APDU to send */
|
|
|
int filled; /* index of the last char in buf */
|
|
|
int cur_pos; /* index of the next char to send in buf */
|
|
@@ -116,14 +116,8 @@ struct kobil_private {
|
|
|
|
|
|
static int kobil_port_probe(struct usb_serial_port *port)
|
|
|
{
|
|
|
- int i;
|
|
|
struct usb_serial *serial = port->serial;
|
|
|
struct kobil_private *priv;
|
|
|
- struct usb_device *pdev;
|
|
|
- struct usb_host_config *actconfig;
|
|
|
- struct usb_interface *interface;
|
|
|
- struct usb_host_interface *altsetting;
|
|
|
- struct usb_host_endpoint *endpoint;
|
|
|
|
|
|
priv = kmalloc(sizeof(struct kobil_private), GFP_KERNEL);
|
|
|
if (!priv)
|
|
@@ -149,23 +143,6 @@ static int kobil_port_probe(struct usb_serial_port *port)
|
|
|
}
|
|
|
usb_set_serial_port_data(port, priv);
|
|
|
|
|
|
- /* search for the necessary endpoints */
|
|
|
- pdev = serial->dev;
|
|
|
- actconfig = pdev->actconfig;
|
|
|
- interface = actconfig->interface[0];
|
|
|
- altsetting = interface->cur_altsetting;
|
|
|
- endpoint = altsetting->endpoint;
|
|
|
-
|
|
|
- for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
|
|
|
- endpoint = &altsetting->endpoint[i];
|
|
|
- if (usb_endpoint_is_int_out(&endpoint->desc)) {
|
|
|
- dev_dbg(&serial->dev->dev,
|
|
|
- "%s Found interrupt out endpoint. Address: %d\n",
|
|
|
- __func__, endpoint->desc.bEndpointAddress);
|
|
|
- priv->write_int_endpoint_address =
|
|
|
- endpoint->desc.bEndpointAddress;
|
|
|
- }
|
|
|
- }
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -197,7 +174,6 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|
|
struct kobil_private *priv;
|
|
|
unsigned char *transfer_buffer;
|
|
|
int transfer_buffer_length = 8;
|
|
|
- int write_urb_transfer_buffer_length = 8;
|
|
|
|
|
|
priv = usb_get_serial_port_data(port);
|
|
|
|
|
@@ -206,27 +182,6 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|
|
if (!transfer_buffer)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
- /* allocate write_urb */
|
|
|
- if (!port->write_urb) {
|
|
|
- dev_dbg(dev, "%s - Allocating port->write_urb\n", __func__);
|
|
|
- port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
|
|
|
- if (!port->write_urb) {
|
|
|
- dev_dbg(dev, "%s - usb_alloc_urb failed\n", __func__);
|
|
|
- kfree(transfer_buffer);
|
|
|
- return -ENOMEM;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* allocate memory for write_urb transfer buffer */
|
|
|
- port->write_urb->transfer_buffer =
|
|
|
- kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL);
|
|
|
- if (!port->write_urb->transfer_buffer) {
|
|
|
- kfree(transfer_buffer);
|
|
|
- usb_free_urb(port->write_urb);
|
|
|
- port->write_urb = NULL;
|
|
|
- return -ENOMEM;
|
|
|
- }
|
|
|
-
|
|
|
/* get hardware version */
|
|
|
result = usb_control_msg(port->serial->dev,
|
|
|
usb_rcvctrlpipe(port->serial->dev, 0),
|
|
@@ -302,12 +257,7 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|
|
static void kobil_close(struct usb_serial_port *port)
|
|
|
{
|
|
|
/* FIXME: Add rts/dtr methods */
|
|
|
- if (port->write_urb) {
|
|
|
- usb_poison_urb(port->write_urb);
|
|
|
- kfree(port->write_urb->transfer_buffer);
|
|
|
- usb_free_urb(port->write_urb);
|
|
|
- port->write_urb = NULL;
|
|
|
- }
|
|
|
+ usb_kill_urb(port->interrupt_out_urb);
|
|
|
usb_kill_urb(port->interrupt_in_urb);
|
|
|
}
|
|
|
|
|
@@ -336,7 +286,7 @@ static void kobil_read_int_callback(struct urb *urb)
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void kobil_write_callback(struct urb *purb)
|
|
|
+static void kobil_write_int_callback(struct urb *urb)
|
|
|
{
|
|
|
}
|
|
|
|
|
@@ -379,23 +329,14 @@ static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
|
|
|
|
|
|
while (todo > 0) {
|
|
|
/* max 8 byte in one urb (endpoint size) */
|
|
|
- length = (todo < 8) ? todo : 8;
|
|
|
+ length = min(todo, port->interrupt_out_size);
|
|
|
/* copy data to transfer buffer */
|
|
|
- memcpy(port->write_urb->transfer_buffer,
|
|
|
+ memcpy(port->interrupt_out_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
|
|
|
- );
|
|
|
+ port->interrupt_out_urb->transfer_buffer_length = length;
|
|
|
|
|
|
priv->cur_pos = priv->cur_pos + length;
|
|
|
- result = usb_submit_urb(port->write_urb, GFP_NOIO);
|
|
|
+ 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;
|
|
|
|