These are things which I consider safe for 2.4.26. - printer.c update with removal of lock_kernel (me) - ftdi_sio forgets to unlink read URB (- forgot who) - mct_u232 backport from 2.6 (me) There were a couple of bugs in Fedora for that one, actually - datafab size - SCSI has one-off semantics (Alan Stern) - Two more US_SC_DEVICE, US_PR_DEVICE (Alan Stern) - Teach usbnet Zaurus SL-6000 (David Brownell) I didn't test this one, but it looks safe - w9968cf.c obvious bugs (Luca Risolia)
-- Pete diff -urN -X dontdiff linux-2.4.26-rc2/drivers/usb/printer.c linux-2.4.26-rc2-nip/drivers/usb/printer.c --- linux-2.4.26-rc2/drivers/usb/printer.c 2004-04-09 17:28:30.000000000 -0700 +++ linux-2.4.26-rc2-nip/drivers/usb/printer.c 2004-04-09 17:31:44.000000000 -0700 @@ -222,6 +222,7 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol); static int usblp_cache_device_id_string(struct usblp *usblp); +static DECLARE_MUTEX(usblp_sem); /* locks the existence of usblp's. */ /* * Functions for usblp control messages. @@ -332,7 +333,7 @@ if (minor < 0 || minor >= USBLP_MINORS) return -ENODEV; - lock_kernel(); + down (&usblp_sem); usblp = usblp_table[minor]; retval = -ENODEV; @@ -374,7 +375,7 @@ } } out: - unlock_kernel(); + up (&usblp_sem); return retval; } @@ -404,15 +405,13 @@ { struct usblp *usblp = file->private_data; - down (&usblp->sem); - lock_kernel(); + down (&usblp_sem); usblp->used = 0; if (usblp->present) { usblp_unlink_urbs(usblp); - up(&usblp->sem); } else /* finish cleanup from disconnect */ usblp_cleanup (usblp); - unlock_kernel(); + up (&usblp_sem); return 0; } @@ -1112,17 +1111,16 @@ BUG (); } + down (&usblp_sem); down (&usblp->sem); - lock_kernel(); usblp->present = 0; usblp_unlink_urbs(usblp); + up (&usblp->sem); if (!usblp->used) usblp_cleanup (usblp); - else /* cleanup later, on release */ - up (&usblp->sem); - unlock_kernel(); + up (&usblp_sem); } static struct usb_device_id usblp_ids [] = { diff -urN -X dontdiff linux-2.4.26-rc2/drivers/usb/serial/ftdi_sio.c linux-2.4.26-rc2-nip/drivers/usb/serial/ftdi_sio.c --- linux-2.4.26-rc2/drivers/usb/serial/ftdi_sio.c 2004-04-09 17:28:30.000000000 -0700 +++ linux-2.4.26-rc2-nip/drivers/usb/serial/ftdi_sio.c 2004-04-09 17:31:44.000000000 -0700 @@ -1343,15 +1343,16 @@ /* drop RTS */ if (set_rts(port, LOW) < 0) { err("Error from RTS LOW urb"); - } - /* shutdown our bulk read */ - if (port->read_urb) { - usb_unlink_urb (port->read_urb); } - /* unlink the running write urbs */ - - } /* Note change no line is hupcl is off */ + + /* shutdown our bulk read */ + if (port->read_urb) { + if(usb_unlink_urb (port->read_urb)<0) + err("Error unlinking urb"); + } + /* unlink the running write urbs */ + } /* if (serial->dev) */ diff -urN -X dontdiff linux-2.4.26-rc2/drivers/usb/serial/mct_u232.c linux-2.4.26-rc2-nip/drivers/usb/serial/mct_u232.c --- linux-2.4.26-rc2/drivers/usb/serial/mct_u232.c 2004-02-26 14:09:59.000000000 -0800 +++ linux-2.4.26-rc2-nip/drivers/usb/serial/mct_u232.c 2004-04-09 17:31:44.000000000 -0700 @@ -169,7 +169,8 @@ struct mct_u232_private { - unsigned long control_state; /* Modem Line Setting (TIOCM) */ + spinlock_t lock; + unsigned int control_state; /* Modem Line Setting (TIOCM) */ unsigned char last_lcr; /* Line Control Register */ unsigned char last_lsr; /* Line Status Register */ unsigned char last_msr; /* Modem Status Register */ @@ -181,25 +182,49 @@ #define WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */ +/* + * Later day 2.6.0-test kernels have new baud rates like B230400 which + * we do not know how to support. We ignore them for the moment. + * XXX Rate-limit the error message, it's user triggerable. + */ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) { if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID || serial->dev->descriptor.idProduct == MCT_U232_BELKIN_F5U109_PID) { switch (value) { - case 300: return 0x01; - case 600: return 0x02; /* this one not tested */ - case 1200: return 0x03; - case 2400: return 0x04; - case 4800: return 0x06; - case 9600: return 0x08; - case 19200: return 0x09; - case 38400: return 0x0a; - case 57600: return 0x0b; - case 115200: return 0x0c; - default: return -1; /* normally not reached */ + case B300: return 0x01; + case B600: return 0x02; /* this one not tested */ + case B1200: return 0x03; + case B2400: return 0x04; + case B4800: return 0x06; + case B9600: return 0x08; + case B19200: return 0x09; + case B38400: return 0x0a; + case B57600: return 0x0b; + case B115200: return 0x0c; + default: + err("MCT USB-RS232: unsupported baudrate request 0x%x," + " using default of B9600", value); + return 0x08; + } + } else { + switch (value) { + case B300: value = 300; + case B600: value = 600; + case B1200: value = 1200; + case B2400: value = 2400; + case B4800: value = 4800; + case B9600: value = 9600; + case B19200: value = 19200; + case B38400: value = 38400; + case B57600: value = 57600; + case B115200: value = 115200; + default: + err("MCT USB-RS232: unsupported baudrate request 0x%x," + " using default of B9600", value); + value = 9600; } + return 115200/value; } - else - return MCT_U232_BAUD_RATE(value); } static int mct_u232_set_baud_rate(struct usb_serial *serial, int value) @@ -207,7 +232,9 @@ unsigned int divisor; int rc; unsigned char zero_byte = 0; + divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value)); + rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), MCT_U232_SET_BAUD_RATE_REQUEST, MCT_U232_SET_REQUEST_TYPE, @@ -215,7 +242,7 @@ WDR_TIMEOUT); if (rc < 0) err("Set BAUD RATE %d failed (error = %d)", value, rc); - dbg("set_baud_rate: value: %d, divisor: 0x%x", value, divisor); + dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor); /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which always sends two extra USB 'device request' messages after the @@ -263,7 +290,7 @@ } /* mct_u232_set_line_ctrl */ static int mct_u232_set_modem_ctrl(struct usb_serial *serial, - unsigned long control_state) + unsigned int control_state) { int rc; unsigned char mcr = MCT_U232_MCR_NONE; @@ -280,7 +307,7 @@ WDR_TIMEOUT); if (rc < 0) err("Set MODEM CTRL 0x%x failed (error = %d)", mcr, rc); - dbg("set_modem_ctrl: state=0x%lx ==> mcr=0x%x", control_state, mcr); + dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr); return rc; } /* mct_u232_set_modem_ctrl */ @@ -301,7 +328,7 @@ return rc; } /* mct_u232_get_modem_stat */ -static void mct_u232_msr_to_state(unsigned long *control_state, unsigned char msr) +static void mct_u232_msr_to_state(unsigned int *control_state, unsigned char msr) { /* Translate Control Line states */ if (msr & MCT_U232_MSR_DSR) @@ -320,7 +347,7 @@ *control_state |= TIOCM_CD; else *control_state &= ~TIOCM_CD; - dbg("msr_to_state: msr=0x%x ==> state=0x%lx", msr, *control_state); + dbg("msr_to_state: msr=0x%x ==> state=0x%x", msr, *control_state); } /* mct_u232_msr_to_state */ /* @@ -330,20 +357,32 @@ static int mct_u232_startup (struct usb_serial *serial) { struct mct_u232_private *priv; + struct usb_serial_port *port, *rport; /* allocate the private data structure */ - serial->port->private = kmalloc(sizeof(struct mct_u232_private), - GFP_KERNEL); - if (!serial->port->private) - return (-1); /* error */ - priv = (struct mct_u232_private *)serial->port->private; + priv = kmalloc(sizeof(struct mct_u232_private), GFP_KERNEL); + if (!priv) + return -ENOMEM; /* set initial values for control structures */ + spin_lock_init(&priv->lock); priv->control_state = 0; priv->last_lsr = 0; priv->last_msr = 0; - + serial->port->private = priv; + init_waitqueue_head(&serial->port->write_wait); - + + /* Puh, that's dirty */ + port = &serial->port[0]; + rport = &serial->port[1]; + if (port->read_urb) { + /* No unlinking, it wasn't submitted yet. */ + usb_free_urb(port->read_urb); + } + port->read_urb = rport->interrupt_in_urb; + rport->interrupt_in_urb = NULL; + port->read_urb->context = port; + return (0); } /* mct_u232_startup */ @@ -354,7 +393,6 @@ dbg("%s", __FUNCTION__); - /* stop reads and writes on all ports */ for (i=0; i < serial->num_ports; ++i) { /* My special items, the standard routines free my urbs */ if (serial->port[i].private) @@ -367,6 +405,10 @@ struct usb_serial *serial = port->serial; struct mct_u232_private *priv = (struct mct_u232_private *)port->private; int retval = 0; + unsigned int control_state; + unsigned long flags; + unsigned char last_lcr; + unsigned char last_msr; dbg("%s port %d", __FUNCTION__, port->number); @@ -383,29 +425,27 @@ * sure if this is really necessary. But it should not harm * either. */ + spin_lock_irqsave(&priv->lock, flags); if (port->tty->termios->c_cflag & CBAUD) priv->control_state = TIOCM_DTR | TIOCM_RTS; else priv->control_state = 0; - mct_u232_set_modem_ctrl(serial, priv->control_state); priv->last_lcr = (MCT_U232_DATA_BITS_8 | MCT_U232_PARITY_NONE | MCT_U232_STOP_BITS_1); - mct_u232_set_line_ctrl(serial, priv->last_lcr); + control_state = priv->control_state; + last_lcr = priv->last_lcr; + spin_unlock_irqrestore(&priv->lock, flags); + mct_u232_set_modem_ctrl(serial, control_state); + mct_u232_set_line_ctrl(serial, last_lcr); /* Read modem status and update control state */ - mct_u232_get_modem_stat(serial, &priv->last_msr); + mct_u232_get_modem_stat(serial, &last_msr); + spin_lock_irqsave(&priv->lock, flags); + priv->last_msr = last_msr; mct_u232_msr_to_state(&priv->control_state, priv->last_msr); - - { - /* Puh, that's dirty */ - struct usb_serial_port *rport; - rport = &serial->port[1]; - rport->tty = port->tty; - rport->private = port->private; - port->read_urb = rport->interrupt_in_urb; - } + spin_unlock_irqrestore(&priv->lock, flags); port->read_urb->dev = port->serial->dev; retval = usb_submit_urb(port->read_urb); @@ -551,6 +591,7 @@ struct usb_serial *serial = port->serial; struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; + unsigned long flags; dbg("%s - port %d", __FUNCTION__, port->number); @@ -587,6 +628,7 @@ * The interrupt-in pipe signals exceptional conditions (modem line * signal changes and errors). data[0] holds MSR, data[1] holds LSR. */ + spin_lock_irqsave(&priv->lock, flags); priv->last_msr = data[MCT_U232_MSR_INDEX]; /* Record Control Line states */ @@ -617,6 +659,7 @@ } } #endif + spin_unlock_irqrestore(&priv->lock, flags); /* INT urbs are automatically re-submitted */ } /* mct_u232_read_int_callback */ @@ -628,125 +671,113 @@ struct usb_serial *serial = port->serial; struct mct_u232_private *priv = (struct mct_u232_private *)port->private; unsigned int iflag = port->tty->termios->c_iflag; - unsigned int old_iflag = old_termios->c_iflag; unsigned int cflag = port->tty->termios->c_cflag; unsigned int old_cflag = old_termios->c_cflag; - + unsigned long flags; + unsigned int control_state, new_state; + unsigned char last_lcr; + + /* get a local copy of the current port settings */ + spin_lock_irqsave(&priv->lock, flags); + control_state = priv->control_state; + spin_unlock_irqrestore(&priv->lock, flags); + last_lcr = 0; + /* - * Update baud rate + * Update baud rate. + * Do not attempt to cache old rates and skip settings, + * disconnects screw such tricks up completely. + * Premature optimization is the root of all evil. */ - if( (cflag & CBAUD) != (old_cflag & CBAUD) ) { - /* reassert DTR and (maybe) RTS on transition from B0 */ - if( (old_cflag & CBAUD) == B0 ) { - dbg("%s: baud was B0", __FUNCTION__); - priv->control_state |= TIOCM_DTR; - /* don't set RTS if using hardware flow control */ - if (!(old_cflag & CRTSCTS)) { - priv->control_state |= TIOCM_RTS; - } - mct_u232_set_modem_ctrl(serial, priv->control_state); - } - - switch(cflag & CBAUD) { - case B0: /* handled below */ - break; - case B300: mct_u232_set_baud_rate(serial, 300); - break; - case B600: mct_u232_set_baud_rate(serial, 600); - break; - case B1200: mct_u232_set_baud_rate(serial, 1200); - break; - case B2400: mct_u232_set_baud_rate(serial, 2400); - break; - case B4800: mct_u232_set_baud_rate(serial, 4800); - break; - case B9600: mct_u232_set_baud_rate(serial, 9600); - break; - case B19200: mct_u232_set_baud_rate(serial, 19200); - break; - case B38400: mct_u232_set_baud_rate(serial, 38400); - break; - case B57600: mct_u232_set_baud_rate(serial, 57600); - break; - case B115200: mct_u232_set_baud_rate(serial, 115200); - break; - default: err("MCT USB-RS232 converter: unsupported baudrate request, using default of 9600"); - mct_u232_set_baud_rate(serial, 9600); break; - } - if ((cflag & CBAUD) == B0 ) { - dbg("%s: baud is B0", __FUNCTION__); - /* Drop RTS and DTR */ - priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); - mct_u232_set_modem_ctrl(serial, priv->control_state); - } + + /* reassert DTR and (maybe) RTS on transition from B0 */ + if ((old_cflag & CBAUD) == B0) { + dbg("%s: baud was B0", __FUNCTION__); + control_state |= TIOCM_DTR; + /* don't set RTS if using hardware flow control */ + if (!(old_cflag & CRTSCTS)) { + control_state |= TIOCM_RTS; + } + mct_u232_set_modem_ctrl(serial, control_state); + } + + mct_u232_set_baud_rate(serial, cflag & CBAUD); + + if ((cflag & CBAUD) == B0 ) { + dbg("%s: baud is B0", __FUNCTION__); + /* Drop RTS and DTR */ + control_state &= ~(TIOCM_DTR | TIOCM_RTS); + mct_u232_set_modem_ctrl(serial, control_state); } /* * Update line control register (LCR) */ - if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD)) - || (cflag & CSIZE) != (old_cflag & CSIZE) - || (cflag & CSTOPB) != (old_cflag & CSTOPB) ) { - - priv->last_lcr = 0; + /* set the parity */ + if (cflag & PARENB) + last_lcr |= (cflag & PARODD) ? + MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN; + else + last_lcr |= MCT_U232_PARITY_NONE; - /* set the parity */ - if (cflag & PARENB) - priv->last_lcr |= (cflag & PARODD) ? - MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN; - else - priv->last_lcr |= MCT_U232_PARITY_NONE; + /* set the number of data bits */ + switch (cflag & CSIZE) { + case CS5: + last_lcr |= MCT_U232_DATA_BITS_5; break; + case CS6: + last_lcr |= MCT_U232_DATA_BITS_6; break; + case CS7: + last_lcr |= MCT_U232_DATA_BITS_7; break; + case CS8: + last_lcr |= MCT_U232_DATA_BITS_8; break; + default: + err("CSIZE was not CS5-CS8, using default of 8"); + last_lcr |= MCT_U232_DATA_BITS_8; + break; + } - /* set the number of data bits */ - switch (cflag & CSIZE) { - case CS5: - priv->last_lcr |= MCT_U232_DATA_BITS_5; break; - case CS6: - priv->last_lcr |= MCT_U232_DATA_BITS_6; break; - case CS7: - priv->last_lcr |= MCT_U232_DATA_BITS_7; break; - case CS8: - priv->last_lcr |= MCT_U232_DATA_BITS_8; break; - default: - err("CSIZE was not CS5-CS8, using default of 8"); - priv->last_lcr |= MCT_U232_DATA_BITS_8; - break; - } + /* set the number of stop bits */ + last_lcr |= (cflag & CSTOPB) ? + MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1; - /* set the number of stop bits */ - priv->last_lcr |= (cflag & CSTOPB) ? - MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1; + mct_u232_set_line_ctrl(serial, last_lcr); - mct_u232_set_line_ctrl(serial, priv->last_lcr); - } - /* * Set flow control: well, I do not really now how to handle DTR/RTS. * Just do what we have seen with SniffUSB on Win98. */ - if( (iflag & IXOFF) != (old_iflag & IXOFF) - || (iflag & IXON) != (old_iflag & IXON) - || (cflag & CRTSCTS) != (old_cflag & CRTSCTS) ) { - - /* Drop DTR/RTS if no flow control otherwise assert */ - if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS) ) - priv->control_state |= TIOCM_DTR | TIOCM_RTS; - else - priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); - mct_u232_set_modem_ctrl(serial, priv->control_state); + /* Drop DTR/RTS if no flow control otherwise assert */ + new_state = control_state; + if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS)) + new_state |= TIOCM_DTR | TIOCM_RTS; + else + new_state &= ~(TIOCM_DTR | TIOCM_RTS); + if (new_state != control_state) { + mct_u232_set_modem_ctrl(serial, control_state); + control_state = new_state; } -} /* mct_u232_set_termios */ + /* save off the modified port settings */ + spin_lock_irqsave(&priv->lock, flags); + priv->control_state = control_state; + priv->last_lcr = last_lcr; + spin_unlock_irqrestore(&priv->lock, flags); +} /* mct_u232_set_termios */ static void mct_u232_break_ctl( struct usb_serial_port *port, int break_state ) { struct usb_serial *serial = port->serial; struct mct_u232_private *priv = (struct mct_u232_private *)port->private; - unsigned char lcr = priv->last_lcr; + unsigned char lcr; + unsigned long flags; dbg("%sstate=%d", __FUNCTION__, break_state); + spin_lock_irqsave(&priv->lock, flags); + lcr = priv->last_lcr; + spin_unlock_irqrestore(&priv->lock, flags); + if (break_state) lcr |= MCT_U232_SET_BREAK; @@ -760,7 +791,8 @@ struct usb_serial *serial = port->serial; struct mct_u232_private *priv = (struct mct_u232_private *)port->private; int mask; - + unsigned long flags; + dbg("%scmd=0x%x", __FUNCTION__, cmd); /* Based on code from acm.c and others */ @@ -775,6 +807,7 @@ if (get_user(mask, (unsigned long *) arg)) return -EFAULT; + spin_lock_irqsave(&priv->lock, flags); if ((cmd == TIOCMSET) || (mask & TIOCM_RTS)) { /* RTS needs set */ if( ((cmd == TIOCMSET) && (mask & TIOCM_RTS)) || @@ -792,6 +825,7 @@ else priv->control_state &= ~TIOCM_DTR; } + spin_unlock_irqrestore(&priv->lock, flags); mct_u232_set_modem_ctrl(serial, priv->control_state); break; diff -urN -X dontdiff linux-2.4.26-rc2/drivers/usb/storage/datafab.c linux-2.4.26-rc2-nip/drivers/usb/storage/datafab.c --- linux-2.4.26-rc2/drivers/usb/storage/datafab.c 2003-06-13 07:51:37.000000000 -0700 +++ linux-2.4.26-rc2-nip/drivers/usb/storage/datafab.c 2004-04-09 17:31:44.000000000 -0700 @@ -695,20 +695,24 @@ } if (srb->cmnd[0] == READ_CAPACITY) { + unsigned int max_sector; + info->ssize = 0x200; // hard coded 512 byte sectors as per ATA spec rc = datafab_id_device(us, info); if (rc != USB_STOR_TRANSPORT_GOOD) return rc; - US_DEBUGP("datafab_transport: READ_CAPACITY: %ld sectors, %ld bytes per sector\n", + US_DEBUGP("datafab_transport: READ_CAPACITY: " + "%ld sectors, %ld bytes per sector\n", info->sectors, info->ssize); // build the reply // - ptr[0] = (info->sectors >> 24) & 0xFF; - ptr[1] = (info->sectors >> 16) & 0xFF; - ptr[2] = (info->sectors >> 8) & 0xFF; - ptr[3] = (info->sectors) & 0xFF; + max_sector = info->sectors - 1; + ptr[0] = (max_sector >> 24) & 0xFF; + ptr[1] = (max_sector >> 16) & 0xFF; + ptr[2] = (max_sector >> 8) & 0xFF; + ptr[3] = (max_sector) & 0xFF; ptr[4] = (info->ssize >> 24) & 0xFF; ptr[5] = (info->ssize >> 16) & 0xFF; diff -urN -X dontdiff linux-2.4.26-rc2/drivers/usb/storage/unusual_devs.h linux-2.4.26-rc2-nip/drivers/usb/storage/unusual_devs.h --- linux-2.4.26-rc2/drivers/usb/storage/unusual_devs.h 2004-04-09 17:28:30.000000000 -0700 +++ linux-2.4.26-rc2-nip/drivers/usb/storage/unusual_devs.h 2004-04-09 17:51:49.000000000 -0700 @@ -249,7 +249,7 @@ UNUSUAL_DEV( 0x054c, 0x0025, 0x0100, 0x0100, "Sony", "Memorystick NW-MS7", - US_SC_UFI, US_PR_CB, NULL, + US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_SINGLE_LUN ), #ifdef CONFIG_USB_STORAGE_ISD200 @@ -360,7 +360,7 @@ UNUSUAL_DEV( 0x05dc, 0xb002, 0x0000, 0x0113, "Lexar", "USB CF Reader", - US_SC_SCSI, US_PR_BULK, NULL, + US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), /* Reported by Carlos Villegas <[EMAIL PROTECTED]> diff -urN -X dontdiff linux-2.4.26-rc2/drivers/usb/usbnet.c linux-2.4.26-rc2-nip/drivers/usb/usbnet.c --- linux-2.4.26-rc2/drivers/usb/usbnet.c 2003-11-29 18:53:05.000000000 -0800 +++ linux-2.4.26-rc2-nip/drivers/usb/usbnet.c 2004-04-09 17:31:45.000000000 -0700 @@ -2594,7 +2594,11 @@ // Hawking UF200, TrendNet TU2-ET100 USB_DEVICE (0x07b8, 0x420a), .driver_info = (unsigned long) &hawking_uf200_info, -}, +}, { + // ATEN UC210T + USB_DEVICE (0x0557, 0x2009), + .driver_info = (unsigned long) &ax8817x_info, +}, #endif #ifdef CONFIG_USB_BELKIN @@ -2724,6 +2728,15 @@ .bInterfaceSubClass = 0x0a, .bInterfaceProtocol = 0x00, .driver_info = (unsigned long) &zaurus_pxa_info, +}, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x04DD, + .idProduct = 0x9032, /* SL-6000 */ + .bInterfaceClass = 0x02, + .bInterfaceSubClass = 0x0a, + .bInterfaceProtocol = 0x00, + .driver_info = (unsigned long) &zaurus_pxa_info, }, #endif diff -urN -X dontdiff linux-2.4.26-rc2/drivers/usb/w9968cf.c linux-2.4.26-rc2-nip/drivers/usb/w9968cf.c --- linux-2.4.26-rc2/drivers/usb/w9968cf.c 2004-02-26 14:09:59.000000000 -0800 +++ linux-2.4.26-rc2-nip/drivers/usb/w9968cf.c 2004-04-09 17:31:45.000000000 -0700 @@ -2943,7 +2943,7 @@ return -ENODEV; } - if (cam->users) { + while (cam->users) { DBG(2, "%s (/dev/video%d) has been already occupied by '%s'.", symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command) if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) { @@ -3632,7 +3632,7 @@ if (copy_from_user(&tuner, arg, sizeof(tuner))) return -EFAULT; - if (tuner.tuner != 0); + if (tuner.tuner != 0) return -EINVAL; strcpy(tuner.name, "no_tuner"); ------------------------------------------------------- This SF.Net email is sponsored by: IBM Linux Tutorials Free Linux tutorial presented by Daniel Robbins, President and CEO of GenToo technologies. Learn everything from fundamentals to system administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel