This source file includes following definitions.
- esp_pcmcia_match
- esp_pcmcia_attach
- esp_pcmcia_init
- esp_pcmcia_detach
- esp_pcmcia_enable
- esp_pcmcia_poll
- esp_pcmcia_read_reg
- esp_pcmcia_write_reg
- esp_pcmcia_dma_isintr
- esp_pcmcia_dma_reset
- esp_pcmcia_dma_intr
- esp_pcmcia_dma_setup
- esp_pcmcia_dma_go
- esp_pcmcia_dma_stop
- esp_pcmcia_dma_isactive
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/device.h>
43 #include <sys/buf.h>
44
45 #include <machine/bus.h>
46 #include <machine/intr.h>
47
48 #include <scsi/scsi_all.h>
49 #include <scsi/scsiconf.h>
50
51 #include <dev/pcmcia/pcmciareg.h>
52 #include <dev/pcmcia/pcmciavar.h>
53 #include <dev/pcmcia/pcmciadevs.h>
54
55 #include <dev/ic/ncr53c9xreg.h>
56 #include <dev/ic/ncr53c9xvar.h>
57
58 struct esp_pcmcia_softc {
59 struct ncr53c9x_softc sc_ncr53c9x;
60
61 int sc_active;
62 int sc_tc;
63 int sc_datain;
64 size_t sc_dmasize;
65 size_t sc_dmatrans;
66 char **sc_dmaaddr;
67 size_t *sc_pdmalen;
68
69
70 struct pcmcia_io_handle sc_pcioh;
71 int sc_io_window;
72 struct pcmcia_function *sc_pf;
73 void *sc_ih;
74 #ifdef ESP_PCMCIA_POLL
75 struct callout sc_poll_ch;
76 #endif
77 int sc_flags;
78 #define ESP_PCMCIA_ATTACHED 1
79 #define ESP_PCMCIA_ATTACHING 2
80 };
81
82 int esp_pcmcia_match(struct device *, void *, void *);
83 void esp_pcmcia_attach(struct device *, struct device *, void *);
84 void esp_pcmcia_init(struct esp_pcmcia_softc *);
85 int esp_pcmcia_detach(struct device *, int);
86 int esp_pcmcia_enable(void *, int);
87
88 struct scsi_adapter esp_pcmcia_adapter = {
89 ncr53c9x_scsi_cmd,
90 minphys,
91 0,
92 0,
93 };
94
95 struct cfattach esp_pcmcia_ca = {
96 sizeof(struct esp_pcmcia_softc), esp_pcmcia_match, esp_pcmcia_attach
97 };
98
99
100
101
102 #ifdef ESP_PCMCIA_POLL
103 void esp_pcmcia_poll(void *);
104 #endif
105 u_char esp_pcmcia_read_reg(struct ncr53c9x_softc *, int);
106 void esp_pcmcia_write_reg(struct ncr53c9x_softc *, int, u_char);
107 int esp_pcmcia_dma_isintr(struct ncr53c9x_softc *);
108 void esp_pcmcia_dma_reset(struct ncr53c9x_softc *);
109 int esp_pcmcia_dma_intr(struct ncr53c9x_softc *);
110 int esp_pcmcia_dma_setup(struct ncr53c9x_softc *, caddr_t *,
111 size_t *, int, size_t *);
112 void esp_pcmcia_dma_go(struct ncr53c9x_softc *);
113 void esp_pcmcia_dma_stop(struct ncr53c9x_softc *);
114 int esp_pcmcia_dma_isactive(struct ncr53c9x_softc *);
115
116 struct ncr53c9x_glue esp_pcmcia_glue = {
117 esp_pcmcia_read_reg,
118 esp_pcmcia_write_reg,
119 esp_pcmcia_dma_isintr,
120 esp_pcmcia_dma_reset,
121 esp_pcmcia_dma_intr,
122 esp_pcmcia_dma_setup,
123 esp_pcmcia_dma_go,
124 esp_pcmcia_dma_stop,
125 esp_pcmcia_dma_isactive,
126 NULL,
127 };
128
129 struct esp_pcmcia_product {
130 u_int16_t app_vendor;
131 u_int16_t app_product;
132 int app_expfunc;
133 } esp_pcmcia_prod[] = {
134 { PCMCIA_VENDOR_PANASONIC, PCMCIA_PRODUCT_PANASONIC_KXLC002, 0 },
135 { PCMCIA_VENDOR_PANASONIC, PCMCIA_PRODUCT_PANASONIC_KME, 0 },
136 { PCMCIA_VENDOR_NEWMEDIA2, PCMCIA_PRODUCT_NEWMEDIA2_BUSTOASTER, 0 }
137 };
138
139 int
140 esp_pcmcia_match(parent, match, aux)
141 struct device *parent;
142 void *match, *aux;
143 {
144 struct pcmcia_attach_args *pa = aux;
145 int i;
146
147 for (i = 0; i < sizeof(esp_pcmcia_prod)/sizeof(esp_pcmcia_prod[0]); i++)
148 if (pa->manufacturer == esp_pcmcia_prod[i].app_vendor &&
149 pa->product == esp_pcmcia_prod[i].app_product &&
150 pa->pf->number == esp_pcmcia_prod[i].app_expfunc)
151 return (1);
152 return (0);
153 }
154
155 void
156 esp_pcmcia_attach(parent, self, aux)
157 struct device *parent, *self;
158 void *aux;
159 {
160 struct esp_pcmcia_softc *esc = (void *)self;
161 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
162 struct pcmcia_attach_args *pa = aux;
163 struct pcmcia_config_entry *cfe;
164 struct pcmcia_function *pf = pa->pf;
165 const char *intrstr;
166
167 esc->sc_pf = pf;
168
169 for (cfe = SIMPLEQ_FIRST(&pf->cfe_head); cfe != NULL;
170 cfe = SIMPLEQ_NEXT(cfe, cfe_list)) {
171 if (cfe->num_memspace != 0 ||
172 cfe->num_iospace != 1)
173 continue;
174
175 if (pcmcia_io_alloc(pa->pf, cfe->iospace[0].start,
176 cfe->iospace[0].length, 0, &esc->sc_pcioh) == 0)
177 break;
178 }
179
180 if (cfe == 0) {
181 printf(": can't alloc i/o space\n");
182 goto no_config_entry;
183 }
184
185
186 pcmcia_function_init(pf, cfe);
187 if (pcmcia_function_enable(pf)) {
188 printf(": function enable failed\n");
189 goto enable_failed;
190 }
191
192
193 if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_AUTO, 0, esc->sc_pcioh.size,
194 &esc->sc_pcioh, &esc->sc_io_window)) {
195 printf(": can't map i/o space\n");
196 goto iomap_failed;
197 }
198
199 printf(" port 0x%lx/%lu", esc->sc_pcioh.addr,
200 (u_long)esc->sc_pcioh.size);
201
202 esp_pcmcia_init(esc);
203
204 esc->sc_ih = pcmcia_intr_establish(esc->sc_pf, IPL_BIO,
205 ncr53c9x_intr, &esc->sc_ncr53c9x, sc->sc_dev.dv_xname);
206 intrstr = pcmcia_intr_string(esc->sc_pf, esc->sc_ih);
207 if (esc->sc_ih == NULL) {
208 printf(", %s\n", intrstr);
209 goto iomap_failed;
210 }
211 if (*intrstr)
212 printf(", %s", intrstr);
213
214
215
216
217 esc->sc_flags |= ESP_PCMCIA_ATTACHING;
218 ncr53c9x_attach(sc, &esp_pcmcia_adapter, NULL);
219 esc->sc_flags &= ~ESP_PCMCIA_ATTACHING;
220 esc->sc_flags |= ESP_PCMCIA_ATTACHED;
221 return;
222
223 iomap_failed:
224
225 pcmcia_function_disable(esc->sc_pf);
226
227 enable_failed:
228
229 pcmcia_io_free(esc->sc_pf, &esc->sc_pcioh);
230
231 no_config_entry:
232 return;
233 }
234
235 void
236 esp_pcmcia_init(esc)
237 struct esp_pcmcia_softc *esc;
238 {
239 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
240 bus_space_tag_t iot = esc->sc_pcioh.iot;
241 bus_space_handle_t ioh = esc->sc_pcioh.ioh;
242
243
244
245 sc->sc_glue = &esp_pcmcia_glue;
246
247 #ifdef ESP_PCMCIA_POLL
248 callout_init(&esc->sc_poll_ch);
249 #endif
250
251 sc->sc_rev = NCR_VARIANT_ESP406;
252 sc->sc_id = 7;
253 sc->sc_freq = 40;
254
255 sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB | NCRCFG1_SLOW;
256
257 sc->sc_cfg2 = NCRCFG2_SCSI2;
258
259 sc->sc_cfg3 = NCRESPCFG3_CDB | NCRESPCFG3_FCLK | NCRESPCFG3_IDM |
260 NCRESPCFG3_FSCSI;
261 sc->sc_cfg4 = NCRCFG4_ACTNEG;
262
263 sc->sc_cfg5 = NCRCFG5_CRS1 | NCRCFG5_AADDR | NCRCFG5_PTRINC;
264 sc->sc_minsync = 0;
265 sc->sc_maxxfer = 64 * 1024;
266
267 bus_space_write_1(iot, ioh, NCR_CFG5, sc->sc_cfg5);
268
269 bus_space_write_1(iot, ioh, NCR_PIOI, 0);
270 bus_space_write_1(iot, ioh, NCR_PSTAT, 0);
271 bus_space_write_1(iot, ioh, 0x09, 0x24);
272
273 bus_space_write_1(iot, ioh, NCR_CFG4, sc->sc_cfg4);
274 }
275
276 #ifdef notyet
277 int
278 esp_pcmcia_detach(self, flags)
279 struct device *self;
280 int flags;
281 {
282 struct esp_pcmcia_softc *esc = (void *)self;
283 int error;
284
285 if ((esc->sc_flags & ESP_PCMCIA_ATTACHED) == 0) {
286
287 return (0);
288 }
289
290 error = ncr53c9x_detach(&esc->sc_ncr53c9x, flags);
291 if (error)
292 return (error);
293
294
295 pcmcia_io_unmap(esc->sc_pf, esc->sc_io_window);
296 pcmcia_io_free(esc->sc_pf, &esc->sc_pcioh);
297
298 return (0);
299 }
300 #endif
301
302 int
303 esp_pcmcia_enable(arg, onoff)
304 void *arg;
305 int onoff;
306 {
307 struct esp_pcmcia_softc *esc = arg;
308
309 if (onoff) {
310 #ifdef ESP_PCMCIA_POLL
311 callout_reset(&esc->sc_poll_ch, 1, esp_pcmcia_poll, esc);
312 #else
313
314 esc->sc_ih = pcmcia_intr_establish(esc->sc_pf, IPL_BIO,
315 ncr53c9x_intr, &esc->sc_ncr53c9x,
316 esc->sc_ncr53c9x.sc_dev.dv_xname);
317 if (esc->sc_ih == NULL) {
318 printf("%s: couldn't establish interrupt handler\n",
319 esc->sc_ncr53c9x.sc_dev.dv_xname);
320 return (EIO);
321 }
322 #endif
323
324
325
326
327
328
329 if ((esc->sc_flags & ESP_PCMCIA_ATTACHING) == 0) {
330 if (pcmcia_function_enable(esc->sc_pf)) {
331 printf("%s: couldn't enable PCMCIA function\n",
332 esc->sc_ncr53c9x.sc_dev.dv_xname);
333 pcmcia_intr_disestablish(esc->sc_pf,
334 esc->sc_ih);
335 return (EIO);
336 }
337
338
339 ncr53c9x_init(&esc->sc_ncr53c9x, 0);
340 }
341 } else {
342 pcmcia_function_disable(esc->sc_pf);
343 #ifdef ESP_PCMCIA_POLL
344 callout_stop(&esc->sc_poll_ch);
345 #else
346 pcmcia_intr_disestablish(esc->sc_pf, esc->sc_ih);
347 #endif
348 }
349
350 return (0);
351 }
352
353 #ifdef ESP_PCMCIA_POLL
354 void
355 esp_pcmcia_poll(arg)
356 void *arg;
357 {
358 struct esp_pcmcia_softc *esc = arg;
359
360 (void) ncr53c9x_intr(&esc->sc_ncr53c9x);
361 callout_reset(&esc->sc_poll_ch, 1, esp_pcmcia_poll, esc);
362 }
363 #endif
364
365
366
367
368 u_char
369 esp_pcmcia_read_reg(sc, reg)
370 struct ncr53c9x_softc *sc;
371 int reg;
372 {
373 struct esp_pcmcia_softc *esc = (struct esp_pcmcia_softc *)sc;
374 u_char v;
375
376 v = bus_space_read_1(esc->sc_pcioh.iot, esc->sc_pcioh.ioh, reg);
377 return v;
378 }
379
380 void
381 esp_pcmcia_write_reg(sc, reg, val)
382 struct ncr53c9x_softc *sc;
383 int reg;
384 u_char val;
385 {
386 struct esp_pcmcia_softc *esc = (struct esp_pcmcia_softc *)sc;
387 u_char v = val;
388
389 if (reg == NCR_CMD && v == (NCRCMD_TRANS|NCRCMD_DMA))
390 v = NCRCMD_TRANS;
391 bus_space_write_1(esc->sc_pcioh.iot, esc->sc_pcioh.ioh, reg, v);
392 }
393
394 int
395 esp_pcmcia_dma_isintr(sc)
396 struct ncr53c9x_softc *sc;
397 {
398
399 return NCR_READ_REG(sc, NCR_STAT) & NCRSTAT_INT;
400 }
401
402 void
403 esp_pcmcia_dma_reset(sc)
404 struct ncr53c9x_softc *sc;
405 {
406 struct esp_pcmcia_softc *esc = (struct esp_pcmcia_softc *)sc;
407
408 esc->sc_active = 0;
409 esc->sc_tc = 0;
410 }
411
412 int
413 esp_pcmcia_dma_intr(sc)
414 struct ncr53c9x_softc *sc;
415 {
416 struct esp_pcmcia_softc *esc = (struct esp_pcmcia_softc *)sc;
417 u_char *p;
418 u_int espphase, espstat, espintr;
419 int cnt;
420
421 if (esc->sc_active == 0) {
422 printf("%s: dma_intr--inactive DMA\n", sc->sc_dev.dv_xname);
423 return -1;
424 }
425
426 if ((sc->sc_espintr & NCRINTR_BS) == 0) {
427 esc->sc_active = 0;
428 return 0;
429 }
430
431 cnt = *esc->sc_pdmalen;
432 if (*esc->sc_pdmalen == 0) {
433 printf("%s: data interrupt, but no count left\n",
434 sc->sc_dev.dv_xname);
435 }
436
437 p = *esc->sc_dmaaddr;
438 espphase = sc->sc_phase;
439 espstat = (u_int) sc->sc_espstat;
440 espintr = (u_int) sc->sc_espintr;
441 do {
442 if (esc->sc_datain) {
443 *p++ = NCR_READ_REG(sc, NCR_FIFO);
444 cnt--;
445 if (espphase == DATA_IN_PHASE)
446 NCR_WRITE_REG(sc, NCR_CMD, NCRCMD_TRANS);
447 else
448 esc->sc_active = 0;
449 } else {
450 if (espphase == DATA_OUT_PHASE ||
451 espphase == MESSAGE_OUT_PHASE) {
452 NCR_WRITE_REG(sc, NCR_FIFO, *p++);
453 cnt--;
454 NCR_WRITE_REG(sc, NCR_CMD, NCRCMD_TRANS);
455 } else
456 esc->sc_active = 0;
457 }
458
459 if (esc->sc_active) {
460 while (!(NCR_READ_REG(sc, NCR_STAT) & NCRSTAT_INT));
461 espstat = NCR_READ_REG(sc, NCR_STAT);
462 espintr = NCR_READ_REG(sc, NCR_INTR);
463 espphase = (espintr & NCRINTR_DIS)
464 ? BUSFREE_PHASE
465 : espstat & PHASE_MASK;
466 }
467 } while (esc->sc_active && espintr);
468 sc->sc_phase = espphase;
469 sc->sc_espstat = (u_char) espstat;
470 sc->sc_espintr = (u_char) espintr;
471 *esc->sc_dmaaddr = p;
472 *esc->sc_pdmalen = cnt;
473
474 if (*esc->sc_pdmalen == 0)
475 esc->sc_tc = NCRSTAT_TC;
476 sc->sc_espstat |= esc->sc_tc;
477 return 0;
478 }
479
480 int
481 esp_pcmcia_dma_setup(sc, addr, len, datain, dmasize)
482 struct ncr53c9x_softc *sc;
483 caddr_t *addr;
484 size_t *len;
485 int datain;
486 size_t *dmasize;
487 {
488 struct esp_pcmcia_softc *esc = (struct esp_pcmcia_softc *)sc;
489
490 esc->sc_dmaaddr = addr;
491 esc->sc_pdmalen = len;
492 esc->sc_datain = datain;
493 esc->sc_dmasize = *dmasize;
494 esc->sc_tc = 0;
495
496 return 0;
497 }
498
499 void
500 esp_pcmcia_dma_go(sc)
501 struct ncr53c9x_softc *sc;
502 {
503 struct esp_pcmcia_softc *esc = (struct esp_pcmcia_softc *)sc;
504
505 esc->sc_active = 1;
506 }
507
508 void
509 esp_pcmcia_dma_stop(sc)
510 struct ncr53c9x_softc *sc;
511 {
512 }
513
514 int
515 esp_pcmcia_dma_isactive(sc)
516 struct ncr53c9x_softc *sc;
517 {
518 struct esp_pcmcia_softc *esc = (struct esp_pcmcia_softc *)sc;
519
520 return (esc->sc_active);
521 }