Exemplo n.º 1
0
/*
 * Match for SCSI devices on the onboard and GIO32 adapter WD33C93 chips
 */
int
wdsc_match(struct device *parent, void *vcf, void *aux)
{
	struct hpc_attach_args *haa = aux;
	struct cfdata *cf = vcf;
	vaddr_t reset, asr;
	uint32_t dummy;
	uint8_t reg;

	if (strcmp(haa->ha_name, cf->cf_driver->cd_name) != 0)
		return 0;

	reset = PHYS_TO_XKPHYS(haa->ha_sh + haa->ha_dmaoff +
	    haa->hpc_regs->scsi0_ctl, CCA_NC);
	if (guarded_read_4(reset, &dummy) != 0)
		return 0;
	*(volatile uint32_t *)reset = haa->hpc_regs->scsi_dmactl_reset;
	delay(1000);
	*(volatile uint32_t *)reset = 0x0;
	delay(1000);

	asr = PHYS_TO_XKPHYS(haa->ha_sh + haa->ha_devoff + 3, CCA_NC);
	if (guarded_read_1(asr, &reg) != 0)
		return 0;
	if ((reg & 0xff) != SBIC_ASR_INT)
		return 0;

	return 1;
}
Exemplo n.º 2
0
/*
 * Try and figure out whether there is a device at the given slot address.
 */
uint32_t
gio_id(vaddr_t va, paddr_t pa, int maybe_gfx)
{
	uint32_t id32, mystery;
	uint16_t id16 = 0;
	uint8_t id8 = 0;

	/*
	 * First, attempt to read the address with various sizes.
	 *
	 * - GIO32 devices will only support reads from 32-bit aligned
	 *   addresses, in all sizes (at least for the ID register).
	 * - frame buffers will support aligned reads from any size at
	 *   any address, but will actually return the access width if
	 *   the slot is pipelined.
	 */

	if (guarded_read_4(va, &id32) != 0)
		return 0;

	/*
	 * If the address doesn't match a base slot address, then we are
	 * only probing for a light(4) frame buffer.
	 */

	if (pa != GIO_ADDR_GFX && pa != GIO_ADDR_EXP0 && pa != GIO_ADDR_EXP1) {
		if (maybe_gfx == 0)
			return 0;
		else {
			if (pa == LIGHT_ADDR_0 || pa == LIGHT_ADDR_1) {
				if (guarded_read_4(va + REX_PAGE1_SET +
				    REX_P1REG_XYOFFSET, &id32) != 0)
					return 0;
				if (id32 == 0x08000800)
					return GIO_PRODUCT_FAKEID_LIGHT;
			}
			return 0;
		}
	}

	/*
	 * GIO32 devices with a 32-bit ID register will not necessarily
	 * answer to addresses not aligned on 32 bit boundaries.
	 */

	if (guarded_read_2(va | 2, &id16) != 0 ||
	    guarded_read_1(va | 3, &id8) != 0) {
		if (GIO_PRODUCT_32BIT_ID(id32))
			return id32;
		else /* not a frame buffer anyway */
			return GIO_PRODUCT_PRODUCTID(id32);
	}

	/*
	 * Of course, GIO32 devices with a 8-bit ID register can use the
	 * other bytes in the first 32-bit word for other purposes.
	 */

	if ((id32 & 0xffff) == id16 && (id32 & 0xff) == id8) {
		if (GIO_PRODUCT_32BIT_ID(id32))
			return id32;
		else if (!GIO_PRODUCT_32BIT_ID(id8) && id8 != 0x00)
			return /*GIO_PRODUCT_PRODUCTID*/(id8);
	}

	/*
	 * If there is a frame buffer device, then either we have hit a
	 * device register (grtwo), or we did not fault because the slot
	 * is pipelined (newport).
	 * In the latter case, we attempt to probe a known register offset.
	 */

	if (maybe_gfx) {
		/*
		 * On (at least) Indy systems with newport graphics, the
		 * presence of a SCSI Expansion board (030-8133) in either
		 * slot will cause extra bits to be set in the topmost byte
		 * of the 32-bit access to the pipelined slot (i.e. the
		 * value of id32 is 0x18000004, not 0x00000004).
		 *
		 * This would prevent newport from being recognized
		 * properly.
		 *
		 * This behaviour seems to be specific to the SCSI board,
		 * since the E++ board does not trigger it. This would
		 * rule out an HPC1.x-specific cause.
		 * 
		 * We work around this by ignoring the topmost byte of id32
		 * from this point on, but it's ugly and isaish...
		 *
		 * Note that this is not necessary on Indigo 2 since this
		 * troublesome board can not be installed on such a system.
		 * Indigo are probably safe from this issues, for they can't
		 * use newport graphics; but the issue at hand might be
		 * HPC 1.x related, so better play safe.
		 */
		if (sys_config.system_type == SGI_IP20 ||
		    (sys_config.system_type == SGI_IP22 &&
		     sys_config.system_subtype != IP22_INDIGO2))
			id32 &= ~0xff000000;

		if (id32 != 4 || id16 != 2 || id8 != 1) {
			if (guarded_read_4(va + HQ2_MYSTERY, &mystery) == 0 &&
			    mystery == HQ2_MYSTERY_VALUE)
				return GIO_PRODUCT_FAKEID_GRTWO;
			else
				return 0;
		}

		/* could be newport(4) */
		if (pa == GIO_ADDR_GFX || pa == GIO_ADDR_EXP0) {
			va += NEWPORT_REX3_OFFSET;
			if (guarded_read_4(va, &id32) == 0 &&
			    guarded_read_2(va | 2, &id16) == 0 &&
			    guarded_read_1(va | 3, &id8) == 0) {
				if (id32 != 4 || id16 != 2 || id8 != 1)
					return GIO_PRODUCT_FAKEID_NEWPORT;
			}
		}

		return 0;
	}

	return 0;
}