Пример #1
0
/*
 * read from SONIC data buffer.
 */
void
snc_nec16_copyfrombuf(struct snc_softc *sc, void *dst, u_int32_t offset,
    size_t size)
{
	bus_space_tag_t memt = sc->sc_memt;
	bus_space_handle_t memh = sc->sc_memh;
	u_int16_t noffset;
	u_int8_t* bptr = dst;

	noffset = snc_nec16_select_bank(sc, offset, 0);

	/* XXX: should check if offset + size < 0x2000. */

	bus_space_barrier(memt, memh, noffset, size,
			  BUS_SPACE_BARRIER_READ);

	if (size > 3)  {
		if (noffset & 3)  {
			size_t asize = 4 - (noffset & 3);

			bus_space_read_region_1(memt, memh, noffset,
			    bptr, asize);
			bptr += asize;
			noffset += asize;
			size -= asize;
		}
		bus_space_read_region_4(memt, memh, noffset,
		    (u_int32_t *) bptr, size >> 2);
		bptr += size & ~3;
		noffset += size & ~3;
		size &= 3;
	}
	if (size)
		bus_space_read_region_1(memt, memh, noffset, bptr, size);
}
Пример #2
0
static u_int8_t *
podulebus_get_chunk(struct podulebus_attach_args *pa, int type)
{
	int i;
	struct podulebus_chunk *pc;
	u_int8_t *chunk;

	for (i = 0; i < pa->pa_nchunks; i++) {
		pc = &pa->pa_chunks[i];
		if (pc->pc_type == type) {
			chunk = malloc( pc->pc_length + 1, M_DEVBUF, M_WAITOK);
#if NPODLOADER > 0
			if (pc->pc_useloader)
				podloader_read_region(pa, pc->pc_offset, chunk,
				    pc->pc_length);
			else
#endif
				bus_space_read_region_1(pa->pa_sync_t,
				    pa->pa_sync_h, pc->pc_offset, chunk,
				    pc->pc_length);
			chunk[pc->pc_length] = 0;
			return chunk;
		}
	}
	return NULL;
}
Пример #3
0
static void
tels016_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
{
	bus_space_tag_t t = sc->sc_maps[1].t;
	bus_space_handle_t h = sc->sc_maps[1].h;
	bus_space_read_region_1(t, h, offset[what], buf, size);
}
Пример #4
0
/*---------------------------------------------------------------------------*
 *	Teles S0/16 fifo read routine
 *---------------------------------------------------------------------------*/
