icap_ebus.c revision 1.1.4.2 1 1.1.4.2 rmind /* $NetBSD: icap_ebus.c,v 1.1.4.2 2011/03/05 20:49:54 rmind Exp $ */
2 1.1.4.2 rmind
3 1.1.4.2 rmind /*-
4 1.1.4.2 rmind * Copyright (c) 2010 The NetBSD Foundation, Inc.
5 1.1.4.2 rmind * All rights reserved.
6 1.1.4.2 rmind *
7 1.1.4.2 rmind * This code was written by Alessandro Forin and Neil Pittman
8 1.1.4.2 rmind * at Microsoft Research and contributed to The NetBSD Foundation
9 1.1.4.2 rmind * by Microsoft Corporation.
10 1.1.4.2 rmind *
11 1.1.4.2 rmind * Redistribution and use in source and binary forms, with or without
12 1.1.4.2 rmind * modification, are permitted provided that the following conditions
13 1.1.4.2 rmind * are met:
14 1.1.4.2 rmind * 1. Redistributions of source code must retain the above copyright
15 1.1.4.2 rmind * notice, this list of conditions and the following disclaimer.
16 1.1.4.2 rmind * 2. Redistributions in binary form must reproduce the above copyright
17 1.1.4.2 rmind * notice, this list of conditions and the following disclaimer in the
18 1.1.4.2 rmind * documentation and/or other materials provided with the distribution.
19 1.1.4.2 rmind *
20 1.1.4.2 rmind * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 1.1.4.2 rmind * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 1.1.4.2 rmind * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 1.1.4.2 rmind * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 1.1.4.2 rmind * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 1.1.4.2 rmind * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 1.1.4.2 rmind * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 1.1.4.2 rmind * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 1.1.4.2 rmind * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 1.1.4.2 rmind * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 1.1.4.2 rmind * POSSIBILITY OF SUCH DAMAGE.
31 1.1.4.2 rmind */
32 1.1.4.2 rmind
33 1.1.4.2 rmind #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
34 1.1.4.2 rmind __KERNEL_RCSID(0, "$NetBSD: icap_ebus.c,v 1.1.4.2 2011/03/05 20:49:54 rmind Exp $");
35 1.1.4.2 rmind
36 1.1.4.2 rmind #include <sys/param.h>
37 1.1.4.2 rmind #include <sys/systm.h>
38 1.1.4.2 rmind #include <sys/buf.h>
39 1.1.4.2 rmind #include <sys/bufq.h>
40 1.1.4.2 rmind #include <sys/proc.h>
41 1.1.4.2 rmind #include <sys/errno.h>
42 1.1.4.2 rmind #include <sys/ioctl.h>
43 1.1.4.2 rmind #include <sys/device.h>
44 1.1.4.2 rmind #include <sys/conf.h>
45 1.1.4.2 rmind #include <uvm/uvm_param.h>
46 1.1.4.2 rmind
47 1.1.4.2 rmind #include <emips/ebus/ebusvar.h>
48 1.1.4.2 rmind #include <emips/emips/machdep.h>
49 1.1.4.2 rmind #include <machine/emipsreg.h>
50 1.1.4.2 rmind
51 1.1.4.2 rmind #define DEBUG_INTR 0x01
52 1.1.4.2 rmind #define DEBUG_XFERS 0x02
53 1.1.4.2 rmind #define DEBUG_STATUS 0x04
54 1.1.4.2 rmind #define DEBUG_FUNCS 0x08
55 1.1.4.2 rmind #define DEBUG_PROBE 0x10
56 1.1.4.2 rmind #define DEBUG_WRITES 0x20
57 1.1.4.2 rmind #define DEBUG_READS 0x40
58 1.1.4.2 rmind #define DEBUG_ERRORS 0x80
59 1.1.4.2 rmind #ifdef DEBUG
60 1.1.4.2 rmind int icap_debug = DEBUG_ERRORS;
61 1.1.4.2 rmind #define ICAP_DEBUG(x) (icap_debug & (x))
62 1.1.4.2 rmind #define DBGME(_lev_,_x_) if ((_lev_) & icap_debug) _x_
63 1.1.4.2 rmind #else
64 1.1.4.2 rmind #define ICAP_DEBUG(x) (0)
65 1.1.4.2 rmind #define DBGME(_lev_,_x_)
66 1.1.4.2 rmind #endif
67 1.1.4.2 rmind #define DEBUG_PRINT(_args_,_lev_) DBGME(_lev_,printf _args_)
68 1.1.4.2 rmind
69 1.1.4.2 rmind /*
70 1.1.4.2 rmind * Device softc
71 1.1.4.2 rmind */
72 1.1.4.2 rmind struct icap_softc {
73 1.1.4.2 rmind device_t sc_dev;
74 1.1.4.2 rmind struct _Icap *sc_dp;
75 1.1.4.2 rmind struct bufq_state *sc_buflist;
76 1.1.4.2 rmind struct buf *sc_bp;
77 1.1.4.2 rmind char *sc_data;
78 1.1.4.2 rmind int sc_count;
79 1.1.4.2 rmind };
80 1.1.4.2 rmind
81 1.1.4.2 rmind /* Required funcs
82 1.1.4.2 rmind */
83 1.1.4.2 rmind static int icap_ebus_match (struct device *, struct cfdata *, void *);
84 1.1.4.2 rmind static void icap_ebus_attach (struct device *, struct device *, void *);
85 1.1.4.2 rmind
86 1.1.4.2 rmind static dev_type_open(icapopen);
87 1.1.4.2 rmind static dev_type_close(icapclose);
88 1.1.4.2 rmind static dev_type_read(icapread);
89 1.1.4.2 rmind static dev_type_write(icapwrite);
90 1.1.4.2 rmind static dev_type_ioctl(icapioctl);
91 1.1.4.2 rmind static dev_type_strategy(icapstrategy);
92 1.1.4.2 rmind
93 1.1.4.2 rmind /* Other functions
94 1.1.4.2 rmind */
95 1.1.4.2 rmind extern paddr_t kvtophys(vaddr_t);
96 1.1.4.2 rmind static void icapstart(struct icap_softc *sc);
97 1.1.4.2 rmind static int icap_ebus_intr(void *cookie, void *f);
98 1.1.4.2 rmind static void icap_reset(struct icap_softc *sc);
99 1.1.4.2 rmind
100 1.1.4.2 rmind /* Config stuff
101 1.1.4.2 rmind */
102 1.1.4.2 rmind extern struct cfdriver icap_cd;
103 1.1.4.2 rmind
104 1.1.4.2 rmind CFATTACH_DECL_NEW(icap_ebus, sizeof (struct icap_softc),
105 1.1.4.2 rmind icap_ebus_match, icap_ebus_attach, NULL, NULL);
106 1.1.4.2 rmind
107 1.1.4.2 rmind static int
108 1.1.4.2 rmind icap_ebus_match(struct device *parent, struct cfdata *match, void *aux)
109 1.1.4.2 rmind {
110 1.1.4.2 rmind struct ebus_attach_args *ia = aux;
111 1.1.4.2 rmind struct _Icap *f = (struct _Icap *)ia->ia_vaddr;
112 1.1.4.2 rmind
113 1.1.4.2 rmind DEBUG_PRINT(("icap_match %x\n", (f) ? f->Tag : 0), DEBUG_PROBE);
114 1.1.4.2 rmind if (strcmp("icap", ia->ia_name) != 0)
115 1.1.4.2 rmind return (0);
116 1.1.4.2 rmind if ((f == NULL) ||
117 1.1.4.2 rmind (! (f->Tag == PMTTAG_ICAP)))
118 1.1.4.2 rmind return (0);
119 1.1.4.2 rmind
120 1.1.4.2 rmind return (1);
121 1.1.4.2 rmind }
122 1.1.4.2 rmind
123 1.1.4.2 rmind static void
124 1.1.4.2 rmind icap_ebus_attach(struct device *parent, struct device *self, void *aux)
125 1.1.4.2 rmind {
126 1.1.4.2 rmind struct icap_softc *sc = device_private(self);
127 1.1.4.2 rmind struct ebus_attach_args *ia =aux;
128 1.1.4.2 rmind
129 1.1.4.2 rmind DEBUG_PRINT(("icap_attach %p\n", sc), DEBUG_PROBE);
130 1.1.4.2 rmind
131 1.1.4.2 rmind sc->sc_dev = self;
132 1.1.4.2 rmind sc->sc_dp = (struct _Icap*)ia->ia_vaddr;
133 1.1.4.2 rmind bufq_alloc(&sc->sc_buflist, "fcfs", 0);
134 1.1.4.2 rmind sc->sc_bp = NULL;
135 1.1.4.2 rmind sc->sc_data = NULL;
136 1.1.4.2 rmind sc->sc_count = 0;
137 1.1.4.2 rmind
138 1.1.4.2 rmind #if DEBUG
139 1.1.4.2 rmind printf(" virt=%p", (void*)sc->sc_dp);
140 1.1.4.2 rmind #endif
141 1.1.4.2 rmind printf(": %s\n", "Internal Configuration Access Port");
142 1.1.4.2 rmind
143 1.1.4.2 rmind ebus_intr_establish(parent, (void*)ia->ia_cookie, IPL_BIO,
144 1.1.4.2 rmind icap_ebus_intr, sc);
145 1.1.4.2 rmind
146 1.1.4.2 rmind icap_reset(sc);
147 1.1.4.2 rmind }
148 1.1.4.2 rmind
149 1.1.4.2 rmind /* The character device handlers
150 1.1.4.2 rmind */
151 1.1.4.2 rmind const struct cdevsw icap_cdevsw = {
152 1.1.4.2 rmind icapopen,
153 1.1.4.2 rmind icapclose,
154 1.1.4.2 rmind icapread,
155 1.1.4.2 rmind icapwrite,
156 1.1.4.2 rmind icapioctl,
157 1.1.4.2 rmind nostop,
158 1.1.4.2 rmind notty,
159 1.1.4.2 rmind nopoll,
160 1.1.4.2 rmind nommap,
161 1.1.4.2 rmind nokqfilter,
162 1.1.4.2 rmind };
163 1.1.4.2 rmind
164 1.1.4.2 rmind /*
165 1.1.4.2 rmind * Handle an open request on the device.
166 1.1.4.2 rmind */
167 1.1.4.2 rmind static int
168 1.1.4.2 rmind icapopen(dev_t device, int flags, int fmt, struct lwp *process)
169 1.1.4.2 rmind {
170 1.1.4.2 rmind struct icap_softc *sc;
171 1.1.4.2 rmind
172 1.1.4.2 rmind DEBUG_PRINT(("icapopen\n"), DEBUG_FUNCS);
173 1.1.4.2 rmind sc = device_lookup_private(&icap_cd, minor(device));
174 1.1.4.2 rmind if (sc == NULL)
175 1.1.4.2 rmind return (ENXIO);
176 1.1.4.2 rmind
177 1.1.4.2 rmind return 0;
178 1.1.4.2 rmind }
179 1.1.4.2 rmind
180 1.1.4.2 rmind /*
181 1.1.4.2 rmind * Handle the close request for the device.
182 1.1.4.2 rmind */
183 1.1.4.2 rmind static int
184 1.1.4.2 rmind icapclose(dev_t device, int flags, int fmt, struct lwp *process)
185 1.1.4.2 rmind {
186 1.1.4.2 rmind DEBUG_PRINT(("icapclose\n"), DEBUG_FUNCS);
187 1.1.4.2 rmind return 0; /* this always succeeds */
188 1.1.4.2 rmind }
189 1.1.4.2 rmind
190 1.1.4.2 rmind /*
191 1.1.4.2 rmind * Handle the read request for the device.
192 1.1.4.2 rmind */
193 1.1.4.2 rmind static int
194 1.1.4.2 rmind icapread(dev_t dev, struct uio *uio, int flags)
195 1.1.4.2 rmind {
196 1.1.4.2 rmind DEBUG_PRINT(("icapread\n"), DEBUG_READS);
197 1.1.4.2 rmind return (physio(icapstrategy, NULL, dev, B_READ, minphys, uio));
198 1.1.4.2 rmind }
199 1.1.4.2 rmind
200 1.1.4.2 rmind /*
201 1.1.4.2 rmind * Handle the write request for the device.
202 1.1.4.2 rmind */
203 1.1.4.2 rmind static int
204 1.1.4.2 rmind icapwrite(dev_t dev, struct uio *uio, int flags)
205 1.1.4.2 rmind {
206 1.1.4.2 rmind DEBUG_PRINT(("icapwrite\n"), DEBUG_WRITES);
207 1.1.4.2 rmind return (physio(icapstrategy, NULL, dev, B_WRITE, minphys, uio));
208 1.1.4.2 rmind }
209 1.1.4.2 rmind
210 1.1.4.2 rmind /*
211 1.1.4.2 rmind * Handle the ioctl request for the device.
212 1.1.4.2 rmind */
213 1.1.4.2 rmind static int
214 1.1.4.2 rmind icapioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l)
215 1.1.4.2 rmind {
216 1.1.4.2 rmind
217 1.1.4.2 rmind return ENOTTY;
218 1.1.4.2 rmind }
219 1.1.4.2 rmind
220 1.1.4.2 rmind /*
221 1.1.4.2 rmind * Strategy function for the device.
222 1.1.4.2 rmind */
223 1.1.4.2 rmind static void
224 1.1.4.2 rmind icapstrategy(struct buf *bp)
225 1.1.4.2 rmind {
226 1.1.4.2 rmind struct icap_softc *sc;
227 1.1.4.2 rmind int s;
228 1.1.4.2 rmind
229 1.1.4.2 rmind DEBUG_PRINT(("icapstrategy\n"), DEBUG_FUNCS);
230 1.1.4.2 rmind
231 1.1.4.2 rmind /* We did nothing lest we did */
232 1.1.4.2 rmind bp->b_resid = bp->b_bcount;
233 1.1.4.2 rmind
234 1.1.4.2 rmind /* Do we know you. */
235 1.1.4.2 rmind sc = device_lookup_private(&icap_cd, minor(bp->b_dev));
236 1.1.4.2 rmind if (sc == NULL) {
237 1.1.4.2 rmind DEBUG_PRINT(("icapstrategy: nodev %x\n",bp->b_dev),
238 1.1.4.2 rmind DEBUG_ERRORS);
239 1.1.4.2 rmind bp->b_error = ENXIO;
240 1.1.4.2 rmind biodone(bp);
241 1.1.4.2 rmind return;
242 1.1.4.2 rmind }
243 1.1.4.2 rmind
244 1.1.4.2 rmind /* Add to Q. If Q was empty get it started */
245 1.1.4.2 rmind s = splbio();
246 1.1.4.2 rmind bufq_put(sc->sc_buflist, bp);
247 1.1.4.2 rmind if (bufq_peek(sc->sc_buflist) == bp) {
248 1.1.4.2 rmind icapstart(sc);
249 1.1.4.2 rmind }
250 1.1.4.2 rmind splx(s);
251 1.1.4.2 rmind }
252 1.1.4.2 rmind
253 1.1.4.2 rmind /*
254 1.1.4.2 rmind * Get the next I/O request started
255 1.1.4.2 rmind */
256 1.1.4.2 rmind static void
257 1.1.4.2 rmind icapstart(struct icap_softc *sc)
258 1.1.4.2 rmind {
259 1.1.4.2 rmind paddr_t phys, phys2;
260 1.1.4.2 rmind vaddr_t virt;
261 1.1.4.2 rmind size_t count;
262 1.1.4.2 rmind uint32_t fl;
263 1.1.4.2 rmind struct buf *bp = sc->sc_bp;
264 1.1.4.2 rmind
265 1.1.4.2 rmind DEBUG_PRINT(("icapstart %p %p\n",sc,bp), DEBUG_FUNCS);
266 1.1.4.2 rmind
267 1.1.4.2 rmind /* Were we idle?
268 1.1.4.2 rmind */
269 1.1.4.2 rmind recheck:
270 1.1.4.2 rmind if (bp == NULL) {
271 1.1.4.2 rmind
272 1.1.4.2 rmind /* Yes, get the next request if any
273 1.1.4.2 rmind */
274 1.1.4.2 rmind bp = bufq_get(sc->sc_buflist);
275 1.1.4.2 rmind DEBUG_PRINT(("icapnext: %p\n",bp), DEBUG_XFERS);
276 1.1.4.2 rmind if (bp == NULL)
277 1.1.4.2 rmind return;
278 1.1.4.2 rmind }
279 1.1.4.2 rmind
280 1.1.4.2 rmind /* Done with this request?
281 1.1.4.2 rmind */
282 1.1.4.2 rmind if ((bp->b_resid == 0) || bp->b_error) {
283 1.1.4.2 rmind
284 1.1.4.2 rmind /* Yes, complete and move to next, if any
285 1.1.4.2 rmind */
286 1.1.4.2 rmind sc->sc_bp = NULL;
287 1.1.4.2 rmind biodone(bp);
288 1.1.4.2 rmind DEBUG_PRINT(("icapdone %p\n",bp), DEBUG_XFERS);
289 1.1.4.2 rmind bp = NULL;
290 1.1.4.2 rmind goto recheck;
291 1.1.4.2 rmind }
292 1.1.4.2 rmind
293 1.1.4.2 rmind /* If new request init the xfer info
294 1.1.4.2 rmind */
295 1.1.4.2 rmind if (sc->sc_bp == NULL) {
296 1.1.4.2 rmind sc->sc_bp = bp;
297 1.1.4.2 rmind sc->sc_data = bp->b_data;
298 1.1.4.2 rmind sc->sc_count = bp->b_resid;
299 1.1.4.2 rmind }
300 1.1.4.2 rmind
301 1.1.4.2 rmind /* Loop filling as many buffers as will fit in the FIFO
302 1.1.4.2 rmind */
303 1.1.4.2 rmind fl = (bp->b_flags & B_READ) ? ICAPS_F_RECV : ICAPS_F_XMIT;
304 1.1.4.2 rmind for (;;) {
305 1.1.4.2 rmind
306 1.1.4.2 rmind /* Make sure there's still room in the FIFO, no errors.
307 1.1.4.2 rmind */
308 1.1.4.2 rmind if (sc->sc_dp->Control & (ICAPC_IF_FULL|ICAPC_ERROR))
309 1.1.4.2 rmind break;
310 1.1.4.2 rmind
311 1.1.4.2 rmind /* How much data do we xfer and where
312 1.1.4.2 rmind */
313 1.1.4.2 rmind virt = (vaddr_t)sc->sc_data;
314 1.1.4.2 rmind phys = kvtophys(virt);
315 1.1.4.2 rmind count = round_page(virt) - virt;
316 1.1.4.2 rmind if (count == 0) count = PAGE_SIZE;/* could(will) be aligned */
317 1.1.4.2 rmind
318 1.1.4.2 rmind /* How much of it is contiguous
319 1.1.4.2 rmind */
320 1.1.4.2 rmind while (count < sc->sc_count) {
321 1.1.4.2 rmind phys2 = kvtophys(virt + count);
322 1.1.4.2 rmind if (phys2 != (phys + count)) {
323 1.1.4.2 rmind
324 1.1.4.2 rmind /* No longer contig, ship it
325 1.1.4.2 rmind */
326 1.1.4.2 rmind break;
327 1.1.4.2 rmind }
328 1.1.4.2 rmind count += PAGE_SIZE;
329 1.1.4.2 rmind }
330 1.1.4.2 rmind
331 1.1.4.2 rmind /* Trim if we went too far
332 1.1.4.2 rmind */
333 1.1.4.2 rmind if (count > sc->sc_count)
334 1.1.4.2 rmind count = sc->sc_count;
335 1.1.4.2 rmind
336 1.1.4.2 rmind /* Ship it
337 1.1.4.2 rmind */
338 1.1.4.2 rmind DEBUG_PRINT(("icapship %lx %d\n",phys,count), DEBUG_XFERS);
339 1.1.4.2 rmind sc->sc_dp->SizeAndFlags = fl | count;
340 1.1.4.2 rmind sc->sc_dp->BufferAddressHi32 = 0; /* BUGBUG 64bit */
341 1.1.4.2 rmind sc->sc_dp->BufferAddressLo32 = phys; /* this pushes the fifo */
342 1.1.4.2 rmind
343 1.1.4.2 rmind /* Adjust pointers and continue
344 1.1.4.2 rmind */
345 1.1.4.2 rmind sc->sc_data += count;
346 1.1.4.2 rmind sc->sc_count -= count;
347 1.1.4.2 rmind
348 1.1.4.2 rmind if (sc->sc_count <= 0)
349 1.1.4.2 rmind break;
350 1.1.4.2 rmind }
351 1.1.4.2 rmind }
352 1.1.4.2 rmind
353 1.1.4.2 rmind /*
354 1.1.4.2 rmind * Interrupt handler
355 1.1.4.2 rmind */
356 1.1.4.2 rmind static int
357 1.1.4.2 rmind icap_ebus_intr(void *cookie, void *f)
358 1.1.4.2 rmind {
359 1.1.4.2 rmind struct icap_softc *sc = cookie;
360 1.1.4.2 rmind struct buf *bp = sc->sc_bp;
361 1.1.4.2 rmind u_int32_t isr, saf = 0, hi, lo;
362 1.1.4.2 rmind
363 1.1.4.2 rmind isr = sc->sc_dp->Control;
364 1.1.4.2 rmind
365 1.1.4.2 rmind DEBUG_PRINT(("i %x\n",isr), DEBUG_INTR);
366 1.1.4.2 rmind
367 1.1.4.2 rmind /* Make sure there is an interrupt and that we should take it
368 1.1.4.2 rmind */
369 1.1.4.2 rmind if ((isr & (ICAPC_INTEN|ICAPC_DONE)) != (ICAPC_INTEN|ICAPC_DONE))
370 1.1.4.2 rmind return (0);
371 1.1.4.2 rmind
372 1.1.4.2 rmind /* Pull out all completed buffers
373 1.1.4.2 rmind */
374 1.1.4.2 rmind while ((isr & ICAPC_OF_EMPTY) == 0) {
375 1.1.4.2 rmind
376 1.1.4.2 rmind if (isr & ICAPC_ERROR) {
377 1.1.4.2 rmind printf("%s: internal error (%x)\n", device_xname(sc->sc_dev),isr);
378 1.1.4.2 rmind icap_reset(sc);
379 1.1.4.2 rmind if (bp) {
380 1.1.4.2 rmind bp->b_error = EIO;
381 1.1.4.2 rmind icapstart(sc);
382 1.1.4.2 rmind }
383 1.1.4.2 rmind return (1);
384 1.1.4.2 rmind }
385 1.1.4.2 rmind
386 1.1.4.2 rmind /* Beware, order matters */
387 1.1.4.2 rmind saf = sc->sc_dp->SizeAndFlags;
388 1.1.4.2 rmind hi = sc->sc_dp->BufferAddressHi32; /* BUGBUG 64bit */
389 1.1.4.2 rmind lo = sc->sc_dp->BufferAddressLo32; /* this pops the fifo */
390 1.1.4.2 rmind
391 1.1.4.2 rmind /* Say its done that much (and sanity)
392 1.1.4.2 rmind */
393 1.1.4.2 rmind if (bp) {
394 1.1.4.2 rmind size_t count = saf & ICAPS_S_MASK;
395 1.1.4.2 rmind /* more sanity */
396 1.1.4.2 rmind if (count > bp->b_resid)
397 1.1.4.2 rmind count = bp->b_resid;
398 1.1.4.2 rmind bp->b_resid -= count;
399 1.1.4.2 rmind }
400 1.1.4.2 rmind
401 1.1.4.2 rmind /* More? */
402 1.1.4.2 rmind isr = sc->sc_dp->Control;
403 1.1.4.2 rmind }
404 1.1.4.2 rmind
405 1.1.4.2 rmind /* Did we pop at least one */
406 1.1.4.2 rmind if (saf)
407 1.1.4.2 rmind icapstart(sc);
408 1.1.4.2 rmind
409 1.1.4.2 rmind return (1);
410 1.1.4.2 rmind }
411 1.1.4.2 rmind
412 1.1.4.2 rmind /*
413 1.1.4.2 rmind * HW (re)Initialization
414 1.1.4.2 rmind */
415 1.1.4.2 rmind static void
416 1.1.4.2 rmind icap_reset(struct icap_softc *sc)
417 1.1.4.2 rmind {
418 1.1.4.2 rmind DEBUG_PRINT(("icap_reset %x\n",sc->sc_dp->Control), DEBUG_STATUS);
419 1.1.4.2 rmind sc->sc_dp->Control = ICAPC_RESET;
420 1.1.4.2 rmind DELAY(2);
421 1.1.4.2 rmind sc->sc_dp->Control = ICAPC_INTEN;
422 1.1.4.2 rmind }
423