Beispiel #1
0
static void intel_8xx_tlbflush(void *mem)
{
    u32_t temp;

    temp = pciReadLong(bridge->PciTag, INTEL_AGPCTRL);
    pciWriteLong(bridge->PciTag, INTEL_AGPCTRL, temp & ~(1 << 7));
    temp = pciReadLong(bridge->PciTag, INTEL_AGPCTRL);
    pciWriteLong(bridge->PciTag, INTEL_AGPCTRL, temp | (1 << 7));
}
Beispiel #2
0
_X_EXPORT CARD16
pciReadWord(PCITAG tag, int offset)
{
  CARD32 tmp;
  int    shift = (offset & 3) * 8;
  int    aligned_offset = offset & ~3;
  int	 bus = PCI_BUS_FROM_TAG(tag);

  if (shift != 0 && shift != 16)
	  FatalError("pciReadWord: Alignment error: Cannot read 16 bits "
		     "at offset %d\n", offset);

  pciInit();

  if ((bus >= 0) && ((bus < pciNumBuses) || inProbe) && pciBusInfo[bus] &&
	pciBusInfo[bus]->funcs->pciReadWord) {
    CARD32 rv = (*pciBusInfo[bus]->funcs->pciReadWord)(tag, offset);

    return(rv);
  } else {
    tmp = pciReadLong(tag, aligned_offset);

    return((CARD16)((tmp >> shift) & 0xffff));
  }
}
Beispiel #3
0
_X_EXPORT void
pciWriteWord(PCITAG tag, int offset, CARD16 val)
{
  CARD32 tmp;
  int    aligned_offset = offset & ~3;
  int    shift = (offset & 3) * 8;
  int	 bus = PCI_BUS_FROM_TAG(tag);

  if (shift != 0 && shift != 16)
	  FatalError("pciWriteWord: Alignment Error: Cannot read 16 bits "
			"from offset %d\n", offset);

  pciInit();

  if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] &&
      pciBusInfo[bus]->funcs->pciWriteWord) {
    (*pciBusInfo[bus]->funcs->pciWriteWord)(tag, offset, val);
  } else {
    tmp = pciReadLong(tag, aligned_offset);

    tmp &= ~(0xffffL << shift);
    tmp |= (((CARD32)val) << shift);
    
    pciWriteLong(tag, aligned_offset, tmp);
  }
}
static void
print_460gx_gxb(pciConfigPtr pcr)
{
    CARD32 tmp;

    tmp = pcr->pci_user_config;
    pcr->pci_user_config = 0;
    print_header_type_0(pcr);
    pcr->pci_user_config = tmp;

    /* Only print what XFree86 might be interested in */
    printf("  BAPBASE   0x%08lx%08lx   AGPSIZ  0x%02x   VGAGE     0x%02x\n",
	   (long)pciReadLong(pcr->tag, 0x009C),
	   (long)pciReadLong(pcr->tag, 0x0098),
	   pciReadByte(pcr->tag, 0x00A2), pciReadByte(pcr->tag, 0x0060));
}
static void
print_460gx_sac(pciConfigPtr pcr)
{
    CARD32 tmp;

    /* Print generalities */
    printf("  STATUS    0x%04x  COMMAND 0x%04x\n",
	   pcr->pci_status, pcr->pci_command);
    printf("  CLASS     0x%02x 0x%02x 0x%02x  REVISION 0x%02x\n",
	   pcr->pci_base_class, pcr->pci_sub_class, pcr->pci_prog_if,
	   pcr->pci_rev_id);

    tmp = pcr->pci_user_config;
    pcr->pci_user_config = 0;
    print_default_class(pcr);
    pcr->pci_user_config = tmp;

    /* Only print what XFree86 might be interested in */
    if (pcr->busnum == 0) {
	if ((pcr->devnum != 0x10) || (pcr->funcnum != 0))
	    return;

	/* Get Chipset Bus Number */
	cbn_460gx = (unsigned int)pciReadByte(pcr->tag, 0x0040);
	printf("  CBN       0x%02x  CBUSES 0x%02x\n",
	       cbn_460gx, pciReadByte(pcr->tag, 0x0044));

	return;
    }

    if ((pcr->busnum != cbn_460gx) || (pcr->funcnum != 0))
	return;

    switch (pcr->devnum) {
    case 0:
	printf("  F16NUM    0x%02x  F16CPL 0x%02x  DEVNPRES 0x%08lx\n",
	       pciReadByte(pcr->tag, 0x0060), pciReadByte(pcr->tag, 0x0078),
	       (long)pciReadLong(pcr->tag, 0x0070));

	return;

    case 0x10:
	printf("  TOM       0x%04x  IORD  0x%04x\n",
	       pciReadWord(pcr->tag, 0x0050), pciReadWord(pcr->tag, 0x008E));
	/* Fall through */

    case 0x11:  case 0x12:  case 0x13:
    case 0x14:  case 0x15:  case 0x16:  case 0x17:
	printf("  BUSNO     0x%02x    SUBNO 0x%02x\n",
	       pciReadByte(pcr->tag, 0x0048), pciReadByte(pcr->tag, 0x0049));
	printf("  VGASE     0x%02x    PCIS  0x%02x    IOR 0x%02x\n",
	       pciReadByte(pcr->tag, 0x0080), pciReadByte(pcr->tag, 0x0084),
	       pciReadByte(pcr->tag, 0x008C));
	/* Fall through */

    default:
	return;
    }
}
Beispiel #6
0
void agp_generic_enable(u32_t requested_mode)
{
    u32_t bridge_agpstat, temp;

    get_agp_version(bridge);

    dbgprintf("Found an AGP %d.%d compliant device.\n",
           bridge->major_version, bridge->minor_version);

    bridge_agpstat = pciReadLong(bridge->PciTag,
                     bridge->capndx + PCI_AGP_STATUS);

    bridge_agpstat = agp_collect_device_status(bridge, requested_mode, bridge_agpstat);
	if (bridge_agpstat == 0)
		/* Something bad happened. FIXME: Return error code? */
		return;

	bridge_agpstat |= AGPSTAT_AGP_ENABLE;

	/* Do AGP version specific frobbing. */
    if (bridge->major_version >= 3)
    {
        if (bridge->mode & AGPSTAT_MODE_3_0)
        {
			/* If we have 3.5, we can do the isoch stuff. */
            if (bridge->minor_version >= 5)
                agp_3_5_enable(bridge);
            agp_device_command(bridge_agpstat, TRUE);
			return;
        }
        else
        {
		    /* Disable calibration cycle in RX91<1> when not in AGP3.0 mode of operation.*/
		    bridge_agpstat &= ~(7<<10) ;
            temp = pciReadLong(bridge->PciTag, bridge->capndx+AGPCTRL);
		    temp |= (1<<9);
            pciWriteLong(bridge->PciTag, bridge->capndx+AGPCTRL, temp);

            dbgprintf("Device is in legacy mode,"
                      " falling back to 2.x\n");
		}
	}

	/* AGP v<3 */
    agp_device_command(bridge_agpstat, FALSE);
}
Beispiel #7
0
void get_agp_version(agp_t *bridge)
{
    u32_t ncapid;

	/* Exit early if already set by errata workarounds. */
	if (bridge->major_version != 0)
		return;

    ncapid = pciReadLong(bridge->PciTag, bridge->capndx);
	bridge->major_version = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf;
	bridge->minor_version = (ncapid >> AGP_MINOR_VERSION_SHIFT) & 0xf;
}
static void
print_460gx_sac(pciConfigPtr pcr)
{
    CARD32 tmp;

    tmp = pcr->pci_user_config;
    pcr->pci_user_config = 0;
    print_header_type_0(pcr);
    pcr->pci_user_config = tmp;

    /* Only print what XFree86 might be interested in */
    if (pcr->busnum == 0) {
	if ((pcr->devnum != 0x10) || (pcr->funcnum != 0))
	    return;

	/* Get Chipset Bus Number */
	cbn_460gx = (unsigned int)pciReadByte(pcr->tag, 0x0040);
	printf("  CBN       0x%02x  CBUSES 0x%02x\n",
	       cbn_460gx, pciReadByte(pcr->tag, 0x0044));

	return;
    }

    if ((pcr->busnum != cbn_460gx) || (pcr->funcnum != 0))
	return;

    switch (pcr->devnum) {
    case 0:
	printf("  F16NUM    0x%02x  F16CPL 0x%02x  DEVNPRES 0x%08lx\n",
	       pciReadByte(pcr->tag, 0x0060), pciReadByte(pcr->tag, 0x0078),
	       (long)pciReadLong(pcr->tag, 0x0070));

	return;

    case 0x10:
	printf("  TOM       0x%04x  IORD  0x%04x\n",
	       pciReadWord(pcr->tag, 0x0050), pciReadWord(pcr->tag, 0x008E));
	/* Fall through */

    case 0x11:  case 0x12:  case 0x13:
    case 0x14:  case 0x15:  case 0x16:  case 0x17:
	printf("  BUSNO     0x%02x    SUBNO 0x%02x\n",
	       pciReadByte(pcr->tag, 0x0048), pciReadByte(pcr->tag, 0x0049));
	printf("  VGASE     0x%02x    PCIS  0x%02x    IOR 0x%02x\n",
	       pciReadByte(pcr->tag, 0x0080), pciReadByte(pcr->tag, 0x0084),
	       pciReadByte(pcr->tag, 0x008C));
	/* Fall through */

    default:
	return;
    }
}
static void
print_460gx_gxb(pciConfigPtr pcr)
{
    CARD32 tmp;

    /* Print generalities */
    printf("  STATUS    0x%04x  COMMAND 0x%04x\n",
	   pcr->pci_status, pcr->pci_command);
    printf("  CLASS     0x%02x 0x%02x 0x%02x  REVISION 0x%02x\n",
	   pcr->pci_base_class, pcr->pci_sub_class, pcr->pci_prog_if,
	   pcr->pci_rev_id);

    tmp = pcr->pci_user_config;
    pcr->pci_user_config = 0;
    print_default_class(pcr);
    pcr->pci_user_config = tmp;

    /* Only print what XFree86 might be interested in */
    printf("  BAPBASE   0x%08lx%08lx   AGPSIZ  0x%02x   VGAGE     0x%02x\n",
	   (long)pciReadLong(pcr->tag, 0x009C),
	   (long)pciReadLong(pcr->tag, 0x0098),
	   pciReadByte(pcr->tag, 0x00A2), pciReadByte(pcr->tag, 0x0060));
}
static void
dump_config(pciConfigPtr pcr, int verbose)
{
    int i, limit;

    if ((pcr->pci_header_type & 0x7f) == 2)
	limit = 32;
    else
	limit = 16;

    for (i = 0;  i < limit;  i++) {
	if (!(i & 3))
	    printf("    0x%03x: ", i * 4);
	if (!(i & 1))
	    printf(" ");
	/* Always display little-endian */
	printf(" %02x%02x%02x%02x",
	       (CARD8)(pcr->cfgspc.dwords[i]),
	       (CARD8)(pcr->cfgspc.dwords[i] >> 8),
	       (CARD8)(pcr->cfgspc.dwords[i] >> 16),
	       (CARD8)(pcr->cfgspc.dwords[i] >> 24));
	if ((i & 3) == 3)
	    printf("\n");
    }

    if (verbose <= 1)
	return;

    i = limit * 4;
    if (verbose > 2)
	limit = 4096;
    else
	limit = 256;

    /* Print the rest */
    for (;  i < limit;  i += 4) {
	CARD32 pcireg = pciReadLong(pcr->tag, i);
	if (!(i & 15))
	    printf("    0x%03x: ", i);
	if (!(i & 7))
	    printf(" ");
	/* Always display little-endian */
	printf(" %02x%02x%02x%02x",
	       (CARD8)(pcireg), (CARD8)(pcireg >> 8),
	       (CARD8)(pcireg >> 16), (CARD8)(pcireg >> 24));
	if ((i & 15) == 12)
	    printf("\n");
    }
}
Beispiel #11
0
u32_t agp_collect_device_status(agp_t *bridge, u32_t requested_mode,
                                u32_t bridge_agpstat)
{
    PCITAG  vgaTag;
    u32_t   vga_agpstat;
    int     cap_ptr;

    for (;;)
    {
        vgaTag = pci_find_class(PCI_CLASS_DISPLAY_VGA);
        if (vgaTag == -1)
        {
            dbgprintf("Couldn't find an AGP VGA controller.\n");
			return 0;
		}
        cap_ptr = pci_find_capability(vgaTag, PCI_CAP_ID_AGP);
		if (cap_ptr)
			break;
	}

	/*
	 * Ok, here we have a AGP device. Disable impossible
	 * settings, and adjust the readqueue to the minimum.
	 */
    vga_agpstat = pciReadLong(vgaTag, cap_ptr+PCI_AGP_STATUS);

	/* adjust RQ depth */
	bridge_agpstat = ((bridge_agpstat & ~AGPSTAT_RQ_DEPTH) |
         min_t(u32_t, (requested_mode & AGPSTAT_RQ_DEPTH),
         min_t(u32_t, (bridge_agpstat & AGPSTAT_RQ_DEPTH), (vga_agpstat & AGPSTAT_RQ_DEPTH))));

	/* disable FW if it's not supported */
	if (!((bridge_agpstat & AGPSTAT_FW) &&
          (vga_agpstat & AGPSTAT_FW) &&
          (requested_mode & AGPSTAT_FW)))
		bridge_agpstat &= ~AGPSTAT_FW;

	/* Check to see if we are operating in 3.0 mode */
    if (bridge->mode & AGPSTAT_MODE_3_0)
		agp_v3_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat);
	else
		agp_v2_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat);

	return bridge_agpstat;
}
Beispiel #12
0
_X_EXPORT CARD8
pciReadByte(PCITAG tag, int offset)
{
  CARD32 tmp;
  int    shift = (offset & 3) * 8;
  int    aligned_offset = offset & ~3;
  int	 bus = PCI_BUS_FROM_TAG(tag);

  pciInit();

  if ((bus >= 0) && ((bus < pciNumBuses) || inProbe) && pciBusInfo[bus] &&
	pciBusInfo[bus]->funcs->pciReadByte) {
    CARD8 rv = (*pciBusInfo[bus]->funcs->pciReadByte)(tag, offset);

    return(rv);
  } else {
    tmp = pciReadLong(tag, aligned_offset);

    return((CARD8)((tmp >> shift) & 0xff));
  }
}
Beispiel #13
0
static int intel_845_configure()
{
    u32_t temp;
    u8_t  temp2;
    aper_size_t *current_size;

    current_size = bridge->current_size;

	/* aperture size */
    pciWriteByte(bridge->PciTag, INTEL_APSIZE, current_size->size_value);

    dbgprintf("INTEL_APSIZE %d\n", current_size->size_value );

    if (bridge->apbase_config != 0)
    {
        pciWriteLong(bridge->PciTag, AGP_APBASE, bridge->apbase_config);
    }
    else
    {
		/* address to map to */
        temp = pciReadLong(bridge->PciTag, AGP_APBASE);
        bridge->gart_addr = (temp & PCI_MAP_MEMORY_ADDRESS_MASK);
        bridge->apbase_config = temp;
	}

    dbgprintf("AGP_APBASE %x\n", temp );

	/* attbase - aperture base */
    pciWriteLong(bridge->PciTag, INTEL_ATTBASE, bridge->gatt_dma);

	/* agpctrl */
    pciWriteLong(bridge->PciTag, INTEL_AGPCTRL, 0x0000);

	/* agpm */
    temp2 = pciReadByte(bridge->PciTag, INTEL_I845_AGPM);
    pciWriteByte(bridge->PciTag, INTEL_I845_AGPM, temp2 | (1 << 1));
	/* clear any possible error conditions */
    pciWriteWord(bridge->PciTag, INTEL_I845_ERRSTS, 0x001c);
	return 0;
}
Beispiel #14
0
_X_EXPORT void
pciWriteByte(PCITAG tag, int offset, CARD8 val)
{
  CARD32 tmp;
  int    aligned_offset = offset & ~3;
  int    shift = (offset & 3) *8 ;
  int	 bus = PCI_BUS_FROM_TAG(tag);

  pciInit();

  if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] &&
      pciBusInfo[bus]->funcs->pciWriteByte) {
	  (*pciBusInfo[bus]->funcs->pciWriteByte)(tag, offset, val);
  } else {

    tmp = pciReadLong(tag, aligned_offset);
    
    tmp &= ~(0xffL << shift);
    tmp |= (((CARD32)val) << shift);
    
    pciWriteLong(tag, aligned_offset, tmp);
  }
}
static void
print_simba(pciConfigPtr pcr)
{
    int   i;
    CARD8 io, mem;

    print_header_type_1(pcr);

    printf("  TICK      0x%08lx         SECCNTL 0x%02x\n", (long)
	   pciReadLong(pcr->tag, 0x00b0), pciReadByte(pcr->tag, 0x00dd));
    printf("  MASTER RETRIES:  PRIMARY 0x%02x,  SECONDARY 0x%02x\n",
	   pciReadByte(pcr->tag, 0x00c0), pciReadByte(pcr->tag, 0x00dc));
    printf("  TARGET RETRIES:  PIO     0x%02x,  DMA       0x%02x\n",
	   pciReadByte(pcr->tag, 0x00d8), pciReadByte(pcr->tag, 0x00da));
    printf("  TARGET LATENCY:  PIO     0x%02x,  DMA       0x%02x\n",
	   pciReadByte(pcr->tag, 0x00d9), pciReadByte(pcr->tag, 0x00db));
    printf("  DMA AFSR  0x%08lx%08lx    AFAR 0x%08lx%08lx\n",
	   (long)pciReadLong(pcr->tag, 0x00cc),
	   (long)pciReadLong(pcr->tag, 0x00c8),
	   (long)pciReadLong(pcr->tag, 0x00d4),
	   (long)pciReadLong(pcr->tag, 0x00d0));
    printf("  PIO AFSR  0x%08lx%08lx    AFAR 0x%08lx%08lx\n",
	   (long)pciReadLong(pcr->tag, 0x00ec),
	   (long)pciReadLong(pcr->tag, 0x00e8),
	   (long)pciReadLong(pcr->tag, 0x00f4),
	   (long)pciReadLong(pcr->tag, 0x00f0));
    printf("  PCI CNTL  0x%08lx%08lx    DIAG 0x%08lx%08lx\n",
	   (long)pciReadLong(pcr->tag, 0x00e4),
	   (long)pciReadLong(pcr->tag, 0x00e0),
	   (long)pciReadLong(pcr->tag, 0x00fc),
	   (long)pciReadLong(pcr->tag, 0x00f8));
    printf("  MAPS:            I/O     0x%02x,  MEM       0x%02x\n",
	   (io  = pciReadByte(pcr->tag, 0x00de)),
	   (mem = pciReadByte(pcr->tag, 0x00df)));
    for (i = 0;  i < 8;  i++)
	if (io & (1 << i))
	    printf("  BUS I/O   0x%06x-0x%06x\n", i << 21, ((i + 1) << 21) - 1);
    for (i = 0;  i < 8;  i++)
	if (mem & (1 << i))
	    printf("  BUS MEM   0x%08x-0x%08x\n", i << 29, ((i + 1) << 29) - 1);
}
Beispiel #16
0
int
pciGetBaseSize(PCITAG tag, int index, Bool destructive, Bool *min)
{
  int offset;
  CARD32 addr1;
  CARD32 addr2;
  CARD32 mask1;
  CARD32 mask2;
  int bits = 0;

  /*
   * Eventually a function for this should be added to pciBusFuncs_t, but for
   * now we'll just use a simple method based on the alignment of the already
   * allocated address.
   */

  /*
   * silently ignore bogus index values.  Valid values are 0-6.  0-5 are
   * the 6 base address registers, and 6 is the ROM base address register.
   */
  if (index < 0 || index > 6)
    return 0;

  pciInit();

  if (xf86GetPciSizeFromOS(tag, index, &bits)) {
      if (min)
	  *min = TRUE;
      return bits;
  }

  if (min)
    *min = destructive;

  /* Get the PCI offset */
  if (index == 6)
    offset = PCI_MAP_ROM_REG;
  else
    offset = PCI_MAP_REG_START + (index << 2);

  addr1 = pciReadLong(tag, offset);
  /*
   * Check if this is the second part of a 64 bit address.
   * XXX need to check how endianness affects 64 bit addresses.
   */
  if (index > 0 && index < 6) {
    addr2 = pciReadLong(tag, offset - 4);
    if (PCI_MAP_IS_MEM(addr2) && PCI_MAP_IS64BITMEM(addr2))
      return 0;
  }

  if (destructive) {
    pciWriteLong(tag, offset, 0xffffffff);
    mask1 = pciReadLong(tag, offset);
    pciWriteLong(tag, offset, addr1);
  } else {
    mask1 = addr1;
  }

  /* Check if this is the first part of a 64 bit address. */
  if (index < 5 && PCI_MAP_IS_MEM(mask1) && PCI_MAP_IS64BITMEM(mask1)) {
    if (PCIGETMEMORY(mask1) == 0) {
      addr2 = pciReadLong(tag, offset + 4);
      if (destructive) {
	pciWriteLong(tag, offset + 4, 0xffffffff);
	mask2 = pciReadLong(tag, offset + 4);
	pciWriteLong(tag, offset + 4, addr2);
      } else {
	mask2 = addr2;
      }
      if (mask2 == 0)
	return 0;
      bits = 32;
      while ((mask2 & 1) == 0) {
	bits++;
	mask2 >>= 1;
      }
      if (bits > 32)
	  return bits;
    }
  }
Beispiel #17
0
/*
 * This checks for, and validates, the presence of the 460GX chipset, and sets
 * cbn_460gx to a positive value accordingly.  This function returns TRUE if
 * the chipset scan is to be stopped, or FALSE if the scan is to move on to the
 * next chipset.
 */
Bool
xf86PreScan460GX(void)
{
    pciBusInfo_t *pBusInfo;
    PCITAG tag;
    CARD32 tmp;
    int i, devno;

    /* Bus zero should already be set up */
    if (!(pBusInfo = pciBusInfo[0])) {
	cbn_460gx = -1;
	return FALSE;
    }

    /* First look for a 460GX's primary host bridge */
    tag = PCI_MAKE_TAG(0, 0x10, 0);
    if (pciReadLong(tag, PCI_ID_REG) != DEVID(INTEL, 460GX_SAC)) {
	cbn_460gx = -1;
	return FALSE;
    }

    /* Get CBN (Chipset bus number) */
    if (!(cbn_460gx = (unsigned int)pciReadByte(tag, CBN))) {
	/* Sanity check failed */
	cbn_460gx = -1;
	return TRUE;
    }

    if (pciNumBuses <= cbn_460gx)
	pciNumBuses = cbn_460gx + 1;

    /* Set up bus CBN */
    if (!pciBusInfo[cbn_460gx]) {
	pciBusInfo[cbn_460gx] = xnfalloc(sizeof(pciBusInfo_t));
	*pciBusInfo[cbn_460gx] = *pBusInfo;
    }

    tag = PCI_MAKE_TAG(cbn_460gx, 0, 0);
    if (pciReadLong(tag, PCI_ID_REG) != DEVID(INTEL, 460GX_SAC)) {
	/* Sanity check failed */
	cbn_460gx = -1;
	return TRUE;
    }

    /*
     * Find out which CBN devices the firmware thinks are present.  Of these,
     * we are only interested in devices 0x10 through 0x17.
     */
    cbdevs_460gx = pciReadLong(tag, DEVNPRES);

    for (i = 0, devno = 0x10;  devno <= 0x17;  i++, devno++) {
	tag = PCI_MAKE_TAG(cbn_460gx, devno, 0);
	if (pciReadLong(tag, PCI_ID_REG) != DEVID(INTEL, 460GX_SAC)) {
	    /* Sanity check failed */
	    cbn_460gx = -1;
	    return TRUE;
	}

	if (devno == 0x10)
	    iord_460gx = pciReadWord(tag, IORD);

	busno_460gx[i] = (unsigned int)pciReadByte(tag, BUSNO);
	subno_460gx[i] = (unsigned int)pciReadByte(tag, SUBNO);
	pcis_460gx[i] = pciReadByte(tag, PCIS);
	ior_460gx[i] = pciReadByte(tag, IOR);

	has_err_460gx[i] = err_460gx[i] = 0;	/* Insurance */

	tag = PCI_MAKE_TAG(cbn_460gx, devno, 1);
	tmp = pciReadLong(tag, PCI_ID_REG);
	switch (tmp) {
	case DEVID(INTEL, 460GX_PXB):
	case DEVID(INTEL, 460GX_WXB):
	    if (cbdevs_460gx & (1 << devno)) {
		/* Sanity check failed */
		cbn_460gx = -1;
		return TRUE;
	    }

	    /*
	     * XXX  I don't have WXB docs, but PCI register dumps indicate that
	     * the registers we are interested in are consistent with those of
	     * the PXB.
	     */
	    err_460gx[i] = pciReadByte(tag, ERRCMD);
	    has_err_460gx[i] = 1;
	    break;

	case DEVID(INTEL, 460GX_GXB_1):
	    if (cbdevs_460gx & (1 << devno)) {
		/* Sanity check failed */
		cbn_460gx = -1;
		return TRUE;
	    }

	    /*
	     * XXX  GXB isn't documented to have an ERRCMD register, nor any
	     * other means of failing master aborts.  For now, assume master
	     * aborts are always allowed to complete normally.
	     */
	    break;

	default:
	    if (((CARD16)(tmp + 1U) <= (CARD16)1U) &&
		(cbdevs_460gx & (1U << devno)))
		break;
	    /* Sanity check failed */
	    cbn_460gx = -1;
	    return TRUE;
	}
    }

    /* Allow master aborts to complete normally */
    for (i = 0, devno = 0x10;  devno <= 0x17;  i++, devno++) {
	if (!(err_460gx[i] & 0x01))
	    continue;

	pciWriteByte(PCI_MAKE_TAG(cbn_460gx, devno, 1),
		     ERRCMD, err_460gx[i] & ~0x01);
    }

    /*
     * The 460GX spec says that any access to busses higher than CBN will be
     * master-aborted.  It seems possible however that this is not the case in
     * all 460GX implementations.  For now, limit the bus scan to CBN, unless
     * we have already found a higher bus number.
     */
    for (i = 0;  subno_460gx[i] < cbn_460gx;  ) {
	if (++i < 8)
	    continue;

	pciMaxBusNum = cbn_460gx + 1;
	break;
    }

    return TRUE;
}
static void
print_simba(pciConfigPtr pcr)
{
    int   i;
    CARD8 io, mem;

    printf("  STATUS    0x%04x  COMMAND 0x%04x\n",
	   pcr->pci_status, pcr->pci_command);
    printf("  CLASS     0x%02x 0x%02x 0x%02x  REVISION 0x%02x\n",
	   pcr->pci_base_class, pcr->pci_sub_class, pcr->pci_prog_if,
	   pcr->pci_rev_id);
    printf("  HEADER    0x%02x  LATENCY 0x%02x  CACHE 0x%02x\n",
	   pcr->pci_header_type, pcr->pci_latency_timer,
	   pcr->pci_cache_line_size);
    printf("  PRIBUS    0x%02x  SECBUS 0x%02x  SUBBUS 0x%02x  SECLT 0x%02x\n",
	   pcr->pci_primary_bus_number, pcr->pci_secondary_bus_number,
	   pcr->pci_subordinate_bus_number, pcr->pci_secondary_latency_timer);
    printf("  SECSTATUS 0x%04x\n",
	   pcr->pci_secondary_status);
    printf("  %sFAST_B2B %sSEC_BUS_RST %sM_ABRT %sVGA_EN %sISA_EN"
	   " %sSERR_EN %sPERR_EN\n",
	   (pcr->pci_bridge_control & PCI_B_FAST_B_B) ? "" : "NO_",
	   (pcr->pci_bridge_control & PCI_B_SB_RESET) ? "" : "NO_",
	   (pcr->pci_bridge_control & PCI_B_M_ABORT) ? "" : "NO_",
	   (pcr->pci_bridge_control & PCI_B_VGA_EN) ? "" : "NO_",
	   (pcr->pci_bridge_control & PCI_B_ISA_EN) ? "" : "NO_",
	   (pcr->pci_bridge_control & PCI_B_SERR_EN) ? "" : "NO_",
	   (pcr->pci_bridge_control & PCI_B_P_ERR) ? "" : "NO_");
    printf("  TICK      0x%08lx         SECCNTL 0x%02x\n", (long)
	   pciReadLong(pcr->tag, 0x00b0), pciReadByte(pcr->tag, 0x00dd));
    printf("  MASTER RETRIES:  PRIMARY 0x%02x,  SECONDARY 0x%02x\n",
	   pciReadByte(pcr->tag, 0x00c0), pciReadByte(pcr->tag, 0x00dc));
    printf("  TARGET RETRIES:  PIO     0x%02x,  DMA       0x%02x\n",
	   pciReadByte(pcr->tag, 0x00d8), pciReadByte(pcr->tag, 0x00da));
    printf("  TARGET LATENCY:  PIO     0x%02x,  DMA       0x%02x\n",
	   pciReadByte(pcr->tag, 0x00d9), pciReadByte(pcr->tag, 0x00db));
    printf("  DMA AFSR  0x%08lx%08lx    AFAR 0x%08lx%08lx\n",
	   (long)pciReadLong(pcr->tag, 0x00cc),
	   (long)pciReadLong(pcr->tag, 0x00c8),
	   (long)pciReadLong(pcr->tag, 0x00d4),
	   (long)pciReadLong(pcr->tag, 0x00d0));
    printf("  PIO AFSR  0x%08lx%08lx    AFAR 0x%08lx%08lx\n",
	   (long)pciReadLong(pcr->tag, 0x00ec),
	   (long)pciReadLong(pcr->tag, 0x00e8),
	   (long)pciReadLong(pcr->tag, 0x00f4),
	   (long)pciReadLong(pcr->tag, 0x00f0));
    printf("  PCI CNTL  0x%08lx%08lx    DIAG 0x%08lx%08lx\n",
	   (long)pciReadLong(pcr->tag, 0x00e4),
	   (long)pciReadLong(pcr->tag, 0x00e0),
	   (long)pciReadLong(pcr->tag, 0x00fc),
	   (long)pciReadLong(pcr->tag, 0x00f8));
    printf("  MAPS:            I/O     0x%02x,  MEM       0x%02x\n",
	   (io  = pciReadByte(pcr->tag, 0x00de)),
	   (mem = pciReadByte(pcr->tag, 0x00df)));
    for (i = 0;  i < 8;  i++)
	if (io & (1 << i))
	    printf("  BUS I/O  0x%06x-0x%06x\n", i << 21, ((i + 1) << 21) - 1);
    for (i = 0;  i < 8;  i++)
	if (mem & (1 << i))
	    printf("  BUS MEM  0x%08x-0x%08x\n", i << 29, ((i + 1) << 29) - 1);
}