static void
tels016_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
{
	bus_space_tag_t    t = rman_get_bustag(sc->sc_resources.mem);
	bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem);
	bus_space_read_region_1(t, h, offset[what], buf, size);
}
Пример #5
0
int
flashread(dev_t dev, struct uio *uio, int flag)
{
	struct flash_softc	*sc;
	bus_space_tag_t		iot;
	bus_space_handle_t	ioh;
	bus_size_t		off;
	int			total;
	int			count;
	int			error;

	sc = device_lookup_private(&athflash_cd, minor(dev));
	iot = sc->sc_iot;
	ioh = sc->sc_ioh;

	off = uio->uio_offset;
	total = min(sc->sc_size - off, uio->uio_resid);

	while (total > 0) {
		count = min(sc->sc_sector_size, uio->uio_resid);
		bus_space_read_region_1(iot, ioh, off, sc->sc_buf, count);
		if ((error = uiomove(sc->sc_buf, count, uio)) != 0)
			return error;
		off += count;
		total -= count;
	}
	return 0;
}
Пример #6
0
static void
cfi_chip_query_1(struct cfi * const cfi)
{
	uint8_t data[0x80];

	bus_space_read_region_1(cfi->cfi_bst, cfi->cfi_bsh, 0, data,
	    __arraycount(data));
	CFI_DUMP_QRY(0, data, sizeof(data), 1);
	CFI_QRY_UNPACK_COMMON(cfi, data, uint8_t);
}
Пример #7
0
static void
ie_copyin(struct ie_softc *sc, void *dst, int offset, size_t size)
{
	if (size == 0)		/* This *can* happen! */
		return;

#if 0
	bus_space_read_region_1(sc->bt, sc->bh, offset, dst, size);
#else
	/* A minor optimisation ;-) */
	memcpy(dst, (void *) ((u_long) sc->bh + (u_long) offset), size);
#endif
}
Пример #8
0
static int
cfi_0002_read_page(device_t self, flash_off_t offset, uint8_t *datap)
{
	struct nor_softc * const sc = device_private(self);
	KASSERT(sc != NULL);
	KASSERT(sc->sc_nor_if != NULL);
	struct cfi *cfi = (struct cfi * const)sc->sc_nor_if->private;
	KASSERT(cfi != NULL);
	struct nor_chip * const chip = &sc->sc_chip;
	KASSERT(chip != NULL);
	KASSERT(chip->nc_page_mask != 0);
	KASSERT((offset & ~chip->nc_page_mask) == 0);
	KASSERT (chip->nc_page_size != 0);
	KASSERT((chip->nc_page_size & ((1 << cfi->cfi_portwidth) - 1)) == 0);

	CFI_0002_STATS_INC(cfi, read_page);

	bus_size_t count = chip->nc_page_size >> cfi->cfi_portwidth;
							/* #words/page */

	int error = cfi_0002_busy_wait(cfi, offset, cfi_0002_time_dflt(cfi));
	if (error != 0)
		return error;

	switch(cfi->cfi_portwidth) {
	case 0:
		bus_space_read_region_1(cfi->cfi_bst, cfi->cfi_bsh, offset,
			(uint8_t *)datap, count);
		break;
	case 1:
		bus_space_read_region_2(cfi->cfi_bst, cfi->cfi_bsh, offset,
			(uint16_t *)datap, count);
		break;
	case 2:
		bus_space_read_region_4(cfi->cfi_bst, cfi->cfi_bsh, offset,
			(uint32_t *)datap, count);
		break;
	default:
		panic("%s: bad port width %d\n", __func__, cfi->cfi_portwidth);
	};

	return 0;
}
Пример #9
0
static void
podulebus_read_chunks(struct podulebus_attach_args *pa, int useloader)
{
	u_int8_t chunk[8];
	u_int ptr, nchunks, type, length, offset;

	nchunks = pa->pa_nchunks;
	if (useloader)
		ptr = 0;
	else
		ptr = EXTECID_SIZE + IRQPTR_SIZE;
	for (;;) {
#if NPODLOADER > 0
		if (useloader)
			podloader_read_region(pa, ptr, chunk, 8);
		else
#endif
			bus_space_read_region_1(pa->pa_sync_t, pa->pa_sync_h,
					ptr, chunk, 8);
		ptr += 8;
		type = chunk[0];
		length = chunk[1] | chunk[2] << 8 | chunk[3] << 16;
		if (length == 0)
			break;
		offset = chunk[4] | chunk[5] << 8 |
		    chunk[6] << 16 | chunk[7] <<  24;
		if ((offset + length) > PODULE_GAP)
			continue;
		nchunks++;
		pa->pa_chunks = realloc(pa->pa_chunks,
					nchunks * sizeof(*pa->pa_chunks),
					M_DEVBUF, M_WAITOK);
		pa->pa_chunks[nchunks-1].pc_type = type;
		pa->pa_chunks[nchunks-1].pc_length = length;
		pa->pa_chunks[nchunks-1].pc_offset = offset;
		pa->pa_chunks[nchunks-1].pc_useloader = useloader;
	}
	pa->pa_nchunks = nchunks;
}
Пример #10
0
static void
cfi_jedec_id_1(struct cfi * const cfi)
{
	struct cfi_jedec_id_data *idp = &cfi->cfi_id_data;
	uint8_t data[0x10];

	bus_space_read_region_1(cfi->cfi_bst, cfi->cfi_bsh, 0, data,
		__arraycount(data));

	CFI_DUMP_JEDEC(0, data, sizeof(data), 1);

	idp->id_mid = (uint16_t)data[0];
	idp->id_did[0] = (uint16_t)data[1];
	idp->id_did[1] = (uint16_t)data[0xe];
	idp->id_did[2] = (uint16_t)data[0xf];
	idp->id_prot_state = (uint16_t)data[2];
	idp->id_indicators = (uint16_t)data[3];

	/* software bits, upper and lower */
	idp->id_swb_lo = data[0xc];
	idp->id_swb_hi = data[0xd];

}
Пример #11
0
static void
orm_identify(driver_t* driver, device_t parent)
{
	bus_space_handle_t	bh;
	bus_space_tag_t		bt;
	device_t		child;
	u_int32_t		chunk = IOMEM_START;
	struct resource		*res;
	int			rid;
	u_int32_t		rom_size;
	struct orm_softc	*sc;
	u_int8_t		buf[3];

	child = BUS_ADD_CHILD(parent, ISA_ORDER_SENSITIVE, "orm", -1);
	device_set_driver(child, driver);
	isa_set_logicalid(child, ORM_ID);
	isa_set_vendorid(child, ORM_ID);
	sc = device_get_softc(child);
	sc->rnum = 0;
	while (chunk < IOMEM_END) {
		bus_set_resource(child, SYS_RES_MEMORY, sc->rnum, chunk,
		    IOMEM_STEP);
		rid = sc->rnum;
		res = bus_alloc_resource_any(child, SYS_RES_MEMORY, &rid,
		    RF_ACTIVE);
		if (res == NULL) {
			bus_delete_resource(child, SYS_RES_MEMORY, sc->rnum);
			chunk += IOMEM_STEP;
			continue;
		}
		bt = rman_get_bustag(res);
		bh = rman_get_bushandle(res);
		bus_space_read_region_1(bt, bh, 0, buf, sizeof(buf));

		/*
		 * We need to release and delete the resource since we're
		 * changing its size, or the rom isn't there.  There
		 * is a checksum field in the ROM to prevent false
		 * positives.  However, some common hardware (IBM thinkpads)
		 * neglects to put a valid checksum in the ROM, so we do
		 * not double check the checksum here.  On the ISA bus
		 * areas that have no hardware read back as 0xff, so the
		 * tests to see if we have 0x55 followed by 0xaa are
		 * generally sufficient.
		 */
		bus_release_resource(child, SYS_RES_MEMORY, rid, res);
		bus_delete_resource(child, SYS_RES_MEMORY, sc->rnum);
		if (buf[0] != 0x55 || buf[1] != 0xAA || (buf[2] & 0x03) != 0) {
			chunk += IOMEM_STEP;
			continue;
		}
		rom_size = buf[2] << 9;
		bus_set_resource(child, SYS_RES_MEMORY, sc->rnum, chunk,
		    rom_size);
		rid = sc->rnum;
		res = bus_alloc_resource_any(child, SYS_RES_MEMORY, &rid, 0);
		if (res == NULL) {
			bus_delete_resource(child, SYS_RES_MEMORY, sc->rnum);
			chunk += IOMEM_STEP;
			continue;
		}
		sc->rid[sc->rnum] = rid;
		sc->res[sc->rnum] = res;
		sc->rnum++;
		chunk += rom_size;
	}

	if (sc->rnum == 0)
		device_delete_child(parent, child);
	else if (sc->rnum == 1)
		device_set_desc(child, "ISA Option ROM");
	else
		device_set_desc(child, "ISA Option ROMs");
}
Пример #12
0
static void
podulebus_probe_podule(struct device *self, int slotnum)
{
	struct podulebus_softc *sc = (struct podulebus_softc *)self;
	bus_space_tag_t id_bst;
	bus_space_handle_t id_bsh;
	int ecid, w;
	u_int8_t extecid[EXTECID_SIZE];
	struct podulebus_attach_args pa;

	bzero(&pa, sizeof(pa));
	id_bst = sc->sc_ioc.ioc_sync_t;
	bus_space_subregion(id_bst, sc->sc_ioc.ioc_sync_h,
			    slotnum * PODULE_GAP, PODULE_GAP, &id_bsh);
	ecid = bus_space_read_1(id_bst, id_bsh, 0);
	/* Skip empty or strange slots */
	if (ecid & (ECID_NOTPRESENT | ECID_NONCONF))
		return;
	if ((ecid & ECID_ID_MASK) == ECID_ID_EXTEND) {
		pa.pa_fast_t = sc->sc_ioc.ioc_fast_t;
		bus_space_subregion(pa.pa_fast_t, sc->sc_ioc.ioc_fast_h,
				    slotnum * PODULE_GAP, PODULE_GAP,
				    &pa.pa_fast_h);
		pa.pa_medium_t = sc->sc_ioc.ioc_medium_t;
		bus_space_subregion(pa.pa_medium_t, sc->sc_ioc.ioc_medium_h,
				    slotnum * PODULE_GAP, PODULE_GAP,
				    &pa.pa_medium_h);
		pa.pa_slow_t = sc->sc_ioc.ioc_slow_t;
		bus_space_subregion(pa.pa_slow_t, sc->sc_ioc.ioc_slow_h,
				    slotnum * PODULE_GAP, PODULE_GAP,
				    &pa.pa_slow_h);
		pa.pa_sync_t = sc->sc_ioc.ioc_sync_t;
		bus_space_subregion(pa.pa_sync_t, sc->sc_ioc.ioc_sync_h,
				    slotnum * PODULE_GAP, PODULE_GAP,
				    &pa.pa_sync_h);
		/* XXX This is a hack! */
		pa.pa_mod_t = &iobus_bs_tag;
		bus_space_map(pa.pa_mod_t,
		    (bus_addr_t)MEMC_IO_BASE + slotnum * (PODULE_GAP << 2),
		    (PODULE_GAP << 2), 0, &pa.pa_mod_h);
		bus_space_read_region_1(id_bst, id_bsh, 0,
					extecid, EXTECID_SIZE);
		/* XXX If you thought that was a hack... */
		pa.pa_mod_base = pa.pa_mod_h;
		pa.pa_fast_base = pa.pa_fast_h;
		pa.pa_medium_base = pa.pa_medium_h;
		pa.pa_slow_base = pa.pa_slow_h;
		pa.pa_sync_base = pa.pa_sync_h;
		pa.pa_ecid = ecid;
		pa.pa_flags1 = extecid[EXTECID_F1];
		pa.pa_manufacturer = (extecid[EXTECID_MLO] |
				      extecid[EXTECID_MHI] << 8);
		pa.pa_product = (extecid[EXTECID_PLO] |
				 extecid[EXTECID_PHI] << 8);
		pa.pa_slotnum = slotnum;
		pa.pa_ih = slotnum;
		if (pa.pa_flags1 & EXTECID_F1_CD) {
			w = pa.pa_flags1 & EXTECID_F1_W_MASK;
			if (w != EXTECID_F1_W_8BIT) {
				/* RISC OS 3 can't handle this either. */
				printf("%s:%d: ROM is not 8 bits wide; "
				    "ignoring it\n",
				    self->dv_xname, pa.pa_slotnum);
			} else {
				podulebus_read_chunks(&pa, 0);
				pa.pa_descr = podulebus_get_chunk(&pa,
							  CHUNK_DEV_DESCR);
			}
		}
		pa.pa_slotflags = 0;
		config_found_sm_loc(self, "podulebus", NULL, &pa,
				podulebus_print, podulebus_submatch);
		if (pa.pa_chunks)
			FREE(pa.pa_chunks, M_DEVBUF);
		if (pa.pa_descr)
			FREE(pa.pa_descr, M_DEVBUF);
		if (pa.pa_loader)
			FREE(pa.pa_loader, M_DEVBUF);
	} else
		printf("%s:%d: non-extended podule ignored.\n",
		       self->dv_xname, slotnum);
}
Пример #13
0
int
gprioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
{
	int unit = GPRUNIT(dev);
	struct gpr_softc *sc = gpr_cd.cd_devs[unit];
	int error;

	DPRINTF(("%s: cmd %d, flags 0x%x\n", __func__, cmd, flags));

	switch (cmd) {
	case GPR_RESET:
	case GPR_SELECT:
	case GPR_POWER:
	case GPR_CLOSE:
		if ((flags & FWRITE) == 0)
			return (EACCES);
	default:
		break;
	}

	switch (cmd) {
	case GPR_RESET:
		/*
		 * To reset and power up the reader, set bit 0 in the
		 * HAP register for at least 5us and wait for 20ms.
		 */
		bus_space_write_1(sc->sc_iot, sc->sc_ioh, GPR400_HAP_CTRL,
		    GPR400_RESET);
		delay(10);
		bus_space_write_1(sc->sc_iot, sc->sc_ioh, GPR400_HAP_CTRL, 0);
		tsleep(sc, PWAIT, "gpreset", hz / 40);
		/* FALLTHROUGH */

	case GPR_SELECT:
		error = tlvput(sc, GPR400_SELECT, "\x02", 1);
		break;

	case GPR_POWER:
		{
			u_int8_t *mode;

			if (*(int *)addr)
				mode = "\x01";	/* Standby	*/
			else
				mode = "\x00";	/* Power down	*/

			error = tlvput(sc, GPR400_POWER, mode, 1);
		}
		break;

	case GPR_CLOSE:
		error = tlvput(sc, GPR400_CLOSE, (u_int8_t *)0, 0);
		break;

	case GPR_RAM:
		{
			struct gpr400_ram r;

			bus_space_read_region_1(sc->sc_memt, sc->sc_memh,
		    	    sc->sc_offset, (u_int8_t *)&r,
			    sizeof(struct gpr400_ram));
			error = copyout(&r, addr, sizeof(struct gpr400_ram));
		}
		break;

	case GPR_CMD:
	case GPR_OPEN:
	case GPR_STATUS:
	case GPR_TLV:
	default:
		error = EINVAL;
		break;
	};

	return (error);
}
Пример #14
0
void
bmdstrategy(struct buf *bp)
{
	int unit = BMD_UNIT(bp->b_dev);
	struct bmd_softc *sc;
	int offset, disksize, resid;
	int page, pg_offset, pg_resid;
	void *data;

	if (unit >= bmd_cd.cd_ndevs) {
		bp->b_error = ENXIO;
		goto done;
	}

	sc = device_lookup_private(&bmd_cd, BMD_UNIT(bp->b_dev));
	if (sc == NULL) {
		bp->b_error = ENXIO;
		goto done;
	}

	DPRINTF(("bmdstrategy: %s blkno %d bcount %ld:",
		(bp->b_flags & B_READ) ? "read " : "write",
		bp->b_blkno, bp->b_bcount));

	bp->b_resid = bp->b_bcount;
	offset = (bp->b_blkno << DEV_BSHIFT);
	disksize = sc->sc_maxpage * BMD_PAGESIZE;
	if (offset >= disksize) {
		/* EOF if read, EIO if write */
		if (bp->b_flags & B_READ)
			goto done;
		bp->b_error = EIO;
		goto done;
	}

	resid = bp->b_resid;
	if (resid > disksize - offset)
		resid = disksize - offset;

	data = bp->b_data;
	do {
		page = offset / BMD_PAGESIZE;
		pg_offset = offset % BMD_PAGESIZE;

		/* length */
		pg_resid = MIN(resid, BMD_PAGESIZE - pg_offset);

		/* switch bank page */
		bus_space_write_1(sc->sc_iot, sc->sc_ioh, BMD_PAGE, page);

		/* XXX we should use DMA transfer? */
		if ((bp->b_flags & B_READ)) {
			bus_space_read_region_1(sc->sc_iot, sc->sc_bank,
				pg_offset, data, pg_resid);
		} else {
			bus_space_write_region_1(sc->sc_iot, sc->sc_bank,
				pg_offset, data, pg_resid);
		}

		data = (char *)data + pg_resid;
		offset += pg_resid;
		resid -= pg_resid;
		bp->b_resid -= pg_resid;
	} while (resid > 0);

	DPRINTF(("\n"));

 done:
	biodone(bp);
}
Пример #15
0
int
gem_pci_enaddr(struct gem_softc *sc, struct pci_attach_args *pa)
{
	struct pci_vpd *vpd;
	bus_space_handle_t romh;
	bus_space_tag_t romt;
	bus_size_t romsize = 0;
	u_int8_t buf[32];
	pcireg_t address;
	int dataoff, vpdoff;
	int rv = -1;

	if (pci_mapreg_map(pa, PCI_ROM_REG, PCI_MAPREG_TYPE_MEM, 0,
	    &romt, &romh, 0, &romsize, 0))
		return (-1);

	address = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
	address |= PCI_ROM_ENABLE;
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, address);

	bus_space_read_region_1(romt, romh, 0, buf, sizeof(buf));
	if (bcmp(buf, gem_promhdr, sizeof(gem_promhdr)))
		goto fail;

	dataoff = buf[PROMHDR_PTR_DATA] | (buf[PROMHDR_PTR_DATA + 1] << 8);
	if (dataoff < 0x1c)
		goto fail;

	bus_space_read_region_1(romt, romh, dataoff, buf, sizeof(buf));
	if (bcmp(buf, gem_promdat, sizeof(gem_promdat)) ||
	    bcmp(buf + PROMDATA_DATA2, gem_promdat2, sizeof(gem_promdat2)))
		goto fail;

	vpdoff = buf[PROMDATA_PTR_VPD] | (buf[PROMDATA_PTR_VPD + 1] << 8);
	if (vpdoff < 0x1c)
		goto fail;

	bus_space_read_region_1(romt, romh, vpdoff, buf, sizeof(buf));

	/*
	 * The VPD of gem is not in PCI 2.2 standard format.  The length
	 * in the resource header is in big endian.
	 */
	vpd = (struct pci_vpd *)(buf + 3);
	if (!PCI_VPDRES_ISLARGE(buf[0]) ||
	    PCI_VPDRES_LARGE_NAME(buf[0]) != PCI_VPDRES_TYPE_VPD)
		goto fail;
	if (vpd->vpd_key0 != 'N' || vpd->vpd_key1 != 'A')
		goto fail;

	bcopy(buf + 6, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
	rv = 0;

 fail:
	if (romsize != 0)
		bus_space_unmap(romt, romh, romsize);

	address = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
	address &= ~PCI_ROM_ENABLE;
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, address);

	return (rv);
}
Пример #16
0
Файл: asp.c Проект: MarginC/kame
void
aspattach(struct device *parent, struct device *self, void *aux)
{
	struct confargs *ca = aux;
	struct asp_softc *sc = (struct asp_softc *)self;
	struct gsc_attach_args ga;
	bus_space_handle_t ioh;
	uint32_t irr;
	int s;

	/*
	 * Map the ASP interrupt registers.
	 */
	if (bus_space_map(ca->ca_iot, ca->ca_hpa + ASP_REG_INT,
			  sizeof(struct asp_trs), 0, &ioh))
		panic("aspattach: can't map interrupt registers.");
	sc->sc_trs = (struct asp_trs *)ioh;

	/*
	 * Map the ASP miscellaneous registers.
	 */
	if (bus_space_map(ca->ca_iot, ca->ca_hpa + ASP_REG_MISC,
			  sizeof(struct asp_hwr), 0, &ioh))
		panic("aspattach: can't map miscellaneous registers.");
	sc->sc_hw = (struct asp_hwr *)ioh;

	/*
	 * Map the Ethernet address and read it out.
	 */
	if (bus_space_map(ca->ca_iot, ca->ca_hpa + ASP_ETHER_ADDR,
			  sizeof(ga.ga_ether_address), 0, &ioh))
		panic("aspattach: can't map EEPROM.");
	bus_space_read_region_1(ca->ca_iot, ioh, 0,
		ga.ga_ether_address, sizeof(ga.ga_ether_address));
	bus_space_unmap(ca->ca_iot, ioh, sizeof(ga.ga_ether_address));

	machine_ledaddr = &sc->sc_trs->asp_cled;
	machine_ledword = asp_spus[sc->sc_trs->asp_spu].ledword;

	/* reset ASP */
	/* sc->sc_hw->asp_reset = 1; */
	/* delay(400000); */

	s = splhigh();
	viper_setintrwnd(1 << ca->ca_irq);

	sc->sc_trs->asp_imr = ~0;
	irr = sc->sc_trs->asp_irr;
	sc->sc_trs->asp_imr = 0;
	splx(s);

	printf (": %s rev %d, lan %d scsi %d\n",
	    asp_spus[sc->sc_trs->asp_spu].name, sc->sc_hw->asp_version,
	    sc->sc_trs->asp_lan, sc->sc_trs->asp_scsi);

	/* Establish the interrupt register. */
	hp700_intr_reg_establish(&sc->sc_int_reg);
	sc->sc_int_reg.int_reg_mask = &sc->sc_trs->asp_imr;
	sc->sc_int_reg.int_reg_req = &sc->sc_trs->asp_irr;

	/* Attach the GSC bus. */
	ga.ga_ca = *ca;	/* clone from us */
	ga.ga_name = "gsc";
	ga.ga_int_reg = &sc->sc_int_reg;
	ga.ga_fix_args = asp_fix_args;
	ga.ga_fix_args_cookie = sc;
	ga.ga_scsi_target = sc->sc_trs->asp_scsi;
	config_found(self, &ga, gscprint);
}
/*
 * Bus read region operations.
 */
