On Wed, Apr 29, 2009 at 12:00:58PM -0400, Alan Stern wrote: > On Wed, 29 Apr 2009, Alan Stern wrote: > > > Looks like the ftdi_sio driver doesn't use proper reference counting > > for its private data structure. Does this patch help? > > Oops, I forgot to initialize the kref. Try this patch instead. Yep, that did it! Very good, thanks a lot. Feel free to add my 'Tested-by' :) Daniel > Index: 2.6.30-rc3/drivers/usb/serial/ftdi_sio.c > =================================================================== > --- 2.6.30-rc3.orig/drivers/usb/serial/ftdi_sio.c > +++ 2.6.30-rc3/drivers/usb/serial/ftdi_sio.c > @@ -56,6 +56,7 @@ static __u16 vendor = FTDI_VID; > static __u16 product; > > struct ftdi_private { > + struct kref kref; > ftdi_chip_type_t chip_type; > /* type of device, either SIO or FT8U232AM */ > int baud_base; /* baud base clock for divisor setting */ > @@ -1352,6 +1353,7 @@ static int ftdi_sio_port_probe(struct us > return -ENOMEM; > } > > + kref_init(&priv->kref); > spin_lock_init(&priv->rx_lock); > spin_lock_init(&priv->tx_lock); > init_waitqueue_head(&priv->delta_msr_wait); > @@ -1468,6 +1470,13 @@ static void ftdi_shutdown(struct usb_ser > dbg("%s", __func__); > } > > +static void ftdi_sio_priv_release(struct kref *k) > +{ > + struct ftdi_private *priv = container_of(k, struct ftdi_private, kref); > + > + kfree(priv); > +} > + > static int ftdi_sio_port_remove(struct usb_serial_port *port) > { > struct ftdi_private *priv = usb_get_serial_port_data(port); > @@ -1482,7 +1491,7 @@ static int ftdi_sio_port_remove(struct u > > if (priv) { > usb_set_serial_port_data(port, NULL); > - kfree(priv); > + kref_put(&priv->kref, ftdi_sio_priv_release); > } > > return 0; > @@ -1547,7 +1556,8 @@ static int ftdi_open(struct tty_struct * > dev_err(&port->dev, > "%s - failed submitting read urb, error %d\n", > __func__, result); > - > + else > + kref_get(&priv->kref); > > return result; > } /* ftdi_open */ > @@ -1589,11 +1599,11 @@ static void ftdi_close(struct tty_struct > mutex_unlock(&port->serial->disc_mutex); > > /* cancel any scheduled reading */ > - cancel_delayed_work(&priv->rx_work); > - flush_scheduled_work(); > + cancel_delayed_work_sync(&priv->rx_work); > > /* shutdown our bulk read */ > usb_kill_urb(port->read_urb); > + kref_put(&priv->kref, ftdi_sio_priv_release); > } /* ftdi_close */ > > > -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html