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