[PATCH] sk98lin: error handling on dual port board
Sk98lin driver error recovery on two port boards is bad. If it fails the second allocation, it will not release resources properly. Also it registers the second port in the pci driver data If second port fails, might as well go with one port. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
This commit is contained in:
parent
bce7c95e4d
commit
decf67aa2f
@ -4899,15 +4899,17 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
|
|||||||
|
|
||||||
boards_found++;
|
boards_found++;
|
||||||
|
|
||||||
|
pci_set_drvdata(pdev, dev);
|
||||||
|
|
||||||
/* More then one port found */
|
/* More then one port found */
|
||||||
if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
|
if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
|
||||||
if ((dev = alloc_etherdev(sizeof(DEV_NET))) == 0) {
|
dev = alloc_etherdev(sizeof(DEV_NET));
|
||||||
printk(KERN_ERR "Unable to allocate etherdev "
|
if (!dev) {
|
||||||
|
printk(KERN_ERR "sk98lin: unable to allocate etherdev "
|
||||||
"structure!\n");
|
"structure!\n");
|
||||||
goto out;
|
goto single_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
pAC->dev[1] = dev;
|
|
||||||
pNet = netdev_priv(dev);
|
pNet = netdev_priv(dev);
|
||||||
pNet->PortNr = 1;
|
pNet->PortNr = 1;
|
||||||
pNet->NetNr = 1;
|
pNet->NetNr = 1;
|
||||||
@ -4939,11 +4941,15 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
|
|||||||
if (using_dac)
|
if (using_dac)
|
||||||
dev->features |= NETIF_F_HIGHDMA;
|
dev->features |= NETIF_F_HIGHDMA;
|
||||||
|
|
||||||
if (register_netdev(dev)) {
|
error = register_netdev(dev);
|
||||||
printk(KERN_ERR "sk98lin: Could not register device for seconf port.\n");
|
if (error) {
|
||||||
|
printk(KERN_ERR "sk98lin: Could not register device"
|
||||||
|
" for second port. (%d)\n", error);
|
||||||
free_netdev(dev);
|
free_netdev(dev);
|
||||||
pAC->dev[1] = pAC->dev[0];
|
goto single_port;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
pAC->dev[1] = dev;
|
||||||
memcpy(&dev->dev_addr,
|
memcpy(&dev->dev_addr,
|
||||||
&pAC->Addr.Net[1].CurrentMacAddress, 6);
|
&pAC->Addr.Net[1].CurrentMacAddress, 6);
|
||||||
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
|
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
|
||||||
@ -4951,7 +4957,8 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
|
|||||||
printk("%s: %s\n", dev->name, DeviceStr);
|
printk("%s: %s\n", dev->name, DeviceStr);
|
||||||
printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
|
printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
single_port:
|
||||||
|
|
||||||
/* Save the hardware revision */
|
/* Save the hardware revision */
|
||||||
pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
|
pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
|
||||||
@ -4964,7 +4971,6 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
|
|||||||
memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA));
|
memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA));
|
||||||
memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA));
|
memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA));
|
||||||
|
|
||||||
pci_set_drvdata(pdev, dev);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_free_resources:
|
out_free_resources:
|
||||||
|
Loading…
Reference in New Issue
Block a user