-/* $OpenBSD: aplns.c,v 1.14 2022/11/09 19:18:11 kettenis Exp $ */
+/* $OpenBSD: aplns.c,v 1.15 2022/11/11 11:45:10 kettenis Exp $ */
/*
* Copyright (c) 2014, 2021 David Gwynne <dlg@openbsd.org>
*
};
int nvme_ans_sart_map(void *, bus_addr_t, bus_size_t);
+int nvme_ans_sart_unmap(void *, bus_addr_t, bus_size_t);
int
aplns_match(struct device *parent, void *match, void *aux)
asc->asc_rtkit.rk_cookie = asc;
asc->asc_rtkit.rk_dmat = faa->fa_dmat;
asc->asc_rtkit.rk_map = nvme_ans_sart_map;
+ asc->asc_rtkit.rk_unmap = nvme_ans_sart_unmap;
asc->asc_rtkit_state =
rtkit_init(faa->fa_node, NULL, 0, &asc->asc_rtkit);
return aplsart_map(asc->asc_sart, addr, size);
}
+int
+nvme_ans_sart_unmap(void *cookie, bus_addr_t addr, bus_size_t size)
+{
+ struct nvme_ans_softc *asc = cookie;
+
+ return aplsart_unmap(asc->asc_sart, addr, size);
+}
+
int
nvme_ans_q_alloc(struct nvme_softc *sc,
struct nvme_queue *q)
-/* $OpenBSD: aplsart.c,v 1.3 2022/11/10 14:15:15 kettenis Exp $ */
+/* $OpenBSD: aplsart.c,v 1.4 2022/11/11 11:45:10 kettenis Exp $ */
/*
* Copyright (c) 2022 Mark Kettenis <kettenis@openbsd.org>
*
return ENXIO;
}
+
+int
+aplsart2_unmap(struct aplsart_softc *sc, bus_addr_t addr, bus_size_t size)
+{
+ int i;
+
+ for (i = 0; i < SART_NUM_ENTRIES; i++) {
+ if (HREAD4(sc, SART2_ADDR(i)) != (addr >> SART_ADDR_SHIFT))
+ continue;
+
+ HWRITE4(sc, SART2_ADDR(i), 0);
+ HWRITE4(sc, SART2_CONFIG(i), 0);
+ return 0;
+ }
+
+ return ENOENT;
+}
+
+int
+aplsart3_unmap(struct aplsart_softc *sc, bus_addr_t addr, bus_size_t size)
+{
+ int i;
+
+ for (i = 0; i < SART_NUM_ENTRIES; i++) {
+ if (HREAD4(sc, SART3_ADDR(i)) != (addr >> SART_ADDR_SHIFT))
+ continue;
+
+ HWRITE4(sc, SART3_ADDR(i), 0);
+ HWRITE4(sc, SART3_SIZE(i), 0);
+ HWRITE4(sc, SART3_CONFIG(i), 0);
+ return 0;
+ }
+
+ return ENOENT;
+}
+
+int
+aplsart_unmap(uint32_t phandle, bus_addr_t addr, bus_size_t size)
+{
+ struct aplsart_softc *sc;
+ int i;
+
+ for (i = 0; i < aplsart_cd.cd_ndevs; i++) {
+ sc = (struct aplsart_softc *)aplsart_cd.cd_devs[i];
+
+ if (sc->sc_phandle == phandle) {
+ if (sc->sc_version == 2)
+ return aplsart2_unmap(sc, addr, size);
+ else
+ return aplsart3_unmap(sc, addr, size);
+ }
+ }
+
+ return ENXIO;
+}
-/* $OpenBSD: rtkit.c,v 1.8 2022/11/09 19:18:11 kettenis Exp $ */
+/* $OpenBSD: rtkit.c,v 1.9 2022/11/11 11:45:10 kettenis Exp $ */
/*
* Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org>
*
#define RTKIT_MINVER 11
#define RTKIT_MAXVER 12
+struct rtkit_dmamem {
+ bus_dmamap_t rdm_map;
+ bus_dma_segment_t rdm_seg;
+ size_t rdm_size;
+};
+
struct rtkit_state {
struct mbox_channel *mc;
struct rtkit *rk;
uint64_t epmap;
void (*callback[32])(void *, uint64_t);
void *arg[32];
+ struct rtkit_dmamem dmamem[32];
+ int ndmamem;
};
int
}
bus_addr_t
-rtkit_alloc(struct rtkit *rk, bus_size_t size)
+rtkit_alloc(struct rtkit_state *state, bus_size_t size)
{
+ struct rtkit *rk = state->rk;
bus_dma_segment_t seg;
bus_dmamap_t map;
int nsegs;
+ if (state->ndmamem >= nitems(state->dmamem))
+ return ENOMEM;
+
if (bus_dmamem_alloc(rk->rk_dmat, size, 16384, 0,
&seg, 1, &nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO))
return (bus_addr_t)-1;
return (bus_addr_t)-1;
}
+ if (rk->rk_map) {
+ if (rk->rk_map(rk->rk_cookie, seg.ds_addr, seg.ds_len)) {
+ bus_dmamap_unload(rk->rk_dmat, map);
+ bus_dmamap_destroy(rk->rk_dmat, map);
+ bus_dmamem_free(rk->rk_dmat, &seg, 1);
+ return (bus_addr_t)-1;
+ }
+ }
+
+ state->dmamem[state->ndmamem].rdm_map = map;
+ state->dmamem[state->ndmamem].rdm_seg = seg;
+ state->dmamem[state->ndmamem].rdm_size = size;
+ state->ndmamem++;
+
return seg.ds_addr;
}
break;
if (rk) {
- addr = rtkit_alloc(rk, size << PAGE_SHIFT);
+ addr = rtkit_alloc(state, size << PAGE_SHIFT);
if (addr == (bus_addr_t)-1)
return ENOMEM;
- if (rk->rk_map) {
- error = rk->rk_map(rk->rk_cookie, addr,
- size << PAGE_SHIFT);
- if (error)
- return error;
- }
}
error = rtkit_send(mc, RTKIT_EP_CRASHLOG, RTKIT_BUFFER_REQUEST,
break;
if (rk) {
- addr = rtkit_alloc(rk, size << PAGE_SHIFT);
+ addr = rtkit_alloc(state, size << PAGE_SHIFT);
if (addr == (bus_addr_t)-1)
return ENOMEM;
- if (rk->rk_map) {
- error = rk->rk_map(rk->rk_cookie, addr,
- size << PAGE_SHIFT);
- if (error)
- return error;
- }
}
error = rtkit_send(mc, RTKIT_EP_SYSLOG, RTKIT_BUFFER_REQUEST,
break;
if (rk) {
- addr = rtkit_alloc(rk, size << PAGE_SHIFT);
+ addr = rtkit_alloc(state, size << PAGE_SHIFT);
if (addr == (bus_addr_t)-1)
return ENOMEM;
- if (rk->rk_map) {
- error = rk->rk_map(rk->rk_cookie, addr,
- size << PAGE_SHIFT);
- if (error)
- return error;
- }
}
error = rtkit_send(mc, RTKIT_EP_IOREPORT, RTKIT_BUFFER_REQUEST,
rtkit_shutdown(struct rtkit_state *state)
{
struct mbox_channel *mc = state->mc;
+ struct rtkit *rk = state->rk;
+ int i;
if (state->ap_pwrstate != RTKIT_MGMT_PWR_STATE_QUIESCED)
rtkit_set_ap_pwrstate(state, RTKIT_MGMT_PWR_STATE_QUIESCED);
KASSERT(state->iop_pwrstate == RTKIT_MGMT_PWR_STATE_SLEEP);
KASSERT(state->ap_pwrstate == RTKIT_MGMT_PWR_STATE_QUIESCED);
state->epmap = 0;
+
+ /* Clean up our memory allocations. */
+ for (i = 0; i < state->ndmamem; i++) {
+ if (rk->rk_unmap) {
+ rk->rk_unmap(rk->rk_cookie,
+ state->dmamem[i].rdm_seg.ds_addr,
+ state->dmamem[i].rdm_seg.ds_len);
+ }
+ bus_dmamap_unload(rk->rk_dmat, state->dmamem[i].rdm_map);
+ bus_dmamap_destroy(rk->rk_dmat, state->dmamem[i].rdm_map);
+ bus_dmamem_free(rk->rk_dmat, &state->dmamem[i].rdm_seg, 1);
+ }
+ state->ndmamem = 0;
}
int