USB: mos7840: fix device-type detection
Fix race in device-type detection introduced by commit 0eafe4de
("USB:
serial: mos7840: add support for MCS7810 devices") which used a static
variable to hold the device type.
Move type detection to probe and use serial data to store the device
type.
Cc: stable@vger.kernel.org
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
d8a083cc74
commit
40c24f2893
|
@ -187,8 +187,6 @@ enum mos7840_flag {
|
|||
MOS7840_FLAG_CTRL_BUSY,
|
||||
};
|
||||
|
||||
static int device_type;
|
||||
|
||||
static const struct usb_device_id id_table[] = {
|
||||
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
|
||||
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
|
||||
|
@ -830,18 +828,6 @@ static void mos7840_bulk_out_data_callback(struct urb *urb)
|
|||
/************************************************************************/
|
||||
/* D R I V E R T T Y I N T E R F A C E F U N C T I O N S */
|
||||
/************************************************************************/
|
||||
#ifdef MCSSerialProbe
|
||||
static int mos7840_serial_probe(struct usb_serial *serial,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
|
||||
/*need to implement the mode_reg reading and updating\
|
||||
structures usb_serial_ device_type\
|
||||
(i.e num_ports, num_bulkin,bulkout etc) */
|
||||
/* Also we can update the changes attach */
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* mos7840_open
|
||||
|
@ -2201,38 +2187,48 @@ static int mos7810_check(struct usb_serial *serial)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mos7840_calc_num_ports(struct usb_serial *serial)
|
||||
static int mos7840_probe(struct usb_serial *serial,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
__u16 data = 0x00;
|
||||
u16 product = serial->dev->descriptor.idProduct;
|
||||
u8 *buf;
|
||||
int mos7840_num_ports;
|
||||
int device_type;
|
||||
|
||||
if (product == MOSCHIP_DEVICE_ID_7810 ||
|
||||
product == MOSCHIP_DEVICE_ID_7820) {
|
||||
device_type = product;
|
||||
goto out;
|
||||
}
|
||||
|
||||
buf = kzalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
|
||||
if (buf) {
|
||||
usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
||||
MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, buf,
|
||||
VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
|
||||
data = *buf;
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
if (serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7810 ||
|
||||
serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7820) {
|
||||
device_type = serial->dev->descriptor.idProduct;
|
||||
} else {
|
||||
/* For a MCS7840 device GPIO0 must be set to 1 */
|
||||
if ((data & 0x01) == 1)
|
||||
device_type = MOSCHIP_DEVICE_ID_7840;
|
||||
else if (mos7810_check(serial))
|
||||
device_type = MOSCHIP_DEVICE_ID_7810;
|
||||
else
|
||||
device_type = MOSCHIP_DEVICE_ID_7820;
|
||||
}
|
||||
/* For a MCS7840 device GPIO0 must be set to 1 */
|
||||
if (buf[0] & 0x01)
|
||||
device_type = MOSCHIP_DEVICE_ID_7840;
|
||||
else if (mos7810_check(serial))
|
||||
device_type = MOSCHIP_DEVICE_ID_7810;
|
||||
else
|
||||
device_type = MOSCHIP_DEVICE_ID_7820;
|
||||
|
||||
kfree(buf);
|
||||
out:
|
||||
usb_set_serial_data(serial, (void *)device_type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mos7840_calc_num_ports(struct usb_serial *serial)
|
||||
{
|
||||
int device_type = (int)usb_get_serial_data(serial);
|
||||
int mos7840_num_ports;
|
||||
|
||||
mos7840_num_ports = (device_type >> 4) & 0x000F;
|
||||
serial->num_bulk_in = mos7840_num_ports;
|
||||
serial->num_bulk_out = mos7840_num_ports;
|
||||
serial->num_ports = mos7840_num_ports;
|
||||
|
||||
return mos7840_num_ports;
|
||||
}
|
||||
|
@ -2240,6 +2236,7 @@ static int mos7840_calc_num_ports(struct usb_serial *serial)
|
|||
static int mos7840_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
int device_type = (int)usb_get_serial_data(serial);
|
||||
struct moschip_port *mos7840_port;
|
||||
int status;
|
||||
int pnum;
|
||||
|
@ -2496,9 +2493,7 @@ static struct usb_serial_driver moschip7840_4port_device = {
|
|||
.throttle = mos7840_throttle,
|
||||
.unthrottle = mos7840_unthrottle,
|
||||
.calc_num_ports = mos7840_calc_num_ports,
|
||||
#ifdef MCSSerialProbe
|
||||
.probe = mos7840_serial_probe,
|
||||
#endif
|
||||
.probe = mos7840_probe,
|
||||
.ioctl = mos7840_ioctl,
|
||||
.set_termios = mos7840_set_termios,
|
||||
.break_ctl = mos7840_break,
|
||||
|
|
Loading…
Reference in New Issue