From owner-freebsd-bugs Thu Mar 18 20:10:23 1999 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id 3D1F91558B for ; Thu, 18 Mar 1999 20:10:21 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.2/8.9.2) id UAA04696; Thu, 18 Mar 1999 20:10:02 -0800 (PST) (envelope-from gnats@FreeBSD.org) Date: Thu, 18 Mar 1999 20:10:02 -0800 (PST) Message-Id: <199903190410.UAA04696@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: "Christopher R. Bowman" Subject: Re: misc/8139: [patch] missing /usr/src/share/examples/drivers/make_pci_driver.sh Reply-To: "Christopher R. Bowman" Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org The following reply was made to PR misc/8139; it has been noted by GNATS. From: "Christopher R. Bowman" To: freebsd-gnats-submit@freebsd.org, crb@ChrisBowman.com Cc: Subject: Re: misc/8139: [patch] missing /usr/src/share/examples/drivers/make_pci_driver.sh Date: Thu, 18 Mar 1999 23:04:37 -0500 --=====================_172594468==_ Content-Type: text/plain; charset="us-ascii" attached find a new version suitable for 3.1 RELEASE --=====================_172594468==_ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="make_pci_driver3.0.sh" #!/bin/sh # This writes a skeleton pci driver and puts it into the kernel tree for= you #arg1 is lowercase "foo" # # It also creates a directory under /usr/src/sys/modules to help you= create # kernel loadable modules, though without much use except for= development. # # files= created: #= /sys/i386/conf/files.FOO #= /sys/i386/conf/FOO # /sys/pci/foo.c # /sys/sys/fooio.h # /usr/src/sys/modules/foo # # Trust me, RUN THIS SCRIPT :) # #-------cut here------------------ cd /sys/i386/conf if [ "${1}X" =3D "X" ] then echo "Hey , how about some help here.. give me a device name!" exit 1 fi if [ -d /usr/src/sys/modules ] then mkdir /usr/src/sys/modules/${1} fi UPPER=3D`echo ${1} |tr "[:lower:]" "[:upper:]"` cat >files.${UPPER} <${UPPER} <>${UPPER} cat >>${UPPER} <../../pci/${1}.c <0 #include "${1}.h" /* generated file.. defines N${UPPER} */ #include #include #include #include /* SYSINIT stuff */ #include /* cdevsw stuff */ #include /* malloc region definitions */ #include /* DELAY() */ #include /* NCPI definitions */ #include /* pci variables etc. */ #include /* pci register definitions etc. */ #include /* ${1} IOCTL definitions */ #ifdef DEVFS #include /* DEVFS defintitions */ #endif /* DEVFS */ #ifdef ${UPPER}_KLD_MODULE #include /* KLD module definitions */ #endif #endif #define ${1}_DEV_PCI_ID CHANGE_ME /* pci device id of your device */ = /* Function prototypes (these should all be static) */ static d_open_t ${1}open; static d_close_t ${1}close; static d_read_t ${1}read; static d_write_t ${1}write; static d_ioctl_t ${1}ioctl; static d_mmap_t ${1}mmap; static d_poll_t ${1}poll; static const char *${1}probe(pcici_t tag, pcidi_t type); static void ${1}attach(pcici_t tag, int unit); static pci_inthand_t ${1}intr; #ifdef ${UPPER}_KLD_MODULE static ointhand2_t ${1}intr; /* should actually have type inthand2_t= */ #endif #define CDEV_MAJOR 20 static struct cdevsw ${1}_cdevsw =3D= { ${1}open, ${1}close, ${1}read, ${1}write, ${1}ioctl, nullstop, nullreset, nodevtotty, ${1}poll, ${1}mmap, NULL, "${1}", NULL, -1 }; static u_long ${1}count; struct pci_device ${1}driver =3D { "${1}", ${1}probe, ${1}attach, &${1}count, NULL }; /* The DATA_SET macro includes the pci device in the set of pci devices * that will be probed at config time. */ DATA_SET (pcidevice_set, ${1}driver); /* * device specific Misc defines */ #define BUFFERSIZE 1024 #define UNIT(dev) minor(dev) /* assume one minor number per unit */ /* * One of these per allocated device */ struct ${1}_softc { #ifdef DEVFS static void *devfs_token; #endif char buffer[BUFFERSIZE]; pcici_t tag; /* PCI tag, for doing PCI commands */ } ; typedef struct ${1}_softc *sc_p; static sc_p sca[N${UPPER}]; /* this function should discriminate if this device is * or is not handled by this driver, often this will be * as simple as testing the pci id of the device */ static const char * ${1}probe(pcici_t tag, pcidi_t type) { switch (type) { case ${1}_DEV_PCI_ID: return("${1}"); }; return ((char *)0); } /* * Called if the probe succeeded. */ static void ${1}attach(pcici_t tag, int unit) { sc_p scp =3D sca[unit]; /* * Allocate storage for this instance . */ scp =3D malloc(sizeof(*scp), M_DEVBUF, M_NOWAIT); if( scp =3D=3D NULL) { printf("${1}%d failed to allocage driver strorage\n",= unit); return; } bzero(scp, sizeof(*scp)); sca[unit] =3D scp; /* * Store whatever seems wise. */ scp->tag =3D tag; #if DEVFS scp->devfs_token =3D devfs_add_devswf(&${1}_cdevsw, unit, DV_CHR, UID_ROOT, GID_KMEM, 0600, "${1}%d", unit); #endif return; } /* * Macro to check that the unit number is valid * Often this isn't needed as once the open() is performed, * the unit number is pretty much safe.. The exception would be if we * implemented devices that could "go away". in which case all these= routines * would be wise to check the number, DIAGNOSTIC or not. */ #define CHECKUNIT(RETVAL) \ do { /* the do-while is a safe way to do this grouping */ \ if (unit > N${UPPER}) { \ printf(__FUNCTION__ ":bad unit %d\n", unit); \ return (RETVAL); \ } \ if (scp =3D=3D NULL) { \ printf( __FUNCTION__ ": unit %d not attached\n", unit);\ return (RETVAL); \ } \ } while (0) #ifdef DIAGNOSTIC #define CHECKUNIT_DIAG(RETVAL) CHECKUNIT(RETVAL) #else /* DIAGNOSTIC */ #define CHECKUNIT_DIAG(RETVAL) #endif /* DIAGNOSTIC */ static void ${1}intr(void *arg) { /* * well we got an interupt, now what? * Theoretically we don't need to check the unit. */ return; } int ${1}ioctl (dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc= *p) { int unit =3D UNIT (dev); sc_p scp =3D sca[unit]; CHECKUNIT_DIAG(ENXIO); switch (cmd) { case DHIOCRESET: /* whatever resets it */ break; default: return ENXIO; } return (0); } /* * You also need read, write, open, close routines. * This should get you started */ static int ${1}open(dev_t dev, int oflags, int devtype, struct proc *p) { int unit =3D UNIT (dev); sc_p scp =3D sca[unit]; CHECKUNIT(ENXIO); /* * Do processing */ return (0); } static int ${1}close(dev_t dev, int fflag, int devtype, struct proc *p) { int unit =3D UNIT (dev); sc_p scp =3D sca[unit]; CHECKUNIT_DIAG(ENXIO); /* * Do processing */ return (0); } static int ${1}read(dev_t dev, struct uio *uio, int ioflag) { int unit =3D UNIT (dev); sc_p scp =3D sca[unit]; int toread; CHECKUNIT_DIAG(ENXIO); /* * Do processing * read from buffer */ toread =3D (min(uio->uio_resid,= sizeof(scp->buffer))); return(uiomove(scp->buffer, toread, uio)); } static int ${1}write(dev_t dev, struct uio *uio, int ioflag) { int unit =3D UNIT (dev); sc_p scp =3D sca[unit]; int towrite; CHECKUNIT_DIAG(ENXIO); /* * Do processing * write to buffer */ towrite =3D (min(uio->uio_resid,= sizeof(scp->buffer))); return(uiomove(scp->buffer, towrite, uio)); } static int ${1}mmap(dev_t dev, vm_offset_t offset, int nprot) { int unit =3D UNIT (dev); sc_p scp =3D sca[unit]; CHECKUNIT_DIAG(-1); /* * Do processing */ #if 0 /* if we had a frame buffer or whatever.. do this */ if (offset > FRAMEBUFFERSIZE - PAGE_SIZE) { return (-1); } return i386_btop((FRAMEBASE + offset)); #else return (-1); #endif } static int ${1}poll(dev_t dev, int which, struct proc *p) { int unit =3D UNIT (dev); sc_p scp =3D sca[unit]; CHECKUNIT_DIAG(ENXIO); /* * Do processing */ return (0); /* this is the wrong value I'm sure */ } #ifndef ${UPPER}_KLD_MODULE /* * Now for some driver initialisation. * Occurs ONCE during boot (very early). * This is if we are NOT a loadable module. */ static void ${1}_drvinit(void *unused) { dev_t dev; dev =3D makedev(CDEV_MAJOR, 0); cdevsw_add(&dev, &${1}_cdevsw, NULL); } SYSINIT(${1}dev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR, ${1}_drvinit, NULL) #else /* ${UPPER}_KLD_MODULE */ static int ${1}_modevent(module_t mod, int type, void *unused) { switch (type) { case MOD_LOAD: break; case MOD_UNLOAD: break; case MOD_SHUTDOWN: break; default: break; } return 0; } static moduledata_t ${1}mod =3D { "${1}", ${1}_modevent, NULL }; DECLARE_MODULE(${1}, ${1}mod, SI_SUB_PSEUDO, SI_ORDER_ANY); #endif /* ${UPPER}_MODULE */ DONE cat >../../sys/${1}io.h < #endif #include /* * define an ioctl here */ #define DHIOCRESET _IO('D', 0) /* reset the ${1} device */ #endif DONE if [ -d /usr/src/sys/modules/${1} ] then cat >/usr/src/sys/modules/${1}/Makefile < DONE fi config ${UPPER} cd ../../compile/${UPPER} make depend make ${1}.o make exit #--------------end of script--------------- # #edit to your taste.. # # --=====================_172594468==_ Content-Type: text/plain; charset="us-ascii" -------- Christopher R. Bowman crb@ChrisBowman.com http://www.ChrisBowman.com/ --=====================_172594468==_-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message