esp_pcmcia.c revision 1.8.4.3 1 1.8.4.3 bouyer /* $NetBSD: esp_pcmcia.c,v 1.8.4.3 2001/01/22 17:58:55 bouyer Exp $ */
2 1.8.4.2 bouyer
3 1.8.4.2 bouyer /*-
4 1.8.4.2 bouyer * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 1.8.4.2 bouyer * All rights reserved.
6 1.8.4.2 bouyer *
7 1.8.4.2 bouyer * This code is derived from software contributed to The NetBSD Foundation
8 1.8.4.2 bouyer * by Charles M. Hannum.
9 1.8.4.2 bouyer *
10 1.8.4.2 bouyer * Redistribution and use in source and binary forms, with or without
11 1.8.4.2 bouyer * modification, are permitted provided that the following conditions
12 1.8.4.2 bouyer * are met:
13 1.8.4.2 bouyer * 1. Redistributions of source code must retain the above copyright
14 1.8.4.2 bouyer * notice, this list of conditions and the following disclaimer.
15 1.8.4.2 bouyer * 2. Redistributions in binary form must reproduce the above copyright
16 1.8.4.2 bouyer * notice, this list of conditions and the following disclaimer in the
17 1.8.4.2 bouyer * documentation and/or other materials provided with the distribution.
18 1.8.4.2 bouyer * 3. All advertising materials mentioning features or use of this software
19 1.8.4.2 bouyer * must display the following acknowledgement:
20 1.8.4.2 bouyer * This product includes software developed by the NetBSD
21 1.8.4.2 bouyer * Foundation, Inc. and its contributors.
22 1.8.4.2 bouyer * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.8.4.2 bouyer * contributors may be used to endorse or promote products derived
24 1.8.4.2 bouyer * from this software without specific prior written permission.
25 1.8.4.2 bouyer *
26 1.8.4.2 bouyer * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.8.4.2 bouyer * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.8.4.2 bouyer * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.8.4.2 bouyer * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.8.4.2 bouyer * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.8.4.2 bouyer * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.8.4.2 bouyer * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.8.4.2 bouyer * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.8.4.2 bouyer * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.8.4.2 bouyer * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.8.4.2 bouyer * POSSIBILITY OF SUCH DAMAGE.
37 1.8.4.2 bouyer */
38 1.8.4.2 bouyer
39 1.8.4.2 bouyer #include <sys/param.h>
40 1.8.4.2 bouyer #include <sys/systm.h>
41 1.8.4.2 bouyer #include <sys/device.h>
42 1.8.4.2 bouyer #include <sys/buf.h>
43 1.8.4.2 bouyer
44 1.8.4.2 bouyer #include <machine/bus.h>
45 1.8.4.2 bouyer #include <machine/intr.h>
46 1.8.4.2 bouyer
47 1.8.4.2 bouyer #include <dev/scsipi/scsi_all.h>
48 1.8.4.2 bouyer #include <dev/scsipi/scsipi_all.h>
49 1.8.4.2 bouyer #include <dev/scsipi/scsiconf.h>
50 1.8.4.2 bouyer
51 1.8.4.2 bouyer #include <dev/pcmcia/pcmciareg.h>
52 1.8.4.2 bouyer #include <dev/pcmcia/pcmciavar.h>
53 1.8.4.2 bouyer #include <dev/pcmcia/pcmciadevs.h>
54 1.8.4.2 bouyer
55 1.8.4.2 bouyer #include <dev/ic/ncr53c9xreg.h>
56 1.8.4.2 bouyer #include <dev/ic/ncr53c9xvar.h>
57 1.8.4.2 bouyer
58 1.8.4.2 bouyer struct esp_pcmcia_softc {
59 1.8.4.2 bouyer struct ncr53c9x_softc sc_ncr53c9x; /* glue to MI code */
60 1.8.4.2 bouyer
61 1.8.4.2 bouyer int sc_active; /* Pseudo-DMA state vars */
62 1.8.4.2 bouyer int sc_tc;
63 1.8.4.2 bouyer int sc_datain;
64 1.8.4.2 bouyer size_t sc_dmasize;
65 1.8.4.2 bouyer size_t sc_dmatrans;
66 1.8.4.2 bouyer char **sc_dmaaddr;
67 1.8.4.2 bouyer size_t *sc_pdmalen;
68 1.8.4.2 bouyer
69 1.8.4.2 bouyer /* PCMCIA-specific goo. */
70 1.8.4.2 bouyer struct pcmcia_io_handle sc_pcioh; /* PCMCIA i/o space info */
71 1.8.4.2 bouyer int sc_io_window; /* our i/o window */
72 1.8.4.2 bouyer struct pcmcia_function *sc_pf; /* our PCMCIA function */
73 1.8.4.2 bouyer void *sc_ih; /* interrupt handler */
74 1.8.4.2 bouyer #ifdef ESP_PCMCIA_POLL
75 1.8.4.2 bouyer struct callout sc_poll_ch;
76 1.8.4.2 bouyer #endif
77 1.8.4.2 bouyer int sc_flags;
78 1.8.4.2 bouyer #define ESP_PCMCIA_ATTACHED 1 /* attach completed */
79 1.8.4.2 bouyer #define ESP_PCMCIA_ATTACHING 2 /* attach in progress */
80 1.8.4.2 bouyer };
81 1.8.4.2 bouyer
82 1.8.4.2 bouyer int esp_pcmcia_match __P((struct device *, struct cfdata *, void *));
83 1.8.4.2 bouyer void esp_pcmcia_attach __P((struct device *, struct device *, void *));
84 1.8.4.2 bouyer void esp_pcmcia_init __P((struct esp_pcmcia_softc *));
85 1.8.4.2 bouyer int esp_pcmcia_detach __P((struct device *, int));
86 1.8.4.2 bouyer int esp_pcmcia_enable __P((void *, int));
87 1.8.4.2 bouyer
88 1.8.4.2 bouyer struct cfattach esp_pcmcia_ca = {
89 1.8.4.2 bouyer sizeof(struct esp_pcmcia_softc), esp_pcmcia_match, esp_pcmcia_attach,
90 1.8.4.2 bouyer esp_pcmcia_detach
91 1.8.4.2 bouyer };
92 1.8.4.2 bouyer
93 1.8.4.2 bouyer /*
94 1.8.4.2 bouyer * Functions and the switch for the MI code.
95 1.8.4.2 bouyer */
96 1.8.4.2 bouyer #ifdef ESP_PCMCIA_POLL
97 1.8.4.2 bouyer void esp_pcmcia_poll __P((void *));
98 1.8.4.2 bouyer #endif
99 1.8.4.2 bouyer u_char esp_pcmcia_read_reg __P((struct ncr53c9x_softc *, int));
100 1.8.4.2 bouyer void esp_pcmcia_write_reg __P((struct ncr53c9x_softc *, int, u_char));
101 1.8.4.2 bouyer int esp_pcmcia_dma_isintr __P((struct ncr53c9x_softc *));
102 1.8.4.2 bouyer void esp_pcmcia_dma_reset __P((struct ncr53c9x_softc *));
103 1.8.4.2 bouyer int esp_pcmcia_dma_intr __P((struct ncr53c9x_softc *));
104 1.8.4.2 bouyer int esp_pcmcia_dma_setup __P((struct ncr53c9x_softc *, caddr_t *,
105 1.8.4.2 bouyer size_t *, int, size_t *));
106 1.8.4.2 bouyer void esp_pcmcia_dma_go __P((struct ncr53c9x_softc *));
107 1.8.4.2 bouyer void esp_pcmcia_dma_stop __P((struct ncr53c9x_softc *));
108 1.8.4.2 bouyer int esp_pcmcia_dma_isactive __P((struct ncr53c9x_softc *));
109 1.8.4.2 bouyer
110 1.8.4.2 bouyer struct ncr53c9x_glue esp_pcmcia_glue = {
111 1.8.4.2 bouyer esp_pcmcia_read_reg,
112 1.8.4.2 bouyer esp_pcmcia_write_reg,
113 1.8.4.2 bouyer esp_pcmcia_dma_isintr,
114 1.8.4.2 bouyer esp_pcmcia_dma_reset,
115 1.8.4.2 bouyer esp_pcmcia_dma_intr,
116 1.8.4.2 bouyer esp_pcmcia_dma_setup,
117 1.8.4.2 bouyer esp_pcmcia_dma_go,
118 1.8.4.2 bouyer esp_pcmcia_dma_stop,
119 1.8.4.2 bouyer esp_pcmcia_dma_isactive,
120 1.8.4.2 bouyer NULL, /* gl_clear_latched_intr */
121 1.8.4.2 bouyer };
122 1.8.4.2 bouyer
123 1.8.4.2 bouyer const struct pcmcia_product esp_pcmcia_products[] = {
124 1.8.4.2 bouyer { PCMCIA_STR_PANASONIC_KXLC002, PCMCIA_VENDOR_PANASONIC,
125 1.8.4.2 bouyer PCMCIA_PRODUCT_PANASONIC_KXLC002, 0 },
126 1.8.4.2 bouyer
127 1.8.4.2 bouyer { NULL }
128 1.8.4.2 bouyer };
129 1.8.4.2 bouyer
130 1.8.4.2 bouyer int
131 1.8.4.2 bouyer esp_pcmcia_match(parent, match, aux)
132 1.8.4.2 bouyer struct device *parent;
133 1.8.4.2 bouyer struct cfdata *match;
134 1.8.4.2 bouyer void *aux;
135 1.8.4.2 bouyer {
136 1.8.4.2 bouyer struct pcmcia_attach_args *pa = aux;
137 1.8.4.2 bouyer
138 1.8.4.2 bouyer if (pcmcia_product_lookup(pa, esp_pcmcia_products,
139 1.8.4.2 bouyer sizeof esp_pcmcia_products[0], NULL) != NULL)
140 1.8.4.2 bouyer return (1);
141 1.8.4.2 bouyer return (0);
142 1.8.4.2 bouyer }
143 1.8.4.2 bouyer
144 1.8.4.2 bouyer void
145 1.8.4.2 bouyer esp_pcmcia_attach(parent, self, aux)
146 1.8.4.2 bouyer struct device *parent, *self;
147 1.8.4.2 bouyer void *aux;
148 1.8.4.2 bouyer {
149 1.8.4.2 bouyer struct esp_pcmcia_softc *esc = (void *)self;
150 1.8.4.2 bouyer struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
151 1.8.4.2 bouyer struct pcmcia_attach_args *pa = aux;
152 1.8.4.2 bouyer struct pcmcia_config_entry *cfe;
153 1.8.4.2 bouyer struct pcmcia_function *pf = pa->pf;
154 1.8.4.2 bouyer const struct pcmcia_product *pp;
155 1.8.4.2 bouyer
156 1.8.4.2 bouyer esc->sc_pf = pf;
157 1.8.4.2 bouyer
158 1.8.4.2 bouyer for (cfe = SIMPLEQ_FIRST(&pf->cfe_head); cfe != NULL;
159 1.8.4.2 bouyer cfe = SIMPLEQ_NEXT(cfe, cfe_list)) {
160 1.8.4.2 bouyer if (cfe->num_memspace != 0 ||
161 1.8.4.2 bouyer cfe->num_iospace != 1)
162 1.8.4.2 bouyer continue;
163 1.8.4.2 bouyer
164 1.8.4.2 bouyer if (pcmcia_io_alloc(pa->pf, cfe->iospace[0].start,
165 1.8.4.2 bouyer cfe->iospace[0].length, 0, &esc->sc_pcioh) == 0)
166 1.8.4.2 bouyer break;
167 1.8.4.2 bouyer }
168 1.8.4.2 bouyer
169 1.8.4.2 bouyer if (cfe == 0) {
170 1.8.4.2 bouyer printf(": can't alloc i/o space\n");
171 1.8.4.2 bouyer goto no_config_entry;
172 1.8.4.2 bouyer }
173 1.8.4.2 bouyer
174 1.8.4.2 bouyer /* Enable the card. */
175 1.8.4.2 bouyer pcmcia_function_init(pf, cfe);
176 1.8.4.2 bouyer if (pcmcia_function_enable(pf)) {
177 1.8.4.2 bouyer printf(": function enable failed\n");
178 1.8.4.2 bouyer goto enable_failed;
179 1.8.4.2 bouyer }
180 1.8.4.2 bouyer
181 1.8.4.2 bouyer /* Map in the I/O space */
182 1.8.4.2 bouyer if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_AUTO, 0, esc->sc_pcioh.size,
183 1.8.4.2 bouyer &esc->sc_pcioh, &esc->sc_io_window)) {
184 1.8.4.2 bouyer printf(": can't map i/o space\n");
185 1.8.4.2 bouyer goto iomap_failed;
186 1.8.4.2 bouyer }
187 1.8.4.2 bouyer
188 1.8.4.2 bouyer pp = pcmcia_product_lookup(pa, esp_pcmcia_products,
189 1.8.4.2 bouyer sizeof esp_pcmcia_products[0], NULL);
190 1.8.4.2 bouyer if (pp == NULL) {
191 1.8.4.2 bouyer printf("\n");
192 1.8.4.2 bouyer panic("esp_pcmcia_attach: impossible");
193 1.8.4.2 bouyer }
194 1.8.4.2 bouyer
195 1.8.4.2 bouyer printf(": %s\n", pp->pp_name);
196 1.8.4.2 bouyer
197 1.8.4.2 bouyer esp_pcmcia_init(esc);
198 1.8.4.2 bouyer
199 1.8.4.2 bouyer /*
200 1.8.4.2 bouyer * Initialize nca board itself.
201 1.8.4.2 bouyer */
202 1.8.4.2 bouyer esc->sc_flags |= ESP_PCMCIA_ATTACHING;
203 1.8.4.3 bouyer sc->sc_adapter.adapt_minphys = minphys;
204 1.8.4.3 bouyer sc->sc_adapter.adapt_request = ncr53c9x_scsipi_request;
205 1.8.4.2 bouyer ncr53c9x_attach(sc);
206 1.8.4.2 bouyer esc->sc_flags &= ~ESP_PCMCIA_ATTACHING;
207 1.8.4.2 bouyer esc->sc_flags |= ESP_PCMCIA_ATTACHED;
208 1.8.4.2 bouyer return;
209 1.8.4.2 bouyer
210 1.8.4.2 bouyer iomap_failed:
211 1.8.4.2 bouyer /* Disable the device. */
212 1.8.4.2 bouyer pcmcia_function_disable(esc->sc_pf);
213 1.8.4.2 bouyer
214 1.8.4.2 bouyer enable_failed:
215 1.8.4.2 bouyer /* Unmap our I/O space. */
216 1.8.4.2 bouyer pcmcia_io_free(esc->sc_pf, &esc->sc_pcioh);
217 1.8.4.2 bouyer
218 1.8.4.2 bouyer no_config_entry:
219 1.8.4.2 bouyer return;
220 1.8.4.2 bouyer }
221 1.8.4.2 bouyer
222 1.8.4.2 bouyer void
223 1.8.4.2 bouyer esp_pcmcia_init(esc)
224 1.8.4.2 bouyer struct esp_pcmcia_softc *esc;
225 1.8.4.2 bouyer {
226 1.8.4.2 bouyer struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
227 1.8.4.2 bouyer bus_space_tag_t iot = esc->sc_pcioh.iot;
228 1.8.4.2 bouyer bus_space_handle_t ioh = esc->sc_pcioh.ioh;
229 1.8.4.2 bouyer
230 1.8.4.2 bouyer /* id 7, clock 40M, parity ON, sync OFF, fast ON, slow ON */
231 1.8.4.2 bouyer
232 1.8.4.2 bouyer sc->sc_glue = &esp_pcmcia_glue;
233 1.8.4.2 bouyer
234 1.8.4.2 bouyer #ifdef ESP_PCMCIA_POLL
235 1.8.4.2 bouyer callout_init(&esc->sc_poll_ch);
236 1.8.4.2 bouyer #endif
237 1.8.4.2 bouyer
238 1.8.4.2 bouyer sc->sc_rev = NCR_VARIANT_ESP406;
239 1.8.4.2 bouyer sc->sc_id = 7;
240 1.8.4.2 bouyer sc->sc_freq = 40;
241 1.8.4.2 bouyer /* try -PARENB -SLOW */
242 1.8.4.2 bouyer sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB | NCRCFG1_SLOW;
243 1.8.4.2 bouyer /* try +FE */
244 1.8.4.2 bouyer sc->sc_cfg2 = NCRCFG2_SCSI2;
245 1.8.4.2 bouyer /* try -IDM -FSCSI -FCLK */
246 1.8.4.2 bouyer sc->sc_cfg3 = NCRESPCFG3_CDB | NCRESPCFG3_FCLK | NCRESPCFG3_IDM |
247 1.8.4.2 bouyer NCRESPCFG3_FSCSI;
248 1.8.4.2 bouyer sc->sc_cfg4 = NCRCFG4_ACTNEG;
249 1.8.4.2 bouyer /* try +INTP */
250 1.8.4.2 bouyer sc->sc_cfg5 = NCRCFG5_CRS1 | NCRCFG5_AADDR | NCRCFG5_PTRINC;
251 1.8.4.2 bouyer sc->sc_minsync = 0;
252 1.8.4.2 bouyer sc->sc_maxxfer = 64 * 1024;
253 1.8.4.2 bouyer
254 1.8.4.2 bouyer bus_space_write_1(iot, ioh, NCR_CFG5, sc->sc_cfg5);
255 1.8.4.2 bouyer
256 1.8.4.2 bouyer bus_space_write_1(iot, ioh, NCR_PIOI, 0);
257 1.8.4.2 bouyer bus_space_write_1(iot, ioh, NCR_PSTAT, 0);
258 1.8.4.2 bouyer bus_space_write_1(iot, ioh, 0x09, 0x24);
259 1.8.4.2 bouyer
260 1.8.4.2 bouyer bus_space_write_1(iot, ioh, NCR_CFG4, sc->sc_cfg4);
261 1.8.4.2 bouyer }
262 1.8.4.2 bouyer
263 1.8.4.2 bouyer int
264 1.8.4.2 bouyer esp_pcmcia_detach(self, flags)
265 1.8.4.2 bouyer struct device *self;
266 1.8.4.2 bouyer int flags;
267 1.8.4.2 bouyer {
268 1.8.4.2 bouyer struct esp_pcmcia_softc *esc = (void *)self;
269 1.8.4.2 bouyer int error;
270 1.8.4.2 bouyer
271 1.8.4.2 bouyer if ((esc->sc_flags & ESP_PCMCIA_ATTACHED) == 0) {
272 1.8.4.2 bouyer /* Nothing to detach. */
273 1.8.4.2 bouyer return (0);
274 1.8.4.2 bouyer }
275 1.8.4.2 bouyer
276 1.8.4.2 bouyer error = ncr53c9x_detach(&esc->sc_ncr53c9x, flags);
277 1.8.4.2 bouyer if (error)
278 1.8.4.2 bouyer return (error);
279 1.8.4.2 bouyer
280 1.8.4.2 bouyer /* Unmap our i/o window and i/o space. */
281 1.8.4.2 bouyer pcmcia_io_unmap(esc->sc_pf, esc->sc_io_window);
282 1.8.4.2 bouyer pcmcia_io_free(esc->sc_pf, &esc->sc_pcioh);
283 1.8.4.2 bouyer
284 1.8.4.2 bouyer return (0);
285 1.8.4.2 bouyer }
286 1.8.4.2 bouyer
287 1.8.4.2 bouyer int
288 1.8.4.2 bouyer esp_pcmcia_enable(arg, onoff)
289 1.8.4.2 bouyer void *arg;
290 1.8.4.2 bouyer int onoff;
291 1.8.4.2 bouyer {
292 1.8.4.2 bouyer struct esp_pcmcia_softc *esc = arg;
293 1.8.4.2 bouyer
294 1.8.4.2 bouyer if (onoff) {
295 1.8.4.2 bouyer #ifdef ESP_PCMCIA_POLL
296 1.8.4.2 bouyer callout_reset(&esc->sc_poll_ch, 1, esp_pcmcia_poll, esc);
297 1.8.4.2 bouyer #else
298 1.8.4.2 bouyer /* Establish the interrupt handler. */
299 1.8.4.2 bouyer esc->sc_ih = pcmcia_intr_establish(esc->sc_pf, IPL_BIO,
300 1.8.4.2 bouyer ncr53c9x_intr, &esc->sc_ncr53c9x);
301 1.8.4.2 bouyer if (esc->sc_ih == NULL) {
302 1.8.4.2 bouyer printf("%s: couldn't establish interrupt handler\n",
303 1.8.4.2 bouyer esc->sc_ncr53c9x.sc_dev.dv_xname);
304 1.8.4.2 bouyer return (EIO);
305 1.8.4.2 bouyer }
306 1.8.4.2 bouyer #endif
307 1.8.4.2 bouyer
308 1.8.4.2 bouyer /*
309 1.8.4.2 bouyer * If attach is in progress, we know that card power is
310 1.8.4.2 bouyer * enabled and chip will be initialized later.
311 1.8.4.2 bouyer * Otherwise, enable and reset now.
312 1.8.4.2 bouyer */
313 1.8.4.2 bouyer if ((esc->sc_flags & ESP_PCMCIA_ATTACHING) == 0) {
314 1.8.4.2 bouyer if (pcmcia_function_enable(esc->sc_pf)) {
315 1.8.4.2 bouyer printf("%s: couldn't enable PCMCIA function\n",
316 1.8.4.2 bouyer esc->sc_ncr53c9x.sc_dev.dv_xname);
317 1.8.4.2 bouyer pcmcia_intr_disestablish(esc->sc_pf,
318 1.8.4.2 bouyer esc->sc_ih);
319 1.8.4.2 bouyer return (EIO);
320 1.8.4.2 bouyer }
321 1.8.4.2 bouyer
322 1.8.4.2 bouyer /* Initialize only chip. */
323 1.8.4.2 bouyer ncr53c9x_init(&esc->sc_ncr53c9x, 0);
324 1.8.4.2 bouyer }
325 1.8.4.2 bouyer } else {
326 1.8.4.2 bouyer pcmcia_function_disable(esc->sc_pf);
327 1.8.4.2 bouyer #ifdef ESP_PCMCIA_POLL
328 1.8.4.2 bouyer callout_stop(&esc->sc_poll_ch);
329 1.8.4.2 bouyer #else
330 1.8.4.2 bouyer pcmcia_intr_disestablish(esc->sc_pf, esc->sc_ih);
331 1.8.4.2 bouyer #endif
332 1.8.4.2 bouyer }
333 1.8.4.2 bouyer
334 1.8.4.2 bouyer return (0);
335 1.8.4.2 bouyer }
336 1.8.4.2 bouyer
337 1.8.4.2 bouyer #ifdef ESP_PCMCIA_POLL
338 1.8.4.2 bouyer void
339 1.8.4.2 bouyer esp_pcmcia_poll(arg)
340 1.8.4.2 bouyer void *arg;
341 1.8.4.2 bouyer {
342 1.8.4.2 bouyer struct esp_pcmcia_softc *esc = arg;
343 1.8.4.2 bouyer
344 1.8.4.2 bouyer (void) ncr53c9x_intr(&esc->sc_ncr53c9x);
345 1.8.4.2 bouyer callout_reset(&esc->sc_poll_ch, 1, esp_pcmcia_poll, esc);
346 1.8.4.2 bouyer }
347 1.8.4.2 bouyer #endif
348 1.8.4.2 bouyer
349 1.8.4.2 bouyer /*
350 1.8.4.2 bouyer * Glue functions.
351 1.8.4.2 bouyer */
352 1.8.4.2 bouyer u_char
353 1.8.4.2 bouyer esp_pcmcia_read_reg(sc, reg)
354 1.8.4.2 bouyer struct ncr53c9x_softc *sc;
355 1.8.4.2 bouyer int reg;
356 1.8.4.2 bouyer {
357 1.8.4.2 bouyer struct esp_pcmcia_softc *esc = (struct esp_pcmcia_softc *)sc;
358 1.8.4.2 bouyer u_char v;
359 1.8.4.2 bouyer
360 1.8.4.2 bouyer v = bus_space_read_1(esc->sc_pcioh.iot, esc->sc_pcioh.ioh, reg);
361 1.8.4.2 bouyer return v;
362 1.8.4.2 bouyer }
363 1.8.4.2 bouyer
364 1.8.4.2 bouyer void
365 1.8.4.2 bouyer esp_pcmcia_write_reg(sc, reg, val)
366 1.8.4.2 bouyer struct ncr53c9x_softc *sc;
367 1.8.4.2 bouyer int reg;
368 1.8.4.2 bouyer u_char val;
369 1.8.4.2 bouyer {
370 1.8.4.2 bouyer struct esp_pcmcia_softc *esc = (struct esp_pcmcia_softc *)sc;
371 1.8.4.2 bouyer u_char v = val;
372 1.8.4.2 bouyer
373 1.8.4.2 bouyer if (reg == NCR_CMD && v == (NCRCMD_TRANS|NCRCMD_DMA))
374 1.8.4.2 bouyer v = NCRCMD_TRANS;
375 1.8.4.2 bouyer bus_space_write_1(esc->sc_pcioh.iot, esc->sc_pcioh.ioh, reg, v);
376 1.8.4.2 bouyer }
377 1.8.4.2 bouyer
378 1.8.4.2 bouyer int
379 1.8.4.2 bouyer esp_pcmcia_dma_isintr(sc)
380 1.8.4.2 bouyer struct ncr53c9x_softc *sc;
381 1.8.4.2 bouyer {
382 1.8.4.2 bouyer
383 1.8.4.2 bouyer return NCR_READ_REG(sc, NCR_STAT) & NCRSTAT_INT;
384 1.8.4.2 bouyer }
385 1.8.4.2 bouyer
386 1.8.4.2 bouyer void
387 1.8.4.2 bouyer esp_pcmcia_dma_reset(sc)
388 1.8.4.2 bouyer struct ncr53c9x_softc *sc;
389 1.8.4.2 bouyer {
390 1.8.4.2 bouyer struct esp_pcmcia_softc *esc = (struct esp_pcmcia_softc *)sc;
391 1.8.4.2 bouyer
392 1.8.4.2 bouyer esc->sc_active = 0;
393 1.8.4.2 bouyer esc->sc_tc = 0;
394 1.8.4.2 bouyer }
395 1.8.4.2 bouyer
396 1.8.4.2 bouyer int
397 1.8.4.2 bouyer esp_pcmcia_dma_intr(sc)
398 1.8.4.2 bouyer struct ncr53c9x_softc *sc;
399 1.8.4.2 bouyer {
400 1.8.4.2 bouyer struct esp_pcmcia_softc *esc = (struct esp_pcmcia_softc *)sc;
401 1.8.4.2 bouyer u_char *p;
402 1.8.4.2 bouyer u_int espphase, espstat, espintr;
403 1.8.4.2 bouyer int cnt;
404 1.8.4.2 bouyer
405 1.8.4.2 bouyer if (esc->sc_active == 0) {
406 1.8.4.2 bouyer printf("%s: dma_intr--inactive DMA\n", sc->sc_dev.dv_xname);
407 1.8.4.2 bouyer return -1;
408 1.8.4.2 bouyer }
409 1.8.4.2 bouyer
410 1.8.4.2 bouyer if ((sc->sc_espintr & NCRINTR_BS) == 0) {
411 1.8.4.2 bouyer esc->sc_active = 0;
412 1.8.4.2 bouyer return 0;
413 1.8.4.2 bouyer }
414 1.8.4.2 bouyer
415 1.8.4.2 bouyer cnt = *esc->sc_pdmalen;
416 1.8.4.2 bouyer if (*esc->sc_pdmalen == 0) {
417 1.8.4.2 bouyer printf("%s: data interrupt, but no count left\n",
418 1.8.4.2 bouyer sc->sc_dev.dv_xname);
419 1.8.4.2 bouyer }
420 1.8.4.2 bouyer
421 1.8.4.2 bouyer p = *esc->sc_dmaaddr;
422 1.8.4.2 bouyer espphase = sc->sc_phase;
423 1.8.4.2 bouyer espstat = (u_int) sc->sc_espstat;
424 1.8.4.2 bouyer espintr = (u_int) sc->sc_espintr;
425 1.8.4.2 bouyer do {
426 1.8.4.2 bouyer if (esc->sc_datain) {
427 1.8.4.2 bouyer *p++ = NCR_READ_REG(sc, NCR_FIFO);
428 1.8.4.2 bouyer cnt--;
429 1.8.4.2 bouyer if (espphase == DATA_IN_PHASE)
430 1.8.4.2 bouyer NCR_WRITE_REG(sc, NCR_CMD, NCRCMD_TRANS);
431 1.8.4.2 bouyer else
432 1.8.4.2 bouyer esc->sc_active = 0;
433 1.8.4.2 bouyer } else {
434 1.8.4.2 bouyer if (espphase == DATA_OUT_PHASE ||
435 1.8.4.2 bouyer espphase == MESSAGE_OUT_PHASE) {
436 1.8.4.2 bouyer NCR_WRITE_REG(sc, NCR_FIFO, *p++);
437 1.8.4.2 bouyer cnt--;
438 1.8.4.2 bouyer NCR_WRITE_REG(sc, NCR_CMD, NCRCMD_TRANS);
439 1.8.4.2 bouyer } else
440 1.8.4.2 bouyer esc->sc_active = 0;
441 1.8.4.2 bouyer }
442 1.8.4.2 bouyer
443 1.8.4.2 bouyer if (esc->sc_active) {
444 1.8.4.2 bouyer while (!(NCR_READ_REG(sc, NCR_STAT) & NCRSTAT_INT));
445 1.8.4.2 bouyer espstat = NCR_READ_REG(sc, NCR_STAT);
446 1.8.4.2 bouyer espintr = NCR_READ_REG(sc, NCR_INTR);
447 1.8.4.2 bouyer espphase = (espintr & NCRINTR_DIS)
448 1.8.4.2 bouyer ? /* Disconnected */ BUSFREE_PHASE
449 1.8.4.2 bouyer : espstat & PHASE_MASK;
450 1.8.4.2 bouyer }
451 1.8.4.2 bouyer } while (esc->sc_active && espintr);
452 1.8.4.2 bouyer sc->sc_phase = espphase;
453 1.8.4.2 bouyer sc->sc_espstat = (u_char) espstat;
454 1.8.4.2 bouyer sc->sc_espintr = (u_char) espintr;
455 1.8.4.2 bouyer *esc->sc_dmaaddr = p;
456 1.8.4.2 bouyer *esc->sc_pdmalen = cnt;
457 1.8.4.2 bouyer
458 1.8.4.2 bouyer if (*esc->sc_pdmalen == 0)
459 1.8.4.2 bouyer esc->sc_tc = NCRSTAT_TC;
460 1.8.4.2 bouyer sc->sc_espstat |= esc->sc_tc;
461 1.8.4.2 bouyer return 0;
462 1.8.4.2 bouyer }
463 1.8.4.2 bouyer
464 1.8.4.2 bouyer int
465 1.8.4.2 bouyer esp_pcmcia_dma_setup(sc, addr, len, datain, dmasize)
466 1.8.4.2 bouyer struct ncr53c9x_softc *sc;
467 1.8.4.2 bouyer caddr_t *addr;
468 1.8.4.2 bouyer size_t *len;
469 1.8.4.2 bouyer int datain;
470 1.8.4.2 bouyer size_t *dmasize;
471 1.8.4.2 bouyer {
472 1.8.4.2 bouyer struct esp_pcmcia_softc *esc = (struct esp_pcmcia_softc *)sc;
473 1.8.4.2 bouyer
474 1.8.4.2 bouyer esc->sc_dmaaddr = addr;
475 1.8.4.2 bouyer esc->sc_pdmalen = len;
476 1.8.4.2 bouyer esc->sc_datain = datain;
477 1.8.4.2 bouyer esc->sc_dmasize = *dmasize;
478 1.8.4.2 bouyer esc->sc_tc = 0;
479 1.8.4.2 bouyer
480 1.8.4.2 bouyer return 0;
481 1.8.4.2 bouyer }
482 1.8.4.2 bouyer
483 1.8.4.2 bouyer void
484 1.8.4.2 bouyer esp_pcmcia_dma_go(sc)
485 1.8.4.2 bouyer struct ncr53c9x_softc *sc;
486 1.8.4.2 bouyer {
487 1.8.4.2 bouyer struct esp_pcmcia_softc *esc = (struct esp_pcmcia_softc *)sc;
488 1.8.4.2 bouyer
489 1.8.4.2 bouyer esc->sc_active = 1;
490 1.8.4.2 bouyer }
491 1.8.4.2 bouyer
492 1.8.4.2 bouyer void
493 1.8.4.2 bouyer esp_pcmcia_dma_stop(sc)
494 1.8.4.2 bouyer struct ncr53c9x_softc *sc;
495 1.8.4.2 bouyer {
496 1.8.4.2 bouyer }
497 1.8.4.2 bouyer
498 1.8.4.2 bouyer int
499 1.8.4.2 bouyer esp_pcmcia_dma_isactive(sc)
500 1.8.4.2 bouyer struct ncr53c9x_softc *sc;
501 1.8.4.2 bouyer {
502 1.8.4.2 bouyer struct esp_pcmcia_softc *esc = (struct esp_pcmcia_softc *)sc;
503 1.8.4.2 bouyer
504 1.8.4.2 bouyer return (esc->sc_active);
505 1.8.4.2 bouyer }
506