summaryrefslogtreecommitdiffstats
path: root/share/examples/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'share/examples/drivers')
-rwxr-xr-xshare/examples/drivers/make_device_driver.sh204
1 files changed, 162 insertions, 42 deletions
diff --git a/share/examples/drivers/make_device_driver.sh b/share/examples/drivers/make_device_driver.sh
index 498745d..f2b668f 100755
--- a/share/examples/drivers/make_device_driver.sh
+++ b/share/examples/drivers/make_device_driver.sh
@@ -17,7 +17,7 @@
#
# $FreeBSD$"
#
-#-------cut here------------------
+#
if [ "${1}X" = "X" ]
then
echo "Hey , how about some help here.. give me a device name!"
@@ -153,9 +153,14 @@ cat >${TOP}/dev/${1}/${1}.c <<DONE
#include <sys/bus.h>
#include <machine/bus.h>
#include <machine/resource.h>
+#include <machine/bus_pio.h>
+#include <machine/bus_memio.h>
#include <sys/rman.h>
#include <sys/time.h>
+#include <pci/pcireg.h>
+#include <pci/pcivar.h>
+
#include <isa/isavar.h>
#include "isa_if.h"
#include <sys/${1}io.h> /* ${1} IOCTL definitions */
@@ -166,14 +171,42 @@ cat >${TOP}/dev/${1}/${1}.c <<DONE
#define SOME_PORT 123
#define EXPECTED_VALUE 0x42
+/*
+ * device specific Misc defines
+ */
+#define BUFFERSIZE 1024
+#define NUMPORTS 4
+#define MEMSIZE (4 * 1024) /* imaginable h/w buffer size */
+
+/*
+ * One of these per allocated device
+ */
+struct ${1}_softc {
+ bus_space_tag_t bt;
+ bus_space_handle_t bh;
+ int rid_ioport;
+ int rid_memory;
+ int rid_irq;
+ int rid_drq;
+ struct resource* res_ioport; /* resource for port range */
+ struct resource* res_memory; /* resource for mem range */
+ struct resource* res_irq; /* resource for irq range */
+ struct resource* res_drq; /* resource for dma channel */
+ device_t device;
+ dev_t dev;
+ void *intr_cookie;
+ void *vaddr; /* Virtual address of mem resource */
+ char buffer[BUFFERSIZE]; /* if we needed to buffer something */
+} ;
+
+typedef struct ${1}_softc *sc_p;
+
/* Function prototypes (these should all be static) */
-static void ${1}_isa_identify (driver_t *, device_t);
-static int ${1}_isa_probe (device_t);
-static int ${1}_isa_attach (device_t);
-static int ${1}_isa_detach (device_t);
static int ${1}_deallocate_resources(device_t device);
static int ${1}_allocate_resources(device_t device);
+static int ${1}_attach(device_t device, sc_p scp);
+static int ${1}_detach(device_t device, sc_p scp);
static d_open_t ${1}open;
static d_close_t ${1}close;
@@ -202,37 +235,13 @@ static struct cdevsw ${1}_cdevsw = {
/* bmaj */ -1
};
-/*
- * device specific Misc defines
- */
-#define BUFFERSIZE 1024
-#define NUMPORTS 4
-#define MEMSIZE (4 * 1024) /* imaginable h/w buffer size */
-
-/*
- * One of these per allocated device
- */
-struct ${1}_softc {
- bus_space_tag_t bt;
- bus_space_handle_t bh;
- int rid_ioport;
- int rid_memory;
- int rid_irq;
- int rid_drq;
- struct resource* res_ioport; /* resource for port range */
- struct resource* res_memory; /* resource for mem range */
- struct resource* res_irq; /* resource for irq range */
- struct resource* res_drq; /* resource for dma channel */
- device_t device;
- dev_t dev;
- void *intr_cookie;
- void *vaddr; /* Virtual address of mem resource */
- char buffer[BUFFERSIZE]; /* if we needed to buffer something */
-} ;
-
-typedef struct ${1}_softc *sc_p;
-
-static devclass_t ${1}_devclass;
+/*****************************************\
+* ISA Attachment structures and functions
+\*****************************************/
+static void ${1}_isa_identify (driver_t *, device_t);
+static int ${1}_isa_probe (device_t);
+static int ${1}_isa_attach (device_t);
+static int ${1}_isa_detach (device_t);
static struct isa_pnp_id ${1}_ids[] = {
{0x12345678, "ABCco Widget"},
@@ -254,6 +263,8 @@ static driver_t ${1}_isa_driver = {
sizeof (struct ${1}_softc)
};
+static devclass_t ${1}_devclass;
+
DRIVER_MODULE(${1}, isa, ${1}_isa_driver, ${1}_devclass, 0, 0);
/*
@@ -421,7 +432,6 @@ ${1}_isa_probe (device_t device)
error = bus_get_resource(device, SYS_RES_IOPORT, 0,
&port_start, &port_count);
-
/* dummy heuristic type probe */
if ( inb(port_start) != EXPECTED_VALUE) {
/*
@@ -473,17 +483,126 @@ errexit:
* Called if the probe succeeded and our bid won the device.
* We can be destructive here as we know we have the device.
* This is the first place we can be sure we have a softc structure.
+ * You would do ISA specific attach things here, but generically there aren't
+ * any (yey new-bus!).
*/
static int
${1}_isa_attach (device_t device)
{
- int unit = device_get_unit(device);
sc_p scp = device_get_softc(device);
+ int error;
+
+ error = ${1}_attach(device, scp);
+ if (error) {
+ ${1}_isa_detach(device);
+ }
+ return (error);
+
+}
+
+/*
+ * detach the driver (e.g. module unload)
+ * call the bus independent version
+ * and undo anything we did in the ISA attach routine.
+ */
+static int
+${1}_isa_detach (device_t device)
+{
+ sc_p scp = device_get_softc(device);
+ int error;
+
+ error = ${1}_detach(device, scp);
+ return (error);
+}
+
+/***************************************\
+* PCI Attachment structures and code *
+\***************************************/
+
+static int ${1}_pci_probe __P((device_t));
+static int ${1}_pci_attach __P((device_t));
+static int ${1}_pci_detach __P((device_t));
+
+static device_method_t ${1}_pci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ${1}_pci_probe),
+ DEVMETHOD(device_attach, ${1}_pci_attach),
+ DEVMETHOD(device_detach, ${1}_pci_detach),
+ { 0, 0 }
+};
+
+static driver_t ${1}_pci_driver = {
+ "${1}",
+ ${1}_pci_methods,
+ sizeof(struct ${1}_softc),
+};
+
+static devclass_t ${1}_pci_devclass;
+
+DRIVER_MODULE(${1}, pci, ${1}_pci_driver, ${1}_pci_devclass, 0, 0);
+
+static struct _pcsid
+{
+ u_int32_t type;
+ const char *desc;
+} pci_ids[] = {
+ { 0x1234abcd, "ACME PCI Widgetplus" },
+ { 0x1234fedc, "Happy moon brand RIPOFFplus" },
+ { 0x00000000, NULL }
+};
+
+static int
+${1}_pci_probe (device_t device)
+{
+ u_int32_t type = pci_get_devid(device);
+ struct _pcsid *ep =pci_ids;
+
+ while (ep->type && ep->type != type)
+ ++ep;
+ if (ep->desc) {
+ device_set_desc(device, ep->desc);
+ return 0;
+ } else {
+ return ENXIO;
+ }
+}
+
+static int
+${1}_pci_attach(device_t device)
+{
+ sc_p scp = device_get_softc(device);
+ int error;
+
+ error = ${1}_attach(device, scp);
+ if (error) {
+ ${1}_pci_detach(device);
+ }
+ return (error);
+}
+
+static int
+${1}_pci_detach (device_t device)
+{
+ sc_p scp = device_get_softc(device);
+ int error;
+
+ error = ${1}_detach(device, scp);
+ return (error);
+}
+
+
+/****************************************\
+* Common Attachment subfunctions *
+\****************************************/
+static int
+${1}_attach(device_t device, sc_p scp)
+{
+ int unit = device_get_unit(device);
device_t parent = device_get_parent(device);
- scp->dev->si_drv1 = scp;
scp->dev = make_dev(&${1}_cdevsw, 0,
UID_ROOT, GID_OPERATOR, 0600, "${1}%d", unit);
+ scp->dev->si_drv1 = scp;
if (${1}_allocate_resources(device)) {
goto errexit;
@@ -508,6 +627,8 @@ ${1}_isa_attach (device_t device)
if (BUS_SETUP_INTR(parent, device, scp->res_irq, INTR_TYPE_TTY,
${1}intr, scp, &scp->intr_cookie) == 0) {
/* do something if successfull */
+ } else {
+ goto errexit;
}
}
@@ -522,14 +643,13 @@ errexit:
/*
* Undo anything we may have done
*/
- ${1}_isa_detach(device);
+ ${1}_detach(device, scp);
return (ENXIO);
}
static int
-${1}_isa_detach (device_t device)
+${1}_detach(device_t device, sc_p scp)
{
- sc_p scp = device_get_softc(device);
device_t parent = device_get_parent(device);
/*
OpenPOWER on IntegriCloud