FreeBSD/Linux Kernel Cross Reference
sys/dev/eisa/ahb.c
1 /* $NetBSD: ahb.c,v 1.70 2021/08/07 16:19:10 thorpej Exp $ */
2
3 /*-
4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
9 * Simulation Facility, NASA Ames Research Center.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * Originally written by Julian Elischer (julian@tfs.com)
35 * for TRW Financial Systems for use under the MACH(2.5) operating system.
36 *
37 * TRW Financial Systems, in accordance with their agreement with Carnegie
38 * Mellon University, makes this software available to CMU to distribute
39 * or use in any manner that they see fit as long as this message is kept with
40 * the software. For this reason TFS also grants any other persons or
41 * organisations permission to use or modify this software.
42 *
43 * TFS supplies this software to be publicly redistributed
44 * on the understanding that TFS is not responsible for the correct
45 * functioning of this software in any circumstances.
46 */
47
48 #include <sys/cdefs.h>
49 __KERNEL_RCSID(0, "$NetBSD: ahb.c,v 1.70 2021/08/07 16:19:10 thorpej Exp $");
50
51 #include "opt_ddb.h"
52
53 #undef AHBDEBUG
54
55 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/kernel.h>
58 #include <sys/errno.h>
59 #include <sys/ioctl.h>
60 #include <sys/device.h>
61 #include <sys/buf.h>
62 #include <sys/proc.h>
63
64 #include <sys/bus.h>
65 #include <sys/intr.h>
66
67 #include <dev/scsipi/scsi_all.h>
68 #include <dev/scsipi/scsipi_all.h>
69 #include <dev/scsipi/scsiconf.h>
70
71 #include <dev/eisa/eisareg.h>
72 #include <dev/eisa/eisavar.h>
73 #include <dev/eisa/eisadevs.h>
74 #include <dev/eisa/ahbreg.h>
75
76 #ifndef DDB
77 #define Debugger() panic("should call debugger here (aha1742.c)")
78 #endif /* ! DDB */
79
80 #define AHB_ECB_MAX 32 /* store up to 32 ECBs at one time */
81 #define ECB_HASH_SIZE 32 /* hash table size for phystokv */
82 #define ECB_HASH_SHIFT 9
83 #define ECB_HASH(x) ((((long)(x))>>ECB_HASH_SHIFT) & (ECB_HASH_SIZE - 1))
84
85 #define AHB_MAXXFER ((AHB_NSEG - 1) << PGSHIFT)
86
87 struct ahb_softc {
88 device_t sc_dev;
89
90 bus_space_tag_t sc_iot;
91 bus_space_handle_t sc_ioh;
92 bus_dma_tag_t sc_dmat;
93 void *sc_ih;
94
95 bus_dmamap_t sc_dmamap_ecb; /* maps the ecbs */
96 struct ahb_ecb *sc_ecbs; /* all our ecbs */
97
98 struct ahb_ecb *sc_ecbhash[ECB_HASH_SIZE];
99 TAILQ_HEAD(, ahb_ecb) sc_free_ecb;
100 struct ahb_ecb *sc_immed_ecb; /* an outstanding immediete command */
101 int sc_numecbs;
102
103 struct scsipi_adapter sc_adapter;
104 struct scsipi_channel sc_channel;
105 };
106
107 /*
108 * Offset of an ECB from the beginning of the ECB DMA mapping.
109 */
110 #define AHB_ECB_OFF(e) (((uintptr_t)(e)) - ((uintptr_t)&sc->sc_ecbs[0]))
111
112 struct ahb_probe_data {
113 int sc_irq;
114 int sc_ist;
115 int sc_scsi_dev;
116 };
117
118 static void ahb_send_mbox(struct ahb_softc *, int, struct ahb_ecb *);
119 static void ahb_send_immed(struct ahb_softc *, u_int32_t, struct ahb_ecb *);
120 static int ahbintr(void *);
121 static void ahb_free_ecb(struct ahb_softc *, struct ahb_ecb *);
122 static struct ahb_ecb *ahb_get_ecb(struct ahb_softc *);
123 static struct ahb_ecb *ahb_ecb_lookup(struct ahb_softc *, uint32_t);
124 static void ahb_done(struct ahb_softc *, struct ahb_ecb *);
125 static int ahb_find(bus_space_tag_t, bus_space_handle_t,
126 struct ahb_probe_data *);
127 static int ahb_init(struct ahb_softc *);
128 static void ahbminphys(struct buf *);
129 static void ahb_scsipi_request(struct scsipi_channel *,
130 scsipi_adapter_req_t, void *);
131 static int ahb_poll(struct ahb_softc *, struct scsipi_xfer *, int);
132 static void ahb_timeout(void *);
133 static int ahb_create_ecbs(struct ahb_softc *, struct ahb_ecb *, int);
134
135 static int ahb_init_ecb(struct ahb_softc *, struct ahb_ecb *);
136
137 static int ahbmatch(device_t, cfdata_t, void *);
138 static void ahbattach(device_t, device_t, void *);
139
140 CFATTACH_DECL_NEW(ahb, sizeof(struct ahb_softc),
141 ahbmatch, ahbattach, NULL, NULL);
142
143 #define AHB_ABORT_TIMEOUT 2000 /* time to wait for abort (mSec) */
144
145 static const struct device_compatible_entry compat_data[] = {
146 { .compat = "ADP0000", .data = EISA_PRODUCT_ADP0000 },
147 { .compat = "ADP0001", .data = EISA_PRODUCT_ADP0001 },
148 { .compat = "ADP0002", .data = EISA_PRODUCT_ADP0002 },
149 { .compat = "ADP0400", .data = EISA_PRODUCT_ADP0400 },
150 DEVICE_COMPAT_EOL
151 };
152
153 /*
154 * Check the slots looking for a board we recognise
155 * If we find one, note its address (slot) and call
156 * the actual probe routine to check it out.
157 */
158 static int
159 ahbmatch(device_t parent, cfdata_t match, void *aux)
160 {
161 struct eisa_attach_args *ea = aux;
162 bus_space_tag_t iot = ea->ea_iot;
163 bus_space_handle_t ioh;
164 int rv;
165
166 if (!eisa_compatible_match(ea, compat_data))
167 return (0);
168
169 if (bus_space_map(iot,
170 EISA_SLOT_ADDR(ea->ea_slot) + AHB_EISA_SLOT_OFFSET,
171 AHB_EISA_IOSIZE, 0, &ioh))
172 return (0);
173
174 rv = !ahb_find(iot, ioh, NULL);
175
176 bus_space_unmap(iot, ioh, AHB_EISA_IOSIZE);
177
178 return (rv);
179 }
180
181 /*
182 * Attach all the sub-devices we can find
183 */
184 static void
185 ahbattach(device_t parent, device_t self, void *aux)
186 {
187 struct eisa_attach_args *ea = aux;
188 struct ahb_softc *sc = device_private(self);
189 const struct device_compatible_entry *dce;
190 bus_space_tag_t iot = ea->ea_iot;
191 bus_space_handle_t ioh;
192 eisa_chipset_tag_t ec = ea->ea_ec;
193 eisa_intr_handle_t ih;
194 const char *intrstr;
195 struct ahb_probe_data apd;
196 struct scsipi_adapter *adapt = &sc->sc_adapter;
197 struct scsipi_channel *chan = &sc->sc_channel;
198 char intrbuf[EISA_INTRSTR_LEN];
199
200 sc->sc_dev = self;
201
202 dce = eisa_compatible_lookup(ea, compat_data);
203 KASSERT(dce != NULL);
204
205 aprint_naive("\n");
206 aprint_normal(": %s\n", (const char *)dce->data);
207
208 if (bus_space_map(iot,
209 EISA_SLOT_ADDR(ea->ea_slot) + AHB_EISA_SLOT_OFFSET,
210 AHB_EISA_IOSIZE, 0, &ioh))
211 panic("ahbattach: could not map I/O addresses");
212
213 sc->sc_iot = iot;
214 sc->sc_ioh = ioh;
215 sc->sc_dmat = ea->ea_dmat;
216 if (ahb_find(iot, ioh, &apd))
217 panic("ahbattach: ahb_find failed!");
218
219 TAILQ_INIT(&sc->sc_free_ecb);
220
221 /*
222 * Fill in the scsipi_adapter.
223 */
224 memset(adapt, 0, sizeof(*adapt));
225 adapt->adapt_dev = sc->sc_dev;
226 adapt->adapt_nchannels = 1;
227 /* adapt_openings initialized below */
228 adapt->adapt_max_periph = 4; /* XXX arbitrary? */
229 adapt->adapt_request = ahb_scsipi_request;
230 adapt->adapt_minphys = ahbminphys;
231
232 /*
233 * Fill in the scsipi_channel.
234 */
235 memset(chan, 0, sizeof(*chan));
236 chan->chan_adapter = adapt;
237 chan->chan_bustype = &scsi_bustype;
238 chan->chan_channel = 0;
239 chan->chan_ntargets = 8;
240 chan->chan_nluns = 8;
241 chan->chan_id = apd.sc_scsi_dev;
242
243 if (ahb_init(sc) != 0) {
244 /* Error during initialization! */
245 return;
246 }
247
248 if (eisa_intr_map(ec, apd.sc_irq, &ih)) {
249 aprint_error_dev(sc->sc_dev, "couldn't map interrupt (%d)\n",
250 apd.sc_irq);
251 return;
252 }
253 intrstr = eisa_intr_string(ec, ih, intrbuf, sizeof(intrbuf));
254 sc->sc_ih = eisa_intr_establish(ec, ih, apd.sc_ist, IPL_BIO,
255 ahbintr, sc);
256 if (sc->sc_ih == NULL) {
257 aprint_error_dev(sc->sc_dev, "couldn't establish interrupt");
258 if (intrstr != NULL)
259 aprint_error(" at %s", intrstr);
260 aprint_error("\n");
261 return;
262 }
263 if (intrstr != NULL) {
264 aprint_normal_dev(sc->sc_dev,
265 "interrupting at %s (%s trigger)\n", intrstr,
266 apd.sc_ist == IST_EDGE ? "edge" : "level");
267 }
268
269 /*
270 * ask the adapter what subunits are present
271 */
272 config_found(self, &sc->sc_channel, scsiprint, CFARGS_NONE);
273 }
274
275 /*
276 * Function to send a command out through a mailbox
277 */
278 static void
279 ahb_send_mbox(struct ahb_softc *sc, int opcode, struct ahb_ecb *ecb)
280 {
281 bus_space_tag_t iot = sc->sc_iot;
282 bus_space_handle_t ioh = sc->sc_ioh;
283 int wait = 300; /* 1ms should be enough */
284
285 while (--wait) {
286 if ((bus_space_read_1(iot, ioh, G2STAT) & (G2STAT_BUSY | G2STAT_MBOX_EMPTY))
287 == (G2STAT_MBOX_EMPTY))
288 break;
289 delay(10);
290 }
291 if (!wait) {
292 printf("%s: board not responding\n", device_xname(sc->sc_dev));
293 Debugger();
294 }
295
296 bus_space_write_4(iot, ioh, MBOXOUT0, ecb->ecb_dma_addr);
297 bus_space_write_1(iot, ioh, ATTN, opcode |
298 ecb->xs->xs_periph->periph_target);
299
300 if ((ecb->xs->xs_control & XS_CTL_POLL) == 0)
301 callout_reset(&ecb->xs->xs_callout,
302 mstohz(ecb->timeout), ahb_timeout, ecb);
303 }
304
305 /*
306 * Function to send an immediate type command to the adapter
307 */
308 static void
309 ahb_send_immed(struct ahb_softc *sc, u_int32_t cmd, struct ahb_ecb *ecb)
310 {
311 bus_space_tag_t iot = sc->sc_iot;
312 bus_space_handle_t ioh = sc->sc_ioh;
313 int wait = 100; /* 1 ms enough? */
314
315 while (--wait) {
316 if ((bus_space_read_1(iot, ioh, G2STAT) & (G2STAT_BUSY | G2STAT_MBOX_EMPTY))
317 == (G2STAT_MBOX_EMPTY))
318 break;
319 delay(10);
320 }
321 if (!wait) {
322 printf("%s: board not responding\n", device_xname(sc->sc_dev));
323 Debugger();
324 }
325
326 bus_space_write_4(iot, ioh, MBOXOUT0, cmd);
327 bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_SET_HOST_READY);
328 bus_space_write_1(iot, ioh, ATTN, OP_IMMED |
329 ecb->xs->xs_periph->periph_target);
330
331 if ((ecb->xs->xs_control & XS_CTL_POLL) == 0)
332 callout_reset(&ecb->xs->xs_callout,
333 mstohz(ecb->timeout), ahb_timeout, ecb);
334 }
335
336 /*
337 * Catch an interrupt from the adaptor
338 */
339 static int
340 ahbintr(void *arg)
341 {
342 struct ahb_softc *sc = arg;
343 bus_space_tag_t iot = sc->sc_iot;
344 bus_space_handle_t ioh = sc->sc_ioh;
345 struct ahb_ecb *ecb;
346 u_char ahbstat;
347 u_int32_t mboxval;
348
349 #ifdef AHBDEBUG
350 printf("%s: ahbintr ", device_xname(sc->sc_dev));
351 #endif /* AHBDEBUG */
352
353 if ((bus_space_read_1(iot, ioh, G2STAT) & G2STAT_INT_PEND) == 0)
354 return 0;
355
356 for (;;) {
357 /*
358 * First get all the information and then
359 * acknowledge the interrupt
360 */
361 ahbstat = bus_space_read_1(iot, ioh, G2INTST);
362 mboxval = bus_space_read_4(iot, ioh, MBOXIN0);
363 bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_CLEAR_EISA_INT);
364
365 #ifdef AHBDEBUG
366 printf("status = 0x%x ", ahbstat);
367 #endif /* AHBDEBUG */
368
369 /*
370 * Process the completed operation
371 */
372 switch (ahbstat & G2INTST_INT_STAT) {
373 case AHB_ECB_OK:
374 case AHB_ECB_RECOVERED:
375 case AHB_ECB_ERR:
376 ecb = ahb_ecb_lookup(sc, mboxval);
377 if (!ecb) {
378 aprint_error_dev(sc->sc_dev,
379 "BAD ECB RETURNED!\n");
380 goto next; /* whatever it was, it'll timeout */
381 }
382 break;
383
384 case AHB_IMMED_ERR:
385 ecb = sc->sc_immed_ecb;
386 sc->sc_immed_ecb = 0;
387 ecb->flags |= ECB_IMMED_FAIL;
388 break;
389
390 case AHB_IMMED_OK:
391 ecb = sc->sc_immed_ecb;
392 sc->sc_immed_ecb = 0;
393 break;
394
395 default:
396 aprint_error_dev(sc->sc_dev,
397 "unexpected interrupt %x\n", ahbstat);
398 goto next;
399 }
400
401 callout_stop(&ecb->xs->xs_callout);
402 ahb_done(sc, ecb);
403
404 next:
405 if ((bus_space_read_1(iot, ioh, G2STAT) & G2STAT_INT_PEND) == 0)
406 return 1;
407 }
408 }
409
410 static inline void
411 ahb_reset_ecb(struct ahb_softc *sc, struct ahb_ecb *ecb)
412 {
413
414 ecb->flags = 0;
415 }
416
417 /*
418 * A ecb (and hence a mbx-out is put onto the
419 * free list.
420 */
421 static void
422 ahb_free_ecb(struct ahb_softc *sc, struct ahb_ecb *ecb)
423 {
424 int s;
425
426 s = splbio();
427 ahb_reset_ecb(sc, ecb);
428 TAILQ_INSERT_HEAD(&sc->sc_free_ecb, ecb, chain);
429 splx(s);
430 }
431
432 /*
433 * Create a set of ecbs and add them to the free list.
434 */
435 static int
436 ahb_init_ecb(struct ahb_softc *sc, struct ahb_ecb *ecb)
437 {
438 bus_dma_tag_t dmat = sc->sc_dmat;
439 int hashnum, error;
440
441 /*
442 * Create the DMA map for this ECB.
443 */
444 error = bus_dmamap_create(dmat, AHB_MAXXFER, AHB_NSEG, AHB_MAXXFER,
445 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, &ecb->dmamap_xfer);
446 if (error) {
447 aprint_error_dev(sc->sc_dev, "can't create ecb dmamap_xfer\n");
448 return (error);
449 }
450
451 ecb->ecb_dma_addr = sc->sc_dmamap_ecb->dm_segs[0].ds_addr +
452 AHB_ECB_OFF(ecb);
453
454 /*
455 * put in the phystokv hash table
456 * Never gets taken out.
457 */
458 hashnum = ECB_HASH(ecb->ecb_dma_addr);
459 ecb->nexthash = sc->sc_ecbhash[hashnum];
460 sc->sc_ecbhash[hashnum] = ecb;
461 ahb_reset_ecb(sc, ecb);
462 return (0);
463 }
464
465 static int
466 ahb_create_ecbs(struct ahb_softc *sc, struct ahb_ecb *ecbstore, int count)
467 {
468 struct ahb_ecb *ecb;
469 int i, error;
470
471 memset(ecbstore, 0, sizeof(struct ahb_ecb) * count);
472 for (i = 0; i < count; i++) {
473 ecb = &ecbstore[i];
474 if ((error = ahb_init_ecb(sc, ecb)) != 0) {
475 aprint_error_dev(sc->sc_dev,
476 "unable to initialize ecb, error = %d\n", error);
477 goto out;
478 }
479 TAILQ_INSERT_TAIL(&sc->sc_free_ecb, ecb, chain);
480 }
481 out:
482 return (i);
483 }
484
485 /*
486 * Get a free ecb
487 *
488 * If there are none, see if we can allocate a new one. If so, put it in the
489 * hash table too otherwise either return an error or sleep.
490 */
491 static struct ahb_ecb *
492 ahb_get_ecb(struct ahb_softc *sc)
493 {
494 struct ahb_ecb *ecb;
495 int s;
496
497 s = splbio();
498 ecb = TAILQ_FIRST(&sc->sc_free_ecb);
499 if (ecb != NULL) {
500 TAILQ_REMOVE(&sc->sc_free_ecb, ecb, chain);
501 ecb->flags |= ECB_ALLOC;
502 }
503 splx(s);
504 return (ecb);
505 }
506
507 /*
508 * Lookup and return the ECB that has the specified DMA address.
509 */
510 static struct ahb_ecb *
511 ahb_ecb_lookup(struct ahb_softc *sc, uint32_t ecb_phys)
512 {
513 int hashnum = ECB_HASH(ecb_phys);
514 struct ahb_ecb *ecb = sc->sc_ecbhash[hashnum];
515
516 while (ecb) {
517 if (ecb->ecb_dma_addr == ecb_phys)
518 break;
519 ecb = ecb->nexthash;
520 }
521 return ecb;
522 }
523
524 /*
525 * We have a ecb which has been processed by the adaptor, now we look to see
526 * how the operation went.
527 */
528 static void
529 ahb_done(struct ahb_softc *sc, struct ahb_ecb *ecb)
530 {
531 bus_dma_tag_t dmat = sc->sc_dmat;
532 struct scsi_sense_data *s1, *s2;
533 struct scsipi_xfer *xs = ecb->xs;
534
535 SC_DEBUG(xs->xs_periph, SCSIPI_DB2, ("ahb_done\n"));
536
537 bus_dmamap_sync(dmat, sc->sc_dmamap_ecb,
538 AHB_ECB_OFF(ecb), sizeof(struct ahb_ecb),
539 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
540
541 /*
542 * If we were a data transfer, unload the map that described
543 * the data buffer.
544 */
545 if (xs->datalen) {
546 bus_dmamap_sync(dmat, ecb->dmamap_xfer, 0,
547 ecb->dmamap_xfer->dm_mapsize,
548 (xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMASYNC_POSTREAD :
549 BUS_DMASYNC_POSTWRITE);
550 bus_dmamap_unload(dmat, ecb->dmamap_xfer);
551 }
552
553 /*
554 * Otherwise, put the results of the operation
555 * into the xfer and call whoever started it
556 */
557 if ((ecb->flags & ECB_ALLOC) == 0) {
558 aprint_error_dev(sc->sc_dev, "exiting ecb not allocated!\n");
559 Debugger();
560 }
561 if (ecb->flags & ECB_IMMED) {
562 if (ecb->flags & ECB_IMMED_FAIL)
563 xs->error = XS_DRIVER_STUFFUP;
564 goto done;
565 }
566 if (xs->error == XS_NOERROR) {
567 if (ecb->ecb_status.host_stat != HS_OK) {
568 switch (ecb->ecb_status.host_stat) {
569 case HS_TIMED_OUT: /* No response */
570 xs->error = XS_SELTIMEOUT;
571 break;
572 default: /* Other scsi protocol messes */
573 printf("%s: host_stat %x\n",
574 device_xname(sc->sc_dev),
575 ecb->ecb_status.host_stat);
576 xs->error = XS_DRIVER_STUFFUP;
577 }
578 } else if (ecb->ecb_status.target_stat != SCSI_OK) {
579 switch (ecb->ecb_status.target_stat) {
580 case SCSI_CHECK:
581 s1 = &ecb->ecb_sense;
582 s2 = &xs->sense.scsi_sense;
583 *s2 = *s1;
584 xs->error = XS_SENSE;
585 break;
586 case SCSI_BUSY:
587 xs->error = XS_BUSY;
588 break;
589 default:
590 printf("%s: target_stat %x\n",
591 device_xname(sc->sc_dev),
592 ecb->ecb_status.target_stat);
593 xs->error = XS_DRIVER_STUFFUP;
594 }
595 } else
596 xs->resid = 0;
597 }
598 done:
599 ahb_free_ecb(sc, ecb);
600 scsipi_done(xs);
601 }
602
603 /*
604 * Start the board, ready for normal operation
605 */
606 static int
607 ahb_find(bus_space_tag_t iot, bus_space_handle_t ioh,
608 struct ahb_probe_data *sc)
609 {
610 u_char intdef;
611 int i, irq, ist, busid;
612 int wait = 1000; /* 1 sec enough? */
613
614 bus_space_write_1(iot, ioh, PORTADDR, PORTADDR_ENHANCED);
615
616 #define NO_NO 1
617 #ifdef NO_NO
618 /*
619 * reset board, If it doesn't respond, assume
620 * that it's not there.. good for the probe
621 */
622 bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_HARD_RESET);
623 delay(1000);
624 bus_space_write_1(iot, ioh, G2CNTRL, 0);
625 delay(10000);
626 while (--wait) {
627 if ((bus_space_read_1(iot, ioh, G2STAT) & G2STAT_BUSY) == 0)
628 break;
629 delay(1000);
630 }
631 if (!wait) {
632 #ifdef AHBDEBUG
633 printf("ahb_find: No answer from aha1742 board\n");
634 #endif /* AHBDEBUG */
635 return ENXIO;
636 }
637 i = bus_space_read_1(iot, ioh, MBOXIN0);
638 if (i) {
639 printf("self test failed, val = 0x%x\n", i);
640 return EIO;
641 }
642
643 /* Set it again, just to be sure. */
644 bus_space_write_1(iot, ioh, PORTADDR, PORTADDR_ENHANCED);
645 #endif
646
647 while (bus_space_read_1(iot, ioh, G2STAT) & G2STAT_INT_PEND) {
648 printf(".");
649 bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_CLEAR_EISA_INT);
650 delay(10000);
651 }
652
653 intdef = bus_space_read_1(iot, ioh, INTDEF);
654 switch (intdef & 0x07) {
655 case INT9:
656 irq = 9;
657 break;
658 case INT10:
659 irq = 10;
660 break;
661 case INT11:
662 irq = 11;
663 break;
664 case INT12:
665 irq = 12;
666 break;
667 case INT14:
668 irq = 14;
669 break;
670 case INT15:
671 irq = 15;
672 break;
673 default:
674 printf("illegal int setting %x\n", intdef);
675 return EIO;
676 }
677
678 /*
679 * On EISA, edge triggered interrupts are signalled by the rising
680 * edge of the interrupt signal, while level tiggered interrupts
681 * are signalled so long as the interrupt signal is driven low.
682 *
683 * So, if the controller is configured for active-high interrupts,
684 * that is "edge trigger" in our parlance, while active-low would
685 * be "level trigger".
686 */
687 if (intdef & INTHIGH) {
688 ist = IST_EDGE;
689 } else {
690 ist = IST_LEVEL;
691 }
692
693 bus_space_write_1(iot, ioh, INTDEF, (intdef | INTEN)); /* make sure we can interrupt */
694
695 /* who are we on the scsi bus? */
696 busid = (bus_space_read_1(iot, ioh, SCSIDEF) & HSCSIID);
697
698 /* if we want to return data, do so now */
699 if (sc) {
700 sc->sc_irq = irq;
701 sc->sc_ist = ist;
702 sc->sc_scsi_dev = busid;
703 }
704
705 /*
706 * Note that we are going and return (to probe)
707 */
708 return 0;
709 }
710
711 static int
712 ahb_init(struct ahb_softc *sc)
713 {
714 bus_dma_segment_t seg;
715 int i, error, rseg;
716
717 #define ECBSIZE (AHB_ECB_MAX * sizeof(struct ahb_ecb))
718
719 /*
720 * Allocate the ECBs.
721 */
722 if ((error = bus_dmamem_alloc(sc->sc_dmat, ECBSIZE,
723 PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
724 aprint_error_dev(sc->sc_dev,
725 "unable to allocate ecbs, error = %d\n", error);
726 return (error);
727 }
728 if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
729 ECBSIZE, (void **)&sc->sc_ecbs,
730 BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
731 aprint_error_dev(sc->sc_dev,
732 "unable to map ecbs, error = %d\n", error);
733 return (error);
734 }
735
736 /*
737 * Create and load the DMA map used for the ecbs.
738 */
739 if ((error = bus_dmamap_create(sc->sc_dmat, ECBSIZE,
740 1, ECBSIZE, 0, BUS_DMA_NOWAIT, &sc->sc_dmamap_ecb)) != 0) {
741 aprint_error_dev(sc->sc_dev,
742 "unable to create ecb DMA map, error = %d\n", error);
743 return (error);
744 }
745 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_ecb,
746 sc->sc_ecbs, ECBSIZE, NULL, BUS_DMA_NOWAIT)) != 0) {
747 aprint_error_dev(sc->sc_dev,
748 "unable to load ecb DMA map, error = %d\n", error);
749 return (error);
750 }
751
752 #undef ECBSIZE
753
754 /*
755 * Initialize the ecbs.
756 */
757 i = ahb_create_ecbs(sc, sc->sc_ecbs, AHB_ECB_MAX);
758 if (i == 0) {
759 aprint_error_dev(sc->sc_dev, "unable to create ecbs\n");
760 return (ENOMEM);
761 } else if (i != AHB_ECB_MAX) {
762 printf("%s: WARNING: only %d of %d ecbs created\n",
763 device_xname(sc->sc_dev), i, AHB_ECB_MAX);
764 }
765
766 sc->sc_adapter.adapt_openings = i;
767
768 return (0);
769 }
770
771 static void
772 ahbminphys(struct buf *bp)
773 {
774
775 if (bp->b_bcount > AHB_MAXXFER)
776 bp->b_bcount = AHB_MAXXFER;
777 minphys(bp);
778 }
779
780 /*
781 * start a scsi operation given the command and the data address. Also needs
782 * the unit, target and lu.
783 */
784 static void
785 ahb_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,
786 void *arg)
787 {
788 struct scsipi_xfer *xs;
789 struct scsipi_periph *periph;
790 struct ahb_softc *sc = device_private(chan->chan_adapter->adapt_dev);
791 bus_dma_tag_t dmat = sc->sc_dmat;
792 struct ahb_ecb *ecb;
793 int error, seg, flags, s;
794
795 switch (req) {
796 case ADAPTER_REQ_RUN_XFER:
797 xs = arg;
798 periph = xs->xs_periph;
799 flags = xs->xs_control;
800
801 SC_DEBUG(periph, SCSIPI_DB2, ("ahb_scsipi_request\n"));
802
803 /* Get an ECB to use. */
804 ecb = ahb_get_ecb(sc);
805 #ifdef DIAGNOSTIC
806 /*
807 * This should never happen as we track the resources
808 * in the mid-layer.
809 */
810 if (ecb == NULL) {
811 scsipi_printaddr(periph);
812 printf("unable to allocate ecb\n");
813 panic("ahb_scsipi_request");
814 }
815 #endif
816
817 ecb->xs = xs;
818 ecb->timeout = xs->timeout;
819
820 /*
821 * If it's a reset, we need to do an 'immediate'
822 * command, and store its ecb for later
823 * if there is already an immediate waiting,
824 * then WE must wait
825 */
826 if (flags & XS_CTL_RESET) {
827 ecb->flags |= ECB_IMMED;
828 if (sc->sc_immed_ecb) {
829 ahb_free_ecb(sc, ecb);
830 xs->error = XS_BUSY;
831 scsipi_done(xs);
832 return;
833 }
834 sc->sc_immed_ecb = ecb;
835
836 s = splbio();
837 ahb_send_immed(sc, AHB_TARG_RESET, ecb);
838 splx(s);
839
840 if ((flags & XS_CTL_POLL) == 0)
841 return;
842
843 /*
844 * If we can't use interrupts, poll on completion
845 */
846 if (ahb_poll(sc, xs, ecb->timeout))
847 ahb_timeout(ecb);
848 return;
849 }
850
851 /*
852 * Put all the arguments for the xfer in the ecb
853 */
854 if (xs->cmdlen > sizeof(ecb->scsi_cmd)) {
855 aprint_error_dev(sc->sc_dev,
856 "cmdlen %d too large for ECB\n", xs->cmdlen);
857 xs->error = XS_DRIVER_STUFFUP;
858 goto out_bad;
859 }
860 ecb->opcode = ECB_SCSI_OP;
861 ecb->opt1 = ECB_SES /*| ECB_DSB*/ | ECB_ARS;
862 ecb->opt2 = periph->periph_lun | ECB_NRB;
863 memcpy(&ecb->scsi_cmd, xs->cmd,
864 ecb->scsi_cmd_length = xs->cmdlen);
865 ecb->sense_ptr = ecb->ecb_dma_addr +
866 offsetof(struct ahb_ecb, ecb_sense);
867 ecb->req_sense_length = sizeof(ecb->ecb_sense);
868 ecb->status = ecb->ecb_dma_addr +
869 offsetof(struct ahb_ecb, ecb_status);
870 ecb->ecb_status.host_stat = 0x00;
871 ecb->ecb_status.target_stat = 0x00;
872
873 if (xs->datalen) {
874 /*
875 * Map the DMA transfer.
876 */
877 #ifdef TFS
878 if (flags & XS_CTL_DATA_UIO) {
879 error = bus_dmamap_load_uio(sc->sc_dmat,
880 ecb->dmamap_xfer, (struct uio *)xs->data,
881 BUS_DMA_NOWAIT);
882 } else
883 #endif /* TFS */
884 {
885 error = bus_dmamap_load(sc->sc_dmat,
886 ecb->dmamap_xfer, xs->data, xs->datalen,
887 NULL, BUS_DMA_NOWAIT);
888 }
889
890 switch (error) {
891 case 0:
892 break;
893
894 case ENOMEM:
895 case EAGAIN:
896 xs->error = XS_RESOURCE_SHORTAGE;
897 goto out_bad;
898
899 default:
900 xs->error = XS_DRIVER_STUFFUP;
901 aprint_error_dev(sc->sc_dev,
902 "error %d loading DMA map\n", error);
903 out_bad:
904 ahb_free_ecb(sc, ecb);
905 scsipi_done(xs);
906 return;
907 }
908
909 bus_dmamap_sync(dmat, ecb->dmamap_xfer, 0,
910 ecb->dmamap_xfer->dm_mapsize,
911 (flags & XS_CTL_DATA_IN) ? BUS_DMASYNC_PREREAD :
912 BUS_DMASYNC_PREWRITE);
913
914 /*
915 * Load the hardware scatter/gather map with the
916 * contents of the DMA map.
917 */
918 for (seg = 0; seg < ecb->dmamap_xfer->dm_nsegs; seg++) {
919 ecb->ahb_dma[seg].seg_addr =
920 ecb->dmamap_xfer->dm_segs[seg].ds_addr;
921 ecb->ahb_dma[seg].seg_len =
922 ecb->dmamap_xfer->dm_segs[seg].ds_len;
923 }
924
925 ecb->data_addr = ecb->ecb_dma_addr +
926 offsetof(struct ahb_ecb, ahb_dma);
927 ecb->data_length = ecb->dmamap_xfer->dm_nsegs *
928 sizeof(struct ahb_dma_seg);
929 ecb->opt1 |= ECB_S_G;
930 } else { /* No data xfer, use non S/G values */
931 ecb->data_addr = 0;
932 ecb->data_length = 0;
933 }
934 ecb->link_addr = 0;
935
936 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ecb,
937 AHB_ECB_OFF(ecb), sizeof(struct ahb_ecb),
938 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
939
940 s = splbio();
941 ahb_send_mbox(sc, OP_START_ECB, ecb);
942 splx(s);
943
944 if ((flags & XS_CTL_POLL) == 0)
945 return;
946
947 /*
948 * If we can't use interrupts, poll on completion
949 */
950 if (ahb_poll(sc, xs, ecb->timeout)) {
951 ahb_timeout(ecb);
952 if (ahb_poll(sc, xs, ecb->timeout))
953 ahb_timeout(ecb);
954 }
955 return;
956
957 case ADAPTER_REQ_GROW_RESOURCES:
958 /* XXX Not supported. */
959 return;
960
961 case ADAPTER_REQ_SET_XFER_MODE:
962 /* XXX How do we do this? */
963 return;
964 }
965 }
966
967 /*
968 * Function to poll for command completion when in poll mode
969 */
970 static int
971 ahb_poll(struct ahb_softc *sc, struct scsipi_xfer *xs, int count)
972 { /* in msec */
973 bus_space_tag_t iot = sc->sc_iot;
974 bus_space_handle_t ioh = sc->sc_ioh;
975
976 while (count) {
977 /*
978 * If we had interrupts enabled, would we
979 * have got an interrupt?
980 */
981 if (bus_space_read_1(iot, ioh, G2STAT) & G2STAT_INT_PEND)
982 ahbintr(sc);
983 if (xs->xs_status & XS_STS_DONE)
984 return 0;
985 delay(1000);
986 count--;
987 }
988 return 1;
989 }
990
991 static void
992 ahb_timeout(void *arg)
993 {
994 struct ahb_ecb *ecb = arg;
995 struct scsipi_xfer *xs = ecb->xs;
996 struct scsipi_periph *periph = xs->xs_periph;
997 struct ahb_softc *sc =
998 device_private(periph->periph_channel->chan_adapter->adapt_dev);
999 int s;
1000
1001 scsipi_printaddr(periph);
1002 printf("timed out");
1003
1004 s = splbio();
1005
1006 if (ecb->flags & ECB_IMMED) {
1007 printf("\n");
1008 ecb->flags |= ECB_IMMED_FAIL;
1009 /* XXX Must reset! */
1010 } else
1011
1012 /*
1013 * If it has been through before, then
1014 * a previous abort has failed, don't
1015 * try abort again
1016 */
1017 if (ecb->flags & ECB_ABORT) {
1018 /* abort timed out */
1019 printf(" AGAIN\n");
1020 /* XXX Must reset! */
1021 } else {
1022 /* abort the operation that has timed out */
1023 printf("\n");
1024 ecb->xs->error = XS_TIMEOUT;
1025 ecb->timeout = AHB_ABORT_TIMEOUT;
1026 ecb->flags |= ECB_ABORT;
1027 ahb_send_mbox(sc, OP_ABORT_ECB, ecb);
1028 }
1029
1030 splx(s);
1031 }
Cache object: fbb9546d9cd2695c7c350464af4f2262
|