diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-01-23 04:09:45 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-01-23 04:09:45 +0000 |
commit | 556aee4bcecb016e52a835606c08798b4c746df5 (patch) | |
tree | 360b30934c1a6fef57e578504970352c144d6d96 | |
parent | 9bc3015fc6e2af4c35e909c5987d65ea2a8260e0 (diff) |
Switch to task queues, except for one little corner case that I need to think
a bit further about.
-rw-r--r-- | sys/arch/sparc64/dev/vdsp.c | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/sys/arch/sparc64/dev/vdsp.c b/sys/arch/sparc64/dev/vdsp.c index 4d788a5b631..ecd630d4257 100644 --- a/sys/arch/sparc64/dev/vdsp.c +++ b/sys/arch/sparc64/dev/vdsp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vdsp.c,v 1.21 2014/01/23 01:37:18 kettenis Exp $ */ +/* $OpenBSD: vdsp.c,v 1.22 2014/01/23 04:09:44 kettenis Exp $ */ /* * Copyright (c) 2009, 2011 Mark Kettenis * @@ -25,6 +25,7 @@ #include <sys/malloc.h> #include <sys/namei.h> #include <sys/systm.h> +#include <sys/task.h> #include <sys/vnode.h> #include <sys/workq.h> @@ -231,7 +232,12 @@ struct vdsp_softc { uint32_t sc_descriptor_size; struct ldc_cookie sc_dring_cookie; + struct task sc_open_task; + struct task sc_alloc_task; + struct task sc_close_task; + caddr_t sc_vd; + struct task *sc_vd_task; int sc_tx_cnt; int sc_tx_prod; @@ -360,6 +366,10 @@ vdsp_attach(struct device *parent, struct device *self, void *aux) goto free_txqueue; } + task_set(&sc->sc_open_task, vdsp_open, sc, NULL); + task_set(&sc->sc_alloc_task, vdsp_alloc, sc, NULL); + task_set(&sc->sc_close_task, vdsp_close, sc, NULL); + printf("\n"); return; @@ -593,7 +603,7 @@ vdsp_rx_vio_attr_info(struct vdsp_softc *sc, struct vio_msg_tag *tag) sc->sc_xfer_mode = ai->xfer_mode; sc->sc_vio_state |= VIO_RCV_ATTR_INFO; - workq_add_task(NULL, 0, vdsp_open, sc, NULL); + task_add(systq, &sc->sc_open_task); break; case VIO_SUBTYPE_ACK: @@ -627,7 +637,7 @@ vdsp_rx_vio_dring_reg(struct vdsp_softc *sc, struct vio_msg_tag *tag) sc->sc_dring_cookie = dr->cookie[0]; sc->sc_vio_state |= VIO_RCV_DRING_REG; - workq_add_task(NULL, 0, vdsp_alloc, sc, NULL); + task_add(systq, &sc->sc_alloc_task); break; case VIO_SUBTYPE_ACK: @@ -694,6 +704,7 @@ vdsp_rx_vio_dring_data(struct vdsp_softc *sc, struct vio_msg_tag *tag) { struct vio_dring_msg *dm = (struct vio_dring_msg *)tag; struct vd_desc *vd; + struct task *task; vaddr_t va; paddr_t pa; uint64_t size, off; @@ -729,28 +740,29 @@ vdsp_rx_vio_dring_data(struct vdsp_softc *sc, struct vio_msg_tag *tag) size -= nbytes; off += nbytes; } + task = &sc->sc_vd_task[dm->start_idx]; DPRINTF(("%s: start_idx %d, end_idx %d, operation %x\n", sc->sc_dv.dv_xname, dm->start_idx, dm->end_idx, vd->operation)); switch (vd->operation) { case VD_OP_BREAD: - workq_add_task(NULL, 0, vdsp_read_dring, sc, vd); + task_set(task, vdsp_read_dring, sc, vd); break; case VD_OP_BWRITE: - workq_add_task(NULL, 0, vdsp_write_dring, sc, vd); + task_set(task, vdsp_write_dring, sc, vd); break; case VD_OP_FLUSH: - workq_add_task(NULL, 0, vdsp_flush_dring, sc, vd); + task_set(task, vdsp_flush_dring, sc, vd); break; case VD_OP_GET_VTOC: - workq_add_task(NULL, 0, vdsp_get_vtoc, sc, vd); + task_set(task, vdsp_get_vtoc, sc, vd); break; case VD_OP_SET_VTOC: - workq_add_task(NULL, 0, vdsp_set_vtoc, sc, vd); + task_set(task, vdsp_set_vtoc, sc, vd); break; case VD_OP_GET_DISKGEOM: - workq_add_task(NULL, 0, vdsp_get_diskgeom, sc, vd); + task_set(task, vdsp_get_diskgeom, sc, vd); break; case VD_OP_GET_WCE: case VD_OP_SET_WCE: @@ -761,14 +773,15 @@ vdsp_rx_vio_dring_data(struct vdsp_softc *sc, struct vio_msg_tag *tag) * to be able to handle failure just fine, so * we silently ignore it. */ - workq_add_task(NULL, 0, vdsp_unimp, sc, vd); + task_set(task, vdsp_unimp, sc, vd); break; default: printf("%s: unsupported operation 0x%02x\n", sc->sc_dv.dv_xname, vd->operation); - workq_add_task(NULL, 0, vdsp_unimp, sc, vd); + task_set(task, vdsp_unimp, sc, vd); break; } + task_add(systq, task); break; case VIO_SUBTYPE_ACK: @@ -830,12 +843,16 @@ vdsp_ldc_reset(struct ldc_conn *lc) free(sc->sc_vd, M_DEVBUF); sc->sc_vd = NULL; } + if (sc->sc_vd_task) { + free(sc->sc_vd_task, M_DEVBUF); + sc->sc_vd_task = NULL; + } if (sc->sc_label) { free(sc->sc_label, M_DEVBUF); sc->sc_label = NULL; } - workq_add_task(NULL, 0, vdsp_close, sc, NULL); + task_add(systq, &sc->sc_close_task); } void @@ -1037,6 +1054,8 @@ vdsp_alloc(void *arg1, void *arg2) KASSERT(sc->sc_descriptor_size <= VDSK_MAX_DESCRIPTOR_SIZE); sc->sc_vd = malloc(sc->sc_num_descriptors * sc->sc_descriptor_size, M_DEVBUF, M_WAITOK); + sc->sc_vd_task = malloc(sc->sc_num_descriptors * sizeof(struct task), + M_DEVBUF, M_WAITOK); bzero(&dr, sizeof(dr)); dr.tag.type = VIO_TYPE_CTRL; |