Am Dienstag, 23. Februar 2010 21:34:36 schrieb Mike Dunn: > From: Mike Dunn <mikedunn@xxxxxxxxxxx> > > Add support for the parallel port on the moschip MCS7715 device. The port > registers itself with the parport subsystem as a low-level driver. A separate > entry to the kernel configuration is added beneath that for the mos7720, to > avoid the need to link with the parport subsystem code for users who don't have > or don't want the parallel port. Only compatibility mode is currently supported > (no ECP/EPP). Tested with both moschip devices (7720 and 7715) on UP and SMP > hosts, including regression testing of serial port, concurrent operation of > serial and parallel ports, and various connect / disconnect scenarios. > > Signed-off-by: Mike Dunn <mikedunn@xxxxxxxxxxx> > --- > > Documentation/usb/usb-serial.txt | 16 + > drivers/usb/serial/Kconfig | 11 + > drivers/usb/serial/mos7720.c | 804 ++++++++++++++++++++++++++++++++++---- > 3 files changed, 747 insertions(+), 84 deletions(-) > > diff --git a/Documentation/usb/usb-serial.txt b/Documentation/usb/usb-serial.txt > index ff2c1ff..1c2894c 100644 > --- a/Documentation/usb/usb-serial.txt > +++ b/Documentation/usb/usb-serial.txt > @@ -435,6 +435,22 @@ Winchiphead CH341 Driver > For any questions or problems with this driver, please contact > frank@xxxxxxxxxxxxxxxxxxxxxxxxxxx > > +Moschip MCS7720, MCS7715 driver > + > + These chips are present in devices sold by various manufacturers. Known > + brands are Syba and Cables Unlimited. There may be others. The 7720 provides > + two serial ports, and the 7715 provides one serial and one standard PC > + parallel port. Support for the 7715's parallel port is enabled by a separate > + option, which will not appear unless parallel port support is first enabled at > + the top-level of the Device Drivers config menu. Currently only compatibility > + mode is supported on the parallel port (no ECP/EPP). > + > + * Read data byte from the specified device register. The data returned by the > + * device is embedded in the value field of the setup packet. > + */ > +static int read_parport_reg(struct mos7715_parport *mos_parport, > + enum mos_regs reg, __u8 *data) > +{ > + struct usb_device *usbdev = mos_parport->serial->dev; > + unsigned int pipe = usb_rcvctrlpipe(usbdev, 0); > + __u8 request = (__u8)0x0d; > + __u8 requesttype = (__u8)0xc0; > + __u16 value = get_reg_value(reg); > + __u16 index = get_reg_index(reg); > + __u16 size = 1; > + int status = usb_control_msg(usbdev, pipe, request, requesttype, value, > + index, data, size, MOS_WDR_TIMEOUT); > + if (status < 0) > + dev_err(&usbdev->dev, > + "mos7720: usb_control_msg() failed: %d", status); > + return status; > +} Where is this data corrected for endianness? > @@ -1685,12 +2286,47 @@ static void mos7720_release(struct usb_serial *serial) > { > int i; > > +#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT > + /* close the parallel port */ > + > + if (le16_to_cpu(serial->dev->descriptor.idProduct) > + == MOSCHIP_DEVICE_ID_7715) { > + struct urbtracker *urbtrack; > + unsigned long flags; > + struct mos7715_parport *mos_parport = > + usb_get_serial_data(serial); > + > + /* prevent NULL ptr dereference in port callbacks */ > + spin_lock(&release_lock); > + mos_parport->pp->private_data = NULL; > + spin_unlock(&release_lock); > + > + /* wait for synchronous usb calls to return */ > + if (mos_parport->msg_pending) > + wait_for_completion_timeout(&mos_parport->syncmsg_compl, > + MOS_WDR_TIMEOUT); > + > + parport_remove_port(mos_parport->pp); > + usb_set_serial_data(serial, NULL); > + mos_parport->serial = NULL; > + > + /* if tasklet currently scheduled, wait for it to complete */ > + tasklet_kill(&mos_parport->urb_tasklet); > + > + /* unlink any urbs sent by the tasklet */ > + spin_lock_irqsave(&mos_parport->listlock, flags); > + list_for_each_entry(urbtrack, > + &mos_parport->active_urbs, > + urblist_entry) > + usb_unlink_urb(urbtrack->urb); > + spin_unlock_irqrestore(&mos_parport->listlock, flags); > + > + kref_put(&mos_parport->ref_count, destroy_mos_parport); usb_unlink_urb() is asynchronous. What makes sure that the URBs not finish after destroy_mos_parport() has freed memory they look at? Regards Oliver -- 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