Initial update pccard code for KLD module support. Module support

however is only marginally useful until the new-style bus (pci and isa)
stuff comes onboard to give us a better shot at actually pci and isa
drivers loadable (or preloadable anyway).
This commit is contained in:
Peter Wemm 1999-01-19 00:18:28 +00:00
parent 6d2a8f1ca0
commit 9b3df7693a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=42819
5 changed files with 85 additions and 157 deletions

View file

@ -7,16 +7,13 @@
#ifndef _PCCARD_DRIVER_H_
#define _PCCARD_DRIVER_H_
struct lkm_table;
struct pccard_device;
extern struct linker_set pccarddrv_set;
void pccard_add_driver __P((struct pccard_device *));
#ifdef _I386_ISA_ISA_DEVICE_H_ /* XXX actually if inthand2_t is declared */
int pccard_alloc_intr __P((u_int imask, inthand2_t *hand, int unit,
u_int *maskp, u_int *pcic_imask));
#endif
void pccard_configure __P((void));
void pccard_remove_driver __P((struct pccard_device *));
int pcic_probe __P((void)); /* XXX should be linker set */

View file

@ -28,7 +28,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: pccard.c,v 1.66 1998/09/24 17:56:31 nate Exp $
* $Id: pccard.c,v 1.67 1998/11/09 09:30:55 peter Exp $
*/
#include "opt_devfs.h"
@ -99,6 +99,9 @@ static void remove_device(struct pccard_devinfo *);
static inthand2_t slot_irq_handler;
static void power_off_slot(void *);
static void pccard_configure(void *);
SYSINIT(pccard, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE + 1, pccard_configure, NULL);
#if NAPM > 0
/*
* For the APM stuff, the apmhook structure is kept
@ -148,26 +151,43 @@ static struct cdevsw crd_cdevsw =
* Each controller indicates the number of slots
* that it sees, and these are mapped to a master
* slot number accessed via the character device entries.
*
* XXX this is a relic. Each controller has it's own probe
* configuration hook. Printing a list of configured devices
* with pccard support probably isn't all that useful.
*/
void
pccard_configure(void)
static void
pccard_configure(dummy)
void *dummy;
{
struct pccard_device **drivers, *drv;
struct pccard_device **driver, *drv;
#include "pcic.h"
#if NPCIC > 0
pcic_probe();
#endif
drivers = (struct pccard_device **)pccarddrv_set.ls_items;
/* This isn't strictly correct, but works because of initialize order */
driver = &drivers;
printf("Initializing PC-card drivers:");
while ((drv = *drivers++)) {
while ((drv = *driver++))
printf(" %s", drv->name);
pccard_add_driver(drv);
}
printf("\n");
}
int
pccard_module_handler(module_t mod, int what, void *arg)
{
struct pccard_device *drv = (struct pccard_device *)arg;
switch(what) {
case MOD_LOAD:
pccard_add_driver(drv);
break;
case MOD_UNLOAD:
pccard_remove_driver(drv);
break;
default:
break;
}
return 0;
}
/*
* pccard_add_driver - Add a new driver to the list of
* drivers available for allocation.

View file

@ -1,6 +1,6 @@
/*
* Intel PCIC or compatible Controller driver
* May be built using LKM to make a loadable module.
* May be built to make a loadable module.
*-------------------------------------------------------------------------
*
* Copyright (c) 1995 Andrew McRae. All rights reserved.
@ -36,6 +36,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/select.h>
#include <sys/interrupt.h>
@ -66,9 +67,8 @@ static void pcic_mapirq __P((struct slot *, int));
static timeout_t pcictimeout;
static struct callout_handle pcictimeout_ch
= CALLOUT_HANDLE_INITIALIZER(&pcictimeout_ch);
#ifdef LKM
static int pcic_handle __P((struct lkm_table *lkmtp, int cmd));
#endif
static int pcic_modevent __P((module_t, int, void *));
static int pcic_unload __P((void));
static int pcic_memory(struct slot *, int);
static int pcic_io(struct slot *, int);
static u_int build_freelist(u_int);
@ -161,12 +161,6 @@ putw(struct pcic_slot *sp, int reg, unsigned short word)
/*
* Loadable kernel module interface.
*/
#ifdef LKM
/*
* This defines the lkm_misc module use by modload
* to define the module name.
*/
MOD_MISC(pcic);
/*
* Module handler that processes loads and unloads.
@ -174,73 +168,56 @@ MOD_MISC(pcic);
* is called to install the slots (if any).
*/
static int
pcic_handle(struct lkm_table *lkmtp, int cmd)
pcic_modevent(module_t mod, int what, void *arg)
{
int err = 0; /* default = success*/
static int pcic_started = 0;
switch(cmd) {
case LKM_E_LOAD:
switch (what) {
case MOD_LOAD:
/*
* Don't load twice! (lkmexists() is exported by kern_lkm.c)
*/
if (lkmexists(lkmtp))
return(EEXIST);
/*
* Call the probe routine to find the slots. If
* no slots exist, then don't bother loading the module.
* XXX but this is not appropriate as a static module.
*/
if (pcic_probe() == 0)
return(ENODEV);
break; /* Success*/
/*
* Attempt to unload the slot driver.
*/
case LKM_E_UNLOAD:
printf("Unloading PCIC driver\n");
err = pcic_unload(lkmtp, cmd);
if (pcic_probe())
pcic_started = 1;
break;
case MOD_UNLOAD:
/*
* Attempt to unload the slot driver.
*/
if (pcic_started) {
printf("Unloading PCIC driver\n");
err = pcic_unload();
pcic_started = 0;
}
break; /* Success*/
default: /* we only understand load/unload*/
err = EINVAL;
default: /* we only care about load/unload; ignore shutdown */
break;
}
return(err);
}
/*
* External entry point; should generally match name of .o file. The
* arguments are always the same for all loaded modules. The "load",
* "unload", and "stat" functions in "DISPATCH" will be called under
* their respective circumstances unless their value is "lkm_nullcmd".
* If called, they are called with the same arguments (cmd is included to
* allow the use of a single function, ver is included for version
* matching between modules and the kernel loader for the modules).
*
* Since we expect to link in the kernel and add external symbols to
* the kernel symbol name space in a future version, generally all
* functions used in the implementation of a particular module should
* be static unless they are expected to be seen in other modules or
* to resolve unresolved symbols alread existing in the kernel (the
* second case is not likely to ever occur).
*
* The entry point should return 0 unless it is refusing load (in which
* case it should return an errno from errno.h).
*/
int
pcic_mod(struct lkm_table *lkmtp, int cmd, int ver)
{
MOD_DISPATCH(pcic, lkmtp, cmd, ver,
pcic_handle, pcic_handle, lkm_nullcmd);
}
static moduledata_t pcic_mod = {
"pcic",
pcic_modevent,
0
};
/* After configure() has run.. bring on the new bus system! */
DECLARE_MODULE(pcic, pcic_mod, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE);
/*
* pcic_unload - Called when unloading a LKM.
* Disables interrupts and resets PCIC.
*/
static int
pcic_unload(struct lkm_table *lkmtp, int cmd)
pcic_unload()
{
int slot;
struct pcic_slot *sp = pcic_slots;
@ -257,7 +234,6 @@ pcic_unload(struct lkm_table *lkmtp, int cmd)
return(0);
}
#endif /* LKM */
#if 0
static void
@ -575,9 +551,6 @@ pcic_probe(void)
cinfo.irqs = free_irqs;
cinfo.imask = &pcic_imask;
#ifdef LKM
bzero(pcic_slots, sizeof(pcic_slots));
#endif
sp = pcic_slots;
for (slotnum = 0; slotnum < PCIC_MAX_SLOTS; slotnum++, sp++) {
/*

View file

@ -41,99 +41,19 @@
#include <sys/select.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <pccard/cardinfo.h>
#include <pccard/driver.h>
#include <pccard/slot.h>
/*
* This defines the lkm_misc module use by modload
* to define the module name.
*/
MOD_MISC(skel);
static int skelinit(struct pccard_devinfo *); /* init device */
static void skelunload(struct pccard_devinfo *); /* Disable driver */
static int skelintr(struct pccard_devinfo *); /* Interrupt handler */
static struct pccard_device skel_info = {
"skel",
skelinit,
skelunload,
skelintr,
0, /* Attributes - presently unused */
&net_imask /* Interrupt mask for device */
};
DATA_SET(pccarddrv_set, skel_info);
PCCARD_MODULE(skel, skelinit, skelunload, skelintr, 0, net_imask);
static int opened; /* Rather minimal device state... */
/*
* Module handler that processes loads and unloads.
* Once the module is loaded, the add driver routine is called
* to register the driver.
* If an unload is requested the remove driver routine is
* called to deregister the driver before unloading.
*/
static int
skel_handle(lkmtp, cmd)
struct lkm_table *lkmtp;
int cmd;
{
int i;
struct lkm_misc *args = lkmtp->private.lkm_misc;
int err = 0; /* default = success*/
switch( cmd) {
case LKM_E_LOAD:
/*
* Now register the driver
*/
pccard_add_driver(&skel_info);
break; /* Success*/
/*
* Attempt to deregister the driver.
*/
case LKM_E_UNLOAD:
pccard_remove_driver(&skel_info);
break; /* Success*/
default: /* we only understand load/unload*/
err = EINVAL;
break;
}
return( err);
}
/*
* External entry point; should generally match name of .o file. The
* arguments are always the same for all loaded modules. The "load",
* "unload", and "stat" functions in "MOD_DISPATCH" will be called under
* their respective circumstances unless their value is "nosys". If
* called, they are called with the same arguments (cmd is included to
* allow the use of a single function, ver is included for version
* matching between modules and the kernel loader for the modules).
*
* Since we expect to link in the kernel and add external symbols to
* the kernel symbol name space in a future version, generally all
* functions used in the implementation of a particular module should
* be static unless they are expected to be seen in other modules or
* to resolve unresolved symbols alread existing in the kernel (the
* second case is not likely to ever occur).
*
* The entry point should return 0 unless it is refusing load (in which
* case it should return an errno from errno.h).
*/
int
skel(lkmtp, cmd, ver)
struct lkm_table *lkmtp;
int cmd;
int ver;
{
MOD_DISPATCH(skel,lkmtp,cmd,ver,skel_handle,skel_handle,nosys)
}
/*
* Skeleton driver entry points for PCCARD configuration.
*/

View file

@ -86,6 +86,24 @@ struct pccard_device {
struct pccard_device *next;
};
int pccard_module_handler __P((module_t mod, int what, void *arg));
#define PCCARD_MODULE(name, enable, disable, handler, attr, imask) \
static struct pccard_device name ## _info = { \
#name, \
enable, \
disable, \
handler, \
attr, \
&imask \
}; \
static moduledata_t name ## _mod = { \
"pccard_" #name, \
pccard_module_handler, \
&name ## _info \
}; \
DECLARE_MODULE(name, name ## _mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
/*
* Device structure for cards. Each card may have one
* or more pccard drivers attached to it; each driver is assumed