Skip site navigation (1)Skip section navigation (2)
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>