From 3d6aa3206540e1e68bda9e8ea11ec71444f1ac71 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 10 Feb 2008 20:23:24 -0600 Subject: [PATCH] USB: cypress_m8: Don't issue GET_CONFIG for certain devices Earthmate LT-20 devices (both "old" and "new" versions) can't tolerate a GET_CONFIG command. The original Earthmate has no trouble with this. Presumably other non-Earthmate devices are still OK as well. This change disables the use of GET_CONFIG for cases where it is known not to work. Signed-off-by: Mike Isely Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cypress_m8.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index c42d3bdbe9..f0c5d2a7ab 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -145,6 +145,7 @@ struct cypress_private { __u8 current_config; /* stores the current configuration byte */ __u8 rx_flags; /* throttling - used from whiteheat/ftdi_sio */ enum packet_format pkt_fmt; /* format to use for packet send / receive */ + int get_cfg_unsafe; /* If true, the CYPRESS_GET_CONFIG is unsafe */ int baud_rate; /* stores current baud rate in integer form */ int cbr_mask; /* stores current baud rate in masked form */ int isthrottled; /* if throttled, discard reads */ @@ -401,6 +402,12 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m } break; case CYPRESS_GET_CONFIG: + if (priv->get_cfg_unsafe) { + /* Not implemented for this device, + and if we try to do it we're likely + to crash the hardware. */ + return -ENOTTY; + } dbg("%s - retreiving serial line settings", __FUNCTION__); /* set initial values in feature buffer */ memset(feature_buffer, 0, sizeof(feature_buffer)); @@ -570,20 +577,30 @@ static int generic_startup (struct usb_serial *serial) static int cypress_earthmate_startup (struct usb_serial *serial) { struct cypress_private *priv; + struct usb_serial_port *port = serial->port[0]; dbg("%s", __FUNCTION__); if (generic_startup(serial)) { dbg("%s - Failed setting up port %d", __FUNCTION__, - serial->port[0]->number); + port->number); return 1; } - priv = usb_get_serial_port_data(serial->port[0]); + priv = usb_get_serial_port_data(port); priv->chiptype = CT_EARTHMATE; /* All Earthmate devices use the separated-count packet format! Idiotic. */ priv->pkt_fmt = packet_format_1; + if (serial->dev->descriptor.idProduct != PRODUCT_ID_EARTHMATEUSB) { + /* The old original USB Earthmate seemed able to + handle GET_CONFIG requests; everything they've + produced since that time crashes if this command is + attempted :-( */ + dbg("%s - Marking this device as unsafe for GET_CONFIG " + "commands", __func__); + priv->get_cfg_unsafe = !0; + } return 0; } /* cypress_earthmate_startup */ -- 2.39.5