ChangeSet 1.738.5.15, 2002/10/11 15:02:34-07:00, stuartm@connecttech.com [PATCH] USB Whiteheat driver patches A couple patches on 2.5.41; issues discovered during QA. 1: The hack to get around the unlinking bug. You said this was also in 2.5.x, so I've included this. 2: filp is NULL when called from usb_serial_disconnect. Fixes an oops. 3: In the case where the module is reloaded; the endpoints in the usbsubsystem don't go away. So when the module comes back, the endpoints still have the unlink thing, and also need to be cleared. Otherwise the firmware appears not respond to the version nubmer query and the driver doesn't attach, and you have no device. diff -Nru a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c --- a/drivers/usb/serial/whiteheat.c Sun Oct 13 17:09:32 2002 +++ b/drivers/usb/serial/whiteheat.c Sun Oct 13 17:09:32 2002 @@ -334,6 +334,12 @@ command_port = &serial->port[COMMAND_PORT]; pipe = usb_sndbulkpipe (serial->dev, command_port->bulk_out_endpointAddress); + /* + * When the module is reloaded the firmware is still there and + * the endpoints are still in the usb core unchanged. This is the + * unlinking bug in disguise. Same for the call below. + */ + usb_clear_halt(serial->dev, pipe); ret = usb_bulk_msg (serial->dev, pipe, command, sizeof(command), &alen, COMMAND_TIMEOUT); if (ret) { err("%s: Couldn't send command [%d]", serial->type->name, ret); @@ -344,6 +350,8 @@ } pipe = usb_rcvbulkpipe (serial->dev, command_port->bulk_in_endpointAddress); + /* See the comment on the usb_clear_halt() above */ + usb_clear_halt(serial->dev, pipe); ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, COMMAND_TIMEOUT); if (ret) { err("%s: Couldn't get results [%d]", serial->type->name, ret); @@ -438,6 +446,10 @@ if (retval) goto exit; + /* Work around HCD bugs */ + usb_clear_halt(port->serial->dev, port->read_urb->pipe); + usb_clear_halt(port->serial->dev, port->write_urb->pipe); + /* Start reading from the device */ port->read_urb->dev = port->serial->dev; retval = usb_submit_urb(port->read_urb, GFP_KERNEL); @@ -489,7 +501,8 @@ { dbg("%s - port %d", __FUNCTION__, port->number); - if (tty_hung_up_p(filp)) { + /* filp is NULL when called from usb_serial_disconnect */ + if (filp && (tty_hung_up_p(filp))) { return; } @@ -1145,6 +1158,9 @@ command_info = (struct whiteheat_command_private *)command_port->private; spin_lock_irqsave(&command_info->lock, flags); if (!command_info->port_running) { + /* Work around HCD bugs */ + usb_clear_halt(serial->dev, command_port->read_urb->pipe); + command_port->read_urb->dev = serial->dev; retval = usb_submit_urb(command_port->read_urb, GFP_KERNEL); if (retval) {