patch-2.4.19 linux-2.4.19/drivers/usb/serial/whiteheat.c
Next file: linux-2.4.19/drivers/usb/serial/whiteheat_fw.h
Previous file: linux-2.4.19/drivers/usb/serial/visor.h
Back to the patch index
Back to the overall index
- Lines: 138
- Date:
Fri Aug 2 17:39:45 2002
- Orig file:
linux-2.4.18/drivers/usb/serial/whiteheat.c
- Orig date:
Fri Dec 21 09:41:55 2001
diff -urN linux-2.4.18/drivers/usb/serial/whiteheat.c linux-2.4.19/drivers/usb/serial/whiteheat.c
@@ -88,7 +88,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.1"
+#define DRIVER_VERSION "v1.2"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
#define DRIVER_DESC "USB ConnectTech WhiteHEAT driver"
@@ -128,8 +128,9 @@
static void whiteheat_set_termios (struct usb_serial_port *port, struct termios * old);
static void whiteheat_throttle (struct usb_serial_port *port);
static void whiteheat_unthrottle (struct usb_serial_port *port);
-static int whiteheat_startup (struct usb_serial *serial);
-static void whiteheat_shutdown (struct usb_serial *serial);
+static int whiteheat_fake_startup (struct usb_serial *serial);
+static int whiteheat_real_startup (struct usb_serial *serial);
+static void whiteheat_real_shutdown (struct usb_serial *serial);
static struct usb_serial_device_type whiteheat_fake_device = {
name: "Connect Tech - WhiteHEAT - (prerenumeration)",
@@ -141,7 +142,7 @@
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
num_ports: 1,
- startup: whiteheat_startup
+ startup: whiteheat_fake_startup,
};
static struct usb_serial_device_type whiteheat_device = {
@@ -160,7 +161,8 @@
unthrottle: whiteheat_unthrottle,
ioctl: whiteheat_ioctl,
set_termios: whiteheat_set_termios,
- shutdown: whiteheat_shutdown,
+ startup: whiteheat_real_startup,
+ shutdown: whiteheat_real_shutdown,
};
struct whiteheat_private {
@@ -539,7 +541,7 @@
- device renumerated itself and comes up as new device id with all
firmware download completed.
*/
-static int whiteheat_startup (struct usb_serial *serial)
+static int whiteheat_fake_startup (struct usb_serial *serial)
{
int response;
const struct whiteheat_hex_record *record;
@@ -598,9 +600,68 @@
}
-static void whiteheat_shutdown (struct usb_serial *serial)
+static int whiteheat_real_startup (struct usb_serial *serial)
{
- struct usb_serial_port *command_port;
+ struct whiteheat_hw_info *hw_info;
+ int pipe;
+ int ret;
+ int alen;
+ __u8 command[2] = { WHITEHEAT_GET_HW_INFO, 0 };
+ __u8 result[sizeof(*hw_info) + 1];
+
+ pipe = usb_rcvbulkpipe (serial->dev, 7);
+ usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, 2 * HZ);
+ /*
+ * We ignore the return code. In the case where rmmod/insmod is
+ * performed with a WhiteHEAT connected, the above times out
+ * because the endpoint is already prepped, meaning the below succeeds
+ * regardless. All other cases the above succeeds.
+ */
+
+ pipe = usb_sndbulkpipe (serial->dev, 7);
+ ret = usb_bulk_msg (serial->dev, pipe, command, sizeof(command), &alen, 2 * HZ);
+ if (ret) {
+ err("%s: Couldn't send command [%d]", serial->type->name, ret);
+ goto error_out;
+ } else if (alen != sizeof(command)) {
+ err("%s: Send command incomplete [%d]", serial->type->name, alen);
+ goto error_out;
+ }
+
+ pipe = usb_rcvbulkpipe (serial->dev, 7);
+ ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, 2 * HZ);
+ if (ret) {
+ err("%s: Couldn't get results [%d]", serial->type->name, ret);
+ goto error_out;
+ } else if (alen != sizeof(result)) {
+ err("%s: Get results incomplete [%d]", serial->type->name, alen);
+ goto error_out;
+ } else if (result[0] != command[0]) {
+ err("%s: Command failed [%d]", serial->type->name, result[0]);
+ goto error_out;
+ }
+
+ hw_info = (struct whiteheat_hw_info *)&result[1];
+
+ info("%s: Driver %s: Firmware v%d.%02d", serial->type->name,
+ DRIVER_VERSION, hw_info->sw_major_rev, hw_info->sw_minor_rev);
+
+ return 0;
+
+error_out:
+ err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->name);
+ /*
+ * Return that we've claimed the interface. A failure here may be
+ * due to interception by the command_callback routine or other
+ * causes that don't mean that the firmware isn't running. This may
+ * change in the future. Probably should actually.
+ */
+ return 0;
+}
+
+static void whiteheat_real_shutdown (struct usb_serial *serial)
+{
+ struct usb_serial_port *command_port;
int i;
dbg(__FUNCTION__);
@@ -623,8 +684,6 @@
}
-
-
static void set_command (struct usb_serial_port *port, unsigned char state, unsigned char command)
{
struct whiteheat_rdb_set rdb_command;
@@ -660,7 +719,7 @@
{
usb_serial_register (&whiteheat_fake_device);
usb_serial_register (&whiteheat_device);
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)