Skip to content

Commit

Permalink
rt2x00: Allow dynamic addition of PCI/USB IDs.
Browse files Browse the repository at this point in the history
Both USB and PCI drivers allow a system administrator to dynamically add
USB/PCI IDs to the device table that a driver supports via the
/sys/bus/{usb,pci,pci_express}/drivers/<driver-name>/new_id files.

However, for the rt2x00 drivers using this method currently crashes the
system with a NULL pointer failure.

This is due to the set-up of rt2x00 where the probe functions require a
rt2x00_ops structure in the driver_info field of the probed device. As
this field is empty for the dynamically added devices this fails for
these devices.

Fix this by introducing driver-specific probe wrappers that do nothing
but calling the bus-specific probe functions with the rt2x00_ops structure
as an argument, rather than depending on the driver_info field.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Gertjan van Wingerde authored and John W. Linville committed Apr 19, 2011
1 parent ce2919c commit e01ae27
Show file tree
Hide file tree
Showing 11 changed files with 404 additions and 369 deletions.
11 changes: 9 additions & 2 deletions drivers/net/wireless/rt2x00/rt2400pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1802,21 +1802,28 @@ static const struct rt2x00_ops rt2400pci_ops = {
* RT2400pci module information.
*/
static DEFINE_PCI_DEVICE_TABLE(rt2400pci_device_table) = {
{ PCI_DEVICE(0x1814, 0x0101), PCI_DEVICE_DATA(&rt2400pci_ops) },
{ PCI_DEVICE(0x1814, 0x0101) },
{ 0, }
};


MODULE_AUTHOR(DRV_PROJECT);
MODULE_VERSION(DRV_VERSION);
MODULE_DESCRIPTION("Ralink RT2400 PCI & PCMCIA Wireless LAN driver.");
MODULE_SUPPORTED_DEVICE("Ralink RT2460 PCI & PCMCIA chipset based cards");
MODULE_DEVICE_TABLE(pci, rt2400pci_device_table);
MODULE_LICENSE("GPL");

static int rt2400pci_probe(struct pci_dev *pci_dev,
const struct pci_device_id *id)
{
return rt2x00pci_probe(pci_dev, &rt2400pci_ops);
}

static struct pci_driver rt2400pci_driver = {
.name = KBUILD_MODNAME,
.id_table = rt2400pci_device_table,
.probe = rt2x00pci_probe,
.probe = rt2400pci_probe,
.remove = __devexit_p(rt2x00pci_remove),
.suspend = rt2x00pci_suspend,
.resume = rt2x00pci_resume,
Expand Down
10 changes: 8 additions & 2 deletions drivers/net/wireless/rt2x00/rt2500pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2095,7 +2095,7 @@ static const struct rt2x00_ops rt2500pci_ops = {
* RT2500pci module information.
*/
static DEFINE_PCI_DEVICE_TABLE(rt2500pci_device_table) = {
{ PCI_DEVICE(0x1814, 0x0201), PCI_DEVICE_DATA(&rt2500pci_ops) },
{ PCI_DEVICE(0x1814, 0x0201) },
{ 0, }
};

Expand All @@ -2106,10 +2106,16 @@ MODULE_SUPPORTED_DEVICE("Ralink RT2560 PCI & PCMCIA chipset based cards");
MODULE_DEVICE_TABLE(pci, rt2500pci_device_table);
MODULE_LICENSE("GPL");

static int rt2500pci_probe(struct pci_dev *pci_dev,
const struct pci_device_id *id)
{
return rt2x00pci_probe(pci_dev, &rt2500pci_ops);
}

static struct pci_driver rt2500pci_driver = {
.name = KBUILD_MODNAME,
.id_table = rt2500pci_device_table,
.probe = rt2x00pci_probe,
.probe = rt2500pci_probe,
.remove = __devexit_p(rt2x00pci_remove),
.suspend = rt2x00pci_suspend,
.resume = rt2x00pci_resume,
Expand Down
70 changes: 38 additions & 32 deletions drivers/net/wireless/rt2x00/rt2500usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1904,54 +1904,54 @@ static const struct rt2x00_ops rt2500usb_ops = {
*/
static struct usb_device_id rt2500usb_device_table[] = {
/* ASUS */
{ USB_DEVICE(0x0b05, 0x1706), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0b05, 0x1707), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0b05, 0x1706) },
{ USB_DEVICE(0x0b05, 0x1707) },
/* Belkin */
{ USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x050d, 0x7051), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x050d, 0x7050) },
{ USB_DEVICE(0x050d, 0x7051) },
/* Cisco Systems */
{ USB_DEVICE(0x13b1, 0x000d), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x13b1, 0x0011), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x13b1, 0x001a), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x13b1, 0x000d) },
{ USB_DEVICE(0x13b1, 0x0011) },
{ USB_DEVICE(0x13b1, 0x001a) },
/* Conceptronic */
{ USB_DEVICE(0x14b2, 0x3c02), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x14b2, 0x3c02) },
/* D-LINK */
{ USB_DEVICE(0x2001, 0x3c00), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x2001, 0x3c00) },
/* Gigabyte */
{ USB_DEVICE(0x1044, 0x8001), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x1044, 0x8007), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x1044, 0x8001) },
{ USB_DEVICE(0x1044, 0x8007) },
/* Hercules */
{ USB_DEVICE(0x06f8, 0xe000), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x06f8, 0xe000) },
/* Melco */
{ USB_DEVICE(0x0411, 0x005e), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0411, 0x0066), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0411, 0x0067), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0411, 0x008b), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0411, 0x0097), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0411, 0x005e) },
{ USB_DEVICE(0x0411, 0x0066) },
{ USB_DEVICE(0x0411, 0x0067) },
{ USB_DEVICE(0x0411, 0x008b) },
{ USB_DEVICE(0x0411, 0x0097) },
/* MSI */
{ USB_DEVICE(0x0db0, 0x6861), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0db0, 0x6865), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0db0, 0x6869), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0db0, 0x6861) },
{ USB_DEVICE(0x0db0, 0x6865) },
{ USB_DEVICE(0x0db0, 0x6869) },
/* Ralink */
{ USB_DEVICE(0x148f, 0x1706), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x148f, 0x2570), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x148f, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x148f, 0x1706) },
{ USB_DEVICE(0x148f, 0x2570) },
{ USB_DEVICE(0x148f, 0x9020) },
/* Sagem */
{ USB_DEVICE(0x079b, 0x004b), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x079b, 0x004b) },
/* Siemens */
{ USB_DEVICE(0x0681, 0x3c06), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0681, 0x3c06) },
/* SMC */
{ USB_DEVICE(0x0707, 0xee13), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0707, 0xee13) },
/* Spairon */
{ USB_DEVICE(0x114b, 0x0110), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x114b, 0x0110) },
/* SURECOM */
{ USB_DEVICE(0x0769, 0x11f3), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0769, 0x11f3) },
/* Trust */
{ USB_DEVICE(0x0eb0, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0eb0, 0x9020) },
/* VTech */
{ USB_DEVICE(0x0f88, 0x3012), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0f88, 0x3012) },
/* Zinwell */
{ USB_DEVICE(0x5a57, 0x0260), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x5a57, 0x0260) },
{ 0, }
};

