* [PATCH 0/4] usb_debug serial, ftdi_sio serial and sysrq
@ 2009-05-11 20:24 Jason Wessel
2009-05-11 20:24 ` [PATCH 1/4] usb_debug, usb_generic_serial: implement multi urb write Jason Wessel
0 siblings, 1 reply; 6+ messages in thread
From: Jason Wessel @ 2009-05-11 20:24 UTC (permalink / raw)
To: greg; +Cc: stern, linux-usb, linux-kernel
The idea behind this patch series is to allow the USB 2.0 debug device
to better operate as a fully functional system console with the full
capability for sysrq.
This is version 2 of the original patches per Greg and Alan's comments.
Included is a fix to the ftdi_sio driver as well.
Thanks,
Jason.
The short log and git info is below, which is against the 2.6.30
development tree.
The following changes since commit a4d7749be5de4a7261bcbe3c7d96c748792ec455:
Linus Torvalds (1):
Merge git://git.kernel.org/.../gregkh/staging-2.6
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb.git for_gregkh
Jason Wessel (4):
usb_debug, usb_generic_serial: implement multi urb write
ftd_sio usb: move status check
usb_debug,usb_generic_serial: implement sysrq and serial break
ftd_sio usb: implement sysrq handling on break
drivers/usb/serial/Kconfig | 7 ++
drivers/usb/serial/ftdi_sio.c | 18 +++--
drivers/usb/serial/generic.c | 151 +++++++++++++++++++++++++++++++++++-----
drivers/usb/serial/usb_debug.c | 41 +++++++++++
include/linux/usb/serial.h | 38 ++++++++++-
5 files changed, 227 insertions(+), 28 deletions(-)
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] usb_debug, usb_generic_serial: implement multi urb write
2009-05-11 20:24 [PATCH 0/4] usb_debug serial, ftdi_sio serial and sysrq Jason Wessel
@ 2009-05-11 20:24 ` Jason Wessel
2009-05-11 20:24 ` [PATCH 2/4] ftd_sio usb: move status check Jason Wessel
0 siblings, 1 reply; 6+ messages in thread
From: Jason Wessel @ 2009-05-11 20:24 UTC (permalink / raw)
To: greg; +Cc: stern, linux-usb, linux-kernel, Jason Wessel
The usb_debug driver, when used as the console, will always fail to
insert the carriage return and new line sequence as well as randomly
drop console output. This is a result of only having the single
write_urb and that the tty layer will have a lock that prevents the
processing of the back to back urb requests.
The solution is to allow more than one urb to be outstanding and have
a slightly deeper transmit queue. The idea and some code is borrowed
from the ftdi_sio usb driver.
The generic usb serial driver was modified so as to allow the classic
method of 1 write urb, or a multi write urb scheme with N allowed
outstanding urbs where N is controlled by max_in_flight_urbs. When
max_in_flight_urbs in a "struct usb_serial_driver" is non zero the
multi write urb scheme will be used.
The size of 4000 was selected for the usb_debug driver so that the
driver lowers possibility of losing the queued console messages during
the kernel startup.
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
---
drivers/usb/serial/generic.c | 121 +++++++++++++++++++++++++++++++++++++--
drivers/usb/serial/usb_debug.c | 2 +
include/linux/usb/serial.h | 4 +
3 files changed, 120 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 4cec990..6a1b45d 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -191,6 +191,88 @@ void usb_serial_generic_close(struct tty_struct *tty,
generic_cleanup(port);
}
+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;
+}
+
int usb_serial_generic_write(struct tty_struct *tty,
struct usb_serial_port *port, const unsigned char *buf, int count)
{
@@ -208,6 +290,11 @@ int usb_serial_generic_write(struct tty_struct *tty,
/* only do something if we have a bulk out endpoint */
if (serial->num_bulk_out) {
unsigned long flags;
+
+ if (serial->type->max_in_flight_urbs)
+ return usb_serial_multi_urb_write(tty, port,
+ buf, count);
+
spin_lock_irqsave(&port->lock, flags);
if (port->write_urb_busy) {
spin_unlock_irqrestore(&port->lock, flags);
@@ -258,15 +345,18 @@ int usb_serial_generic_write_room(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
+ unsigned long flags;
int room = 0;
dbg("%s - port %d", __func__, port->number);
-
- /* FIXME: Locking */
- if (serial->num_bulk_out) {
- if (!(port->write_urb_busy))
+ 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;
+ } else if (serial->num_bulk_out && !(port->write_urb_busy)) {
+ room = port->bulk_out_size;
}
+ spin_unlock_irqrestore(&port->lock, flags);
dbg("%s - returns %d", __func__, room);
return room;
@@ -277,11 +367,16 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
int chars = 0;
+ unsigned long flags;
dbg("%s - port %d", __func__, port->number);
- /* FIXME: Locking */
- if (serial->num_bulk_out) {
+ if (serial->type->max_in_flight_urbs) {
+ spin_lock_irqsave(&port->lock, flags);
+ chars = port->tx_bytes_flight;
+ spin_unlock_irqrestore(&port->lock, flags);
+ } else if (serial->num_bulk_out) {
+ /* FIXME: Locking */
if (port->write_urb_busy)
chars = port->write_urb->transfer_buffer_length;
}
@@ -364,12 +459,24 @@ EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
void usb_serial_generic_write_bulk_callback(struct urb *urb)
{
+ unsigned long flags;
struct usb_serial_port *port = urb->context;
int status = urb->status;
dbg("%s - port %d", __func__, port->number);
- port->write_urb_busy = 0;
+ if (port->serial->type->max_in_flight_urbs) {
+ spin_lock_irqsave(&port->lock, flags);
+ --port->urbs_in_flight;
+ port->tx_bytes_flight -= urb->transfer_buffer_length;
+ if (port->urbs_in_flight < 0)
+ port->urbs_in_flight = 0;
+ spin_unlock_irqrestore(&port->lock, flags);
+ } else {
+ /* Handle the case for single urb mode */
+ port->write_urb_busy = 0;
+ }
+
if (status) {
dbg("%s - nonzero write bulk status received: %d",
__func__, status);
diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c
index 6c9cbb5..157a6e2 100644
--- a/drivers/usb/serial/usb_debug.c
+++ b/drivers/usb/serial/usb_debug.c
@@ -15,6 +15,7 @@
#include <linux/usb.h>
#include <linux/usb/serial.h>
+#define URB_DEBUG_MAX_IN_FLIGHT_URBS 4000
#define USB_DEBUG_MAX_PACKET_SIZE 8
static struct usb_device_id id_table [] = {
@@ -46,6 +47,7 @@ static struct usb_serial_driver debug_device = {
.id_table = id_table,
.num_ports = 1,
.open = usb_debug_open,
+ .max_in_flight_urbs = URB_DEBUG_MAX_IN_FLIGHT_URBS,
};
static int __init debug_init(void)
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index 625e9e4..5cacba1 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -91,6 +91,9 @@ struct usb_serial_port {
int write_urb_busy;
__u8 bulk_out_endpointAddress;
+ int tx_bytes_flight;
+ int urbs_in_flight;
+
wait_queue_head_t write_wait;
struct work_struct work;
char throttled;
@@ -207,6 +210,7 @@ struct usb_serial_driver {
struct device_driver driver;
struct usb_driver *usb_driver;
struct usb_dynids dynids;
+ int max_in_flight_urbs;
int (*probe)(struct usb_serial *serial, const struct usb_device_id *id);
int (*attach)(struct usb_serial *serial);
--
1.6.3.rc0.1.gf800
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] ftd_sio usb: move status check
2009-05-11 20:24 ` [PATCH 1/4] usb_debug, usb_generic_serial: implement multi urb write Jason Wessel
@ 2009-05-11 20:24 ` Jason Wessel
2009-05-11 20:24 ` [PATCH 3/4] usb_debug,usb_generic_serial: implement sysrq and serial break Jason Wessel
0 siblings, 1 reply; 6+ messages in thread
From: Jason Wessel @ 2009-05-11 20:24 UTC (permalink / raw)
To: greg; +Cc: stern, linux-usb, linux-kernel, Jason Wessel
Alan Stern commented that the private driver counts must be updated
regard less of the status return on the urb when the write call back
is executed.
This patch alters the behavior to update the private driver counts by
simply moving the status check to after the driver count update.
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
---
drivers/usb/serial/ftdi_sio.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 0ab8474..3a1b84d 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -1755,11 +1755,6 @@ static void ftdi_write_bulk_callback(struct urb *urb)
dbg("%s - port %d", __func__, port->number);
- if (status) {
- dbg("nonzero write bulk status received: %d", status);
- return;
- }
-
priv = usb_get_serial_port_data(port);
if (!priv) {
dbg("%s - bad port private data pointer - exiting", __func__);
@@ -1777,6 +1772,11 @@ static void ftdi_write_bulk_callback(struct urb *urb)
priv->tx_outstanding_bytes -= countback;
spin_unlock_irqrestore(&priv->tx_lock, flags);
+ if (status) {
+ dbg("nonzero write bulk status received: %d", status);
+ return;
+ }
+
usb_serial_port_softint(port);
} /* ftdi_write_bulk_callback */
--
1.6.3.rc0.1.gf800
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] usb_debug,usb_generic_serial: implement sysrq and serial break
2009-05-11 20:24 ` [PATCH 2/4] ftd_sio usb: move status check Jason Wessel
@ 2009-05-11 20:24 ` Jason Wessel
2009-05-11 20:24 ` [PATCH 4/4] ftd_sio usb: implement sysrq handling on break Jason Wessel
2009-05-12 17:02 ` [PATCH 3/4] usb_debug,usb_generic_serial: implement sysrq and serial break Greg KH
0 siblings, 2 replies; 6+ messages in thread
From: Jason Wessel @ 2009-05-11 20:24 UTC (permalink / raw)
To: greg; +Cc: stern, linux-usb, linux-kernel, Jason Wessel
The usb_debug driver was modified to implement serial break handling
by using a "magic" data packet comprised of the sequence:
0x00 0xff 0x01 0xfe 0x00 0xfe 0x01 0xff
When the tty layer requests a serial break the usb_debug driver sends
the magic packet. On the receiving side the magic packet is thrown
away or a sysrq is activated depending on what kernel .config options
have been set.
The generic serial driver was modified as well as the usb serial
headers to generically implement sysrq processing in the same way the
non usb uart based drivers implement the sysrq handling. This will
allow other usb serial devices to implement sysrq handling as desired.
The new usb serial functions are named similarly and implemented
similarly to the uart functions as follows:
usb_serial_handle_break <-> uart_handle_break
usb_serial_handle_sysrq_char <-> uart_handle_sysrq_char
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
---
drivers/usb/serial/Kconfig | 7 +++++++
drivers/usb/serial/generic.c | 30 ++++++++++++++++++------------
drivers/usb/serial/usb_debug.c | 39 +++++++++++++++++++++++++++++++++++++++
include/linux/usb/serial.h | 34 ++++++++++++++++++++++++++++++++--
4 files changed, 96 insertions(+), 14 deletions(-)
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index c480ea4..3229321 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -42,6 +42,13 @@ config USB_SERIAL_CONSOLE
If unsure, say N.
+config USB_SERIAL_SYSRQ
+ bool "Support inbound sysrq"
+ depends on USB_SERIAL_CONSOLE && MAGIC_SYSRQ
+ help
+ Say y here to enable support for sysrq if the usb serial
+ driver implements support for sysrq.
+
config USB_EZUSB
bool "Functions for loading firmware on EZUSB chips"
help
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 6a1b45d..534d84d 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -352,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;
}
@@ -386,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;
@@ -407,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)
@@ -516,7 +522,7 @@ 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);
}
}
diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c
index 157a6e2..f1878c2 100644
--- a/drivers/usb/serial/usb_debug.c
+++ b/drivers/usb/serial/usb_debug.c
@@ -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) },
@@ -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,
@@ -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)
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index 5cacba1..6ee63e8 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -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 :) */
@@ -99,6 +100,9 @@ struct usb_serial_port {
char throttled;
char throttle_req;
char console;
+#ifdef CONFIG_USB_SERIAL_SYSRQ
+ unsigned long sysrq; /* sysrq timeout */
+#endif /* CONFIG_USB_SERIAL_SYSRQ */
struct device dev;
};
#define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev)
@@ -299,6 +303,8 @@ 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);
+void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port,
+ gfp_t mem_flags);
extern int usb_serial_bus_register(struct usb_serial_driver *device);
extern void usb_serial_bus_deregister(struct usb_serial_driver *device);
@@ -332,7 +338,31 @@ static inline void usb_serial_debug_data(int debug,
## arg); \
} while (0)
-
-
+static inline int
+usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch)
+{
+#ifdef CONFIG_USB_SERIAL_SYSRQ
+ 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;
+ }
+#endif /* CONFIG_USB_SERIAL_SYSRQ */
+ return 0;
+}
+static inline int usb_serial_handle_break(struct usb_serial_port *port)
+{
+#ifdef CONFIG_USB_SERIAL_SYSRQ
+ if (!port->sysrq) {
+ port->sysrq = jiffies + HZ*5;
+ return 1;
+ }
+ port->sysrq = 0;
+#endif /* CONFIG_USB_SERIAL_SYSRQ */
+ return 0;
+}
#endif /* __LINUX_USB_SERIAL_H */
--
1.6.3.rc0.1.gf800
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] ftd_sio usb: implement sysrq handling on break
2009-05-11 20:24 ` [PATCH 3/4] usb_debug,usb_generic_serial: implement sysrq and serial break Jason Wessel
@ 2009-05-11 20:24 ` Jason Wessel
2009-05-12 17:02 ` [PATCH 3/4] usb_debug,usb_generic_serial: implement sysrq and serial break Greg KH
1 sibling, 0 replies; 6+ messages in thread
From: Jason Wessel @ 2009-05-11 20:24 UTC (permalink / raw)
To: greg; +Cc: stern, linux-usb, linux-kernel, Jason Wessel
Change driver to make use of the new functions in
include/linux/usb/serial.h so as to allow the driver to handle the
sysrq when the .config has CONFIG_USB_SERIAL_SYSRQ=y.
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
---
drivers/usb/serial/ftdi_sio.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 3a1b84d..a93b76a 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -1991,6 +1991,7 @@ static void ftdi_process_read(struct work_struct *work)
if (data[packet_offset+1] & FTDI_RS_BI) {
error_flag = TTY_BREAK;
dbg("BREAK received");
+ usb_serial_handle_break(port);
}
if (data[packet_offset+1] & FTDI_RS_PE) {
error_flag = TTY_PARITY;
@@ -2005,8 +2006,11 @@ static void ftdi_process_read(struct work_struct *work)
/* Note that the error flag is duplicated for
every character received since we don't know
which character it applied to */
- tty_insert_flip_char(tty,
- data[packet_offset + i], error_flag);
+ if (!usb_serial_handle_sysrq_char(port,
+ data[packet_offset + i]))
+ tty_insert_flip_char(tty,
+ data[packet_offset + i],
+ error_flag);
}
need_flip = 1;
}
--
1.6.3.rc0.1.gf800
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 3/4] usb_debug,usb_generic_serial: implement sysrq and serial break
2009-05-11 20:24 ` [PATCH 3/4] usb_debug,usb_generic_serial: implement sysrq and serial break Jason Wessel
2009-05-11 20:24 ` [PATCH 4/4] ftd_sio usb: implement sysrq handling on break Jason Wessel
@ 2009-05-12 17:02 ` Greg KH
1 sibling, 0 replies; 6+ messages in thread
From: Greg KH @ 2009-05-12 17:02 UTC (permalink / raw)
To: Jason Wessel; +Cc: stern, linux-usb, linux-kernel
On Mon, May 11, 2009 at 03:24:09PM -0500, Jason Wessel wrote:
> The usb_debug driver was modified to implement serial break handling
> by using a "magic" data packet comprised of the sequence:
>
> 0x00 0xff 0x01 0xfe 0x00 0xfe 0x01 0xff
>
> When the tty layer requests a serial break the usb_debug driver sends
> the magic packet. On the receiving side the magic packet is thrown
> away or a sysrq is activated depending on what kernel .config options
> have been set.
>
> The generic serial driver was modified as well as the usb serial
> headers to generically implement sysrq processing in the same way the
> non usb uart based drivers implement the sysrq handling. This will
> allow other usb serial devices to implement sysrq handling as desired.
>
> The new usb serial functions are named similarly and implemented
> similarly to the uart functions as follows:
>
> usb_serial_handle_break <-> uart_handle_break
> usb_serial_handle_sysrq_char <-> uart_handle_sysrq_char
>
> Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
> ---
> drivers/usb/serial/Kconfig | 7 +++++++
> drivers/usb/serial/generic.c | 30 ++++++++++++++++++------------
> drivers/usb/serial/usb_debug.c | 39 +++++++++++++++++++++++++++++++++++++++
> include/linux/usb/serial.h | 34 ++++++++++++++++++++++++++++++++--
> 4 files changed, 96 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
> index c480ea4..3229321 100644
> --- a/drivers/usb/serial/Kconfig
> +++ b/drivers/usb/serial/Kconfig
> @@ -42,6 +42,13 @@ config USB_SERIAL_CONSOLE
>
> If unsure, say N.
>
> +config USB_SERIAL_SYSRQ
> + bool "Support inbound sysrq"
> + depends on USB_SERIAL_CONSOLE && MAGIC_SYSRQ
> + help
> + Say y here to enable support for sysrq if the usb serial
> + driver implements support for sysrq.
> +
I took this Kconfig option out, as it would just be confusing. Just
always enable this, and if a driver wants to support it, it can, no need
for ifdefs or anything else.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2009-05-12 17:15 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-11 20:24 [PATCH 0/4] usb_debug serial, ftdi_sio serial and sysrq Jason Wessel
2009-05-11 20:24 ` [PATCH 1/4] usb_debug, usb_generic_serial: implement multi urb write Jason Wessel
2009-05-11 20:24 ` [PATCH 2/4] ftd_sio usb: move status check Jason Wessel
2009-05-11 20:24 ` [PATCH 3/4] usb_debug,usb_generic_serial: implement sysrq and serial break Jason Wessel
2009-05-11 20:24 ` [PATCH 4/4] ftd_sio usb: implement sysrq handling on break Jason Wessel
2009-05-12 17:02 ` [PATCH 3/4] usb_debug,usb_generic_serial: implement sysrq and serial break Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox