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:
committed by
Greg Kroah-Hartman
parent
d8a083cc74
commit
40c24f2893
@@ -187,8 +187,6 @@ enum mos7840_flag {
|
|||||||
MOS7840_FLAG_CTRL_BUSY,
|
MOS7840_FLAG_CTRL_BUSY,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int device_type;
|
|
||||||
|
|
||||||
static const struct usb_device_id id_table[] = {
|
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_7840)},
|
||||||
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
|
{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 */
|
/* 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
|
* mos7840_open
|
||||||
@@ -2201,38 +2187,48 @@ static int mos7810_check(struct usb_serial *serial)
|
|||||||
return 0;
|
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;
|
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);
|
buf = kzalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
|
||||||
if (buf) {
|
if (!buf)
|
||||||
usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
return -ENOMEM;
|
||||||
|
|
||||||
|
usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
||||||
MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, buf,
|
MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, buf,
|
||||||
VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
|
VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
|
||||||
data = *buf;
|
|
||||||
kfree(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7810 ||
|
/* For a MCS7840 device GPIO0 must be set to 1 */
|
||||||
serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7820) {
|
if (buf[0] & 0x01)
|
||||||
device_type = serial->dev->descriptor.idProduct;
|
device_type = MOSCHIP_DEVICE_ID_7840;
|
||||||
} else {
|
else if (mos7810_check(serial))
|
||||||
/* For a MCS7840 device GPIO0 must be set to 1 */
|
device_type = MOSCHIP_DEVICE_ID_7810;
|
||||||
if ((data & 0x01) == 1)
|
else
|
||||||
device_type = MOSCHIP_DEVICE_ID_7840;
|
device_type = MOSCHIP_DEVICE_ID_7820;
|
||||||
else if (mos7810_check(serial))
|
|
||||||
device_type = MOSCHIP_DEVICE_ID_7810;
|
kfree(buf);
|
||||||
else
|
out:
|
||||||
device_type = MOSCHIP_DEVICE_ID_7820;
|
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;
|
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;
|
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)
|
static int mos7840_port_probe(struct usb_serial_port *port)
|
||||||
{
|
{
|
||||||
struct usb_serial *serial = port->serial;
|
struct usb_serial *serial = port->serial;
|
||||||
|
int device_type = (int)usb_get_serial_data(serial);
|
||||||
struct moschip_port *mos7840_port;
|
struct moschip_port *mos7840_port;
|
||||||
int status;
|
int status;
|
||||||
int pnum;
|
int pnum;
|
||||||
@@ -2496,9 +2493,7 @@ static struct usb_serial_driver moschip7840_4port_device = {
|
|||||||
.throttle = mos7840_throttle,
|
.throttle = mos7840_throttle,
|
||||||
.unthrottle = mos7840_unthrottle,
|
.unthrottle = mos7840_unthrottle,
|
||||||
.calc_num_ports = mos7840_calc_num_ports,
|
.calc_num_ports = mos7840_calc_num_ports,
|
||||||
#ifdef MCSSerialProbe
|
.probe = mos7840_probe,
|
||||||
.probe = mos7840_serial_probe,
|
|
||||||
#endif
|
|
||||||
.ioctl = mos7840_ioctl,
|
.ioctl = mos7840_ioctl,
|
||||||
.set_termios = mos7840_set_termios,
|
.set_termios = mos7840_set_termios,
|
||||||
.break_ctl = mos7840_break,
|
.break_ctl = mos7840_break,
|
||||||
|
Reference in New Issue
Block a user