Expand All @@ -1962,10 +1962,16 @@ MODULE_SUPPORTED_DEVICE("Ralink RT2570 USB chipset based cards");
MODULE_DEVICE_TABLE(usb, rt2500usb_device_table);
MODULE_LICENSE("GPL");

static int rt2500usb_probe(struct usb_interface *usb_intf,
const struct usb_device_id *id)
{
return rt2x00usb_probe(usb_intf, &rt2500usb_ops);
}

static struct usb_driver rt2500usb_driver = {
.name = KBUILD_MODNAME,
.id_table = rt2500usb_device_table,
.probe = rt2x00usb_probe,
.probe = rt2500usb_probe,
.disconnect = rt2x00usb_disconnect,
.suspend = rt2x00usb_suspend,
.resume = rt2x00usb_resume,
Expand Down
58 changes: 32 additions & 26 deletions drivers/net/wireless/rt2x00/rt2800pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1117,36 +1117,36 @@ static const struct rt2x00_ops rt2800pci_ops = {
*/
#ifdef CONFIG_PCI
static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
{ PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x0701), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x0781), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x3090), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x3091), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7708), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7727), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7728), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7738), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7748), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7758), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7768), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1462, 0x891a), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x0601) },
{ PCI_DEVICE(0x1814, 0x0681) },
{ PCI_DEVICE(0x1814, 0x0701) },
{ PCI_DEVICE(0x1814, 0x0781) },
{ PCI_DEVICE(0x1814, 0x3090) },
{ PCI_DEVICE(0x1814, 0x3091) },
{ PCI_DEVICE(0x1814, 0x3092) },
{ PCI_DEVICE(0x1432, 0x7708) },
{ PCI_DEVICE(0x1432, 0x7727) },
{ PCI_DEVICE(0x1432, 0x7728) },
{ PCI_DEVICE(0x1432, 0x7738) },
{ PCI_DEVICE(0x1432, 0x7748) },
{ PCI_DEVICE(0x1432, 0x7758) },
{ PCI_DEVICE(0x1432, 0x7768) },
{ PCI_DEVICE(0x1462, 0x891a) },
{ PCI_DEVICE(0x1a3b, 0x1059) },
#ifdef CONFIG_RT2800PCI_RT33XX
{ PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x3390) },
#endif
#ifdef CONFIG_RT2800PCI_RT35XX
{ PCI_DEVICE(0x1432, 0x7711), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7722), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x3593), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7711) },
{ PCI_DEVICE(0x1432, 0x7722) },
{ PCI_DEVICE(0x1814, 0x3060) },
{ PCI_DEVICE(0x1814, 0x3062) },
{ PCI_DEVICE(0x1814, 0x3562) },
{ PCI_DEVICE(0x1814, 0x3592) },
{ PCI_DEVICE(0x1814, 0x3593) },
#endif
#ifdef CONFIG_RT2800PCI_RT53XX
{ PCI_DEVICE(0x1814, 0x5390), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x5390) },
#endif
{ 0, }
};
Expand Down Expand Up @@ -1182,10 +1182,16 @@ static struct platform_driver rt2800soc_driver = {
#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */

#ifdef CONFIG_PCI
static int rt2800pci_probe(struct pci_dev *pci_dev,
const struct pci_device_id *id)
{
return rt2x00pci_probe(pci_dev, &rt2800pci_ops);
}

static struct pci_driver rt2800pci_driver = {
.name = KBUILD_MODNAME,
.id_table = rt2800pci_device_table,
.probe = rt2x00pci_probe,
.probe = rt2800pci_probe,
.remove = __devexit_p(rt2x00pci_remove),
.suspend = rt2x00pci_suspend,
.resume = rt2x00pci_resume,
Expand Down
Loading

0 comments on commit e01ae27

Please sign in to comment.