void
bs_through_bs_rr_1(bus_space_tag_t t, bus_space_handle_t bsh,
	    bus_size_t offset, u_int8_t *addr, bus_size_t count)
{
	bus_space_read_region_1(t->bs_base, bsh, offset, addr, count);
}
Пример #18
0
/*
 * Given a NIC memory source address and a host memory destination
 *	address, copy 'amount' from NIC to host using shared memory.
 * This routine accesses things as 8 bit quantities.
 */
void
ed_shmem_readmem8(struct ed_softc *sc, bus_size_t src, uint8_t *dst,
    uint16_t amount)
{
	bus_space_read_region_1(sc->mem_bst, sc->mem_bsh, src, dst, amount);
}
Пример #19
0
int
cas_pci_enaddr(struct cas_softc *sc, struct pci_attach_args *pa)
{
	struct pci_vpd_largeres *res;
	struct pci_vpd *vpd;
	bus_space_handle_t romh;
	bus_space_tag_t romt;
	bus_size_t romsize;
	u_int8_t buf[32], *desc;
	pcireg_t address, mask;
	int dataoff, vpdoff, len;
	int rv = -1;

	address = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, 0xfffffffe);
	mask = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
	address |= PCI_ROM_ENABLE;
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, address);

	romt = pa->pa_memt;
	romsize = PCI_ROM_SIZE(mask);
	if (bus_space_map(romt, PCI_ROM_ADDR(address), romsize, 0, &romh)) {
		romsize = 0;
		goto fail;
	}

	bus_space_read_region_1(romt, romh, 0, buf, sizeof(buf));
	if (bcmp(buf, cas_promhdr, sizeof(cas_promhdr)))
		goto fail;

	dataoff = buf[PROMHDR_PTR_DATA] | (buf[PROMHDR_PTR_DATA + 1] << 8);
	if (dataoff < 0x1c)
		goto fail;

	bus_space_read_region_1(romt, romh, dataoff, buf, sizeof(buf));
	if (bcmp(buf, cas_promdat, sizeof(cas_promdat)) ||
	    bcmp(buf + PROMDATA_DATA2, cas_promdat2, sizeof(cas_promdat2)))
		goto fail;

	vpdoff = buf[PROMDATA_PTR_VPD] | (buf[PROMDATA_PTR_VPD + 1] << 8);
	if (vpdoff < 0x1c)
		goto fail;

