Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 151366
b: refs/heads/master
c: 98fcb5f
h: refs/heads/master
v: v3
  • Loading branch information
Jason Wessel authored and Greg Kroah-Hartman committed Jun 16, 2009
1 parent 742794e commit 49ea7bc
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 87c1edd217a6742e48028db6664d7763de0449f6
refs/heads/master: 98fcb5f78165b8a3d93870ad7afd4d9ebbb8b43a
56 changes: 44 additions & 12 deletions trunk/drivers/usb/serial/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ int usb_serial_generic_write(struct tty_struct *tty,
/* no bulk out, so return 0 bytes written */
return 0;
}
EXPORT_SYMBOL_GPL(usb_serial_generic_write);

int usb_serial_generic_write_room(struct tty_struct *tty)
{
Expand All @@ -351,7 +352,9 @@ int usb_serial_generic_write_room(struct tty_struct *tty)
spin_lock_irqsave(&port->lock, flags);
if (serial->type->max_in_flight_urbs) {
if (port->urbs_in_flight < serial->type->max_in_flight_urbs)
room = port->bulk_out_size;
room = port->bulk_out_size *
(serial->type->max_in_flight_urbs -
port->urbs_in_flight);
} else if (serial->num_bulk_out && !(port->write_urb_busy)) {
room = port->bulk_out_size;
}
Expand Down Expand Up @@ -385,7 +388,8 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
}


static void resubmit_read_urb(struct usb_serial_port *port, gfp_t mem_flags)
void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port,
gfp_t mem_flags)
{
struct urb *urb = port->read_urb;
struct usb_serial *serial = port->serial;
Expand All @@ -406,25 +410,28 @@ static void resubmit_read_urb(struct usb_serial_port *port, gfp_t mem_flags)
"%s - failed resubmitting read urb, error %d\n",
__func__, result);
}
EXPORT_SYMBOL_GPL(usb_serial_generic_resubmit_read_urb);

/* Push data to tty layer and resubmit the bulk read URB */
static void flush_and_resubmit_read_urb(struct usb_serial_port *port)
{
struct urb *urb = port->read_urb;
struct tty_struct *tty = tty_port_tty_get(&port->port);
int room;
char *ch = (char *)urb->transfer_buffer;
int i;

if (!tty)
goto done;

/* Push data to tty */
if (tty && urb->actual_length) {
room = tty_buffer_request_room(tty, urb->actual_length);
if (room) {
tty_insert_flip_string(tty, urb->transfer_buffer, room);
tty_flip_buffer_push(tty);
}
for (i = 0; i < urb->actual_length; i++, ch++) {
if (!usb_serial_handle_sysrq_char(port, *ch))
tty_insert_flip_char(tty, *ch, TTY_NORMAL);
}
tty_flip_buffer_push(tty);
tty_kref_put(tty);

resubmit_read_urb(port, GFP_ATOMIC);
done:
usb_serial_generic_resubmit_read_urb(port, GFP_ATOMIC);
}

void usb_serial_generic_read_bulk_callback(struct urb *urb)
Expand Down Expand Up @@ -515,10 +522,35 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)

if (was_throttled) {
/* Resume reading from device */
resubmit_read_urb(port, GFP_KERNEL);
usb_serial_generic_resubmit_read_urb(port, GFP_KERNEL);
}
}

int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch)
{
if (port->sysrq) {
if (ch && time_before(jiffies, port->sysrq)) {
handle_sysrq(ch, tty_port_tty_get(&port->port));
port->sysrq = 0;
return 1;
}
port->sysrq = 0;
}
return 0;
}
EXPORT_SYMBOL_GPL(usb_serial_handle_sysrq_char);

int usb_serial_handle_break(struct usb_serial_port *port)
{
if (!port->sysrq) {
port->sysrq = jiffies + HZ*5;
return 1;
}
port->sysrq = 0;
return 0;
}
EXPORT_SYMBOL_GPL(usb_serial_handle_break);

void usb_serial_generic_shutdown(struct usb_serial *serial)
{
int i;
Expand Down
39 changes: 39 additions & 0 deletions trunk/drivers/usb/serial/usb_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@

#define URB_DEBUG_MAX_IN_FLIGHT_URBS 4000
#define USB_DEBUG_MAX_PACKET_SIZE 8
#define USB_DEBUG_BRK_SIZE 8
static char USB_DEBUG_BRK[USB_DEBUG_BRK_SIZE] = {
0x00,
0xff,
0x01,
0xfe,
0x00,
0xfe,
0x01,
0xff,
};

static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x0525, 0x127a) },
Expand All @@ -39,6 +50,32 @@ static int usb_debug_open(struct tty_struct *tty, struct usb_serial_port *port,
return usb_serial_generic_open(tty, port, filp);
}

/* This HW really does not support a serial break, so one will be
* emulated when ever the break state is set to true.
*/
static void usb_debug_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
if (!break_state)
return;
usb_serial_generic_write(tty, port, USB_DEBUG_BRK, USB_DEBUG_BRK_SIZE);
}

static void usb_debug_read_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;

if (urb->actual_length == USB_DEBUG_BRK_SIZE &&
memcmp(urb->transfer_buffer, USB_DEBUG_BRK,
USB_DEBUG_BRK_SIZE) == 0) {
usb_serial_handle_break(port);
usb_serial_generic_resubmit_read_urb(port, GFP_ATOMIC);
return;
}

usb_serial_generic_read_bulk_callback(urb);
}

static struct usb_serial_driver debug_device = {
.driver = {
.owner = THIS_MODULE,
Expand All @@ -48,6 +85,8 @@ static struct usb_serial_driver debug_device = {
.num_ports = 1,
.open = usb_debug_open,
.max_in_flight_urbs = URB_DEBUG_MAX_IN_FLIGHT_URBS,
.break_ctl = usb_debug_break_ctl,
.read_bulk_callback = usb_debug_read_bulk_callback,
};

static int __init debug_init(void)
Expand Down
8 changes: 8 additions & 0 deletions trunk/include/linux/usb/serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include <linux/kref.h>
#include <linux/mutex.h>
#include <linux/sysrq.h>

#define SERIAL_TTY_MAJOR 188 /* Nice legal number now */
#define SERIAL_TTY_MINORS 254 /* loads of devices :) */
Expand Down Expand Up @@ -99,6 +100,7 @@ struct usb_serial_port {
char throttled;
char throttle_req;
char console;
unsigned long sysrq; /* sysrq timeout */
struct device dev;
};
#define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev)
Expand Down Expand Up @@ -301,6 +303,12 @@ extern void usb_serial_generic_unthrottle(struct tty_struct *tty);
extern void usb_serial_generic_shutdown(struct usb_serial *serial);
extern int usb_serial_generic_register(int debug);
extern void usb_serial_generic_deregister(void);
extern void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port,
gfp_t mem_flags);
extern int usb_serial_handle_sysrq_char(struct usb_serial_port *port,
unsigned int ch);
extern int usb_serial_handle_break(struct usb_serial_port *port);


extern int usb_serial_bus_register(struct usb_serial_driver *device);
extern void usb_serial_bus_deregister(struct usb_serial_driver *device);
Expand Down

0 comments on commit 49ea7bc

Please sign in to comment.