Date: Sun, 13 Jul 2003 20:21:19 -0400 (EDT) From: John Wehle <john@feith.com> To: freebsd-hardware@freebsd.org Subject: FreeBSD 4.8 Patch to support NetMos NM9805 1284 Printer port Message-ID: <200307140021.h6E0LJe13039@jwlab.FEITH.COM>
next in thread | raw e-mail | index | archive | help
The enclosed patch adds support for PCI parallel ports. It has been tested on FreeBSD 4.8 with a StarTech PCI parallel card attached to a Canon BJC-250 printer. Changes: 1) Add NetMos NM9805 1284 Printer port to puc_devices. 2) Have puc_pci_attach also attach parallel ports. 3) Fix print_resource_list / puc_print_resource_list debug typo in puc_pci_attach. 4) Have puc_alloc_resource, puc_get_resource, puc_setup_intr, and puc_teardown_intr handle a request from a grandchild (i.e. a child of ppbus). 5) Have puc_alloc_resource and puc_get_resource gracefully fail if a resource of something other than IOPORT or IRQ is requested (i.e. DMA). 6) Have ppc support puc as a parent bus. Enjoy, John Wehle ------------------8<------------------------8<------------------------ *** sys/dev/puc/pucdata.c.ORIGINAL Wed May 14 05:43:22 2003 --- sys/dev/puc/pucdata.c Thu Jun 26 00:07:02 2003 *************** const struct puc_device_description puc_ *** 812,817 **** --- 812,826 ---- }, }, + /* NetMos 0S1P PCI : 0S, 1P */ + { "NetMos NM9805 1284 Printer port", + { 0x9710, 0x9805, 0, 0 }, + { 0xffff, 0xffff, 0, 0 }, + { + { PUC_PORT_TYPE_LPT, 0x10, 0x00, 0x00 }, + }, + }, + /* NetMos 2S1P PCI 16C650 : 2S, 1P */ { "NetMos NM9835 Dual UART and 1284 Printer port", { 0x9710, 0x9835, 0, 0 }, *** sys/dev/puc/puc.c.ORIGINAL Fri Apr 4 03:42:17 2003 --- sys/dev/puc/puc.c Thu Jun 26 00:07:02 2003 *************** puc_pci_attach(device_t dev) *** 293,298 **** --- 293,301 ---- case PUC_PORT_TYPE_COM: typestr = "sio"; break; + case PUC_PORT_TYPE_LPT: + typestr = "ppc"; + break; default: continue; } *************** puc_pci_attach(device_t dev) *** 360,366 **** sc->sc_desc->ports[i].type, sc->sc_desc->ports[i].bar, sc->sc_desc->ports[i].offset); ! print_resource_list(&pdev->resources); #endif device_set_flags(sc->sc_ports[i].dev, sc->sc_desc->ports[i].flags); --- 363,369 ---- sc->sc_desc->ports[i].type, sc->sc_desc->ports[i].bar, sc->sc_desc->ports[i].offset); ! puc_print_resource_list(&pdev->resources); #endif device_set_flags(sc->sc_ports[i].dev, sc->sc_desc->ports[i].flags); *************** static struct resource * *** 621,631 **** --- 624,643 ---- puc_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { + device_t parent; struct puc_device *pdev; struct resource *retval; struct resource_list *rl; struct resource_list_entry *rle; + /* The child might be a grandchild (i.e. a child of ppbus). */ + while (child && (parent = device_get_parent(child)) != dev) + child = parent; + if (! child) { + printf("puc_alloc_resource: oops child not found\n"); + return (NULL); + } + pdev = device_get_ivars(child); rl = &pdev->resources; *************** puc_alloc_resource(device_t dev, device_ *** 634,639 **** --- 646,658 ---- pdev, type, *rid); puc_print_resource_list(rl); #endif + switch (type) { + case SYS_RES_IOPORT: + case SYS_RES_IRQ: + break; + default: + return (NULL); + } retval = NULL; rle = resource_list_find(rl, type, *rid); if (rle) { *************** static int *** 661,670 **** --- 680,698 ---- puc_get_resource(device_t dev, device_t child, int type, int rid, u_long *startp, u_long *countp) { + device_t parent; struct puc_device *pdev; struct resource_list *rl; struct resource_list_entry *rle; + /* The child might be a grandchild (i.e. a child of ppbus). */ + while (child && (parent = device_get_parent(child)) != dev) + child = parent; + if (! child) { + printf("puc_get_resource: oops child not found\n"); + return (ENXIO); + } + pdev = device_get_ivars(child); rl = &pdev->resources; *************** puc_get_resource(device_t dev, device_t *** 673,678 **** --- 701,713 ---- type, rid); puc_print_resource_list(rl); #endif + switch (type) { + case SYS_RES_IOPORT: + case SYS_RES_IRQ: + break; + default: + return (ENXIO); + } rle = resource_list_find(rl, type, rid); if (rle) { #ifdef PUC_DEBUG *************** static int *** 695,703 **** --- 730,747 ---- puc_setup_intr(device_t dev, device_t child, struct resource *r, int flags, void (*ihand)(void *), void *arg, void **cookiep) { + device_t parent; int i; struct puc_softc *sc; + /* The child might be a grandchild (i.e. a child of ppbus). */ + while (child && (parent = device_get_parent(child)) != dev) + child = parent; + if (! child) { + printf("puc_setup_intr: oops child not found\n"); + return (ENXIO); + } + sc = (struct puc_softc *)device_get_softc(dev); for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++) { if (sc->sc_ports[i].dev == child) { *************** static int *** 716,723 **** --- 760,776 ---- puc_teardown_intr(device_t dev, device_t child, struct resource *r, void *cookie) { + device_t parent; int i; struct puc_softc *sc; + + /* The child might be a grandchild (i.e. a child of ppbus). */ + while (child && (parent = device_get_parent(child)) != dev) + child = parent; + if (! child) { + printf("puc_teardown_intr: oops child not found\n"); + return (ENXIO); + } sc = (struct puc_softc *)device_get_softc(dev); for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++) { *** sys/isa/ppc.c.ORIGINAL Tue Oct 2 01:21:45 2001 --- sys/isa/ppc.c Thu Jun 26 00:07:02 2003 *************** *** 28,33 **** --- 28,36 ---- */ #include "opt_ppc.h" + #ifdef __i386__ + #include "puc.h" + #endif #include <sys/param.h> #include <sys/systm.h> *************** *** 45,50 **** --- 48,56 ---- #include <isa/isareg.h> #include <isa/isavar.h> + #if NPUC > 0 + #include <dev/puc/pucvar.h> + #endif #include <dev/ppbus/ppbconf.h> #include <dev/ppbus/ppb_msq.h> *************** static int ppc_setup_intr(device_t, devi *** 81,89 **** void (*)(void *), void *, void **); static int ppc_teardown_intr(device_t, device_t, struct resource *, void *); ! static device_method_t ppc_methods[] = { /* device interface */ ! DEVMETHOD(device_probe, ppc_probe), DEVMETHOD(device_attach, ppc_attach), /* bus interface */ --- 87,97 ---- void (*)(void *), void *, void **); static int ppc_teardown_intr(device_t, device_t, struct resource *, void *); ! static int ppc_isa_probe(device_t dev); ! ! static device_method_t ppc_isa_methods[] = { /* device interface */ ! DEVMETHOD(device_probe, ppc_isa_probe), DEVMETHOD(device_attach, ppc_attach), /* bus interface */ *************** static device_method_t ppc_methods[] = { *** 104,115 **** { 0, 0 } }; ! static driver_t ppc_driver = { "ppc", ! ppc_methods, sizeof(struct ppc_data), }; static char *ppc_models[] = { "SMC-like", "SMC FDC37C665GT", "SMC FDC37C666GT", "PC87332", "PC87306", "82091AA", "Generic", "W83877F", "W83877AF", "Winbond", "PC87334", --- 112,154 ---- { 0, 0 } }; ! static driver_t ppc_isa_driver = { "ppc", ! ppc_isa_methods, sizeof(struct ppc_data), }; + #if NPUC > 0 + static device_method_t ppc_puc_methods[] = { + /* device interface */ + DEVMETHOD(device_probe, ppc_probe), + DEVMETHOD(device_attach, ppc_attach), + + /* bus interface */ + DEVMETHOD(bus_read_ivar, ppc_read_ivar), + DEVMETHOD(bus_setup_intr, ppc_setup_intr), + DEVMETHOD(bus_teardown_intr, ppc_teardown_intr), + DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), + + /* ppbus interface */ + DEVMETHOD(ppbus_io, ppc_io), + DEVMETHOD(ppbus_exec_microseq, ppc_exec_microseq), + DEVMETHOD(ppbus_reset_epp, ppc_reset_epp), + DEVMETHOD(ppbus_setmode, ppc_setmode), + DEVMETHOD(ppbus_ecp_sync, ppc_ecp_sync), + DEVMETHOD(ppbus_read, ppc_read), + DEVMETHOD(ppbus_write, ppc_write), + + { 0, 0 } + }; + + static driver_t ppc_puc_driver = { + "ppc", + ppc_puc_methods, + sizeof(struct ppc_data), + }; + #endif /* NPUC > 0 */ + static char *ppc_models[] = { "SMC-like", "SMC FDC37C665GT", "SMC FDC37C666GT", "PC87332", "PC87306", "82091AA", "Generic", "W83877F", "W83877AF", "Winbond", "PC87334", *************** static struct isa_pnp_id lpc_ids[] = { *** 1827,1838 **** }; static int ! ppc_probe(device_t dev) { #ifdef __i386__ static short next_bios_ppc = 0; #endif - struct ppc_data *ppc; device_t parent; int error; u_long port; --- 1866,1876 ---- }; static int ! ppc_isa_probe(device_t dev) { #ifdef __i386__ static short next_bios_ppc = 0; #endif device_t parent; int error; u_long port; *************** ppc_probe(device_t dev) *** 1845,1859 **** else if (error != 0) /* XXX shall be set after detection */ device_set_desc(dev, "Parallel port"); - /* - * Allocate the ppc_data structure. - */ - ppc = DEVTOSOFTC(dev); - bzero(ppc, sizeof(struct ppc_data)); - - ppc->rid_irq = ppc->rid_drq = ppc->rid_ioport = 0; - ppc->res_irq = ppc->res_drq = ppc->res_ioport = 0; - /* retrieve ISA parameters */ error = bus_get_resource(dev, SYS_RES_IOPORT, 0, &port, NULL); --- 1883,1888 ---- *************** ppc_probe(device_t dev) *** 1886,1891 **** --- 1915,1937 ---- } #endif + return (ppc_probe(dev)); + } + + static int + ppc_probe(device_t dev) + { + struct ppc_data *ppc; + + /* + * Allocate the ppc_data structure. + */ + ppc = DEVTOSOFTC(dev); + bzero(ppc, sizeof(struct ppc_data)); + + ppc->rid_irq = ppc->rid_drq = ppc->rid_ioport = 0; + ppc->res_irq = ppc->res_drq = ppc->res_ioport = 0; + /* IO port is mandatory */ /* Try "extended" IO port range...*/ *************** ppc_teardown_intr(device_t bus, device_t *** 2161,2164 **** return (error); } ! DRIVER_MODULE(ppc, isa, ppc_driver, ppc_devclass, 0, 0); --- 2207,2213 ---- return (error); } ! DRIVER_MODULE(ppc, isa, ppc_isa_driver, ppc_devclass, 0, 0); ! #if NPUC > 0 ! DRIVER_MODULE(ppc, puc, ppc_puc_driver, ppc_devclass, 0, 0); ! #endif /* NPUC > 0 */ ------------------------------------------------------------------------- | Feith Systems | Voice: 1-215-646-8000 | Email: john@feith.com | | John Wehle | Fax: 1-215-540-5495 | | -------------------------------------------------------------------------
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200307140021.h6E0LJe13039>