next:
	bus_space_read_region_1(romt, romh, vpdoff, buf, sizeof(buf));
	if (!PCI_VPDRES_ISLARGE(buf[0]))
		goto fail;

	res = (struct pci_vpd_largeres *)buf;
	vpdoff += sizeof(*res);

	len = ((res->vpdres_len_msb << 8) + res->vpdres_len_lsb);
	switch(PCI_VPDRES_LARGE_NAME(res->vpdres_byte0)) {
	case PCI_VPDRES_TYPE_IDENTIFIER_STRING:
		/* Skip identifier string. */
		vpdoff += len;
		goto next;

	case PCI_VPDRES_TYPE_VPD:
		while (len > 0) {
			bus_space_read_region_1(romt, romh, vpdoff,
			     buf, sizeof(buf));

			vpd = (struct pci_vpd *)buf;
			vpdoff += sizeof(*vpd) + vpd->vpd_len;
			len -= sizeof(*vpd) + vpd->vpd_len;

			/*
			 * We're looking for an "Enhanced" VPD...
			 */
			if (vpd->vpd_key0 != 'Z')
				continue;

			desc = buf + sizeof(*vpd);

			/* 
			 * ...which is an instance property...
			 */
			if (desc[0] != 'I')
				continue;
			desc += 3;

			/* 
			 * ...that's a byte array with the proper
			 * length for a MAC address...
			 */
			if (desc[0] != 'B' || desc[1] != ETHER_ADDR_LEN)
				continue;
			desc += 2;

			/*
			 * ...named "local-mac-address".
			 */
			if (strcmp(desc, "local-mac-address") != 0)
				continue;
			desc += strlen("local-mac-address") + 1;
					
			bcopy(desc, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
			rv = 0;
		}
		break;

	default:
		goto fail;
	}

 fail:
	if (romsize != 0)
		bus_space_unmap(romt, romh, romsize);

	address = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
	address &= ~PCI_ROM_ENABLE;
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, address);

	return (rv);
}
Пример #20
0
int
hme_pci_attach(device_t dev)
{
	struct hme_pci_softc *hsc;
	struct hme_softc *sc;
	bus_space_tag_t	memt;
	bus_space_handle_t memh;
	int i, error = 0;
#if !(defined(__powerpc__) || defined(__sparc64__))
	device_t *children, ebus_dev;
	struct resource *ebus_rres;
	int j, slot;
#endif

	pci_enable_busmaster(dev);
	/*
	 * Some Sun HMEs do have their intpin register bogusly set to 0,
	 * although it should be 1.  Correct that.
	 */
	if (pci_get_intpin(dev) == 0)
		pci_set_intpin(dev, 1);

	hsc = device_get_softc(dev);
	sc = &hsc->hsc_hme;
	sc->sc_dev = dev;
	sc->sc_flags |= HME_PCI;
	mtx_init(&sc->sc_lock, device_get_nameunit(dev), MTX_NETWORK_LOCK,
	    MTX_DEF);

	/*
	 * Map five register banks:
	 *
	 *	bank 0: HME SEB registers:	+0x0000
	 *	bank 1: HME ETX registers:	+0x2000
	 *	bank 2: HME ERX registers:	+0x4000
	 *	bank 3: HME MAC registers:	+0x6000
	 *	bank 4: HME MIF registers:	+0x7000
	 *
	 */
	i = PCIR_BAR(0);
	hsc->hsc_sres = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &i, RF_ACTIVE);
	if (hsc->hsc_sres == NULL) {
		device_printf(dev, "could not map device registers\n");
		error = ENXIO;
		goto fail_mtx;
	}
	i = 0;
	hsc->hsc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
	    &i, RF_SHAREABLE | RF_ACTIVE);
	if (hsc->hsc_ires == NULL) {
		device_printf(dev, "could not allocate interrupt\n");
		error = ENXIO;
		goto fail_sres;
	}
	memt = rman_get_bustag(hsc->hsc_sres);
	memh = rman_get_bushandle(hsc->hsc_sres);
	sc->sc_sebt = sc->sc_etxt = sc->sc_erxt = sc->sc_mact = sc->sc_mift =
	    memt;
	bus_space_subregion(memt, memh, 0x0000, 0x1000, &sc->sc_sebh);
	bus_space_subregion(memt, memh, 0x2000, 0x1000, &sc->sc_etxh);
	bus_space_subregion(memt, memh, 0x4000, 0x1000, &sc->sc_erxh);
	bus_space_subregion(memt, memh, 0x6000, 0x1000, &sc->sc_mach);
	bus_space_subregion(memt, memh, 0x7000, 0x1000, &sc->sc_mifh);

