int 
cs_ssextio_probe(device_t parent, cfdata_t cf, void *aux)
{
	struct s3c2xx0_attach_args *sa = aux;
	bus_space_tag_t iot = sa->sa_iot;
	bus_space_handle_t ioh;
	struct cs_softc sc;
	int rv = 0, have_io = 0;
	vaddr_t ioaddr;

	if (sa->sa_intr == SSEXTIOCF_INTR_DEFAULT)
		sa->sa_intr = 9;
	if (sa->sa_addr == SSEXTIOCF_ADDR_DEFAULT)
		sa->sa_addr = S3C2410_BANK_START(3);

	/*
	 * Map the I/O space.
	 */
	ioaddr = IOADDR(sa->sa_addr);
	if (bus_space_map(iot, ioaddr, CS8900_IOSIZE, 0, &ioh))
		goto out;
	have_io = 1;

	memset(&sc, 0, sizeof sc);
	sc.sc_iot = iot;
	sc.sc_ioh = ioh;

	if (0) {
		int i;

		for (i=0; i <=PKTPG_IND_ADDR; i += 2) {
			if (i % 16 == 0)
				printf( "\n%04x: ", i);
			printf("%04x ", CS_READ_PACKET_PAGE_IO(&sc, i));
		}

	}

	/* Verify that it's a Crystal product. */
	if (CS_READ_PACKET_PAGE_IO(&sc, PKTPG_EISA_NUM) != EISA_NUM_CRYSTAL)
		goto out;

	/*
	 * Verify that it's a supported chip.
	 */
	switch (CS_READ_PACKET_PAGE_IO(&sc, PKTPG_PRODUCT_ID) & PROD_ID_MASK) {
	case PROD_ID_CS8900:
#ifdef notyet
	case PROD_ID_CS8920:
	case PROD_ID_CS8920M:
#endif
		rv = 1;
	}

 out:
	if (have_io)
		bus_space_unmap(iot, ioh, CS8900_IOSIZE);

	return (rv);
}
Ejemplo n.º 2
0
int
cs_isa_probe(struct device *parent, struct cfdata *cf,
    void *aux)
{
	struct isa_attach_args *ia = aux;
	bus_space_tag_t iot = ia->ia_iot;
	bus_space_tag_t memt = ia->ia_memt;
	bus_space_handle_t ioh, memh;
	struct cs_softc sc;
	int rv = 0, have_io = 0, have_mem = 0;
	u_int16_t isa_cfg, isa_membase;
	int maddr, irq;

	if (ia->ia_nio < 1)
		return (0);
	if (ia->ia_nirq < 1)
		return (0);

	if (ISA_DIRECT_CONFIG(ia))
		return (0);

	/*
	 * Disallow wildcarded I/O base.
	 */
	if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
		return (0);

	if (ia->ia_niomem > 0)
		maddr = ia->ia_iomem[0].ir_addr;
	else
		maddr = ISA_UNKNOWN_IOMEM;

	/*
	 * Map the I/O space.
	 */
	if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, CS8900_IOSIZE,
	    0, &ioh))
		goto out;
	have_io = 1;

	memset(&sc, 0, sizeof sc);
	sc.sc_iot = iot;
	sc.sc_ioh = ioh;
	/* Verify that it's a Crystal product. */
	if (CS_READ_PACKET_PAGE_IO(&sc, PKTPG_EISA_NUM) !=
	    EISA_NUM_CRYSTAL)
		goto out;

	/*
	 * Verify that it's a supported chip.
	 */
	switch (CS_READ_PACKET_PAGE_IO(&sc, PKTPG_PRODUCT_ID) &
	    PROD_ID_MASK) {
	case PROD_ID_CS8900:
#ifdef notyet
	case PROD_ID_CS8920:
	case PROD_ID_CS8920M:
#endif
		break;
	default:
		/* invalid product ID */
		goto out;
	}

	/*
	 * If the IRQ or memory address were not specified, read the
	 * ISA_CFG EEPROM location.
	 */
	if (maddr == ISA_UNKNOWN_IOMEM ||
	    ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ) {
		if (cs_verify_eeprom(&sc) == CS_ERROR) {
			printf("cs_isa_probe: EEPROM bad or missing\n");
			goto out;
		}
		if (cs_read_eeprom(&sc, EEPROM_ISA_CFG, &isa_cfg)
		    == CS_ERROR) {
			printf("cs_isa_probe: unable to read ISA_CFG\n");
			goto out;
		}
	}

	/*
	 * If the IRQ wasn't specified, get it from the EEPROM.
	 */
	if (ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ) {
		irq = isa_cfg & ISA_CFG_IRQ_MASK;
		if (irq == 3)
			irq = 5;
		else
			irq += 10;
	} else
		irq = ia->ia_irq[0].ir_irq;

	/*
	 * If the memory address wasn't specified, get it from the EEPROM.
	 */
	if (maddr == ISA_UNKNOWN_IOMEM) {
		if ((isa_cfg & ISA_CFG_MEM_MODE) == 0) {
			/* EEPROM says don't use memory mode. */
			goto out;
		}
		if (cs_read_eeprom(&sc, EEPROM_MEM_BASE, &isa_membase)
		    == CS_ERROR) {
			printf("cs_isa_probe: unable to read MEM_BASE\n");
			goto out;
		}

		isa_membase &= MEM_BASE_MASK;
		maddr = (int)isa_membase << 8;
	}

	/*
	 * We now have a valid mem address; attempt to map it.
	 */
	if (bus_space_map(ia->ia_memt, maddr, CS8900_MEMSIZE, 0, &memh)) {
		/* Can't map it; fall back on i/o-only mode. */
		printf("cs_isa_probe: unable to map memory space\n");
		maddr = ISA_UNKNOWN_IOMEM;
	} else
		have_mem = 1;

	ia->ia_nio = 1;
	ia->ia_io[0].ir_size = CS8900_IOSIZE;

	if (maddr == ISA_UNKNOWN_IOMEM)
		ia->ia_niomem = 0;
	else {
		ia->ia_niomem = 1;
		ia->ia_iomem[0].ir_addr = maddr;
		ia->ia_iomem[0].ir_size = CS8900_MEMSIZE;
	}

	ia->ia_nirq = 1;
	ia->ia_irq[0].ir_irq = irq;

	rv = 1;

 out:
	if (have_io)
		bus_space_unmap(iot, ioh, CS8900_IOSIZE);
	if (have_mem)
		bus_space_unmap(memt, memh, CS8900_MEMSIZE);

	return (rv);
}