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 @@
* History:
*
* $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
* fix: MTU init problems
*
......@@ -275,6 +278,10 @@
#include "h/skdrv2nd.h"
/* defines ******************************************************************/
#define DRV_MODULE_NAME "sk98lin"
#define PFX DRV_MODULE_NAME ": "
/* for debuging on x86 only */
/* #define BREAKPOINT() asm(" int $3"); */
......@@ -361,9 +368,7 @@ static void DumpLong(char*, int);
/* global variables *********************************************************/
static const char *BootString = BOOT_STRING;
struct net_device *sk98lin_root_dev = NULL;
static int probed __initdata = 0;
static int boards_found;
struct inode_operations SkInodeOps;
//static struct file_operations SkFileOps; /* with open/relase */
......@@ -371,236 +376,219 @@ struct inode_operations SkInodeOps;
static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
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:
* This function scans the PCI bus for SK-98xx adapters. Resources for
* each adapter are allocated and the adapter is brought into Init 1
* state.
* This function allocates resources for an SK-98xx adapter and brings
* it into Init 1 state.
*
* Returns:
* 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;
DEV_NET *pNet = NULL;
struct pci_dev *pdev = NULL;
unsigned long base_address;
struct net_device *dev = NULL;
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);
}
DEV_NET *pNet;
unsigned long base_address;
struct net_device *dev;
int ret;
while((pdev = pci_find_device(PCI_VENDOR_ID_SYSKONNECT,
PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) {
#ifndef MODULE
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))
continue;
/* Configure DMA attributes. */
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. */
if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL) &&
pci_set_dma_mask(pdev, (u64) 0xffffffff))
continue;
ret = -ENOMEM;
dev = alloc_etherdev(sizeof(DEV_NET));
if (!dev) {
printk(KERN_ERR "Unable to allocate etherdev "
"structure!\n");
break;
}
dev = alloc_etherdev(sizeof(DEV_NET));
if (!dev) {
printk(KERN_ERR "Unable to allocate etherdev structure!\n");
goto out_disable;
}
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;
}
pNet = dev->priv;
memset(pNet->pAC, 0, sizeof(SK_AC));
pAC = pNet->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;
pAC = kmalloc(sizeof(*pAC), GFP_KERNEL);
if (pAC == NULL){
printk(KERN_ERR "Unable to allocate adapter structure!\n");
goto out_free_dev;
}
memset(pAC, 0, sizeof(SK_AC));
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->Up = 0;
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;
}
pNet->Mtu = 1500;
pNet->Up = 0;
dev->irq = pdev->irq;
/*
* Dummy value.
*/
dev->base_addr = 42;
pci_set_master(pdev);
base_address = pci_resource_start (pdev, 0);
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
ret = SkGeDevInit(dev);
if (ret < 0)
goto out_free_priv;
/*
* Dummy value.
*/
dev->base_addr = 42;
pci_set_master(pdev);
base_address = pci_resource_start(pdev, 0);
#ifdef SK_BIG_ENDIAN
/*
* On big endian machines, we use the adapter's aibility of
* reading the descriptors as big endian.
*/
{
/*
* On big endian machines, we use the adapter's ability of
* reading the descriptors as big endian.
*/
{
SK_U32 our2;
SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2);
our2 |= PCI_REV_DESC;
SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2);
}
SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2);
our2 |= PCI_REV_DESC;
SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2);
}
#endif /* BIG ENDIAN */
/*
* Remap the regs into kernel space.
*/
/*
* Remap the regs into kernel space.
*/
pAC->IoBase = (char*)ioremap(base_address, 0x4000);
if (!pAC->IoBase){
printk(KERN_ERR "%s: Unable to map I/O register, "
"SK 98xx No. %i will be disabled.\n",
dev->name, boards_found);
kfree(dev);
break;
}
pAC->Index = boards_found;
pAC->IoBase = (char*)ioremap(base_address, 0x4000);
if (!pAC->IoBase) {
printk(KERN_ERR PFX "unable to map I/O register. "
"SK 98xx device disabled.\n");
ret = -EIO;
goto out_dev_uninit;
}
pAC->Index = boards_found++;
if (SkGeBoardInit(dev, pAC)) {
FreeResources(dev);
kfree(dev);
continue;
}
ret = SkGeBoardInit(dev, pAC);
if (ret < 0)
goto out_free_resources;
memcpy((caddr_t) &dev->dev_addr,
(caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
memcpy((caddr_t) &dev->dev_addr,
(caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
pNet->PortNr = 0;
pNet->NetNr = 0;
pNet->PortNr = 0;
pNet->NetNr = 0;
if (register_netdev(dev) != 0) {
printk(KERN_ERR "Unable to register etherdev\n");
sk98lin_root_dev = pAC->Next;
remove_proc_entry(dev->name, pSkRootDir);
FreeResources(dev);
kfree(dev);
continue;
}
/* More then one port found */
if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
struct net_device *sec_dev;
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;
sec_dev = alloc_etherdev(sizeof(DEV_NET));
if (!sec_dev) {
printk(KERN_ERR PFX
"Unable to allocate etherdev structure!\n");
ret = -ENOMEM;
goto out_free_resources;
}
boards_found++;
/* More then one port found */
if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
dev = alloc_etherdev(sizeof(DEV_NET));
if (!dev) {
printk(KERN_ERR "Unable to allocate etherdev "
"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;
}
pAC->dev[1] = sec_dev;
pNet = sec_dev->priv;
pNet->PortNr = 1;
pNet->NetNr = 1;
pNet->pAC = pAC;
pNet->Mtu = 1500;
pNet->Up = 0;
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;
}
}
ret = SkGeDevInit(sec_dev);
if (ret < 0)
goto out_free_secondary_dev;
memcpy((caddr_t) &sec_dev->dev_addr,
(caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
/*
* This is bollocks, but we need to tell the net-init
* code that it shall go for the next device.
*/
#ifndef MODULE
dev->base_addr = 0;
#endif
printk("%s: %s\n", sec_dev->name, pAC->DeviceStr);
printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
}
pci_set_drvdata(pdev, dev);
/*
* If we're at this point we're going through skge_probe() for
* the first time. Return success (0) if we've initialized 1
* or more boards. Otherwise, return failure (-ENODEV).
*/
ret = 0;
out:
return ret;
return boards_found;
} /* skge_probe */
out_free_secondary_dev:
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] = {"", };
static int debug = 0; /* not used */
static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */
/*****************************************************************************
*
* skge_init_module - module initialization function
*
* 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
* skge_remove_one - remove a single instance of a SK-98xx adapter
*
* Description:
* Disable adapter if it is still running, free resources,
......@@ -758,82 +716,65 @@ spinlock_t sk_devs_lock = SPIN_LOCK_UNLOCKED;
*
* Returns: N/A
*/
static void __exit skge_cleanup_module(void)
static void __devexit skge_remove_one(struct pci_dev *pdev)
{
DEV_NET *pNet;
SK_AC *pAC;
struct net_device *next;
unsigned long Flags;
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*/
}
struct net_device *dev = pci_get_drvdata(pdev);
DEV_NET *pNet = dev->priv;
SK_AC *pAC = pNet->pAC;
unsigned long Flags;
SK_EVPARA EvPara;
if(pAC->BoardLevel == 1) {
/* board is still alive */
SkGeDeInit(pAC, pAC->IoBase);
pAC->BoardLevel = 0;
}
if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){
pNet = (DEV_NET*) pAC->dev[1]->priv;
if (pNet->proc) {
spin_lock(&sk_devs_lock);
pNet->proc->data = NULL;
spin_unlock(&sk_devs_lock);
}
unregister_netdev(pAC->dev[1]);
kfree(pAC->dev[1]);
}
netif_stop_queue(dev);
SkGeYellowLED(pAC, pAC->IoBase, 0);
if (pNet->proc) {
spin_lock(&sk_devs_lock);
pNet->proc->data = NULL;
spin_unlock(&sk_devs_lock);
remove_proc_entry(dev->name, pSkRootDir);
}
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;
/*
* otherwise unregister_netdev calls get_stats with
* invalid IO ... :-(
*/
unregister_netdev(sk98lin_root_dev);
kfree(sk98lin_root_dev);
kfree(pAC);
sk98lin_root_dev = next;
if (pAC->BoardLevel == 1) {
/* board is still alive */
SkGeDeInit(pAC, pAC->IoBase);
pAC->BoardLevel = 0;
}
/* clear proc-dir */
remove_proc_entry(pSkRootDir->name, proc_net);
if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2) {
SkGeDevCleanUp(pAC->dev[1]);
kfree(pAC->dev[1]);
}
} /* skge_cleanup_module */
FreeResources(dev);
module_init(skge_init_module);
module_exit(skge_cleanup_module);
dev->get_stats = NULL;
/*
* 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 */
SkGeYellowLED(pAC, pAC->IoBase, 1);
/*
* Register the device here
*/
pAC->Next = sk98lin_root_dev;
sk98lin_root_dev = dev;
return (0);
} /* SkGeBoardInit */
......@@ -4097,9 +4032,62 @@ int l;
#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:
* compile-command: "make"
* 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