Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
60cc5147
Commit
60cc5147
authored
Aug 02, 2007
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ISDN] hysdn: convert to PCI hotplug API
Signed-off-by:
Jeff Garzik
<
jeff@garzik.org
>
parent
782e3b3b
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
130 additions
and
144 deletions
+130
-144
drivers/isdn/hysdn/hysdn_init.c
drivers/isdn/hysdn/hysdn_init.c
+130
-144
No files found.
drivers/isdn/hysdn/hysdn_init.c
View file @
60cc5147
...
...
@@ -20,10 +20,15 @@
#include "hysdn_defs.h"
static
struct
pci_device_id
hysdn_pci_tbl
[]
=
{
{
PCI_VENDOR_ID_HYPERCOPE
,
PCI_DEVICE_ID_HYPERCOPE_PLX
,
PCI_ANY_ID
,
PCI_SUBDEVICE_ID_HYPERCOPE_METRO
},
{
PCI_VENDOR_ID_HYPERCOPE
,
PCI_DEVICE_ID_HYPERCOPE_PLX
,
PCI_ANY_ID
,
PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2
},
{
PCI_VENDOR_ID_HYPERCOPE
,
PCI_DEVICE_ID_HYPERCOPE_PLX
,
PCI_ANY_ID
,
PCI_SUBDEVICE_ID_HYPERCOPE_ERGO
},
{
PCI_VENDOR_ID_HYPERCOPE
,
PCI_DEVICE_ID_HYPERCOPE_PLX
,
PCI_ANY_ID
,
PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO
},
{
PCI_VENDOR_ID_HYPERCOPE
,
PCI_DEVICE_ID_HYPERCOPE_PLX
,
PCI_ANY_ID
,
PCI_SUBDEVICE_ID_HYPERCOPE_METRO
,
0
,
0
,
BD_METRO
},
{
PCI_VENDOR_ID_HYPERCOPE
,
PCI_DEVICE_ID_HYPERCOPE_PLX
,
PCI_ANY_ID
,
PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2
,
0
,
0
,
BD_CHAMP2
},
{
PCI_VENDOR_ID_HYPERCOPE
,
PCI_DEVICE_ID_HYPERCOPE_PLX
,
PCI_ANY_ID
,
PCI_SUBDEVICE_ID_HYPERCOPE_ERGO
,
0
,
0
,
BD_ERGO
},
{
PCI_VENDOR_ID_HYPERCOPE
,
PCI_DEVICE_ID_HYPERCOPE_PLX
,
PCI_ANY_ID
,
PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO
,
0
,
0
,
BD_ERGO
},
{
}
/* Terminating entry */
};
MODULE_DEVICE_TABLE
(
pci
,
hysdn_pci_tbl
);
...
...
@@ -34,128 +39,7 @@ MODULE_LICENSE("GPL");
static
char
*
hysdn_init_revision
=
"$Revision: 1.6.6.6 $"
;
static
int
cardmax
;
/* number of found cards */
hysdn_card
*
card_root
=
NULL
;
/* pointer to first card */
/**********************************************/
/* table assigning PCI-sub ids to board types */
/* the last entry contains all 0 */
/**********************************************/
static
struct
{
unsigned
short
subid
;
/* PCI sub id */
unsigned
char
cardtyp
;
/* card type assigned */
}
pci_subid_map
[]
=
{
{
PCI_SUBDEVICE_ID_HYPERCOPE_METRO
,
BD_METRO
},
{
PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2
,
BD_CHAMP2
},
{
PCI_SUBDEVICE_ID_HYPERCOPE_ERGO
,
BD_ERGO
},
{
PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO
,
BD_ERGO
},
{
0
,
0
}
/* terminating entry */
};
/*********************************************************************/
/* search_cards searches for available cards in the pci config data. */
/* If a card is found, the card structure is allocated and the cards */
/* ressources are reserved. cardmax is incremented. */
/*********************************************************************/
static
void
search_cards
(
void
)
{
struct
pci_dev
*
akt_pcidev
=
NULL
;
hysdn_card
*
card
,
*
card_last
;
int
i
;
card_root
=
NULL
;
card_last
=
NULL
;
while
((
akt_pcidev
=
pci_find_device
(
PCI_VENDOR_ID_HYPERCOPE
,
PCI_DEVICE_ID_HYPERCOPE_PLX
,
akt_pcidev
))
!=
NULL
)
{
if
(
pci_enable_device
(
akt_pcidev
))
continue
;
if
(
!
(
card
=
kzalloc
(
sizeof
(
hysdn_card
),
GFP_KERNEL
)))
{
printk
(
KERN_ERR
"HYSDN: unable to alloc device mem
\n
"
);
return
;
}
card
->
myid
=
cardmax
;
/* set own id */
card
->
bus
=
akt_pcidev
->
bus
->
number
;
card
->
devfn
=
akt_pcidev
->
devfn
;
/* slot + function */
card
->
subsysid
=
akt_pcidev
->
subsystem_device
;
card
->
irq
=
akt_pcidev
->
irq
;
card
->
iobase
=
pci_resource_start
(
akt_pcidev
,
PCI_REG_PLX_IO_BASE
);
card
->
plxbase
=
pci_resource_start
(
akt_pcidev
,
PCI_REG_PLX_MEM_BASE
);
card
->
membase
=
pci_resource_start
(
akt_pcidev
,
PCI_REG_MEMORY_BASE
);
card
->
brdtype
=
BD_NONE
;
/* unknown */
card
->
debug_flags
=
DEF_DEB_FLAGS
;
/* set default debug */
card
->
faxchans
=
0
;
/* default no fax channels */
card
->
bchans
=
2
;
/* and 2 b-channels */
for
(
i
=
0
;
pci_subid_map
[
i
].
subid
;
i
++
)
if
(
pci_subid_map
[
i
].
subid
==
card
->
subsysid
)
{
card
->
brdtype
=
pci_subid_map
[
i
].
cardtyp
;
break
;
}
if
(
card
->
brdtype
!=
BD_NONE
)
{
if
(
ergo_inithardware
(
card
))
{
printk
(
KERN_WARNING
"HYSDN: card at io 0x%04x already in use
\n
"
,
card
->
iobase
);
kfree
(
card
);
continue
;
}
}
else
{
printk
(
KERN_WARNING
"HYSDN: unknown card id 0x%04x
\n
"
,
card
->
subsysid
);
kfree
(
card
);
/* release mem */
continue
;
}
cardmax
++
;
card
->
next
=
NULL
;
/*end of chain */
if
(
card_last
)
card_last
->
next
=
card
;
/* pointer to next card */
else
card_root
=
card
;
card_last
=
card
;
/* new chain end */
}
/* device found */
}
/* search_cards */
/************************************************************************************/
/* free_resources frees the acquired PCI resources and returns the allocated memory */
/************************************************************************************/
static
void
free_resources
(
void
)
{
hysdn_card
*
card
;
while
(
card_root
)
{
card
=
card_root
;
if
(
card
->
releasehardware
)
card
->
releasehardware
(
card
);
/* free all hardware resources */
card_root
=
card_root
->
next
;
/* remove card from chain */
kfree
(
card
);
/* return mem */
}
/* while card_root */
}
/* free_resources */
/**************************************************************************/
/* stop_cards disables (hardware resets) all cards and disables interrupt */
/**************************************************************************/
static
void
stop_cards
(
void
)
{
hysdn_card
*
card
;
card
=
card_root
;
/* first in chain */
while
(
card
)
{
if
(
card
->
stopcard
)
card
->
stopcard
(
card
);
card
=
card
->
next
;
/* remove card from chain */
}
/* while card */
}
/* stop_cards */
static
hysdn_card
*
card_last
=
NULL
;
/* pointer to first card */
/****************************************************************************/
...
...
@@ -191,31 +75,138 @@ hysdn_getrev(const char *revision)
/* and the module is added to the list in /proc/modules, otherwise an error */
/* is assumed and the module will not be kept in memory. */
/****************************************************************************/
static
int
__devinit
hysdn_pci_init_one
(
struct
pci_dev
*
akt_pcidev
,
const
struct
pci_device_id
*
ent
)
{
hysdn_card
*
card
;
int
rc
;
rc
=
pci_enable_device
(
akt_pcidev
);
if
(
rc
)
return
rc
;
if
(
!
(
card
=
kzalloc
(
sizeof
(
hysdn_card
),
GFP_KERNEL
)))
{
printk
(
KERN_ERR
"HYSDN: unable to alloc device mem
\n
"
);
rc
=
-
ENOMEM
;
goto
err_out
;
}
card
->
myid
=
cardmax
;
/* set own id */
card
->
bus
=
akt_pcidev
->
bus
->
number
;
card
->
devfn
=
akt_pcidev
->
devfn
;
/* slot + function */
card
->
subsysid
=
akt_pcidev
->
subsystem_device
;
card
->
irq
=
akt_pcidev
->
irq
;
card
->
iobase
=
pci_resource_start
(
akt_pcidev
,
PCI_REG_PLX_IO_BASE
);
card
->
plxbase
=
pci_resource_start
(
akt_pcidev
,
PCI_REG_PLX_MEM_BASE
);
card
->
membase
=
pci_resource_start
(
akt_pcidev
,
PCI_REG_MEMORY_BASE
);
card
->
brdtype
=
BD_NONE
;
/* unknown */
card
->
debug_flags
=
DEF_DEB_FLAGS
;
/* set default debug */
card
->
faxchans
=
0
;
/* default no fax channels */
card
->
bchans
=
2
;
/* and 2 b-channels */
card
->
brdtype
=
ent
->
driver_data
;
if
(
ergo_inithardware
(
card
))
{
printk
(
KERN_WARNING
"HYSDN: card at io 0x%04x already in use
\n
"
,
card
->
iobase
);
rc
=
-
EBUSY
;
goto
err_out_card
;
}
cardmax
++
;
card
->
next
=
NULL
;
/*end of chain */
if
(
card_last
)
card_last
->
next
=
card
;
/* pointer to next card */
else
card_root
=
card
;
card_last
=
card
;
/* new chain end */
pci_set_drvdata
(
akt_pcidev
,
card
);
return
0
;
err_out_card:
kfree
(
card
);
err_out:
pci_disable_device
(
akt_pcidev
);
return
rc
;
}
static
void
__devexit
hysdn_pci_remove_one
(
struct
pci_dev
*
akt_pcidev
)
{
hysdn_card
*
card
=
pci_get_drvdata
(
akt_pcidev
);
pci_set_drvdata
(
akt_pcidev
,
NULL
);
if
(
card
->
stopcard
)
card
->
stopcard
(
card
);
#ifdef CONFIG_HYSDN_CAPI
hycapi_capi_release
(
card
);
#endif
if
(
card
->
releasehardware
)
card
->
releasehardware
(
card
);
/* free all hardware resources */
if
(
card
==
card_root
)
{
card_root
=
card_root
->
next
;
if
(
!
card_root
)
card_last
=
NULL
;
}
else
{
hysdn_card
*
tmp
=
card_root
;
while
(
tmp
)
{
if
(
tmp
->
next
==
card
)
tmp
->
next
=
card
->
next
;
card_last
=
tmp
;
tmp
=
tmp
->
next
;
}
}
kfree
(
card
);
pci_disable_device
(
akt_pcidev
);
}
static
struct
pci_driver
hysdn_pci_driver
=
{
.
name
=
"hysdn"
,
.
id_table
=
hysdn_pci_tbl
,
.
probe
=
hysdn_pci_init_one
,
.
remove
=
__devexit_p
(
hysdn_pci_remove_one
),
};
static
int
hysdn_have_procfs
;
static
int
__init
hysdn_init
(
void
)
{
char
tmp
[
50
];
int
rc
;
strcpy
(
tmp
,
hysdn_init_revision
);
printk
(
KERN_NOTICE
"HYSDN: module Rev: %s loaded
\n
"
,
hysdn_getrev
(
tmp
));
strcpy
(
tmp
,
hysdn_net_revision
);
printk
(
KERN_NOTICE
"HYSDN: network interface Rev: %s
\n
"
,
hysdn_getrev
(
tmp
));
search_cards
();
rc
=
pci_register_driver
(
&
hysdn_pci_driver
);
if
(
rc
)
return
rc
;
printk
(
KERN_INFO
"HYSDN: %d card(s) found.
\n
"
,
cardmax
);
if
(
hysdn_procconf_init
())
{
free_resources
();
/* proc file_sys not created */
return
(
-
1
);
}
if
(
!
hysdn_procconf_init
())
hysdn_have_procfs
=
1
;
#ifdef CONFIG_HYSDN_CAPI
if
(
cardmax
>
0
)
{
if
(
hycapi_init
())
{
printk
(
KERN_ERR
"HYCAPI: init failed
\n
"
);
return
(
-
1
);
if
(
hysdn_have_procfs
)
hysdn_procconf_release
();
pci_unregister_driver
(
&
hysdn_pci_driver
);
return
-
ESPIPE
;
}
}
#endif
/* CONFIG_HYSDN_CAPI */
return
(
0
);
/* no error */
return
0
;
/* no error */
}
/* init_module */
...
...
@@ -230,20 +221,15 @@ hysdn_init(void)
static
void
__exit
hysdn_exit
(
void
)
{
if
(
hysdn_have_procfs
)
hysdn_procconf_release
();
pci_unregister_driver
(
&
hysdn_pci_driver
);
#ifdef CONFIG_HYSDN_CAPI
hysdn_card
*
card
;
#endif
/* CONFIG_HYSDN_CAPI */
stop_cards
();
#ifdef CONFIG_HYSDN_CAPI
card
=
card_root
;
/* first in chain */
while
(
card
)
{
hycapi_capi_release
(
card
);
card
=
card
->
next
;
/* remove card from chain */
}
/* while card */
hycapi_cleanup
();
#endif
/* CONFIG_HYSDN_CAPI */
hysdn_procconf_release
();
free_resources
();
printk
(
KERN_NOTICE
"HYSDN: module unloaded
\n
"
);
}
/* cleanup_module */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment