Loading drivers/usb/serial/kobil_sct.c +297 −260 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ #include <linux/tty_flip.h> #include <linux/module.h> #include <linux/spinlock.h> #include <asm/uaccess.h> #include <linux/uaccess.h> #include <linux/usb.h> #include <linux/usb/serial.h> #include <linux/ioctl.h> Loading Loading @@ -134,9 +134,9 @@ static struct usb_serial_driver kobil_device = { struct kobil_private { int write_int_endpoint_address; int read_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 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 */ __u16 device_type; }; Loading @@ -152,9 +152,8 @@ static int kobil_startup (struct usb_serial *serial) struct usb_host_endpoint *endpoint; priv = kmalloc(sizeof(struct kobil_private), GFP_KERNEL); if (!priv){ if (!priv) return -ENOMEM; } priv->filled = 0; priv->cur_pos = 0; Loading @@ -165,7 +164,8 @@ static int kobil_startup (struct usb_serial *serial) printk(KERN_DEBUG "KOBIL B1 PRO / KAAN PRO detected\n"); break; case KOBIL_ADAPTER_K_PRODUCT_ID: printk(KERN_DEBUG "KOBIL KAAN Standard Plus / SecOVID Reader Plus detected\n"); printk(KERN_DEBUG "KOBIL KAAN Standard Plus / SecOVID Reader Plus detected\n"); break; case KOBIL_USBTWIN_PRODUCT_ID: printk(KERN_DEBUG "KOBIL USBTWIN detected\n"); Loading @@ -176,7 +176,7 @@ static int kobil_startup (struct usb_serial *serial) } usb_set_serial_port_data(serial->port[0], priv); // search for the necessary endpoints /* search for the necessary endpoints */ pdev = serial->dev; actconfig = pdev->actconfig; interface = actconfig->interface[0]; Loading @@ -186,12 +186,16 @@ static int kobil_startup (struct usb_serial *serial) for (i = 0; i < altsetting->desc.bNumEndpoints; i++) { endpoint = &altsetting->endpoint[i]; if (usb_endpoint_is_int_out(&endpoint->desc)) { dbg("%s Found interrupt out endpoint. Address: %d", __func__, endpoint->desc.bEndpointAddress); priv->write_int_endpoint_address = endpoint->desc.bEndpointAddress; dbg("%s Found interrupt out endpoint. Address: %d", __func__, endpoint->desc.bEndpointAddress); priv->write_int_endpoint_address = endpoint->desc.bEndpointAddress; } if (usb_endpoint_is_int_in(&endpoint->desc)) { dbg("%s Found interrupt in endpoint. Address: %d", __func__, endpoint->desc.bEndpointAddress); priv->read_int_endpoint_address = endpoint->desc.bEndpointAddress; dbg("%s Found interrupt in endpoint. Address: %d", __func__, endpoint->desc.bEndpointAddress); priv->read_int_endpoint_address = endpoint->desc.bEndpointAddress; } } return 0; Loading @@ -204,9 +208,8 @@ static void kobil_shutdown (struct usb_serial *serial) dbg("%s - port %d", __func__, serial->port[0]->number); for (i = 0; i < serial->num_ports; ++i) { while (serial->port[i]->port.count > 0) { while (serial->port[i]->port.count > 0) kobil_close(NULL, serial->port[i], NULL); } kfree(usb_get_serial_port_data(serial->port[i])); usb_set_serial_port_data(serial->port[i], NULL); } Loading @@ -225,7 +228,7 @@ static int kobil_open(struct tty_struct *tty, dbg("%s - port %d", __func__, port->number); priv = usb_get_serial_port_data(port); // someone sets the dev to 0 if the close method has been called /* someone sets the dev to 0 if the close method has been called */ port->interrupt_in_urb->dev = port->serial->dev; Loading @@ -238,29 +241,33 @@ static int kobil_open(struct tty_struct *tty, /* Default to echo off and other sane device settings */ tty->termios->c_lflag = 0; tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE); tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE); tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF; tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) /* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */ tty->termios->c_oflag &= ~ONLCR; } // allocate memory for transfer buffer /* allocate memory for transfer buffer */ transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); if (! transfer_buffer) { if (!transfer_buffer) return -ENOMEM; } // allocate write_urb /* allocate write_urb */ if (!port->write_urb) { dbg("%s - port %d Allocating port->write_urb", __func__, port->number); dbg("%s - port %d Allocating port->write_urb", __func__, port->number); port->write_urb = usb_alloc_urb(0, GFP_KERNEL); if (!port->write_urb) { dbg("%s - port %d usb_alloc_urb failed", __func__, port->number); dbg("%s - port %d usb_alloc_urb failed", __func__, port->number); 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); /* 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); Loading @@ -268,7 +275,7 @@ static int kobil_open(struct tty_struct *tty, return -ENOMEM; } // get hardware version /* get hardware version */ result = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), SUSBCRequest_GetMisc, Loading @@ -279,10 +286,12 @@ static int kobil_open(struct tty_struct *tty, transfer_buffer_length, KOBIL_TIMEOUT ); dbg("%s - port %d Send get_HW_version URB returns: %i", __func__, port->number, result); dbg("Harware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2] ); dbg("%s - port %d Send get_HW_version URB returns: %i", __func__, port->number, result); dbg("Harware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2]); // get firmware version /* get firmware version */ result = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), SUSBCRequest_GetMisc, Loading @@ -293,24 +302,29 @@ static int kobil_open(struct tty_struct *tty, transfer_buffer_length, KOBIL_TIMEOUT ); dbg("%s - port %d Send get_FW_version URB returns: %i", __func__, port->number, result); dbg("Firmware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2] ); if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) { // Setting Baudrate, Parity and Stopbits dbg("%s - port %d Send get_FW_version URB returns: %i", __func__, port->number, result); dbg("Firmware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2]); if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) { /* Setting Baudrate, Parity and Stopbits */ result = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), SUSBCRequest_SetBaudRateParityAndStopBits, USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, SUSBCR_SBR_9600 | SUSBCR_SPASB_EvenParity | SUSBCR_SPASB_1StopBit, SUSBCR_SBR_9600 | SUSBCR_SPASB_EvenParity | SUSBCR_SPASB_1StopBit, 0, transfer_buffer, 0, KOBIL_TIMEOUT ); dbg("%s - port %d Send set_baudrate URB returns: %i", __func__, port->number, result); dbg("%s - port %d Send set_baudrate URB returns: %i", __func__, port->number, result); // reset all queues /* reset all queues */ result = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), SUSBCRequest_Misc, Loading @@ -321,13 +335,16 @@ static int kobil_open(struct tty_struct *tty, 0, KOBIL_TIMEOUT ); dbg("%s - port %d Send reset_all_queues URB returns: %i", __func__, port->number, result); dbg("%s - port %d Send reset_all_queues URB returns: %i", __func__, port->number, result); } if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { // start reading (Adapter B 'cause PNP string) /* start reading (Adapter B 'cause PNP string) */ result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result); dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result); } kfree(transfer_buffer); Loading Loading @@ -356,7 +373,7 @@ static void kobil_read_int_callback(struct urb *urb) struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; int status = urb->status; // char *dbg_data; /* char *dbg_data; */ dbg("%s - port %d", __func__, port->number); Loading @@ -369,9 +386,10 @@ static void kobil_read_int_callback(struct urb *urb) tty = port->port.tty; if (urb->actual_length) { // BEGIN DEBUG /* BEGIN DEBUG */ /* dbg_data = kzalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL); dbg_data = kzalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL); if (! dbg_data) { return; } Loading @@ -381,18 +399,18 @@ static void kobil_read_int_callback(struct urb *urb) dbg(" <-- %s", dbg_data); kfree(dbg_data); */ // END DEBUG /* END DEBUG */ tty_buffer_request_room(tty, urb->actual_length); tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); } // someone sets the dev to 0 if the close method has been called /* 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); dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result); } Loading @@ -410,7 +428,8 @@ static int kobil_write (struct tty_struct *tty, struct usb_serial_port *port, struct kobil_private *priv; if (count == 0) { dbg("%s - port %d write request of 0 bytes", __func__, port->number); dbg("%s - port %d write request of 0 bytes", __func__, port->number); return 0; } Loading @@ -421,29 +440,33 @@ static int kobil_write (struct tty_struct *tty, struct usb_serial_port *port, return -ENOMEM; } // Copy data to buffer /* Copy data to buffer */ memcpy(priv->buf + priv->filled, buf, count); usb_serial_debug_data(debug, &port->dev, __func__, count, priv->buf + priv->filled); usb_serial_debug_data(debug, &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. /* 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) ) /* 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) /* 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 ); /* 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), usb_sndintpipe(port->serial->dev, priv->write_int_endpoint_address), port->write_urb->transfer_buffer, length, kobil_write_callback, Loading @@ -453,28 +476,32 @@ static int kobil_write (struct tty_struct *tty, struct usb_serial_port *port, 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", __func__, port->number, result); dbg("%s - port %d Send write URB returns: %i", __func__, port->number, result); todo = priv->filled - priv->cur_pos; if (todo > 0) { 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 /* 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 /* 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", __func__, port->number, result); result = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result); } } return count; Loading @@ -483,7 +510,7 @@ static int kobil_write (struct tty_struct *tty, struct usb_serial_port *port, static int kobil_write_room(struct tty_struct *tty) { //dbg("%s - port %d", __func__, port->number); /* dbg("%s - port %d", __func__, port->number); */ /* FIXME */ return 8; } Loading @@ -498,16 +525,16 @@ static int kobil_tiocmget(struct tty_struct *tty, struct file *file) int transfer_buffer_length = 8; priv = usb_get_serial_port_data(port); if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) { // This device doesn't support ioctl calls if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { /* This device doesn't support ioctl calls */ return -EINVAL; } // allocate memory for transfer buffer /* allocate memory for transfer buffer */ transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); if (!transfer_buffer) { if (!transfer_buffer) return -ENOMEM; } result = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), Loading Loading @@ -542,16 +569,16 @@ static int kobil_tiocmset(struct tty_struct *tty, struct file *file, /* FIXME: locking ? */ priv = usb_get_serial_port_data(port); if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) { // This device doesn't support ioctl calls if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { /* This device doesn't support ioctl calls */ return -EINVAL; } // allocate memory for transfer buffer /* allocate memory for transfer buffer */ transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); if (! transfer_buffer) { if (!transfer_buffer) return -ENOMEM; } if (set & TIOCM_RTS) rts = 1; Loading @@ -564,9 +591,11 @@ static int kobil_tiocmset(struct tty_struct *tty, struct file *file, if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) { if (dtr != 0) dbg("%s - port %d Setting DTR", __func__, port->number); dbg("%s - port %d Setting DTR", __func__, port->number); else dbg("%s - port %d Clearing DTR", __func__, port->number); dbg("%s - port %d Clearing DTR", __func__, port->number); result = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), SUSBCRequest_SetStatusLinesOrQueues, Loading @@ -578,9 +607,11 @@ static int kobil_tiocmset(struct tty_struct *tty, struct file *file, KOBIL_TIMEOUT); } else { if (rts != 0) dbg("%s - port %d Setting RTS", __func__, port->number); dbg("%s - port %d Setting RTS", __func__, port->number); else dbg("%s - port %d Clearing RTS", __func__, port->number); dbg("%s - port %d Clearing RTS", __func__, port->number); result = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), SUSBCRequest_SetStatusLinesOrQueues, Loading @@ -591,7 +622,8 @@ static int kobil_tiocmset(struct tty_struct *tty, struct file *file, 0, KOBIL_TIMEOUT); } dbg("%s - port %d Send set_status_line URB returns: %i", __func__, port->number, result); dbg("%s - port %d Send set_status_line URB returns: %i", __func__, port->number, result); kfree(transfer_buffer); return (result < 0) ? result : 0; } Loading @@ -607,11 +639,13 @@ static void kobil_set_termios(struct tty_struct *tty, void *settings; priv = usb_get_serial_port_data(port); if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) // This device doesn't support ioctl calls if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) /* This device doesn't support ioctl calls */ return; switch (speed = tty_get_baud_rate(tty)) { speed = tty_get_baud_rate(tty); switch (speed) { case 1200: urb_val = SUSBCR_SBR_1200; break; Loading @@ -621,7 +655,8 @@ static void kobil_set_termios(struct tty_struct *tty, urb_val = SUSBCR_SBR_9600; break; } urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit; urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit; settings = kzalloc(50, GFP_KERNEL); if (!settings) Loading Loading @@ -657,7 +692,8 @@ static void kobil_set_termios(struct tty_struct *tty, kfree(settings); } static int kobil_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) static int kobil_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; struct kobil_private *priv = usb_get_serial_port_data(port); Loading @@ -665,8 +701,9 @@ static int kobil_ioctl(struct tty_struct *tty, struct file * file, unsigned int int transfer_buffer_length = 8; int result; if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) // This device doesn't support ioctl calls if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) /* This device doesn't support ioctl calls */ return 0; switch (cmd) { Loading @@ -681,7 +718,7 @@ static int kobil_ioctl(struct tty_struct *tty, struct file * file, unsigned int USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, SUSBCR_MSC_ResetAllQueues, 0, NULL,//transfer_buffer, NULL, /* transfer_buffer, */ 0, KOBIL_TIMEOUT ); Loading Loading
drivers/usb/serial/kobil_sct.c +297 −260 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ #include <linux/tty_flip.h> #include <linux/module.h> #include <linux/spinlock.h> #include <asm/uaccess.h> #include <linux/uaccess.h> #include <linux/usb.h> #include <linux/usb/serial.h> #include <linux/ioctl.h> Loading Loading @@ -134,9 +134,9 @@ static struct usb_serial_driver kobil_device = { struct kobil_private { int write_int_endpoint_address; int read_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 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 */ __u16 device_type; }; Loading @@ -152,9 +152,8 @@ static int kobil_startup (struct usb_serial *serial) struct usb_host_endpoint *endpoint; priv = kmalloc(sizeof(struct kobil_private), GFP_KERNEL); if (!priv){ if (!priv) return -ENOMEM; } priv->filled = 0; priv->cur_pos = 0; Loading @@ -165,7 +164,8 @@ static int kobil_startup (struct usb_serial *serial) printk(KERN_DEBUG "KOBIL B1 PRO / KAAN PRO detected\n"); break; case KOBIL_ADAPTER_K_PRODUCT_ID: printk(KERN_DEBUG "KOBIL KAAN Standard Plus / SecOVID Reader Plus detected\n"); printk(KERN_DEBUG "KOBIL KAAN Standard Plus / SecOVID Reader Plus detected\n"); break; case KOBIL_USBTWIN_PRODUCT_ID: printk(KERN_DEBUG "KOBIL USBTWIN detected\n"); Loading @@ -176,7 +176,7 @@ static int kobil_startup (struct usb_serial *serial) } usb_set_serial_port_data(serial->port[0], priv); // search for the necessary endpoints /* search for the necessary endpoints */ pdev = serial->dev; actconfig = pdev->actconfig; interface = actconfig->interface[0]; Loading @@ -186,12 +186,16 @@ static int kobil_startup (struct usb_serial *serial) for (i = 0; i < altsetting->desc.bNumEndpoints; i++) { endpoint = &altsetting->endpoint[i]; if (usb_endpoint_is_int_out(&endpoint->desc)) { dbg("%s Found interrupt out endpoint. Address: %d", __func__, endpoint->desc.bEndpointAddress); priv->write_int_endpoint_address = endpoint->desc.bEndpointAddress; dbg("%s Found interrupt out endpoint. Address: %d", __func__, endpoint->desc.bEndpointAddress); priv->write_int_endpoint_address = endpoint->desc.bEndpointAddress; } if (usb_endpoint_is_int_in(&endpoint->desc)) { dbg("%s Found interrupt in endpoint. Address: %d", __func__, endpoint->desc.bEndpointAddress); priv->read_int_endpoint_address = endpoint->desc.bEndpointAddress; dbg("%s Found interrupt in endpoint. Address: %d", __func__, endpoint->desc.bEndpointAddress); priv->read_int_endpoint_address = endpoint->desc.bEndpointAddress; } } return 0; Loading @@ -204,9 +208,8 @@ static void kobil_shutdown (struct usb_serial *serial) dbg("%s - port %d", __func__, serial->port[0]->number); for (i = 0; i < serial->num_ports; ++i) { while (serial->port[i]->port.count > 0) { while (serial->port[i]->port.count > 0) kobil_close(NULL, serial->port[i], NULL); } kfree(usb_get_serial_port_data(serial->port[i])); usb_set_serial_port_data(serial->port[i], NULL); } Loading @@ -225,7 +228,7 @@ static int kobil_open(struct tty_struct *tty, dbg("%s - port %d", __func__, port->number); priv = usb_get_serial_port_data(port); // someone sets the dev to 0 if the close method has been called /* someone sets the dev to 0 if the close method has been called */ port->interrupt_in_urb->dev = port->serial->dev; Loading @@ -238,29 +241,33 @@ static int kobil_open(struct tty_struct *tty, /* Default to echo off and other sane device settings */ tty->termios->c_lflag = 0; tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE); tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE); tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF; tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) /* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */ tty->termios->c_oflag &= ~ONLCR; } // allocate memory for transfer buffer /* allocate memory for transfer buffer */ transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); if (! transfer_buffer) { if (!transfer_buffer) return -ENOMEM; } // allocate write_urb /* allocate write_urb */ if (!port->write_urb) { dbg("%s - port %d Allocating port->write_urb", __func__, port->number); dbg("%s - port %d Allocating port->write_urb", __func__, port->number); port->write_urb = usb_alloc_urb(0, GFP_KERNEL); if (!port->write_urb) { dbg("%s - port %d usb_alloc_urb failed", __func__, port->number); dbg("%s - port %d usb_alloc_urb failed", __func__, port->number); 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); /* 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); Loading @@ -268,7 +275,7 @@ static int kobil_open(struct tty_struct *tty, return -ENOMEM; } // get hardware version /* get hardware version */ result = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), SUSBCRequest_GetMisc, Loading @@ -279,10 +286,12 @@ static int kobil_open(struct tty_struct *tty, transfer_buffer_length, KOBIL_TIMEOUT ); dbg("%s - port %d Send get_HW_version URB returns: %i", __func__, port->number, result); dbg("Harware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2] ); dbg("%s - port %d Send get_HW_version URB returns: %i", __func__, port->number, result); dbg("Harware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2]); // get firmware version /* get firmware version */ result = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), SUSBCRequest_GetMisc, Loading @@ -293,24 +302,29 @@ static int kobil_open(struct tty_struct *tty, transfer_buffer_length, KOBIL_TIMEOUT ); dbg("%s - port %d Send get_FW_version URB returns: %i", __func__, port->number, result); dbg("Firmware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2] ); if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) { // Setting Baudrate, Parity and Stopbits dbg("%s - port %d Send get_FW_version URB returns: %i", __func__, port->number, result); dbg("Firmware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2]); if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) { /* Setting Baudrate, Parity and Stopbits */ result = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), SUSBCRequest_SetBaudRateParityAndStopBits, USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, SUSBCR_SBR_9600 | SUSBCR_SPASB_EvenParity | SUSBCR_SPASB_1StopBit, SUSBCR_SBR_9600 | SUSBCR_SPASB_EvenParity | SUSBCR_SPASB_1StopBit, 0, transfer_buffer, 0, KOBIL_TIMEOUT ); dbg("%s - port %d Send set_baudrate URB returns: %i", __func__, port->number, result); dbg("%s - port %d Send set_baudrate URB returns: %i", __func__, port->number, result); // reset all queues /* reset all queues */ result = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), SUSBCRequest_Misc, Loading @@ -321,13 +335,16 @@ static int kobil_open(struct tty_struct *tty, 0, KOBIL_TIMEOUT ); dbg("%s - port %d Send reset_all_queues URB returns: %i", __func__, port->number, result); dbg("%s - port %d Send reset_all_queues URB returns: %i", __func__, port->number, result); } if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { // start reading (Adapter B 'cause PNP string) /* start reading (Adapter B 'cause PNP string) */ result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result); dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result); } kfree(transfer_buffer); Loading Loading @@ -356,7 +373,7 @@ static void kobil_read_int_callback(struct urb *urb) struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; int status = urb->status; // char *dbg_data; /* char *dbg_data; */ dbg("%s - port %d", __func__, port->number); Loading @@ -369,9 +386,10 @@ static void kobil_read_int_callback(struct urb *urb) tty = port->port.tty; if (urb->actual_length) { // BEGIN DEBUG /* BEGIN DEBUG */ /* dbg_data = kzalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL); dbg_data = kzalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL); if (! dbg_data) { return; } Loading @@ -381,18 +399,18 @@ static void kobil_read_int_callback(struct urb *urb) dbg(" <-- %s", dbg_data); kfree(dbg_data); */ // END DEBUG /* END DEBUG */ tty_buffer_request_room(tty, urb->actual_length); tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); } // someone sets the dev to 0 if the close method has been called /* 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); dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result); } Loading @@ -410,7 +428,8 @@ static int kobil_write (struct tty_struct *tty, struct usb_serial_port *port, struct kobil_private *priv; if (count == 0) { dbg("%s - port %d write request of 0 bytes", __func__, port->number); dbg("%s - port %d write request of 0 bytes", __func__, port->number); return 0; } Loading @@ -421,29 +440,33 @@ static int kobil_write (struct tty_struct *tty, struct usb_serial_port *port, return -ENOMEM; } // Copy data to buffer /* Copy data to buffer */ memcpy(priv->buf + priv->filled, buf, count); usb_serial_debug_data(debug, &port->dev, __func__, count, priv->buf + priv->filled); usb_serial_debug_data(debug, &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. /* 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) ) /* 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) /* 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 ); /* 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), usb_sndintpipe(port->serial->dev, priv->write_int_endpoint_address), port->write_urb->transfer_buffer, length, kobil_write_callback, Loading @@ -453,28 +476,32 @@ static int kobil_write (struct tty_struct *tty, struct usb_serial_port *port, 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", __func__, port->number, result); dbg("%s - port %d Send write URB returns: %i", __func__, port->number, result); todo = priv->filled - priv->cur_pos; if (todo > 0) { 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 /* 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 /* 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", __func__, port->number, result); result = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result); } } return count; Loading @@ -483,7 +510,7 @@ static int kobil_write (struct tty_struct *tty, struct usb_serial_port *port, static int kobil_write_room(struct tty_struct *tty) { //dbg("%s - port %d", __func__, port->number); /* dbg("%s - port %d", __func__, port->number); */ /* FIXME */ return 8; } Loading @@ -498,16 +525,16 @@ static int kobil_tiocmget(struct tty_struct *tty, struct file *file) int transfer_buffer_length = 8; priv = usb_get_serial_port_data(port); if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) { // This device doesn't support ioctl calls if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { /* This device doesn't support ioctl calls */ return -EINVAL; } // allocate memory for transfer buffer /* allocate memory for transfer buffer */ transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); if (!transfer_buffer) { if (!transfer_buffer) return -ENOMEM; } result = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), Loading Loading @@ -542,16 +569,16 @@ static int kobil_tiocmset(struct tty_struct *tty, struct file *file, /* FIXME: locking ? */ priv = usb_get_serial_port_data(port); if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) { // This device doesn't support ioctl calls if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { /* This device doesn't support ioctl calls */ return -EINVAL; } // allocate memory for transfer buffer /* allocate memory for transfer buffer */ transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); if (! transfer_buffer) { if (!transfer_buffer) return -ENOMEM; } if (set & TIOCM_RTS) rts = 1; Loading @@ -564,9 +591,11 @@ static int kobil_tiocmset(struct tty_struct *tty, struct file *file, if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) { if (dtr != 0) dbg("%s - port %d Setting DTR", __func__, port->number); dbg("%s - port %d Setting DTR", __func__, port->number); else dbg("%s - port %d Clearing DTR", __func__, port->number); dbg("%s - port %d Clearing DTR", __func__, port->number); result = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), SUSBCRequest_SetStatusLinesOrQueues, Loading @@ -578,9 +607,11 @@ static int kobil_tiocmset(struct tty_struct *tty, struct file *file, KOBIL_TIMEOUT); } else { if (rts != 0) dbg("%s - port %d Setting RTS", __func__, port->number); dbg("%s - port %d Setting RTS", __func__, port->number); else dbg("%s - port %d Clearing RTS", __func__, port->number); dbg("%s - port %d Clearing RTS", __func__, port->number); result = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), SUSBCRequest_SetStatusLinesOrQueues, Loading @@ -591,7 +622,8 @@ static int kobil_tiocmset(struct tty_struct *tty, struct file *file, 0, KOBIL_TIMEOUT); } dbg("%s - port %d Send set_status_line URB returns: %i", __func__, port->number, result); dbg("%s - port %d Send set_status_line URB returns: %i", __func__, port->number, result); kfree(transfer_buffer); return (result < 0) ? result : 0; } Loading @@ -607,11 +639,13 @@ static void kobil_set_termios(struct tty_struct *tty, void *settings; priv = usb_get_serial_port_data(port); if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) // This device doesn't support ioctl calls if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) /* This device doesn't support ioctl calls */ return; switch (speed = tty_get_baud_rate(tty)) { speed = tty_get_baud_rate(tty); switch (speed) { case 1200: urb_val = SUSBCR_SBR_1200; break; Loading @@ -621,7 +655,8 @@ static void kobil_set_termios(struct tty_struct *tty, urb_val = SUSBCR_SBR_9600; break; } urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit; urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit; settings = kzalloc(50, GFP_KERNEL); if (!settings) Loading Loading @@ -657,7 +692,8 @@ static void kobil_set_termios(struct tty_struct *tty, kfree(settings); } static int kobil_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) static int kobil_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; struct kobil_private *priv = usb_get_serial_port_data(port); Loading @@ -665,8 +701,9 @@ static int kobil_ioctl(struct tty_struct *tty, struct file * file, unsigned int int transfer_buffer_length = 8; int result; if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) // This device doesn't support ioctl calls if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) /* This device doesn't support ioctl calls */ return 0; switch (cmd) { Loading @@ -681,7 +718,7 @@ static int kobil_ioctl(struct tty_struct *tty, struct file * file, unsigned int USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, SUSBCR_MSC_ResetAllQueues, 0, NULL,//transfer_buffer, NULL, /* transfer_buffer, */ 0, KOBIL_TIMEOUT ); Loading