USB: serial: mos7840: clean up device-type handling
The current device-type detection is fragile and can't really be relied upon. Instead of sprinkling device-id conditionals throughout the driver, let's use the device-id table to encode the number of ports and whether the device has a driver-controlled activity LED (MCS7810). Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Johan Hovold <johan@kernel.org>
This commit is contained in:
parent
92fe35fb9c
commit
375cb533c0
|
@ -89,17 +89,10 @@
|
||||||
/* For higher baud Rates use TIOCEXBAUD */
|
/* For higher baud Rates use TIOCEXBAUD */
|
||||||
#define TIOCEXBAUD 0x5462
|
#define TIOCEXBAUD 0x5462
|
||||||
|
|
||||||
/* vendor id and device id defines */
|
/*
|
||||||
|
* Vendor id and device id defines
|
||||||
/* The native mos7840/7820 component */
|
*
|
||||||
#define USB_VENDOR_ID_MOSCHIP 0x9710
|
* NOTE: Do not add new defines, add entries directly to the id_table instead.
|
||||||
#define MOSCHIP_DEVICE_ID_7840 0x7840
|
|
||||||
#define MOSCHIP_DEVICE_ID_7843 0x7843
|
|
||||||
#define MOSCHIP_DEVICE_ID_7820 0x7820
|
|
||||||
#define MOSCHIP_DEVICE_ID_7810 0x7810
|
|
||||||
/* The native component can have its vendor/device id's overridden
|
|
||||||
* in vendor-specific implementations. Such devices can be handled
|
|
||||||
* by making a change here, in id_table.
|
|
||||||
*/
|
*/
|
||||||
#define USB_VENDOR_ID_BANDB 0x0856
|
#define USB_VENDOR_ID_BANDB 0x0856
|
||||||
#define BANDB_DEVICE_ID_USO9ML2_2 0xAC22
|
#define BANDB_DEVICE_ID_USO9ML2_2 0xAC22
|
||||||
|
@ -116,18 +109,6 @@
|
||||||
#define BANDB_DEVICE_ID_USOPTL4_4P 0xBC03
|
#define BANDB_DEVICE_ID_USOPTL4_4P 0xBC03
|
||||||
#define BANDB_DEVICE_ID_USOPTL2_4 0xAC24
|
#define BANDB_DEVICE_ID_USOPTL2_4 0xAC24
|
||||||
|
|
||||||
/* This driver also supports
|
|
||||||
* ATEN UC2324 device using Moschip MCS7840
|
|
||||||
* ATEN UC2322 device using Moschip MCS7820
|
|
||||||
* MOXA UPort 2210 device using Moschip MCS7820
|
|
||||||
*/
|
|
||||||
#define USB_VENDOR_ID_ATENINTL 0x0557
|
|
||||||
#define ATENINTL_DEVICE_ID_UC2324 0x2011
|
|
||||||
#define ATENINTL_DEVICE_ID_UC2322 0x7820
|
|
||||||
|
|
||||||
#define USB_VENDOR_ID_MOXA 0x110a
|
|
||||||
#define MOXA_DEVICE_ID_2210 0x2210
|
|
||||||
|
|
||||||
/* Interrupt Routine Defines */
|
/* Interrupt Routine Defines */
|
||||||
|
|
||||||
#define SERIAL_IIR_RLS 0x06
|
#define SERIAL_IIR_RLS 0x06
|
||||||
|
@ -179,27 +160,34 @@ enum mos7840_flag {
|
||||||
MOS7840_FLAG_LED_BUSY,
|
MOS7840_FLAG_LED_BUSY,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MCS_PORT_MASK GENMASK(2, 0)
|
||||||
|
#define MCS_PORTS(nr) ((nr) & MCS_PORT_MASK)
|
||||||
|
#define MCS_LED BIT(3)
|
||||||
|
|
||||||
|
#define MCS_DEVICE(vid, pid, flags) \
|
||||||
|
USB_DEVICE((vid), (pid)), .driver_info = (flags)
|
||||||
|
|
||||||
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)},
|
{ MCS_DEVICE(0x0557, 0x2011, MCS_PORTS(4)) }, /* ATEN UC2324 */
|
||||||
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7843)},
|
{ MCS_DEVICE(0x0557, 0x7820, MCS_PORTS(2)) }, /* ATEN UC2322 */
|
||||||
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
|
{ MCS_DEVICE(0x110a, 0x2210, MCS_PORTS(2)) }, /* Moxa UPort 2210 */
|
||||||
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7810)},
|
{ MCS_DEVICE(0x9710, 0x7810, MCS_PORTS(1) | MCS_LED) }, /* ASIX MCS7810 */
|
||||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
|
{ MCS_DEVICE(0x9710, 0x7820, MCS_PORTS(2)) }, /* MosChip MCS7820 */
|
||||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)},
|
{ MCS_DEVICE(0x9710, 0x7840, MCS_PORTS(4)) }, /* MosChip MCS7840 */
|
||||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
|
{ MCS_DEVICE(0x9710, 0x7843, MCS_PORTS(3)) }, /* ASIX MCS7840 3 port */
|
||||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P)},
|
{ USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2) },
|
||||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)},
|
{ USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P) },
|
||||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)},
|
{ USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4) },
|
||||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)},
|
{ USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P) },
|
||||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)},
|
{ USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2) },
|
||||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
|
{ USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4) },
|
||||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)},
|
{ USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2) },
|
||||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
|
{ USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4) },
|
||||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)},
|
{ USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2) },
|
||||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)},
|
{ USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P) },
|
||||||
{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
|
{ USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4) },
|
||||||
{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)},
|
{ USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P) },
|
||||||
{USB_DEVICE(USB_VENDOR_ID_MOXA, MOXA_DEVICE_ID_2210)},
|
{ USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4) },
|
||||||
{} /* terminating entry */
|
{} /* terminating entry */
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(usb, id_table);
|
MODULE_DEVICE_TABLE(usb, id_table);
|
||||||
|
@ -2024,22 +2012,12 @@ static int mos7810_check(struct usb_serial *serial)
|
||||||
static int mos7840_probe(struct usb_serial *serial,
|
static int mos7840_probe(struct usb_serial *serial,
|
||||||
const struct usb_device_id *id)
|
const struct usb_device_id *id)
|
||||||
{
|
{
|
||||||
u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
|
unsigned long device_flags = id->driver_info;
|
||||||
u16 vid = le16_to_cpu(serial->dev->descriptor.idVendor);
|
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
int device_type;
|
|
||||||
|
|
||||||
if (product == MOSCHIP_DEVICE_ID_7810 ||
|
/* Skip device-type detection if we already have device flags. */
|
||||||
product == MOSCHIP_DEVICE_ID_7820 ||
|
if (device_flags)
|
||||||
product == MOSCHIP_DEVICE_ID_7843) {
|
|
||||||
device_type = product;
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
if (vid == USB_VENDOR_ID_MOXA && product == MOXA_DEVICE_ID_2210) {
|
|
||||||
device_type = MOSCHIP_DEVICE_ID_7820;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = kzalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
|
buf = kzalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
|
@ -2051,15 +2029,15 @@ static int mos7840_probe(struct usb_serial *serial,
|
||||||
|
|
||||||
/* For a MCS7840 device GPIO0 must be set to 1 */
|
/* For a MCS7840 device GPIO0 must be set to 1 */
|
||||||
if (buf[0] & 0x01)
|
if (buf[0] & 0x01)
|
||||||
device_type = MOSCHIP_DEVICE_ID_7840;
|
device_flags = MCS_PORTS(4);
|
||||||
else if (mos7810_check(serial))
|
else if (mos7810_check(serial))
|
||||||
device_type = MOSCHIP_DEVICE_ID_7810;
|
device_flags = MCS_PORTS(1) | MCS_LED;
|
||||||
else
|
else
|
||||||
device_type = MOSCHIP_DEVICE_ID_7820;
|
device_flags = MCS_PORTS(2);
|
||||||
|
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
out:
|
out:
|
||||||
usb_set_serial_data(serial, (void *)(unsigned long)device_type);
|
usb_set_serial_data(serial, (void *)device_flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2067,19 +2045,10 @@ out:
|
||||||
static int mos7840_calc_num_ports(struct usb_serial *serial,
|
static int mos7840_calc_num_ports(struct usb_serial *serial,
|
||||||
struct usb_serial_endpoints *epds)
|
struct usb_serial_endpoints *epds)
|
||||||
{
|
{
|
||||||
int device_type = (unsigned long)usb_get_serial_data(serial);
|
unsigned long device_flags = (unsigned long)usb_get_serial_data(serial);
|
||||||
int num_ports;
|
int num_ports = MCS_PORTS(device_flags);
|
||||||
|
|
||||||
if (device_type == MOSCHIP_DEVICE_ID_7843)
|
if (num_ports == 0 || num_ports > 4)
|
||||||
num_ports = 3;
|
|
||||||
else
|
|
||||||
num_ports = (device_type >> 4) & 0x000F;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* num_ports is currently never zero as device_type is one of
|
|
||||||
* MOSCHIP_DEVICE_ID_78{1,2,4}0.
|
|
||||||
*/
|
|
||||||
if (num_ports == 0)
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (epds->num_bulk_in < num_ports || epds->num_bulk_out < num_ports) {
|
if (epds->num_bulk_in < num_ports || epds->num_bulk_out < num_ports) {
|
||||||
|
@ -2093,7 +2062,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 = (unsigned long)usb_get_serial_data(serial);
|
unsigned long device_flags = (unsigned long)usb_get_serial_data(serial);
|
||||||
struct moschip_port *mos7840_port;
|
struct moschip_port *mos7840_port;
|
||||||
int status;
|
int status;
|
||||||
int pnum;
|
int pnum;
|
||||||
|
@ -2255,12 +2224,10 @@ static int mos7840_port_probe(struct usb_serial_port *port)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
mos7840_port->has_led = false;
|
mos7840_port->has_led = device_flags & MCS_LED;
|
||||||
|
|
||||||
/* Initialize LED timers */
|
/* Initialize LED timers */
|
||||||
if (device_type == MOSCHIP_DEVICE_ID_7810) {
|
if (mos7840_port->has_led) {
|
||||||
mos7840_port->has_led = true;
|
|
||||||
|
|
||||||
mos7840_port->led_urb = usb_alloc_urb(0, GFP_KERNEL);
|
mos7840_port->led_urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||||
mos7840_port->led_dr = kmalloc(sizeof(*mos7840_port->led_dr),
|
mos7840_port->led_dr = kmalloc(sizeof(*mos7840_port->led_dr),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
|
|
Loading…
Reference in New Issue