#if defined(__powerpc__) || defined(__sparc64__)
	OF_getetheraddr(dev, sc->sc_enaddr);
#else
	/*
	 * Dig out VPD (vital product data) and read NA (network address).
	 *
	 * The PCI HME is a PCIO chip, which is composed of two functions:
	 *	function 0: PCI-EBus2 bridge, and
	 *	function 1: HappyMeal Ethernet controller.
	 *
	 * The VPD of HME resides in the Boot PROM (PCI FCode) attached
	 * to the EBus bridge and can't be accessed via the PCI capability
	 * pointer.
	 * ``Writing FCode 3.x Programs'' (newer ones, dated 1997 and later)
	 * chapter 2 describes the data structure.
	 *
	 * We don't have a MI EBus driver since no EBus device exists
	 * (besides the FCode PROM) on add-on HME boards.  The ``no driver
	 * attached'' message for function 0 therefore is what is expected.
	 */

#define	PCI_ROMHDR_SIZE			0x1c
#define	PCI_ROMHDR_SIG			0x00
#define	PCI_ROMHDR_SIG_MAGIC		0xaa55		/* little endian */
#define	PCI_ROMHDR_PTR_DATA		0x18
#define	PCI_ROM_SIZE			0x18
#define	PCI_ROM_SIG			0x00
#define	PCI_ROM_SIG_MAGIC		0x52494350	/* "PCIR", endian */
							/* reversed */
