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>
