Пример #1
0
int
an_write_bap(struct an_softc *sc, int id, int off, void *buf, int buflen)
{
	int error, cnt;

	if (buflen == 0)
		return 0;
	if (off == -1)
		off = sc->sc_bap_off;
	if (id != sc->sc_bap_id || off != sc->sc_bap_off) {
		if ((error = an_seek_bap(sc, id, off)) != 0)
			return EIO;
	}

	cnt = (buflen + 1) / 2;
	CSR_WRITE_MULTI_STREAM_2(sc, AN_DATA0, (u_int16_t *)buf, cnt);
	sc->sc_bap_off += cnt * 2;
	return 0;
}
Пример #2
0
int
an_mwrite_bap(struct an_softc *sc, int id, int off, struct mbuf *m, int totlen)
{
	int error, len, cnt;

	if (off == -1)
		off = sc->sc_bap_off;
	if (id != sc->sc_bap_id || off != sc->sc_bap_off) {
		if ((error = an_seek_bap(sc, id, off)) != 0)
			return EIO;
	}

	for (len = 0; m != NULL; m = m->m_next) {
		if (m->m_len == 0)
			continue;
		len = min(m->m_len, totlen);

		if ((mtod(m, u_long) & 0x1) || (len & 0x1)) {
			m_copydata(m, 0, totlen, (caddr_t)&sc->sc_buf.sc_txbuf);
			cnt = (totlen + 1) / 2;
			an_swap16((u_int16_t *)&sc->sc_buf.sc_txbuf, cnt); 
			CSR_WRITE_MULTI_STREAM_2(sc, AN_DATA0,
			    sc->sc_buf.sc_val, cnt);
			off += cnt * 2;
			break;
		}
		cnt = len / 2;
		an_swap16((u_int16_t *)mtod(m, u_int16_t *), cnt); 
		CSR_WRITE_MULTI_STREAM_2(sc, AN_DATA0, mtod(m, u_int16_t *),
		    cnt);
		off += len;
		totlen -= len;
	}
	sc->sc_bap_off = off;
	return 0;
}
Пример #3
0
static int
wi_pcmcia_write_firm(struct wi_softc *sc, const void *buf, int buflen,
    const void *ebuf, int ebuflen)
{
	const u_int8_t *p, *ep, *q, *eq;
	char *endp;
	u_int32_t addr, id, eid;
	int i, len, elen, nblk, pdrlen;

	/*
	 * Parse the header of the firmware image.
	 */
	p = buf;
	ep = p + buflen;
	while (p < ep && *p++ != ' ');	/* FILE: */
	while (p < ep && *p++ != ' ');	/* filename */
	while (p < ep && *p++ != ' ');	/* type of the firmware */
	nblk = strtoul(p, &endp, 10);
	p = (void *)endp;
	pdrlen = strtoul(p + 1, &endp, 10);
	p = (void *)endp;
	while (p < ep && *p++ != 0x1a);	/* skip rest of header */

	/*
	 * Block records: address[4], length[2], data[length];
	 */
	for (i = 0; i < nblk; i++) {
		addr = GETLE32(p);	p += 4;
		len  = GETLE16(p);	p += 2;
		CSR_WRITE_2(sc, WI_AUX_PAGE, addr / WI_AUX_PGSZ);
		CSR_WRITE_2(sc, WI_AUX_OFFSET, addr % WI_AUX_PGSZ);
		CSR_WRITE_MULTI_STREAM_2(sc, WI_AUX_DATA,
		    (const u_int16_t *)p, len / 2);
		p += len;
	}

	/*
	 * PDR: id[4], address[4], length[4];
	 */
	for (i = 0; i < pdrlen; ) {
		id   = GETLE32(p);	p += 4; i += 4;
		addr = GETLE32(p);	p += 4; i += 4;
		len  = GETLE32(p);	p += 4; i += 4;
		/* replace PDR entry with the values from EEPROM, if any */
		for (q = ebuf, eq = q + ebuflen; q < eq; q += elen * 2) {
			elen = GETLE16(q);	q += 2;
			eid  = GETLE16(q);	q += 2;
			elen--;		/* elen includes eid */
			if (eid == 0)
				break;
			if (eid != id)
				continue;
			CSR_WRITE_2(sc, WI_AUX_PAGE, addr / WI_AUX_PGSZ);
			CSR_WRITE_2(sc, WI_AUX_OFFSET, addr % WI_AUX_PGSZ);
			CSR_WRITE_MULTI_STREAM_2(sc, WI_AUX_DATA,
			    (const u_int16_t *)q, len / 2);
			break;
		}
	}
	return 0;
}