diff options
author | julian <julian@FreeBSD.org> | 2000-11-11 09:49:49 +0000 |
---|---|---|
committer | julian <julian@FreeBSD.org> | 2000-11-11 09:49:49 +0000 |
commit | b1e3e6e70f23df9589426083a6494eee2ef2409b (patch) | |
tree | 3ec69990872e99a2136278e0d146820837b55d7f /share/examples/drivers/make_device_driver.sh | |
parent | efa3fc82ba5e2cc8062f74b0cc2b46abec2564c3 (diff) | |
download | FreeBSD-src-b1e3e6e70f23df9589426083a6494eee2ef2409b.zip FreeBSD-src-b1e3e6e70f23df9589426083a6494eee2ef2409b.tar.gz |
Add basic PCI capability
Not sure how unit numbers are carried across between
PCI and ISA though.. maybe there should be only one devclass between the two?
Diffstat (limited to 'share/examples/drivers/make_device_driver.sh')
-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); /* |