Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 19 Mar 2009 21:00:03 GMT
From:      dfilter@FreeBSD.ORG (dfilter service)
To:        freebsd-sparc64@FreeBSD.org
Subject:   Re: sparc64/131371: commit references a PR
Message-ID:  <200903192100.n2JL03S2034199@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR sparc64/131371; it has been noted by GNATS.

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: sparc64/131371: commit references a PR
Date: Thu, 19 Mar 2009 20:52:59 +0000 (UTC)

 Author: marius
 Date: Thu Mar 19 20:52:46 2009
 New Revision: 190109
 URL: http://svn.freebsd.org/changeset/base/190109
 
 Log:
   - Ensure we find no unexpected partner.
   - Failing to register as interrupt controller during attach shouldn't
     be fatal so just inform about this instead of panicing.
   - Disable rerun of the streaming cache as workaround for a silicon bug
     of certain Psycho versions.
   - Remove the comment regarding lack of newbus'ified bus_dma(9) as being
     able to associate a DMA tag with a device would allow to implement
     CDMA flushing/syncing in bus_dmamap_sync(9) but that would totally
     kill performance. Given that for devices not behind a PCI-PCI bridge
     the host-to-PCI bridges also only do CDMA flushing/syncing based on
     interrupts there's no additional disadvantage for polling(4) callbacks
     in the case schizo(4) has to do the CDMA flushing/syncing but rather a
     general problem.
   - Don't panic if the power failure, power management or over-temperature
     interrupts doesn't exist as these aren't mandatory and not available
     with all controllers (not even Psychos). [1]
   - Take advantage of KOBJMETHOD_END.
   - Remove some redundant variables.
   - Add missing const.
   
   PR:	131371 [1]
 
 Modified:
   head/sys/sparc64/pci/psycho.c
   head/sys/sparc64/pci/psychovar.h
 
 Modified: head/sys/sparc64/pci/psycho.c
 ==============================================================================
 --- head/sys/sparc64/pci/psycho.c	Thu Mar 19 20:48:47 2009	(r190108)
 +++ head/sys/sparc64/pci/psycho.c	Thu Mar 19 20:52:46 2009	(r190109)
 @@ -83,7 +83,7 @@ static void psycho_set_intr(struct psych
      driver_filter_t, driver_intr_t);
  static int psycho_find_intrmap(struct psycho_softc *, u_int, bus_addr_t *,
      bus_addr_t *, u_long *);
 -static driver_filter_t psycho_dmasync;
 +static driver_filter_t psycho_dma_sync_stub;
  static void psycho_intr_enable(void *);
  static void psycho_intr_disable(void *);
  static void psycho_intr_assign(void *);
 @@ -150,7 +150,7 @@ static device_method_t psycho_methods[] 
  	/* ofw_bus interface */
  	DEVMETHOD(ofw_bus_get_node,	psycho_get_node),
  
 -	{ 0, 0 }
 +	KOBJMETHOD_END
  };
  
  static devclass_t psycho_devclass;
 @@ -175,7 +175,7 @@ struct psycho_icarg {
  	bus_addr_t		pica_clr;
  };
  
 -struct psycho_dmasync {
 +struct psycho_dma_sync {
  	struct psycho_softc	*pds_sc;
  	driver_filter_t		*pds_handler;	/* handler to call */
  	void			*pds_arg;	/* argument for the handler */
 @@ -232,14 +232,14 @@ struct psycho_desc {
  	const char	*pd_name;
  };
  
 -static const struct psycho_desc psycho_compats[] = {
 +static const struct psycho_desc const psycho_compats[] = {
  	{ "pci108e,8000", PSYCHO_MODE_PSYCHO,	"Psycho compatible" },
  	{ "pci108e,a000", PSYCHO_MODE_SABRE,	"Sabre compatible" },
  	{ "pci108e,a001", PSYCHO_MODE_SABRE,	"Hummingbird compatible" },
  	{ NULL,		  0,			NULL }
  };
  
 -static const struct psycho_desc psycho_models[] = {
 +static const struct psycho_desc const psycho_models[] = {
  	{ "SUNW,psycho",  PSYCHO_MODE_PSYCHO,	"Psycho" },
  	{ "SUNW,sabre",   PSYCHO_MODE_SABRE,	"Sabre" },
  	{ NULL,		  0,			NULL }
 @@ -296,8 +296,8 @@ psycho_attach(device_t dev)
  	phandle_t child, node;
  	uint32_t dvmabase, prop, prop_array[2];
  	int32_t rev;
 -	u_int ver;
 -	int i, n, nrange, rid;
 +	u_int rerun, ver;
 +	int i, n;
  
  	node = ofw_bus_get_node(dev);
  	sc = device_get_softc(dev);
 @@ -315,7 +315,7 @@ psycho_attach(device_t dev)
  	 * (2) the shared Psycho configuration registers
  	 */
  	if (sc->sc_mode == PSYCHO_MODE_PSYCHO) {
 -		rid = 2;
 +		i = 2;
  		sc->sc_pcictl =
  		    bus_get_resource_start(dev, SYS_RES_MEMORY, 0) -
  		    bus_get_resource_start(dev, SYS_RES_MEMORY, 2);
 @@ -332,18 +332,18 @@ psycho_attach(device_t dev)
  			/* NOTREACHED */
  		}
  	} else {
 -		rid = 0;
 +		i = 0;
  		sc->sc_pcictl = PSR_PCICTL0;
  		sc->sc_half = 0;
  	}
 -	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
 +	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i,
  	    (sc->sc_mode == PSYCHO_MODE_PSYCHO ? RF_SHAREABLE : 0) |
  	    RF_ACTIVE);
  	if (sc->sc_mem_res == NULL)
  		panic("%s: could not allocate registers", __func__);
  
  	/*
 -	 * Match other Psycho's that are already configured against
 +	 * Match other Psychos that are already configured against
  	 * the base physical address.  This will be the same for a
  	 * pair of devices that share register space.
  	 */
 @@ -363,6 +363,8 @@ psycho_attach(device_t dev)
  			panic("%s: could not malloc mutex", __func__);
  		mtx_init(sc->sc_mtx, "pcib_mtx", NULL, MTX_SPIN);
  	} else {
 +		if (sc->sc_mode != PSYCHO_MODE_PSYCHO)
 +			panic("%s: no partner expected", __func__);
  		if (mtx_initialized(osc->sc_mtx) == 0)
  			panic("%s: mutex not initialized", __func__);
  		sc->sc_mtx = osc->sc_mtx;
 @@ -408,16 +410,17 @@ psycho_attach(device_t dev)
  	case 0:
  		dr |= DIAG_RTRY_DIS;
  		dr &= ~DIAG_DWSYNC_DIS;
 -		/* XXX need to also disable rerun of the streaming buffers. */
 +		rerun = 0;
  		break;
  	case 1:
  		csr &= ~PCICTL_ARB_PARK;
  		dr |= DIAG_RTRY_DIS | DIAG_DWSYNC_DIS;
 -		/* XXX need to also disable rerun of the streaming buffers. */
 +		rerun = 0;
  		break;
  	default:
  		dr |= DIAG_DWSYNC_DIS;
  		dr &= ~DIAG_RTRY_DIS;
 +		rerun = 1;
  		break;
  	}
  
 @@ -460,13 +463,12 @@ psycho_attach(device_t dev)
  	    rman_manage_region(&sc->sc_pci_mem_rman, 0, PSYCHO_MEM_SIZE) != 0)
  		panic("%s: failed to set up memory rman", __func__);
  
 -	nrange = OF_getprop_alloc(node, "ranges", sizeof(*range),
 -	    (void **)&range);
 +	n = OF_getprop_alloc(node, "ranges", sizeof(*range), (void **)&range);
  	/*
  	 * Make sure that the expected ranges are present.  The
  	 * OFW_PCI_CS_MEM64 one is not currently used though.
  	 */
 -	if (nrange != PSYCHO_NRANGE)
 +	if (n != PSYCHO_NRANGE)
  		panic("%s: unsupported number of ranges", __func__);
  	/*
  	 * Find the addresses of the various bus spaces.
 @@ -493,7 +495,8 @@ psycho_attach(device_t dev)
  		/*
  		 * Hunt through all the interrupt mapping regs and register
  		 * our interrupt controller for the corresponding interrupt
 -		 * vectors.
 +		 * vectors.  We do this early in order to be able to catch
 +		 * stray interrupts.
  		 */
  		for (n = 0; n <= PSYCHO_MAX_INO; n++) {
  			if (psycho_find_intrmap(sc, n, &intrmap, &intrclr,
 @@ -523,22 +526,23 @@ psycho_attach(device_t dev)
  			    INTMAP_ENABLE(INTMAP_VEC(sc->sc_ign, n),
  			    PCPU_GET(mid)));
  #endif
 -			if (intr_controller_register(INTMAP_VEC(sc->sc_ign, n),
 -			    &psycho_ic, pica) != 0)
 -				panic("%s: could not register interrupt "
 -				    "controller for INO %d", __func__, n);
 +			i = intr_controller_register(INTMAP_VEC(sc->sc_ign, n),
 +			    &psycho_ic, pica);
 +			if (i != 0)
 +				device_printf(dev, "could not register "
 +				    "interrupt controller for INO %d (%d)\n",
 +				    n, i);
  		}
  
 -		if (sc->sc_mode == PSYCHO_MODE_PSYCHO) {
 -			/* Initialize the counter-timer. */
 +		if (sc->sc_mode == PSYCHO_MODE_PSYCHO)
  			sparc64_counter_init(device_get_nameunit(dev),
  			    rman_get_bustag(sc->sc_mem_res),
  			    rman_get_bushandle(sc->sc_mem_res), PSR_TC0);
 -		}
  
  		/*
  		 * Set up IOMMU and PCI configuration if we're the first
 -		 * of a pair of Psycho's to arrive here.
 +		 * of a pair of Psychos to arrive here or a Hummingbird
 +		 * or Sabre.
  		 *
  		 * We should calculate a TSB size based on amount of RAM
  		 * and number of bus controllers and number and type of
 @@ -556,10 +560,10 @@ psycho_attach(device_t dev)
  		else
  			sc->sc_is->is_pmaxaddr =
  			    IOMMU_MAXADDR(PSYCHO_IOMMU_BITS);
 -		sc->sc_is->is_sb[0] = 0;
 -		sc->sc_is->is_sb[1] = 0;
 +		sc->sc_is->is_sb[0] = sc->sc_is->is_sb[1] = 0;
  		if (OF_getproplen(node, "no-streaming-cache") < 0)
  			sc->sc_is->is_sb[0] = sc->sc_pcictl + PCR_STRBUF;
 +		sc->sc_is->is_flags |= (rerun != 1) ? IOMMU_RERUN_DISABLE : 0;
  		psycho_iommu_init(sc, 3, dvmabase);
  	} else {
  		/* Just copy IOMMU state, config tag and address. */
 @@ -694,12 +698,20 @@ psycho_set_intr(struct psycho_softc *sc,
  	rid = index;
  	sc->sc_irq_res[index] = bus_alloc_resource_any(sc->sc_dev, SYS_RES_IRQ,
  	    &rid, RF_ACTIVE);
 +	if (sc->sc_irq_res[index] == NULL && intrmap >= PSR_POWER_INT_MAP) {
 +		/*
 +		 * These interrupts aren't mandatory and not available
 +		 * with all controllers (not even Psychos).
 +		 */
 +		return;
 +	}
  	if (sc->sc_irq_res[index] == NULL ||
  	    INTIGN(vec = rman_get_start(sc->sc_irq_res[index])) != sc->sc_ign ||
  	    INTVEC(PSYCHO_READ8(sc, intrmap)) != vec ||
  	    intr_vectors[vec].iv_ic != &psycho_ic ||
 -	    bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index], INTR_TYPE_MISC,
 -	    filt, intr, sc, &sc->sc_ihand[index]) != 0)
 +	    bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index],
 +	    INTR_TYPE_MISC | INTR_FAST, filt, intr, sc,
 +	    &sc->sc_ihand[index]) != 0)
  		panic("%s: failed to set up interrupt %d", __func__, index);
  }
  
 @@ -1065,9 +1077,9 @@ psycho_read_ivar(device_t dev, device_t 
  }
  
  static int
 -psycho_dmasync(void *arg)
 +psycho_dma_sync_stub(void *arg)
  {
 -	struct psycho_dmasync *pds = arg;
 +	struct psycho_dma_sync *pds = arg;
  
  	(void)PCIB_READ_CONFIG(pds->pds_ppb, pds->pds_bus, pds->pds_slot,
  	    pds->pds_func, PCIR_VENDOR, 2);
 @@ -1125,7 +1137,7 @@ psycho_setup_intr(device_t dev, device_t
  	devclass_t pci_devclass;
  	device_t cdev, pdev, pcidev;
  	struct psycho_softc *sc;
 -	struct psycho_dmasync *pds;
 +	struct psycho_dma_sync *pds;
  	u_long vec;
  	int error;
  
 @@ -1142,17 +1154,12 @@ psycho_setup_intr(device_t dev, device_t
  	}
  
  	/*
 -	 * The Sabre-APB-combination has a bug where it does not drain
 -	 * DMA write data for devices behind additional PCI-PCI bridges
 -	 * underneath the APB PCI-PCI bridge.  The workaround is to do
 -	 * a read on the farest PCI-PCI bridge followed by a read of the
 -	 * PCI DMA write sync register of the Sabre.
 -	 * XXX installing the wrapper for an affected device and the
 -	 * actual workaround in psycho_dmasync() should be moved to
 -	 * psycho(4)-specific bus_dma_tag_create() and bus_dmamap_sync()
 -	 * methods, respectively, once DMA tag creation is newbus'ified,
 -	 * so the workaround isn't only applied for interrupt handlers
 -	 * but also for polling(4) callbacks.
 +	 * The Sabre-APB-combination does not automatically flush DMA
 +	 * write data for devices behind additional PCI-PCI bridges
 +	 * underneath the APB PCI-PCI bridge.  The procedure for a
 +	 * manual flush is to do a PIO read on the far side of the
 +	 * farthest PCI-PCI bridge followed by a read of the PCI DMA
 +	 * write sync register of the Sabre.
  	 */
  	if (sc->sc_mode == PSYCHO_MODE_SABRE) {
  		pds = malloc(sizeof(*pds), M_DEVBUF, M_NOWAIT | M_ZERO);
 @@ -1191,20 +1198,20 @@ psycho_setup_intr(device_t dev, device_t
  			pds->pds_func = pci_get_function(pcidev);
  			if (bootverbose)
  				device_printf(dev, "installed DMA sync "
 -				    "workaround for device %d.%d on bus %d\n",
 +				    "wrapper for device %d.%d on bus %d\n",
  				    pds->pds_slot, pds->pds_func,
  				    pds->pds_bus);
  			if (intr == NULL) {
  				pds->pds_handler = filt;
  				error = bus_generic_setup_intr(dev, child,
 -				    ires, flags, psycho_dmasync, intr, pds,
 -				    cookiep);
 +				    ires, flags, psycho_dma_sync_stub, intr,
 +				    pds, cookiep);
  			} else {
  				pds->pds_handler = (driver_filter_t *)intr;
  				error = bus_generic_setup_intr(dev, child,
  				    ires, flags, filt,
 -				    (driver_intr_t *)psycho_dmasync, pds,
 -				    cookiep);
 +				    (driver_intr_t *)psycho_dma_sync_stub,
 +				    pds, cookiep);
  			}
  		} else
  			error = bus_generic_setup_intr(dev, child, ires,
 @@ -1226,7 +1233,7 @@ psycho_teardown_intr(device_t dev, devic
      void *cookie)
  {
  	struct psycho_softc *sc;
 -	struct psycho_dmasync *pds;
 +	struct psycho_dma_sync *pds;
  	int error;
  
  	sc = device_get_softc(dev);
 @@ -1314,8 +1321,8 @@ psycho_activate_resource(device_t bus, d
  		    type, rid, r));
  	if (type == SYS_RES_MEMORY) {
  		/*
 -		 * Need to memory-map the device space, as some drivers depend
 -		 * on the virtual address being set and useable.
 +		 * Need to memory-map the device space, as some drivers
 +		 * depend on the virtual address being set and usable.
  		 */
  		error = sparc64_bus_mem_map(rman_get_bustag(r),
  		    rman_get_bushandle(r), rman_get_size(r), 0, 0, &p);
 
 Modified: head/sys/sparc64/pci/psychovar.h
 ==============================================================================
 --- head/sys/sparc64/pci/psychovar.h	Thu Mar 19 20:48:47 2009	(r190108)
 +++ head/sys/sparc64/pci/psychovar.h	Thu Mar 19 20:52:46 2009	(r190109)
 @@ -49,8 +49,8 @@ struct psycho_softc {
  
  	phandle_t			sc_node;	/* Firmware node */
  	u_int				sc_mode;
 -#define	PSYCHO_MODE_SABRE	1
 -#define	PSYCHO_MODE_PSYCHO	2
 +#define	PSYCHO_MODE_SABRE		0
 +#define	PSYCHO_MODE_PSYCHO		1
  
  	/* Bus A or B of a psycho pair? */
  	u_int				sc_half;
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903192100.n2JL03S2034199>