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; }
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; }
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; }