#define	PCI_ROM_VENDOR			0x04
#define	PCI_ROM_DEVICE			0x06
#define	PCI_ROM_PTR_VPD			0x08
#define	PCI_VPDRES_BYTE0		0x00
#define	PCI_VPDRES_ISLARGE(x)		((x) & 0x80)
#define	PCI_VPDRES_LARGE_NAME(x)	((x) & 0x7f)
#define	PCI_VPDRES_TYPE_VPD		0x10		/* large */
#define	PCI_VPDRES_LARGE_LEN_LSB	0x01
#define	PCI_VPDRES_LARGE_LEN_MSB	0x02
#define	PCI_VPDRES_LARGE_DATA		0x03
#define	PCI_VPD_SIZE			0x03
#define	PCI_VPD_KEY0			0x00
#define	PCI_VPD_KEY1			0x01
#define	PCI_VPD_LEN			0x02
#define	PCI_VPD_DATA			0x03

#define	HME_ROM_READ_N(n, offs)	bus_space_read_ ## n (memt, memh, (offs))
#define	HME_ROM_READ_1(offs)	HME_ROM_READ_N(1, (offs))
#define	HME_ROM_READ_2(offs)	HME_ROM_READ_N(2, (offs))
#define	HME_ROM_READ_4(offs)	HME_ROM_READ_N(4, (offs))

	/* Search accompanying EBus bridge. */
	slot = pci_get_slot(dev);
	if (device_get_children(device_get_parent(dev), &children, &i) != 0) {
		device_printf(dev, "could not get children\n");
		error = ENXIO;
		goto fail_sres;
	}
	ebus_dev = NULL;
	for (j = 0; j < i; j++) {
		if (pci_get_class(children[j]) == PCIC_BRIDGE &&
		    pci_get_vendor(children[j]) == PCI_VENDOR_SUN &&
		    pci_get_device(children[j]) == PCI_PRODUCT_SUN_EBUS &&
		    pci_get_slot(children[j]) == slot) {
			ebus_dev = children[j];
			break;
		}
	}
	if (ebus_dev == NULL) {
		device_printf(dev, "could not find EBus bridge\n");
		error = ENXIO;
		goto fail_children;
	}

	/* Map EBus bridge PROM registers. */
	i = PCIR_BAR(0);
	if ((ebus_rres = bus_alloc_resource_any(ebus_dev, SYS_RES_MEMORY,
	    &i, RF_ACTIVE)) == NULL) {
		device_printf(dev, "could not map PROM registers\n");
		error = ENXIO;
		goto fail_children;
	}
	memt = rman_get_bustag(ebus_rres);
	memh = rman_get_bushandle(ebus_rres);

	/* Read PCI Expansion ROM header. */
	if (HME_ROM_READ_2(PCI_ROMHDR_SIG) != PCI_ROMHDR_SIG_MAGIC ||
	    (i = HME_ROM_READ_2(PCI_ROMHDR_PTR_DATA)) < PCI_ROMHDR_SIZE) {
		device_printf(dev, "unexpected PCI Expansion ROM header\n");
		error = ENXIO;
		goto fail_rres;
	}

	/* Read PCI Expansion ROM data. */
	if (HME_ROM_READ_4(i + PCI_ROM_SIG) != PCI_ROM_SIG_MAGIC ||
	    HME_ROM_READ_2(i + PCI_ROM_VENDOR) != pci_get_vendor(dev) ||
	    HME_ROM_READ_2(i + PCI_ROM_DEVICE) != pci_get_device(dev) ||
	    (j = HME_ROM_READ_2(i + PCI_ROM_PTR_VPD)) < i + PCI_ROM_SIZE) {
		device_printf(dev, "unexpected PCI Expansion ROM data\n");
		error = ENXIO;
		goto fail_rres;
	}

	/*
	 * Read PCI VPD.
	 * SUNW,hme cards have a single large resource VPD-R tag
	 * containing one NA.  SUNW,qfe cards have four large resource
	 * VPD-R tags containing one NA each (all four HME chips share
	 * the same PROM).
	 * The VPD used on both cards is not in PCI 2.2 standard format
	 * however.  The length in the resource header is in big endian
	 * and the end tag is non-standard (0x79) and followed by an
	 * all-zero "checksum" byte.  Sun calls this a "Fresh Choice
	 * Ethernet" VPD...
	 */
	/* Look at the end tag to determine whether this is a VPD with 4 NAs. */
	if (HME_ROM_READ_1(j + PCI_VPDRES_LARGE_DATA + PCI_VPD_SIZE +
	    ETHER_ADDR_LEN) != 0x79 &&
	    HME_ROM_READ_1(j + 4 * (PCI_VPDRES_LARGE_DATA + PCI_VPD_SIZE +
	    ETHER_ADDR_LEN)) == 0x79)
		/* Use the Nth NA for the Nth HME on this SUNW,qfe. */
		j += slot * (PCI_VPDRES_LARGE_DATA + PCI_VPD_SIZE +
		    ETHER_ADDR_LEN);
	if (PCI_VPDRES_ISLARGE(HME_ROM_READ_1(j + PCI_VPDRES_BYTE0)) == 0 ||
	    PCI_VPDRES_LARGE_NAME(HME_ROM_READ_1(j + PCI_VPDRES_BYTE0)) !=
	    PCI_VPDRES_TYPE_VPD ||
	    (HME_ROM_READ_1(j + PCI_VPDRES_LARGE_LEN_LSB) << 8 |
	    HME_ROM_READ_1(j + PCI_VPDRES_LARGE_LEN_MSB)) !=
	    PCI_VPD_SIZE + ETHER_ADDR_LEN ||
	    HME_ROM_READ_1(j + PCI_VPDRES_LARGE_DATA + PCI_VPD_KEY0) !=
	    0x4e /* N */ ||
	    HME_ROM_READ_1(j + PCI_VPDRES_LARGE_DATA + PCI_VPD_KEY1) !=
	    0x41 /* A */ ||
	    HME_ROM_READ_1(j + PCI_VPDRES_LARGE_DATA + PCI_VPD_LEN) !=
	    ETHER_ADDR_LEN) {
		device_printf(dev, "unexpected PCI VPD\n");
		error = ENXIO;
		goto fail_rres;
	}
	bus_space_read_region_1(memt, memh, j + PCI_VPDRES_LARGE_DATA +
	    PCI_VPD_DATA, sc->sc_enaddr, ETHER_ADDR_LEN);

fail_rres:
	bus_release_resource(ebus_dev, SYS_RES_MEMORY,
	    rman_get_rid(ebus_rres), ebus_rres);
fail_children:
	free(children, M_TEMP);
	if (error != 0)
		goto fail_sres;
#endif

	sc->sc_burst = 64;	/* XXX */

	/*
	 * call the main configure
	 */
	if ((error = hme_config(sc)) != 0) {
		device_printf(dev, "could not be configured\n");
		goto fail_ires;
	}

	if ((error = bus_setup_intr(dev, hsc->hsc_ires, INTR_TYPE_NET |
	    INTR_MPSAFE, NULL, hme_intr, sc, &hsc->hsc_ih)) != 0) {
		device_printf(dev, "couldn't establish interrupt\n");
		hme_detach(sc);
		goto fail_ires;
	}
	return (0);

fail_ires:
	bus_release_resource(dev, SYS_RES_IRQ,
	    rman_get_rid(hsc->hsc_ires), hsc->hsc_ires);
fail_sres:
	bus_release_resource(dev, SYS_RES_MEMORY,
	    rman_get_rid(hsc->hsc_sres), hsc->hsc_sres);
fail_mtx:
	mtx_destroy(&sc->sc_lock);
	return (error);
}