Add 'pcilkm' module.
It is a layer to make it possible to have loadable PCI device drivers. First you load (with symbols) the pcilkm module, then you can load PCI drivers that have been compiled to work with pcilkm. Two examples are provided. 'pcienum', the first one, is a simple demonstration of how to use pcilkm: it is the basic skeleton of a PCI driver, and will attach at load time to all PCI devices known to the system. The second example 'auich' demonstrates how simple it is to use an existing driver as a LKM. It simply includes the code for auich(4) and then adds the necessary pcilkm logic. However there are some drawbacks that are described in the README file.
This commit is contained in:
parent
f41923b7dd
commit
4791863f66
6
sys/lkm/dev/pcilkm/Makefile
Normal file
6
sys/lkm/dev/pcilkm/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $NetBSD: Makefile,v 1.1 2004/07/02 13:26:40 cube Exp $
|
||||
|
||||
KMOD= pcilkm
|
||||
SRCS= pcilkm_lkm.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
8
sys/lkm/dev/pcilkm/examples/auich/Makefile
Normal file
8
sys/lkm/dev/pcilkm/examples/auich/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $NetBSD: Makefile,v 1.1 2004/07/02 13:26:41 cube Exp $
|
||||
|
||||
KMOD= auich
|
||||
MAN= #
|
||||
|
||||
SRCS= auich_lkm.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
22
sys/lkm/dev/pcilkm/examples/auich/README
Normal file
22
sys/lkm/dev/pcilkm/examples/auich/README
Normal file
@ -0,0 +1,22 @@
|
||||
$NetBSD: README,v 1.1 2004/07/02 13:26:41 cube Exp $
|
||||
|
||||
The auich module is provided as an example of the use of the pcilkm layer.
|
||||
|
||||
It should be noted that it has limitations. First, it cannot be unloaded.
|
||||
This is because auich(4) does not provide a detach() method, thus neither
|
||||
the underlying audio(4) device not the auich(4) device ca be detached.
|
||||
Therefore the pcilkm layer prevents the auich module from being removed.
|
||||
|
||||
Second, auich(4) has some dependencies, listed in dev/pci/files.pci, which
|
||||
are required for the module to work properly. This includes audio, ac97
|
||||
and some other components that may interact with each other.
|
||||
|
||||
For example, the aurateconv component, needed by auich(4), is optional in
|
||||
the NetBSD kernel for audio(4) operations, and does not change the API.
|
||||
If aurateconv is lacking, loading the auich module will result in a
|
||||
panic. It might be considered as a bug, but it is not really relevant
|
||||
since most of the kernel is not ready for device drivers modules.
|
||||
|
||||
To test that module, I recommend that you keep in your kernel config file
|
||||
the definition for auvia* at pci?, since auvia(4) has the same list of
|
||||
requirements as auich(4).
|
49
sys/lkm/dev/pcilkm/examples/auich/auich_lkm.c
Normal file
49
sys/lkm/dev/pcilkm/examples/auich/auich_lkm.c
Normal file
@ -0,0 +1,49 @@
|
||||
/* $NetBSD: auich_lkm.c,v 1.1 2004/07/02 13:26:41 cube Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 The NetBSD Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to the NetBSD Foundation
|
||||
* by Quentin Garnier.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <dev/pci/auich.c>
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: auich_lkm.c,v 1.1 2004/07/02 13:26:41 cube Exp $");
|
||||
|
||||
#include <sys/lkm.h>
|
||||
#include <lkm/dev/pcilkm/pcilkm.h>
|
||||
|
||||
MOD_MISC("auich");
|
||||
|
||||
static const char * const auich_attrs[] = { "audiobus", NULL };
|
||||
PCILKM_DECLARE(auich, DV_DULL, auich_attrs);
|
5
sys/lkm/dev/pcilkm/examples/pcienum/Makefile
Normal file
5
sys/lkm/dev/pcilkm/examples/pcienum/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
KMOD= pcienum
|
||||
MAN= #
|
||||
SRCS= pcienum_lkm.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
89
sys/lkm/dev/pcilkm/examples/pcienum/pcienum_lkm.c
Normal file
89
sys/lkm/dev/pcilkm/examples/pcienum/pcienum_lkm.c
Normal file
@ -0,0 +1,89 @@
|
||||
/* $NetBSD: pcienum_lkm.c,v 1.1 2004/07/02 13:26:41 cube Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 The NetBSD Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to the NetBSD Foundation
|
||||
* by Quentin Garnier.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: pcienum_lkm.c,v 1.1 2004/07/02 13:26:41 cube Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/lkm.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <lkm/dev/pcilkm/pcilkm.h>
|
||||
|
||||
static int pcienum_match(struct device *, struct cfdata *, void *);
|
||||
static void pcienum_attach(struct device *, struct device *, void *);
|
||||
static int pcienum_detach(struct device *, int);
|
||||
|
||||
MOD_MISC("pcienum");
|
||||
CFATTACH_DECL(pcienum, sizeof(struct device), pcienum_match,
|
||||
pcienum_attach, pcienum_detach, NULL);
|
||||
PCILKM_DECLARE(pcienum, DV_DULL, NULL);
|
||||
|
||||
static int
|
||||
pcienum_match(struct device *parent, struct cfdata *match, void *aux)
|
||||
{
|
||||
/* That sample will match every device */
|
||||
#if 0
|
||||
struct pci_attach_args *pa = aux;
|
||||
|
||||
if (PCI_VENDOR(pa->pa_id) == MY_PCI_VENDOR &&
|
||||
PCI_PRODUCT(pa->pa_id) == MY_PCI_DEVICE)
|
||||
#endif
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
pcienum_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct pci_attach_args *pa = aux;
|
||||
aprint_normal(": vendor 0x%04x device 0x%04x\n",
|
||||
PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id));
|
||||
}
|
||||
|
||||
static int
|
||||
pcienum_detach(struct device *self, int flags)
|
||||
{
|
||||
return (0);
|
||||
}
|
163
sys/lkm/dev/pcilkm/pcilkm.4
Normal file
163
sys/lkm/dev/pcilkm/pcilkm.4
Normal file
@ -0,0 +1,163 @@
|
||||
.\" $NetBSD: pcilkm.4,v 1.1 2004/07/02 13:26:40 cube Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2004 The NetBSD Foundation.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to the NetBSD Foundation
|
||||
.\" by Quentin Garnier.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the NetBSD
|
||||
.\" Foundation, Inc. and its contributors.
|
||||
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
.\" contributors may be used to endorse or promote products derived
|
||||
.\" from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd July 2nd, 2004
|
||||
.Dt PCILKM 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm pcilkm
|
||||
.Nd Loadable Kernel Module that can load PCI device drivers
|
||||
.Sh SYNOPSIS
|
||||
.In sys/lkm.h
|
||||
.In lkm/dev/pcilkm/pcilkm.h
|
||||
.Fn PCILKM_DECLARE name class attrs
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is meant to be a layer between the kernel and loadable PCI device drivers,
|
||||
making the necessary operations to glue the driver to
|
||||
.Xr autoconf 9 .
|
||||
.Pp
|
||||
It works by catching the usual load/unload calls of the LKM framework.
|
||||
The
|
||||
.Xr autoconf 9
|
||||
structures are updated to reflect the addition of the new driver.
|
||||
Then
|
||||
.Nm
|
||||
performs a scan of the PCI buses that will call the
|
||||
.Fn match
|
||||
and
|
||||
.Fn attach
|
||||
functions of the driver as it would be the case for a compiled-in
|
||||
PCI device driver.
|
||||
.Pp
|
||||
.Nm
|
||||
was designed to minimize the difference between a regular compiled-in
|
||||
driver and a loadable driver.
|
||||
The programmer only has to add the required
|
||||
.Em MOD_*
|
||||
directive, depending on the type of the driver,
|
||||
and then attach the driver to the
|
||||
.Nm
|
||||
framework by using the
|
||||
.Fn PCILKM_DECLARE
|
||||
macro.
|
||||
.Pp
|
||||
The
|
||||
.Em name
|
||||
argument is used to build various structure names and must match the name
|
||||
given to the
|
||||
.Fn CFATTACH_DECL
|
||||
macro.
|
||||
Since the
|
||||
.Em struct cfattach
|
||||
variable is referenced by
|
||||
.Fn PCILKM_DECLARE ,
|
||||
the
|
||||
.Fn CFATTACH_DECL
|
||||
directive must appear earlier in the source file.
|
||||
.Pp
|
||||
The
|
||||
.Em class
|
||||
and
|
||||
.Em attrs
|
||||
arguments are the ones
|
||||
.Xr config 8
|
||||
would write down in the
|
||||
.Fn CFDRIVER_DECL
|
||||
directive of that driver if it was compiled-in and properly referenced in
|
||||
the kernel configuration file.
|
||||
The values
|
||||
.Em DV_DULL
|
||||
and
|
||||
.Em NULL
|
||||
will fit in most cases, unless you want to have other devices attached to
|
||||
the managed device, in which case a properly built
|
||||
.Em attrs
|
||||
structure has to be passed.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
module must be loaded along with its symbol table to be useful,
|
||||
since actual device driver loaded afterwards reference an exported
|
||||
function.
|
||||
Therefore,
|
||||
.Xr ksyms 4
|
||||
support is required in the kernel.
|
||||
.Sh EXAMPLE
|
||||
The following piece of code shows the basic skeleton of a loadable PCI
|
||||
device driver:
|
||||
.Bd -literal -offset indent -compact
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/lkm.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <lkm/dev/pcilkm/pcilkm.h>
|
||||
.sp
|
||||
static int foo_attach(struct device *, struct cfdata *, void *);
|
||||
static void foo_attach(struct device *, struct device *, void *);
|
||||
static int foo_detach(struct device *, int);
|
||||
.sp
|
||||
MOD_MISC("foo");
|
||||
CFATTACH_DECL(foo, sizeof(struct device), foo_match,
|
||||
foo_attach, foo_detach, NULL);
|
||||
PCILKM_DECLARE(foo, DV_DULL, NULL);
|
||||
.sp
|
||||
static int
|
||||
foo_match(struct device *parent, struct cfdata *match, void *aux)
|
||||
{
|
||||
...
|
||||
}
|
||||
.sp
|
||||
static void
|
||||
foo_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
...
|
||||
}
|
||||
.sp
|
||||
static int
|
||||
foo_detach(struct device *self, int flags)
|
||||
{
|
||||
...
|
||||
}
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr autoconf 9 ,
|
||||
.Xr ksyms 4 ,
|
||||
.Xr lkm 4 ,
|
||||
.Xr pci 4
|
71
sys/lkm/dev/pcilkm/pcilkm.h
Normal file
71
sys/lkm/dev/pcilkm/pcilkm.h
Normal file
@ -0,0 +1,71 @@
|
||||
/* $NetBSD: pcilkm.h,v 1.1 2004/07/02 13:26:40 cube Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 The NetBSD Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to the NetBSD Foundation
|
||||
* by Quentin Garnier.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _PCILKM_H_
|
||||
#define _PCILKM_H_
|
||||
|
||||
struct pcilkm_driver {
|
||||
struct lkm_any *pld_module;
|
||||
struct cfattach *pld_cfa;
|
||||
struct cfdriver *pld_cfd;
|
||||
struct cftable pld_cft;
|
||||
};
|
||||
|
||||
int pcilkm_hostlkmentry(struct lkm_table *, int, int, struct pcilkm_driver *);
|
||||
extern const struct cfparent pcilkm_pspec;
|
||||
extern int pcilkm_loc[];
|
||||
extern const char * const pcilkmcf_locnames[];
|
||||
|
||||
#define PCILKM_DECLARE(name, class, attrs) \
|
||||
CFDRIVER_DECL(name, class, attrs); \
|
||||
struct cfdata __CONCAT(name,_cfdata) [] = { \
|
||||
{ __STRING(name), __STRING(name), 0, \
|
||||
FSTATE_STAR, pcilkm_loc, 0, \
|
||||
&pcilkm_pspec, pcilkmcf_locnames }, \
|
||||
{ 0 } }; \
|
||||
struct pcilkm_driver __CONCAT(name,_pld) = { \
|
||||
(struct lkm_any *)& _module, \
|
||||
& __CONCAT(name,_ca), \
|
||||
& __CONCAT(name,_cd), \
|
||||
{ __CONCAT(name,_cfdata) } }; \
|
||||
int __CONCAT(name,_lkmentry) (struct lkm_table *lkmtp, \
|
||||
int cmd, int ver) \
|
||||
{ return pcilkm_hostlkmentry(lkmtp, cmd, ver, \
|
||||
& __CONCAT(name,_pld)); }
|
||||
|
||||
#endif /* !_PCILKM_H */
|
226
sys/lkm/dev/pcilkm/pcilkm_lkm.c
Normal file
226
sys/lkm/dev/pcilkm/pcilkm_lkm.c
Normal file
@ -0,0 +1,226 @@
|
||||
/* $NetBSD: pcilkm_lkm.c,v 1.1 2004/07/02 13:26:40 cube Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 The NetBSD Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to the NetBSD Foundation
|
||||
* by Quentin Garnier.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: pcilkm_lkm.c,v 1.1 2004/07/02 13:26:40 cube Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/lkm.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
#include <machine/vmparam.h>
|
||||
#include <machine/pmap.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcidevs.h>
|
||||
|
||||
#include <lkm/dev/pcilkm/pcilkm.h>
|
||||
|
||||
MOD_MISC("pcilkm");
|
||||
|
||||
/* Module functions */
|
||||
int pcilkm_lkmentry(struct lkm_table *, int, int);
|
||||
static int pcilkm_lkmload(struct lkm_table *, int);
|
||||
static int pcilkm_lkmunload(struct lkm_table *, int);
|
||||
static int pcilkm_submatch(struct device *, struct cfdata *, void *);
|
||||
static int pcilkm_print(void *, const char *);
|
||||
static int pcilkm_probe(struct pci_attach_args *);
|
||||
|
||||
/* Host functions */
|
||||
int pcilkm_hostlkmentry(struct lkm_table *, int, int, struct pcilkm_driver *);
|
||||
static int pcilkm_hostlkmload(struct pcilkm_driver *pld);
|
||||
static int pcilkm_hostlkmunload(struct pcilkm_driver *pld);
|
||||
|
||||
/* Non-exported PCI functions */
|
||||
int pciprint __P((void *, const char *));
|
||||
int pcisubmatch __P((struct device *, struct cfdata *, void *));
|
||||
|
||||
static struct pcilkm_driver *cur_module;
|
||||
static struct simplelock curmod_lock;
|
||||
static int nclients;
|
||||
|
||||
MALLOC_DEFINE(M_PCILKM, "pcilkm", "LKM PCI driver helper");
|
||||
|
||||
const struct cfparent pcilkm_pspec = { "pci", "pci", DVUNIT_ANY };
|
||||
int pcilkm_loc[] = { -1, -1 };
|
||||
const char * const pcilkmcf_locnames[] = { "dev", "function", NULL };
|
||||
|
||||
/* LKM management routines */
|
||||
|
||||
int
|
||||
pcilkm_lkmentry(struct lkm_table *lkmtp, int cmd, int ver)
|
||||
{
|
||||
DISPATCH(lkmtp, cmd, ver, pcilkm_lkmload, pcilkm_lkmunload, lkm_nofunc);
|
||||
}
|
||||
|
||||
static int
|
||||
pcilkm_lkmload(struct lkm_table *lkmtp, int cmd)
|
||||
{
|
||||
malloc_type_attach(M_PCILKM);
|
||||
simple_lock_init(&curmod_lock);
|
||||
nclients = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pcilkm_lkmunload(struct lkm_table *lkmtp, int cmd)
|
||||
{
|
||||
if (nclients > 0)
|
||||
return (EBUSY);
|
||||
|
||||
malloc_type_detach(M_PCILKM);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Host LKM management routines */
|
||||
|
||||
int
|
||||
pcilkm_hostlkmentry(struct lkm_table *lkmtp, int cmd, int ver, struct pcilkm_driver *pld)
|
||||
{
|
||||
switch(cmd) {
|
||||
int error;
|
||||
case LKM_E_LOAD:
|
||||
lkmtp->private.lkm_any = (void *)pld->pld_module;
|
||||
if ((error = lkmdispatch(lkmtp, cmd)) != 0)
|
||||
return error;
|
||||
if ((error = pcilkm_hostlkmload(pld)) != 0)
|
||||
return error;
|
||||
break;
|
||||
case LKM_E_UNLOAD:
|
||||
if ((error = pcilkm_hostlkmunload(pld)) != 0)
|
||||
return error;
|
||||
if ((error = lkmdispatch(lkmtp, cmd)) != 0)
|
||||
return error;
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pcilkm_hostlkmload(struct pcilkm_driver *pld)
|
||||
{
|
||||
int error;
|
||||
|
||||
if ((error = config_cfdriver_attach(pld->pld_cfd)) != 0)
|
||||
return error;
|
||||
if ((error = config_cfattach_attach(pld->pld_module->lkm_name, pld->pld_cfa)) != 0)
|
||||
return error;
|
||||
|
||||
TAILQ_INSERT_TAIL(&allcftables, &pld->pld_cft, ct_list);
|
||||
|
||||
simple_lock(&curmod_lock);
|
||||
cur_module = pld;
|
||||
(void)pci_find_device(NULL, pcilkm_probe);
|
||||
simple_unlock(&curmod_lock);
|
||||
|
||||
if (pld->pld_cfd->cd_ndevs == 0) {
|
||||
TAILQ_REMOVE(&allcftables, &pld->pld_cft, ct_list);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
nclients++;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pcilkm_hostlkmunload(struct pcilkm_driver *pld)
|
||||
{
|
||||
int error, i;
|
||||
|
||||
for (i = 0; i<pld->pld_cfd->cd_ndevs; i++)
|
||||
if ((error = config_detach(pld->pld_cfd->cd_devs[i], 0)) != 0)
|
||||
return error;
|
||||
|
||||
if ((error = config_cfattach_detach(pld->pld_module->lkm_name, pld->pld_cfa)) != 0)
|
||||
return error;
|
||||
if ((error = config_cfdriver_detach(pld->pld_cfd)) != 0)
|
||||
return error;
|
||||
TAILQ_REMOVE(&allcftables, &pld->pld_cft, ct_list);
|
||||
|
||||
nclients--;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* PCI bus probe call-back */
|
||||
|
||||
static int
|
||||
pcilkm_submatch(struct device *parent, struct cfdata *cf, void *aux)
|
||||
{
|
||||
if (cf != cur_module->pld_cft.ct_cfdata)
|
||||
return (0);
|
||||
|
||||
return (pcisubmatch(parent, cf, aux));
|
||||
}
|
||||
|
||||
static int
|
||||
pcilkm_print(void *aux, const char *pnp)
|
||||
{
|
||||
if (pnp == NULL)
|
||||
return pciprint(aux, pnp);
|
||||
|
||||
return (QUIET);
|
||||
}
|
||||
|
||||
static int
|
||||
pcilkm_probe(struct pci_attach_args *paa)
|
||||
{
|
||||
struct device *parent = device_lookup(&pci_cd, paa->pa_bus);
|
||||
|
||||
if (parent)
|
||||
(void)config_found_sm(parent, (void *)paa, pcilkm_print,
|
||||
pcilkm_submatch);
|
||||
|
||||
/*
|
||||
* The way pci_find_device() is designed doesn't
|
||||
* allow us to report a success to the caller,
|
||||
* unfortunately, since returning non-zero makes
|
||||
* the probe stop, although there may be more
|
||||
* cards.
|
||||
*/
|
||||
return (0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user