Ejemplo n.º 1
0
static int
cfi_0002_program_page(device_t self, flash_off_t offset, const 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, program_page);

	bus_size_t count = chip->nc_page_size >> cfi->cfi_portwidth;
							/* #words/page */
	bus_size_t sa = offset << (3 - cfi->cfi_portwidth);
							/* sector addr */
	uint32_t wc = count - 1;			/* #words - 1 */

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

	cfi_cmd(cfi, cfi->cfi_unlock_addr1, 0xaa);
	cfi_cmd(cfi, cfi->cfi_unlock_addr2, 0x55);
	cfi_cmd(cfi, sa,                    0x25); /* Write To Buffer */
	cfi_cmd(cfi, sa,                    wc);

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

	cfi_cmd(cfi, sa, 0x29);	/*  Write Buffer Program Confirm */

	error = cfi_0002_busy_wait(cfi, offset, cfi_0002_time_write_nbyte(cfi));

	return error;
}
Ejemplo n.º 2
0
/*
 * Copy packet from mbuf to the board memory Currently uses an extra
 * buffer/extra memory copy, unless the whole packet fits in one mbuf.
 *
 * As in the test_mem function, we use word-wide writes.
 */
int
ae_write_mbuf(struct dp8390_softc *sc, struct mbuf *m, int buf)
{
	u_char *data, savebyte[2];
	int len, wantbyte;
	u_short totlen = 0;

	wantbyte = 0;

	for (; m ; m = m->m_next) {
		data = mtod(m, u_char *);
		len = m->m_len;
		totlen += len;
		if (len > 0) {
			/* Finish the last word. */
			if (wantbyte) {
				savebyte[1] = *data;
				bus_space_write_region_2(sc->sc_buft,
				    sc->sc_bufh, buf, (u_int16_t *)savebyte, 1);
				buf += 2;
				data++;
				len--;
				wantbyte = 0;
			}
			/* Output contiguous words. */
			if (len > 1) {
				bus_space_write_region_2(
				    sc->sc_buft, sc->sc_bufh,
				    buf, (u_int16_t *)data, len >> 1);
				buf += len & ~1;
				data += len & ~1;
				len &= 1;
			}
			/* Save last byte, if necessary. */
			if (len == 1) {
				savebyte[0] = *data;
				wantbyte = 1;
			}
		}
	}
void
bs_through_bs_wr_2(bus_space_tag_t t, bus_space_handle_t bsh,
    bus_size_t offset, const u_int16_t *addr, bus_size_t count)
{
	bus_space_write_region_2(t->bs_base, bsh, offset, addr, count);
}