提交 1138c37b 编写于 作者: M Michal Schmidt 提交者: John W. Linville

[PATCH] airo: fix a race causing initialization failures

Matteo Croce reported Aironet initialization failures. They were caused by
a race in airo. airo finds a free interface name, then initializes the card
and finally registers the interface. Another device may get the same name
in the meantime.
The reason airo gets its name early is to use it in informative printks and
to name the resources it requests. The printks will be just fine without
the interface name and the resources can use the driver's name - that's
what other network drivers do anyway.
One of the talkative functions is setup_card(). It is called once before
registration and can be called later again. Let's have an empty dev->name
during the first call, so it doesn't print the ugly "airo(eth%d)" message.
Signed-off-by: NMichal Schmidt <mschmidt@redhat.com>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 1c2b7db8
...@@ -52,6 +52,8 @@ ...@@ -52,6 +52,8 @@
#include "airo.h" #include "airo.h"
#define DRV_NAME "airo"
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
static struct pci_device_id card_ids[] = { static struct pci_device_id card_ids[] = {
{ 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, }, { 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
...@@ -71,7 +73,7 @@ static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state); ...@@ -71,7 +73,7 @@ static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state);
static int airo_pci_resume(struct pci_dev *pdev); static int airo_pci_resume(struct pci_dev *pdev);
static struct pci_driver airo_driver = { static struct pci_driver airo_driver = {
.name = "airo", .name = DRV_NAME,
.id_table = card_ids, .id_table = card_ids,
.probe = airo_pci_probe, .probe = airo_pci_probe,
.remove = __devexit_p(airo_pci_remove), .remove = __devexit_p(airo_pci_remove),
...@@ -1250,7 +1252,7 @@ static int flashputbuf(struct airo_info *ai); ...@@ -1250,7 +1252,7 @@ static int flashputbuf(struct airo_info *ai);
static int flashrestart(struct airo_info *ai,struct net_device *dev); static int flashrestart(struct airo_info *ai,struct net_device *dev);
#define airo_print(type, name, fmt, args...) \ #define airo_print(type, name, fmt, args...) \
{ printk(type "airo(%s): " fmt "\n", name, ##args); } printk(type DRV_NAME "(%s): " fmt "\n", name, ##args)
#define airo_print_info(name, fmt, args...) \ #define airo_print_info(name, fmt, args...) \
airo_print(KERN_INFO, name, fmt, ##args) airo_print(KERN_INFO, name, fmt, ##args)
...@@ -2582,8 +2584,7 @@ static int mpi_init_descriptors (struct airo_info *ai) ...@@ -2582,8 +2584,7 @@ static int mpi_init_descriptors (struct airo_info *ai)
* 2) Map PCI memory for issueing commands. * 2) Map PCI memory for issueing commands.
* 3) Allocate memory (shared) to send and receive ethernet frames. * 3) Allocate memory (shared) to send and receive ethernet frames.
*/ */
static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci, static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci)
const char *name)
{ {
unsigned long mem_start, mem_len, aux_start, aux_len; unsigned long mem_start, mem_len, aux_start, aux_len;
int rc = -1; int rc = -1;
...@@ -2597,34 +2598,34 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci, ...@@ -2597,34 +2598,34 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
aux_start = pci_resource_start(pci, 2); aux_start = pci_resource_start(pci, 2);
aux_len = AUXMEMSIZE; aux_len = AUXMEMSIZE;
if (!request_mem_region(mem_start, mem_len, name)) { if (!request_mem_region(mem_start, mem_len, DRV_NAME)) {
airo_print_err(ai->dev->name, "Couldn't get region %x[%x] for %s", airo_print_err("", "Couldn't get region %x[%x]",
(int)mem_start, (int)mem_len, name); (int)mem_start, (int)mem_len);
goto out; goto out;
} }
if (!request_mem_region(aux_start, aux_len, name)) { if (!request_mem_region(aux_start, aux_len, DRV_NAME)) {
airo_print_err(ai->dev->name, "Couldn't get region %x[%x] for %s", airo_print_err("", "Couldn't get region %x[%x]",
(int)aux_start, (int)aux_len, name); (int)aux_start, (int)aux_len);
goto free_region1; goto free_region1;
} }
ai->pcimem = ioremap(mem_start, mem_len); ai->pcimem = ioremap(mem_start, mem_len);
if (!ai->pcimem) { if (!ai->pcimem) {
airo_print_err(ai->dev->name, "Couldn't map region %x[%x] for %s", airo_print_err("", "Couldn't map region %x[%x]",
(int)mem_start, (int)mem_len, name); (int)mem_start, (int)mem_len);
goto free_region2; goto free_region2;
} }
ai->pciaux = ioremap(aux_start, aux_len); ai->pciaux = ioremap(aux_start, aux_len);
if (!ai->pciaux) { if (!ai->pciaux) {
airo_print_err(ai->dev->name, "Couldn't map region %x[%x] for %s", airo_print_err("", "Couldn't map region %x[%x]",
(int)aux_start, (int)aux_len, name); (int)aux_start, (int)aux_len);
goto free_memmap; goto free_memmap;
} }
/* Reserve PKTSIZE for each fid and 2K for the Rids */ /* Reserve PKTSIZE for each fid and 2K for the Rids */
ai->shared = pci_alloc_consistent(pci, PCI_SHARED_LEN, &ai->shared_dma); ai->shared = pci_alloc_consistent(pci, PCI_SHARED_LEN, &ai->shared_dma);
if (!ai->shared) { if (!ai->shared) {
airo_print_err(ai->dev->name, "Couldn't alloc_consistent %d", airo_print_err("", "Couldn't alloc_consistent %d",
PCI_SHARED_LEN); PCI_SHARED_LEN);
goto free_auxmap; goto free_auxmap;
} }
...@@ -2770,7 +2771,7 @@ static int airo_networks_allocate(struct airo_info *ai) ...@@ -2770,7 +2771,7 @@ static int airo_networks_allocate(struct airo_info *ai)
kzalloc(AIRO_MAX_NETWORK_COUNT * sizeof(BSSListElement), kzalloc(AIRO_MAX_NETWORK_COUNT * sizeof(BSSListElement),
GFP_KERNEL); GFP_KERNEL);
if (!ai->networks) { if (!ai->networks) {
airo_print_warn(ai->dev->name, "Out of memory allocating beacons"); airo_print_warn("", "Out of memory allocating beacons");
return -ENOMEM; return -ENOMEM;
} }
...@@ -2798,7 +2799,6 @@ static int airo_test_wpa_capable(struct airo_info *ai) ...@@ -2798,7 +2799,6 @@ static int airo_test_wpa_capable(struct airo_info *ai)
{ {
int status; int status;
CapabilityRid cap_rid; CapabilityRid cap_rid;
const char *name = ai->dev->name;
status = readCapabilityRid(ai, &cap_rid, 1); status = readCapabilityRid(ai, &cap_rid, 1);
if (status != SUCCESS) return 0; if (status != SUCCESS) return 0;
...@@ -2806,12 +2806,12 @@ static int airo_test_wpa_capable(struct airo_info *ai) ...@@ -2806,12 +2806,12 @@ static int airo_test_wpa_capable(struct airo_info *ai)
/* Only firmware versions 5.30.17 or better can do WPA */ /* Only firmware versions 5.30.17 or better can do WPA */
if ((cap_rid.softVer > 0x530) if ((cap_rid.softVer > 0x530)
|| ((cap_rid.softVer == 0x530) && (cap_rid.softSubVer >= 17))) { || ((cap_rid.softVer == 0x530) && (cap_rid.softSubVer >= 17))) {
airo_print_info(name, "WPA is supported."); airo_print_info("", "WPA is supported.");
return 1; return 1;
} }
/* No WPA support */ /* No WPA support */
airo_print_info(name, "WPA unsupported (only firmware versions 5.30.17" airo_print_info("", "WPA unsupported (only firmware versions 5.30.17"
" and greater support WPA. Detected %s)", cap_rid.prodVer); " and greater support WPA. Detected %s)", cap_rid.prodVer);
return 0; return 0;
} }
...@@ -2825,15 +2825,11 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, ...@@ -2825,15 +2825,11 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
int i, rc; int i, rc;
/* Create the network device object. */ /* Create the network device object. */
dev = alloc_etherdev(sizeof(*ai)); dev = alloc_netdev(sizeof(*ai), "", ether_setup);
if (!dev) { if (!dev) {
airo_print_err("", "Couldn't alloc_etherdev"); airo_print_err("", "Couldn't alloc_etherdev");
return NULL; return NULL;
} }
if (dev_alloc_name(dev, dev->name) < 0) {
airo_print_err("", "Couldn't get name!");
goto err_out_free;
}
ai = dev->priv; ai = dev->priv;
ai->wifidev = NULL; ai->wifidev = NULL;
...@@ -2841,7 +2837,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, ...@@ -2841,7 +2837,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
ai->jobs = 0; ai->jobs = 0;
ai->dev = dev; ai->dev = dev;
if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) { if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) {
airo_print_dbg(dev->name, "Found an MPI350 card"); airo_print_dbg("", "Found an MPI350 card");
set_bit(FLAG_MPI, &ai->flags); set_bit(FLAG_MPI, &ai->flags);
} }
spin_lock_init(&ai->aux_lock); spin_lock_init(&ai->aux_lock);
...@@ -2882,7 +2878,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, ...@@ -2882,7 +2878,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
msleep(400); msleep(400);
if (!is_pcmcia) { if (!is_pcmcia) {
if (!request_region( dev->base_addr, 64, dev->name )) { if (!request_region(dev->base_addr, 64, DRV_NAME)) {
rc = -EBUSY; rc = -EBUSY;
airo_print_err(dev->name, "Couldn't request region"); airo_print_err(dev->name, "Couldn't request region");
goto err_out_nets; goto err_out_nets;
...@@ -2890,8 +2886,8 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, ...@@ -2890,8 +2886,8 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
} }
if (test_bit(FLAG_MPI,&ai->flags)) { if (test_bit(FLAG_MPI,&ai->flags)) {
if (mpi_map_card(ai, pci, dev->name)) { if (mpi_map_card(ai, pci)) {
airo_print_err(dev->name, "Could not map memory"); airo_print_err("", "Could not map memory");
goto err_out_res; goto err_out_res;
} }
} }
...@@ -2919,6 +2915,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, ...@@ -2919,6 +2915,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra); ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra);
} }
strcpy(dev->name, "eth%d");
rc = register_netdev(dev); rc = register_netdev(dev);
if (rc) { if (rc) {
airo_print_err(dev->name, "Couldn't register_netdev"); airo_print_err(dev->name, "Couldn't register_netdev");
...@@ -4014,7 +4011,7 @@ static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap ) ...@@ -4014,7 +4011,7 @@ static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap )
} }
if ( !(max_tries--) ) { if ( !(max_tries--) ) {
airo_print_err(ai->dev->name, airo_print_err(ai->dev->name,
"airo: BAP setup error too many retries\n"); "BAP setup error too many retries\n");
return ERROR; return ERROR;
} }
// -- PC4500 missed it, try again // -- PC4500 missed it, try again
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册