diff options
Diffstat (limited to 'share/examples/drivers')
-rwxr-xr-x | share/examples/drivers/make_device_driver.sh | 204 |
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); /* |