1 /* $NetBSD: dmover_process.c,v 1.4 2008/01/05 02:47:03 matt Exp $ */ 2 3 /* 4 * Copyright (c) 2002 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 /* 39 * dmover_process.c: Processing engine for dmover-api. 40 */ 41 42 #include <sys/cdefs.h> 43 __KERNEL_RCSID(0, "$NetBSD: dmover_process.c,v 1.4 2008/01/05 02:47:03 matt Exp $"); 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/proc.h> 48 #include <sys/intr.h> 49 #include <sys/simplelock.h> 50 51 #include <dev/dmover/dmovervar.h> 52 53 TAILQ_HEAD(, dmover_request) dmover_completed_q; 54 struct simplelock dmover_completed_q_slock; /* must be held at splbio */ 55 56 void *dmover_completed_si; 57 58 void dmover_complete(void *); 59 60 /* 61 * dmover_process_init: 62 * 63 * Initialize the processing engine. 64 */ 65 void 66 dmover_process_initialize(void) 67 { 68 69 TAILQ_INIT(&dmover_completed_q); 70 simple_lock_init(&dmover_completed_q_slock); 71 72 dmover_completed_si = softint_establish(SOFTINT_CLOCK, 73 dmover_complete, NULL); 74 } 75 76 /* 77 * dmover_process: [client interface function] 78 * 79 * Submit a tranform request for processing. 80 */ 81 void 82 dmover_process(struct dmover_request *dreq) 83 { 84 struct dmover_session *dses = dreq->dreq_session; 85 struct dmover_assignment *das; 86 struct dmover_backend *dmb; 87 int s; 88 89 #ifdef DIAGNOSTIC 90 if ((dreq->dreq_flags & DMOVER_REQ_WAIT) != 0 && 91 dreq->dreq_callback != NULL) 92 panic("dmover_process: WAIT used with callback"); 93 #endif 94 95 /* Clear unwanted flag bits. */ 96 dreq->dreq_flags &= __DMOVER_REQ_FLAGS_PRESERVE; 97 98 s = splbio(); 99 100 /* XXXLOCK */ 101 102 /* XXX Right now, the back-end is statically assigned. */ 103 das = &dses->__dses_assignment; 104 105 dmb = das->das_backend; 106 dreq->dreq_assignment = das; 107 108 dmover_session_insque(dses, dreq); 109 dmover_backend_insque(dmb, dreq); 110 111 /* XXXUNLOCK */ 112 113 splx(s); 114 115 /* Kick the back-end into action. */ 116 (*dmb->dmb_process)(das->das_backend); 117 118 if (dreq->dreq_flags & DMOVER_REQ_WAIT) { 119 s = splbio(); 120 /* XXXLOCK */ 121 while ((dreq->dreq_flags & DMOVER_REQ_DONE) == 0) 122 (void) tsleep(dreq, PRIBIO, "dmover", 0); 123 /* XXXUNLOCK */ 124 splx(s); 125 } 126 } 127 128 /* 129 * dmover_done: [back-end interface function] 130 * 131 * Back-end notification that the dmover is done. 132 */ 133 void 134 dmover_done(struct dmover_request *dreq) 135 { 136 struct dmover_session *dses = dreq->dreq_session; 137 int s; 138 139 s = splbio(); 140 141 /* XXXLOCK */ 142 143 dmover_session_remque(dses, dreq); 144 /* backend has removed it from its queue */ 145 146 /* XXXUNLOCK */ 147 148 dreq->dreq_flags |= DMOVER_REQ_DONE; 149 dreq->dreq_flags &= ~DMOVER_REQ_RUNNING; 150 dreq->dreq_assignment = NULL; 151 152 if (dreq->dreq_callback != NULL) { 153 simple_lock(&dmover_completed_q_slock); 154 TAILQ_INSERT_TAIL(&dmover_completed_q, dreq, dreq_dmbq); 155 simple_unlock(&dmover_completed_q_slock); 156 softint_schedule(dmover_completed_si); 157 } else if (dreq->dreq_flags & DMOVER_REQ_WAIT) 158 wakeup(dreq); 159 160 splx(s); 161 } 162 163 /* 164 * dmover_complete: 165 * 166 * Complete a request by invoking the callback. 167 */ 168 void 169 dmover_complete(void *arg) 170 { 171 struct dmover_request *dreq; 172 int s; 173 174 for (;;) { 175 s = splbio(); 176 simple_lock(&dmover_completed_q_slock); 177 if ((dreq = TAILQ_FIRST(&dmover_completed_q)) != NULL) 178 TAILQ_REMOVE(&dmover_completed_q, dreq, dreq_dmbq); 179 simple_unlock(&dmover_completed_q_slock); 180 splx(s); 181 182 if (dreq == NULL) 183 return; 184 185 (*dreq->dreq_callback)(dreq); 186 } 187 } 188