Commit 0f416829 authored by François Romieu's avatar François Romieu Committed by Jeff Garzik

[netdrvr sk98lin] PCI API conversion, and some cleanups


- PCI API init style conversion for drivers/net/sk98lin/skge.c;
- new helpers: SkGeDev{Init/CleanUp};
- sk_devs_lock moved around as it's needed early.

Compiles without error. Untested.
parent d5f303f1
...@@ -48,6 +48,9 @@ ...@@ -48,6 +48,9 @@
* History: * History:
* *
* $Log: skge.c,v $ * $Log: skge.c,v $
* Revision x.xx.x.x 2003/06/07 02:31:17 romieu@fr.zoreil.com
* pci api style init.
*
* Revision 1.29.2.6 2001/05/21 07:59:29 mlindner * Revision 1.29.2.6 2001/05/21 07:59:29 mlindner
* fix: MTU init problems * fix: MTU init problems
* *
...@@ -275,6 +278,10 @@ ...@@ -275,6 +278,10 @@
#include "h/skdrv2nd.h" #include "h/skdrv2nd.h"
/* defines ******************************************************************/ /* defines ******************************************************************/
#define DRV_MODULE_NAME "sk98lin"
#define PFX DRV_MODULE_NAME ": "
/* for debuging on x86 only */ /* for debuging on x86 only */
/* #define BREAKPOINT() asm(" int $3"); */ /* #define BREAKPOINT() asm(" int $3"); */
...@@ -361,9 +368,7 @@ static void DumpLong(char*, int); ...@@ -361,9 +368,7 @@ static void DumpLong(char*, int);
/* global variables *********************************************************/ /* global variables *********************************************************/
static const char *BootString = BOOT_STRING; static int boards_found;
struct net_device *sk98lin_root_dev = NULL;
static int probed __initdata = 0;
struct inode_operations SkInodeOps; struct inode_operations SkInodeOps;
//static struct file_operations SkFileOps; /* with open/relase */ //static struct file_operations SkFileOps; /* with open/relase */
...@@ -371,236 +376,219 @@ struct inode_operations SkInodeOps; ...@@ -371,236 +376,219 @@ struct inode_operations SkInodeOps;
static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}}; static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480}; static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
spinlock_t sk_devs_lock = SPIN_LOCK_UNLOCKED;
static int SkGeDevInit(struct net_device *dev)
{
DEV_NET *pNet = dev->priv;
int ret = 0;
dev->open = &SkGeOpen;
dev->stop = &SkGeClose;
dev->hard_start_xmit = &SkGeXmit;
dev->get_stats = &SkGeStats;
dev->set_multicast_list = &SkGeSetRxMode;
dev->set_mac_address = &SkGeSetMacAddr;
dev->do_ioctl = &SkGeIoctl;
dev->change_mtu = &SkGeChangeMtu;
if (register_netdev(dev) != 0) {
printk(KERN_ERR "Unable to register etherdev\n");
ret = -ENOMEM;
goto out;
}
pNet->proc = create_proc_entry(dev->name, S_IFREG | 0444, pSkRootDir);
if (pNet->proc) {
pNet->proc->data = dev;
pNet->proc->owner = THIS_MODULE;
pNet->proc->proc_fops = &sk_proc_fops;
}
out:
return ret;
}
static void SkGeDevCleanUp(struct net_device *dev)
{
DEV_NET *pNet = dev->priv;
if (pNet->proc) {
spin_lock(&sk_devs_lock);
pNet->proc->data = NULL;
spin_unlock(&sk_devs_lock);
remove_proc_entry(dev->name, pSkRootDir);
}
unregister_netdev(dev);
}
/***************************************************************************** /*****************************************************************************
* *
* skge_probe - find all SK-98xx adapters * skge_init_one - init a single instance of a SK-98xx adapter
* *
* Description: * Description:
* This function scans the PCI bus for SK-98xx adapters. Resources for * This function allocates resources for an SK-98xx adapter and brings
* each adapter are allocated and the adapter is brought into Init 1 * it into Init 1 state.
* state.
* *
* Returns: * Returns:
* 0, if everything is ok * 0, if everything is ok
* !=0, on error * <0, on error
*/ */
static int __init skge_probe (void) static int __devinit skge_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{ {
int proc_root_initialized = 0;
int boards_found = 0;
int version_disp = 0;
SK_AC *pAC; SK_AC *pAC;
DEV_NET *pNet = NULL; DEV_NET *pNet;
struct pci_dev *pdev = NULL; unsigned long base_address;
unsigned long base_address; struct net_device *dev;
struct net_device *dev = NULL; int ret;
if (probed)
return -ENODEV;
probed++;
/* display driver info */
if (!version_disp)
{
/* set display flag to TRUE so that */
/* we only display this string ONCE */
version_disp = 1;
printk("%s\n", BootString);
}
while((pdev = pci_find_device(PCI_VENDOR_ID_SYSKONNECT, #ifndef MODULE
PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) { static int version_disp = 0;
pNet = NULL; if (!version_disp++)
printk(KERN_INFO "%s\n", BOOT_STRING);
#endif
ret = pci_enable_device(pdev);
if (ret)
goto out;
if (pci_enable_device(pdev)) /* Configure DMA attributes. */
continue; if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff)) {
ret = pci_set_dma_mask(pdev, (u64) 0xffffffff);
if (ret) {
printk(KERN_ERR PFX "No usable DMA configuration\n");
goto out_disable;
}
}
/* Configure DMA attributes. */ ret = -ENOMEM;
if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL) &&
pci_set_dma_mask(pdev, (u64) 0xffffffff))
continue;
dev = alloc_etherdev(sizeof(DEV_NET)); dev = alloc_etherdev(sizeof(DEV_NET));
if (!dev) { if (!dev) {
printk(KERN_ERR "Unable to allocate etherdev " printk(KERN_ERR "Unable to allocate etherdev structure!\n");
"structure!\n"); goto out_disable;
break; }
}
pNet = dev->priv; pNet = dev->priv;
pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
if (pNet->pAC == NULL){
kfree(dev);
printk(KERN_ERR "Unable to allocate adapter "
"structure!\n");
break;
}
memset(pNet->pAC, 0, sizeof(SK_AC)); pAC = kmalloc(sizeof(*pAC), GFP_KERNEL);
pAC = pNet->pAC; if (pAC == NULL){
pAC->PciDev = *pdev; printk(KERN_ERR "Unable to allocate adapter structure!\n");
pAC->PciDevId = pdev->device; goto out_free_dev;
pAC->dev[0] = dev; }
pAC->dev[1] = dev;
sprintf(pAC->Name, "SysKonnect SK-98xx"); memset(pAC, 0, sizeof(SK_AC));
pAC->CheckQueue = SK_FALSE; pNet->pAC = pAC;
pAC->PciDev = *pdev;
pAC->PciDevId = pdev->device;
pAC->dev[0] = dev;
pAC->dev[1] = dev;
sprintf(pAC->Name, "SysKonnect SK-98xx");
pAC->CheckQueue = SK_FALSE;
pNet->Mtu = 1500; pNet->Mtu = 1500;
pNet->Up = 0; pNet->Up = 0;
dev->irq = pdev->irq; dev->irq = pdev->irq;
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
dev->open = &SkGeOpen;
dev->stop = &SkGeClose;
dev->hard_start_xmit = &SkGeXmit;
dev->get_stats = &SkGeStats;
dev->set_multicast_list = &SkGeSetRxMode;
dev->set_mac_address = &SkGeSetMacAddr;
dev->do_ioctl = &SkGeIoctl;
dev->change_mtu = &SkGeChangeMtu;
if(!proc_root_initialized) {
pSkRootDir = create_proc_entry(SK_Root_Dir_entry,
S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net);
pSkRootDir->owner = THIS_MODULE;
proc_root_initialized = 1;
}
/* SET_MODULE_OWNER(dev);
* Dummy value. SET_NETDEV_DEV(dev, &pdev->dev);
*/ ret = SkGeDevInit(dev);
dev->base_addr = 42; if (ret < 0)
pci_set_master(pdev); goto out_free_priv;
base_address = pci_resource_start (pdev, 0);
/*
* Dummy value.
*/
dev->base_addr = 42;
pci_set_master(pdev);
base_address = pci_resource_start(pdev, 0);
#ifdef SK_BIG_ENDIAN #ifdef SK_BIG_ENDIAN
/* /*
* On big endian machines, we use the adapter's aibility of * On big endian machines, we use the adapter's ability of
* reading the descriptors as big endian. * reading the descriptors as big endian.
*/ */
{ {
SK_U32 our2; SK_U32 our2;
SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2); SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2);
our2 |= PCI_REV_DESC; our2 |= PCI_REV_DESC;
SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2); SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2);
} }
#endif /* BIG ENDIAN */ #endif /* BIG ENDIAN */
/* /*
* Remap the regs into kernel space. * Remap the regs into kernel space.
*/ */
pAC->IoBase = (char*)ioremap(base_address, 0x4000); pAC->IoBase = (char*)ioremap(base_address, 0x4000);
if (!pAC->IoBase){ if (!pAC->IoBase) {
printk(KERN_ERR "%s: Unable to map I/O register, " printk(KERN_ERR PFX "unable to map I/O register. "
"SK 98xx No. %i will be disabled.\n", "SK 98xx device disabled.\n");
dev->name, boards_found); ret = -EIO;
kfree(dev); goto out_dev_uninit;
break; }
} pAC->Index = boards_found++;
pAC->Index = boards_found;
if (SkGeBoardInit(dev, pAC)) { ret = SkGeBoardInit(dev, pAC);
FreeResources(dev); if (ret < 0)
kfree(dev); goto out_free_resources;
continue;
}
memcpy((caddr_t) &dev->dev_addr, memcpy((caddr_t) &dev->dev_addr,
(caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6); (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
pNet->PortNr = 0; pNet->PortNr = 0;
pNet->NetNr = 0; pNet->NetNr = 0;
if (register_netdev(dev) != 0) { /* More then one port found */
printk(KERN_ERR "Unable to register etherdev\n"); if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
sk98lin_root_dev = pAC->Next; struct net_device *sec_dev;
remove_proc_entry(dev->name, pSkRootDir);
FreeResources(dev);
kfree(dev);
continue;
}
pNet->proc = create_proc_entry(dev->name, sec_dev = alloc_etherdev(sizeof(DEV_NET));
S_IFREG | 0444, pSkRootDir); if (!sec_dev) {
if (pNet->proc) { printk(KERN_ERR PFX
pNet->proc->data = dev; "Unable to allocate etherdev structure!\n");
pNet->proc->owner = THIS_MODULE; ret = -ENOMEM;
pNet->proc->proc_fops = &sk_proc_fops; goto out_free_resources;
} }
boards_found++; pAC->dev[1] = sec_dev;
pNet = sec_dev->priv;
/* More then one port found */ pNet->PortNr = 1;
if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { pNet->NetNr = 1;
dev = alloc_etherdev(sizeof(DEV_NET)); pNet->pAC = pAC;
if (!dev) { pNet->Mtu = 1500;
printk(KERN_ERR "Unable to allocate etherdev " pNet->Up = 0;
"structure!\n");
break;
}
pAC->dev[1] = dev;
pNet = dev->priv;
pNet->PortNr = 1;
pNet->NetNr = 1;
pNet->pAC = pAC;
pNet->Mtu = 1500;
pNet->Up = 0;
dev->open = &SkGeOpen;
dev->stop = &SkGeClose;
dev->hard_start_xmit = &SkGeXmit;
dev->get_stats = &SkGeStats;
dev->set_multicast_list = &SkGeSetRxMode;
dev->set_mac_address = &SkGeSetMacAddr;
dev->do_ioctl = &SkGeIoctl;
dev->change_mtu = &SkGeChangeMtu;
memcpy((caddr_t) &dev->dev_addr,
(caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6);
printk("%s: %s\n", dev->name, pAC->DeviceStr);
printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
if (register_netdev(dev) != 0) {
printk(KERN_ERR "Unable to register etherdev\n");
kfree(dev);
break;
}
pNet->proc = create_proc_entry(dev->name, ret = SkGeDevInit(sec_dev);
S_IFREG | 0444, pSkRootDir); if (ret < 0)
if (pNet->proc) { goto out_free_secondary_dev;
pNet->proc->data = dev;
pNet->proc->owner = THIS_MODULE;
pNet->proc->proc_fops = &sk_proc_fops;
}
}
memcpy((caddr_t) &sec_dev->dev_addr,
(caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
/* printk("%s: %s\n", sec_dev->name, pAC->DeviceStr);
* This is bollocks, but we need to tell the net-init printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
* code that it shall go for the next device.
*/
#ifndef MODULE
dev->base_addr = 0;
#endif
} }
pci_set_drvdata(pdev, dev);
/* ret = 0;
* If we're at this point we're going through skge_probe() for out:
* the first time. Return success (0) if we've initialized 1 return ret;
* or more boards. Otherwise, return failure (-ENODEV).
*/
return boards_found; out_free_secondary_dev:
} /* skge_probe */ kfree(pAC->dev[1]);
out_free_resources:
FreeResources(dev);
out_dev_uninit:
SkGeDevCleanUp(dev);
out_free_priv:
kfree(pAC);
out_free_dev:
kfree(dev);
out_disable:
pci_disable_device(pdev);
goto out;
} /* skge_init_one */
/***************************************************************************** /*****************************************************************************
* *
...@@ -718,39 +706,9 @@ static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", }; ...@@ -718,39 +706,9 @@ static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", };
static int debug = 0; /* not used */ static int debug = 0; /* not used */
static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */ static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */
/***************************************************************************** /*****************************************************************************
* *
* skge_init_module - module initialization function * skge_remove_one - remove a single instance of a SK-98xx adapter
*
* Description:
* Very simple, only call skge_probe and return approriate result.
*
* Returns:
* 0, if everything is ok
* !=0, on error
*/
static int __init skge_init_module(void)
{
int cards;
sk98lin_root_dev = NULL;
/* just to avoid warnings ... */
debug = 0;
options[0] = 0;
cards = skge_probe();
if (cards == 0) {
printk("No adapter found\n");
}
return cards ? 0 : -ENODEV;
} /* skge_init_module */
spinlock_t sk_devs_lock = SPIN_LOCK_UNLOCKED;
/*****************************************************************************
*
* skge_cleanup_module - module unload function
* *
* Description: * Description:
* Disable adapter if it is still running, free resources, * Disable adapter if it is still running, free resources,
...@@ -758,82 +716,65 @@ spinlock_t sk_devs_lock = SPIN_LOCK_UNLOCKED; ...@@ -758,82 +716,65 @@ spinlock_t sk_devs_lock = SPIN_LOCK_UNLOCKED;
* *
* Returns: N/A * Returns: N/A
*/ */
static void __exit skge_cleanup_module(void) static void __devexit skge_remove_one(struct pci_dev *pdev)
{ {
DEV_NET *pNet; struct net_device *dev = pci_get_drvdata(pdev);
SK_AC *pAC; DEV_NET *pNet = dev->priv;
struct net_device *next; SK_AC *pAC = pNet->pAC;
unsigned long Flags; unsigned long Flags;
SK_EVPARA EvPara; SK_EVPARA EvPara;
while (sk98lin_root_dev) {
pNet = (DEV_NET*) sk98lin_root_dev->priv;
pAC = pNet->pAC;
next = pAC->Next;
netif_stop_queue(sk98lin_root_dev);
SkGeYellowLED(pAC, pAC->IoBase, 0);
if (pNet->proc) {
spin_lock(&sk_devs_lock);
pNet->proc->data = NULL;
spin_unlock(&sk_devs_lock);
}
if(pAC->BoardLevel == 2) {
/* board is still alive */
spin_lock_irqsave(&pAC->SlowPathLock, Flags);
EvPara.Para32[0] = 0;
EvPara.Para32[1] = -1;
SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
EvPara.Para32[0] = 1;
EvPara.Para32[1] = -1;
SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
SkEventDispatcher(pAC, pAC->IoBase);
/* disable interrupts */
SK_OUT32(pAC->IoBase, B0_IMSK, 0);
SkGeDeInit(pAC, pAC->IoBase);
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
pAC->BoardLevel = 0;
/* We do NOT check here, if IRQ was pending, of course*/
}
if(pAC->BoardLevel == 1) {
/* board is still alive */
SkGeDeInit(pAC, pAC->IoBase);
pAC->BoardLevel = 0;
}
if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){ netif_stop_queue(dev);
pNet = (DEV_NET*) pAC->dev[1]->priv; SkGeYellowLED(pAC, pAC->IoBase, 0);
if (pNet->proc) { if (pNet->proc) {
spin_lock(&sk_devs_lock); spin_lock(&sk_devs_lock);
pNet->proc->data = NULL; pNet->proc->data = NULL;
spin_unlock(&sk_devs_lock); spin_unlock(&sk_devs_lock);
} remove_proc_entry(dev->name, pSkRootDir);
unregister_netdev(pAC->dev[1]); }
kfree(pAC->dev[1]);
}
FreeResources(sk98lin_root_dev); if (pAC->BoardLevel == 2) {
/* board is still alive */
spin_lock_irqsave(&pAC->SlowPathLock, Flags);
EvPara.Para32[0] = 0;
EvPara.Para32[1] = -1;
SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
EvPara.Para32[0] = 1;
EvPara.Para32[1] = -1;
SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
SkEventDispatcher(pAC, pAC->IoBase);
/* disable interrupts */
SK_OUT32(pAC->IoBase, B0_IMSK, 0);
SkGeDeInit(pAC, pAC->IoBase);
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
pAC->BoardLevel = 0;
/* We do NOT check here, if IRQ was pending, of course*/
}
sk98lin_root_dev->get_stats = NULL; if (pAC->BoardLevel == 1) {
/* /* board is still alive */
* otherwise unregister_netdev calls get_stats with SkGeDeInit(pAC, pAC->IoBase);
* invalid IO ... :-( pAC->BoardLevel = 0;
*/
unregister_netdev(sk98lin_root_dev);
kfree(sk98lin_root_dev);
kfree(pAC);
sk98lin_root_dev = next;
} }
/* clear proc-dir */ if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2) {
remove_proc_entry(pSkRootDir->name, proc_net); SkGeDevCleanUp(pAC->dev[1]);
kfree(pAC->dev[1]);
}
} /* skge_cleanup_module */ FreeResources(dev);
module_init(skge_init_module); dev->get_stats = NULL;
module_exit(skge_cleanup_module); /*
* otherwise unregister_netdev calls get_stats with
* invalid IO ... :-(
*/
unregister_netdev(dev);
kfree(dev);
kfree(pAC);
boards_found--;
} /* skge_remove_one */
/***************************************************************************** /*****************************************************************************
* *
...@@ -968,12 +909,6 @@ int Ret; /* return code of request_irq */ ...@@ -968,12 +909,6 @@ int Ret; /* return code of request_irq */
SkGeYellowLED(pAC, pAC->IoBase, 1); SkGeYellowLED(pAC, pAC->IoBase, 1);
/*
* Register the device here
*/
pAC->Next = sk98lin_root_dev;
sk98lin_root_dev = dev;
return (0); return (0);
} /* SkGeBoardInit */ } /* SkGeBoardInit */
...@@ -4097,9 +4032,62 @@ int l; ...@@ -4097,9 +4032,62 @@ int l;
#endif /* DEBUG */ #endif /* DEBUG */
static struct pci_device_id skge_pci_tbl[] __devinitdata = {
{ PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE,
PCI_ANY_ID, PCI_ANY_ID, },
{ 0,}
};
MODULE_DEVICE_TABLE(pci, skge_pci_tbl);
static struct pci_driver skge_driver = {
.name = DRV_MODULE_NAME,
.id_table = skge_pci_tbl,
.probe = skge_init_one,
.remove = __devexit_p(skge_remove_one),
};
/*****************************************************************************
*
* skge_init - module initialization function
*
* Description:
* root /proc directory allocation and pci driver invocation.
*
* Returns:
* 0, if everything is ok
* !=0, on error
*/
static int __init skge_init(void)
{
int ret = -ENOMEM;
/* just to avoid warnings ... */
debug = 0;
options[0] = 0;
pSkRootDir = create_proc_entry(DRV_MODULE_NAME,
S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net);
if (pSkRootDir) {
pSkRootDir->owner = THIS_MODULE;
ret = pci_module_init(&skge_driver);
if (ret)
remove_proc_entry(pSkRootDir->name, proc_net);
}
return ret;
} /* skge_init */
static void __exit skge_cleanup(void)
{
remove_proc_entry(pSkRootDir->name, proc_net);
pci_unregister_driver(&skge_driver);
}
module_init(skge_init);
module_exit(skge_cleanup);
/* /*
* Local variables: * Local variables:
* compile-command: "make" * compile-command: "make"
* End: * End:
*/ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment