1 /* $NetBSD: ahb.c,v 1.57 2009/11/23 02:13:45 rmind Exp $ */
4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
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.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
34 * Originally written by Julian Elischer (julian@tfs.com)
35 * for TRW Financial Systems for use under the MACH(2.5) operating system.
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.
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.
48 #include <sys/cdefs.h>
49 __KERNEL_RCSID(0, "$NetBSD: ahb.c,v 1.57 2009/11/23 02:13:45 rmind Exp $");
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/malloc.h>
65 #include <uvm/uvm_extern.h>
70 #include <dev/scsipi/scsi_all.h>
71 #include <dev/scsipi/scsipi_all.h>
72 #include <dev/scsipi/scsiconf.h>
74 #include <dev/eisa/eisareg.h>
75 #include <dev/eisa/eisavar.h>
76 #include <dev/eisa/eisadevs.h>
77 #include <dev/eisa/ahbreg.h>
80 #define Debugger() panic("should call debugger here (aha1742.c)")
83 #define AHB_ECB_MAX 32 /* store up to 32 ECBs at one time */
84 #define ECB_HASH_SIZE 32 /* hash table size for phystokv */
85 #define ECB_HASH_SHIFT 9
86 #define ECB_HASH(x) ((((long)(x))>>ECB_HASH_SHIFT) & (ECB_HASH_SIZE - 1))
88 #define AHB_MAXXFER ((AHB_NSEG - 1) << PGSHIFT)
93 bus_space_tag_t sc_iot
;
94 bus_space_handle_t sc_ioh
;
95 bus_dma_tag_t sc_dmat
;
98 bus_dmamap_t sc_dmamap_ecb
; /* maps the ecbs */
99 struct ahb_ecb
*sc_ecbs
; /* all our ecbs */
101 struct ahb_ecb
*sc_ecbhash
[ECB_HASH_SIZE
];
102 TAILQ_HEAD(, ahb_ecb
) sc_free_ecb
;
103 struct ahb_ecb
*sc_immed_ecb
; /* an outstanding immediete command */
106 struct scsipi_adapter sc_adapter
;
107 struct scsipi_channel sc_channel
;
111 * Offset of an ECB from the beginning of the ECB DMA mapping.
113 #define AHB_ECB_OFF(e) (((u_long)(e)) - ((u_long)&sc->sc_ecbs[0]))
115 struct ahb_probe_data
{
120 static void ahb_send_mbox(struct ahb_softc
*, int, struct ahb_ecb
*);
121 static void ahb_send_immed(struct ahb_softc
*, u_int32_t
, struct ahb_ecb
*);
122 static int ahbintr(void *);
123 static void ahb_free_ecb(struct ahb_softc
*, struct ahb_ecb
*);
124 static struct ahb_ecb
*ahb_get_ecb(struct ahb_softc
*);
125 static struct ahb_ecb
*ahb_ecb_phys_kv(struct ahb_softc
*, physaddr
);
126 static void ahb_done(struct ahb_softc
*, struct ahb_ecb
*);
127 static int ahb_find(bus_space_tag_t
, bus_space_handle_t
,
128 struct ahb_probe_data
*);
129 static int ahb_init(struct ahb_softc
*);
130 static void ahbminphys(struct buf
*);
131 static void ahb_scsipi_request(struct scsipi_channel
*,
132 scsipi_adapter_req_t
, void *);
133 static int ahb_poll(struct ahb_softc
*, struct scsipi_xfer
*, int);
134 static void ahb_timeout(void *);
135 static int ahb_create_ecbs(struct ahb_softc
*, struct ahb_ecb
*, int);
137 static int ahb_init_ecb(struct ahb_softc
*, struct ahb_ecb
*);
139 static int ahbmatch(device_t
, cfdata_t
, void *);
140 static void ahbattach(device_t
, device_t
, void *);
142 CFATTACH_DECL(ahb
, sizeof(struct ahb_softc
),
143 ahbmatch
, ahbattach
, NULL
, NULL
);
145 #define AHB_ABORT_TIMEOUT 2000 /* time to wait for abort (mSec) */
148 * Check the slots looking for a board we recognise
149 * If we find one, note it's address (slot) and call
150 * the actual probe routine to check it out.
153 ahbmatch(device_t parent
, cfdata_t match
,
156 struct eisa_attach_args
*ea
= aux
;
157 bus_space_tag_t iot
= ea
->ea_iot
;
158 bus_space_handle_t ioh
;
161 /* must match one of our known ID strings */
162 if (strcmp(ea
->ea_idstring
, "ADP0000") &&
163 strcmp(ea
->ea_idstring
, "ADP0001") &&
164 strcmp(ea
->ea_idstring
, "ADP0002") &&
165 strcmp(ea
->ea_idstring
, "ADP0400"))
168 if (bus_space_map(iot
,
169 EISA_SLOT_ADDR(ea
->ea_slot
) + AHB_EISA_SLOT_OFFSET
, AHB_EISA_IOSIZE
,
173 rv
= !ahb_find(iot
, ioh
, NULL
);
175 bus_space_unmap(iot
, ioh
, AHB_EISA_IOSIZE
);
181 * Attach all the sub-devices we can find
184 ahbattach(device_t parent
, device_t self
, void *aux
)
186 struct eisa_attach_args
*ea
= aux
;
187 struct ahb_softc
*sc
= device_private(self
);
188 bus_space_tag_t iot
= ea
->ea_iot
;
189 bus_space_handle_t ioh
;
190 eisa_chipset_tag_t ec
= ea
->ea_ec
;
191 eisa_intr_handle_t ih
;
192 const char *model
, *intrstr
;
193 struct ahb_probe_data apd
;
194 struct scsipi_adapter
*adapt
= &sc
->sc_adapter
;
195 struct scsipi_channel
*chan
= &sc
->sc_channel
;
197 if (!strcmp(ea
->ea_idstring
, "ADP0000"))
198 model
= EISA_PRODUCT_ADP0000
;
199 else if (!strcmp(ea
->ea_idstring
, "ADP0001"))
200 model
= EISA_PRODUCT_ADP0001
;
201 else if (!strcmp(ea
->ea_idstring
, "ADP0002"))
202 model
= EISA_PRODUCT_ADP0002
;
203 else if (!strcmp(ea
->ea_idstring
, "ADP0400"))
204 model
= EISA_PRODUCT_ADP0400
;
206 model
= "unknown model!";
207 printf(": %s\n", model
);
209 if (bus_space_map(iot
,
210 EISA_SLOT_ADDR(ea
->ea_slot
) + AHB_EISA_SLOT_OFFSET
, AHB_EISA_IOSIZE
,
212 panic("ahbattach: could not map I/O addresses");
216 sc
->sc_dmat
= ea
->ea_dmat
;
217 if (ahb_find(iot
, ioh
, &apd
))
218 panic("ahbattach: ahb_find failed!");
220 TAILQ_INIT(&sc
->sc_free_ecb
);
223 * Fill in the scsipi_adapter.
225 memset(adapt
, 0, sizeof(*adapt
));
226 adapt
->adapt_dev
= &sc
->sc_dev
;
227 adapt
->adapt_nchannels
= 1;
228 /* adapt_openings initialized below */
229 adapt
->adapt_max_periph
= 4; /* XXX arbitrary? */
230 adapt
->adapt_request
= ahb_scsipi_request
;
231 adapt
->adapt_minphys
= ahbminphys
;
234 * Fill in the scsipi_channel.
236 memset(chan
, 0, sizeof(*chan
));
237 chan
->chan_adapter
= adapt
;
238 chan
->chan_bustype
= &scsi_bustype
;
239 chan
->chan_channel
= 0;
240 chan
->chan_ntargets
= 8;
241 chan
->chan_nluns
= 8;
242 chan
->chan_id
= apd
.sc_scsi_dev
;
244 if (ahb_init(sc
) != 0) {
245 /* Error during initialization! */
249 if (eisa_intr_map(ec
, apd
.sc_irq
, &ih
)) {
250 aprint_error_dev(&sc
->sc_dev
, "couldn't map interrupt (%d)\n",
254 intrstr
= eisa_intr_string(ec
, ih
);
255 sc
->sc_ih
= eisa_intr_establish(ec
, ih
, IST_LEVEL
, IPL_BIO
,
257 if (sc
->sc_ih
== NULL
) {
258 aprint_error_dev(&sc
->sc_dev
, "couldn't establish interrupt");
260 aprint_error(" at %s", intrstr
);
265 aprint_normal_dev(&sc
->sc_dev
, "interrupting at %s\n",
269 * ask the adapter what subunits are present
271 config_found(self
, &sc
->sc_channel
, scsiprint
);
275 * Function to send a command out through a mailbox
278 ahb_send_mbox(struct ahb_softc
*sc
, int opcode
, struct ahb_ecb
*ecb
)
280 bus_space_tag_t iot
= sc
->sc_iot
;
281 bus_space_handle_t ioh
= sc
->sc_ioh
;
282 int wait
= 300; /* 1ms should be enough */
285 if ((bus_space_read_1(iot
, ioh
, G2STAT
) & (G2STAT_BUSY
| G2STAT_MBOX_EMPTY
))
286 == (G2STAT_MBOX_EMPTY
))
291 printf("%s: board not responding\n", device_xname(&sc
->sc_dev
));
296 * don't know if this will work.
297 * XXX WHAT DOES THIS COMMENT MEAN?! --thorpej
299 bus_space_write_4(iot
, ioh
, MBOXOUT0
,
300 sc
->sc_dmamap_ecb
->dm_segs
[0].ds_addr
+ AHB_ECB_OFF(ecb
));
301 bus_space_write_1(iot
, ioh
, ATTN
, opcode
|
302 ecb
->xs
->xs_periph
->periph_target
);
304 if ((ecb
->xs
->xs_control
& XS_CTL_POLL
) == 0)
305 callout_reset(&ecb
->xs
->xs_callout
,
306 mstohz(ecb
->timeout
), ahb_timeout
, ecb
);
310 * Function to send an immediate type command to the adapter
313 ahb_send_immed(struct ahb_softc
*sc
, u_int32_t cmd
, struct ahb_ecb
*ecb
)
315 bus_space_tag_t iot
= sc
->sc_iot
;
316 bus_space_handle_t ioh
= sc
->sc_ioh
;
317 int wait
= 100; /* 1 ms enough? */
320 if ((bus_space_read_1(iot
, ioh
, G2STAT
) & (G2STAT_BUSY
| G2STAT_MBOX_EMPTY
))
321 == (G2STAT_MBOX_EMPTY
))
326 printf("%s: board not responding\n", device_xname(&sc
->sc_dev
));
330 bus_space_write_4(iot
, ioh
, MBOXOUT0
, cmd
); /* don't know this will work */
331 bus_space_write_1(iot
, ioh
, G2CNTRL
, G2CNTRL_SET_HOST_READY
);
332 bus_space_write_1(iot
, ioh
, ATTN
, OP_IMMED
|
333 ecb
->xs
->xs_periph
->periph_target
);
335 if ((ecb
->xs
->xs_control
& XS_CTL_POLL
) == 0)
336 callout_reset(&ecb
->xs
->xs_callout
,
337 mstohz(ecb
->timeout
), ahb_timeout
, ecb
);
341 * Catch an interrupt from the adaptor
346 struct ahb_softc
*sc
= arg
;
347 bus_space_tag_t iot
= sc
->sc_iot
;
348 bus_space_handle_t ioh
= sc
->sc_ioh
;
354 printf("%s: ahbintr ", device_xname(&sc
->sc_dev
));
355 #endif /* AHBDEBUG */
357 if ((bus_space_read_1(iot
, ioh
, G2STAT
) & G2STAT_INT_PEND
) == 0)
362 * First get all the information and then
363 * acknowledge the interrupt
365 ahbstat
= bus_space_read_1(iot
, ioh
, G2INTST
);
366 mboxval
= bus_space_read_4(iot
, ioh
, MBOXIN0
);
367 bus_space_write_1(iot
, ioh
, G2CNTRL
, G2CNTRL_CLEAR_EISA_INT
);
370 printf("status = 0x%x ", ahbstat
);
371 #endif /* AHBDEBUG */
374 * Process the completed operation
376 switch (ahbstat
& G2INTST_INT_STAT
) {
378 case AHB_ECB_RECOVERED
:
380 ecb
= ahb_ecb_phys_kv(sc
, mboxval
);
382 aprint_error_dev(&sc
->sc_dev
, "BAD ECB RETURNED!\n");
383 goto next
; /* whatever it was, it'll timeout */
388 ecb
= sc
->sc_immed_ecb
;
389 sc
->sc_immed_ecb
= 0;
390 ecb
->flags
|= ECB_IMMED_FAIL
;
394 ecb
= sc
->sc_immed_ecb
;
395 sc
->sc_immed_ecb
= 0;
399 aprint_error_dev(&sc
->sc_dev
, "unexpected interrupt %x\n",
404 callout_stop(&ecb
->xs
->xs_callout
);
408 if ((bus_space_read_1(iot
, ioh
, G2STAT
) & G2STAT_INT_PEND
) == 0)
414 ahb_reset_ecb(struct ahb_softc
*sc
, struct ahb_ecb
*ecb
)
421 * A ecb (and hence a mbx-out is put onto the
425 ahb_free_ecb(struct ahb_softc
*sc
, struct ahb_ecb
*ecb
)
430 ahb_reset_ecb(sc
, ecb
);
431 TAILQ_INSERT_HEAD(&sc
->sc_free_ecb
, ecb
, chain
);
436 * Create a set of ecbs and add them to the free list.
439 ahb_init_ecb(struct ahb_softc
*sc
, struct ahb_ecb
*ecb
)
441 bus_dma_tag_t dmat
= sc
->sc_dmat
;
445 * Create the DMA map for this ECB.
447 error
= bus_dmamap_create(dmat
, AHB_MAXXFER
, AHB_NSEG
, AHB_MAXXFER
,
448 0, BUS_DMA_NOWAIT
|BUS_DMA_ALLOCNOW
, &ecb
->dmamap_xfer
);
450 aprint_error_dev(&sc
->sc_dev
, "can't create ecb dmamap_xfer\n");
455 * put in the phystokv hash table
456 * Never gets taken out.
458 ecb
->hashkey
= sc
->sc_dmamap_ecb
->dm_segs
[0].ds_addr
+
460 hashnum
= ECB_HASH(ecb
->hashkey
);
461 ecb
->nexthash
= sc
->sc_ecbhash
[hashnum
];
462 sc
->sc_ecbhash
[hashnum
] = ecb
;
463 ahb_reset_ecb(sc
, ecb
);
468 ahb_create_ecbs(struct ahb_softc
*sc
, struct ahb_ecb
*ecbstore
, int count
)
473 memset(ecbstore
, 0, sizeof(struct ahb_ecb
) * count
);
474 for (i
= 0; i
< count
; i
++) {
476 if ((error
= ahb_init_ecb(sc
, ecb
)) != 0) {
477 aprint_error_dev(&sc
->sc_dev
, "unable to initialize ecb, error = %d\n",
481 TAILQ_INSERT_TAIL(&sc
->sc_free_ecb
, ecb
, chain
);
490 * If there are none, see if we can allocate a new one. If so, put it in the
491 * hash table too otherwise either return an error or sleep.
493 static struct ahb_ecb
*
494 ahb_get_ecb(struct ahb_softc
*sc
)
500 ecb
= TAILQ_FIRST(&sc
->sc_free_ecb
);
502 TAILQ_REMOVE(&sc
->sc_free_ecb
, ecb
, chain
);
503 ecb
->flags
|= ECB_ALLOC
;
510 * given a physical address, find the ecb that it corresponds to.
512 static struct ahb_ecb
*
513 ahb_ecb_phys_kv(struct ahb_softc
*sc
, physaddr ecb_phys
)
515 int hashnum
= ECB_HASH(ecb_phys
);
516 struct ahb_ecb
*ecb
= sc
->sc_ecbhash
[hashnum
];
519 if (ecb
->hashkey
== ecb_phys
)
527 * We have a ecb which has been processed by the adaptor, now we look to see
528 * how the operation went.
531 ahb_done(struct ahb_softc
*sc
, struct ahb_ecb
*ecb
)
533 bus_dma_tag_t dmat
= sc
->sc_dmat
;
534 struct scsi_sense_data
*s1
, *s2
;
535 struct scsipi_xfer
*xs
= ecb
->xs
;
537 SC_DEBUG(xs
->xs_periph
, SCSIPI_DB2
, ("ahb_done\n"));
539 bus_dmamap_sync(dmat
, sc
->sc_dmamap_ecb
,
540 AHB_ECB_OFF(ecb
), sizeof(struct ahb_ecb
),
541 BUS_DMASYNC_POSTREAD
|BUS_DMASYNC_POSTWRITE
);
544 * If we were a data transfer, unload the map that described
548 bus_dmamap_sync(dmat
, ecb
->dmamap_xfer
, 0,
549 ecb
->dmamap_xfer
->dm_mapsize
,
550 (xs
->xs_control
& XS_CTL_DATA_IN
) ? BUS_DMASYNC_POSTREAD
:
551 BUS_DMASYNC_POSTWRITE
);
552 bus_dmamap_unload(dmat
, ecb
->dmamap_xfer
);
556 * Otherwise, put the results of the operation
557 * into the xfer and call whoever started it
559 if ((ecb
->flags
& ECB_ALLOC
) == 0) {
560 aprint_error_dev(&sc
->sc_dev
, "exiting ecb not allocated!\n");
563 if (ecb
->flags
& ECB_IMMED
) {
564 if (ecb
->flags
& ECB_IMMED_FAIL
)
565 xs
->error
= XS_DRIVER_STUFFUP
;
568 if (xs
->error
== XS_NOERROR
) {
569 if (ecb
->ecb_status
.host_stat
!= HS_OK
) {
570 switch (ecb
->ecb_status
.host_stat
) {
571 case HS_TIMED_OUT
: /* No response */
572 xs
->error
= XS_SELTIMEOUT
;
574 default: /* Other scsi protocol messes */
575 printf("%s: host_stat %x\n",
576 device_xname(&sc
->sc_dev
), ecb
->ecb_status
.host_stat
);
577 xs
->error
= XS_DRIVER_STUFFUP
;
579 } else if (ecb
->ecb_status
.target_stat
!= SCSI_OK
) {
580 switch (ecb
->ecb_status
.target_stat
) {
582 s1
= &ecb
->ecb_sense
;
583 s2
= &xs
->sense
.scsi_sense
;
585 xs
->error
= XS_SENSE
;
591 printf("%s: target_stat %x\n",
592 device_xname(&sc
->sc_dev
), ecb
->ecb_status
.target_stat
);
593 xs
->error
= XS_DRIVER_STUFFUP
;
599 ahb_free_ecb(sc
, ecb
);
604 * Start the board, ready for normal operation
607 ahb_find(bus_space_tag_t iot
, bus_space_handle_t ioh
, struct ahb_probe_data
*sc
)
611 int wait
= 1000; /* 1 sec enough? */
613 bus_space_write_1(iot
, ioh
, PORTADDR
, PORTADDR_ENHANCED
);
618 * reset board, If it doesn't respond, assume
619 * that it's not there.. good for the probe
621 bus_space_write_1(iot
, ioh
, G2CNTRL
, G2CNTRL_HARD_RESET
);
623 bus_space_write_1(iot
, ioh
, G2CNTRL
, 0);
626 if ((bus_space_read_1(iot
, ioh
, G2STAT
) & G2STAT_BUSY
) == 0)
632 printf("ahb_find: No answer from aha1742 board\n");
633 #endif /* AHBDEBUG */
636 i
= bus_space_read_1(iot
, ioh
, MBOXIN0
);
638 printf("self test failed, val = 0x%x\n", i
);
642 /* Set it again, just to be sure. */
643 bus_space_write_1(iot
, ioh
, PORTADDR
, PORTADDR_ENHANCED
);
646 while (bus_space_read_1(iot
, ioh
, G2STAT
) & G2STAT_INT_PEND
) {
648 bus_space_write_1(iot
, ioh
, G2CNTRL
, G2CNTRL_CLEAR_EISA_INT
);
652 intdef
= bus_space_read_1(iot
, ioh
, INTDEF
);
653 switch (intdef
& 0x07) {
673 printf("illegal int setting %x\n", intdef
);
677 bus_space_write_1(iot
, ioh
, INTDEF
, (intdef
| INTEN
)); /* make sure we can interrupt */
679 /* who are we on the scsi bus? */
680 busid
= (bus_space_read_1(iot
, ioh
, SCSIDEF
) & HSCSIID
);
682 /* if we want to return data, do so now */
685 sc
->sc_scsi_dev
= busid
;
689 * Note that we are going and return (to probe)
695 ahb_init(struct ahb_softc
*sc
)
697 bus_dma_segment_t seg
;
700 #define ECBSIZE (AHB_ECB_MAX * sizeof(struct ahb_ecb))
705 if ((error
= bus_dmamem_alloc(sc
->sc_dmat
, ECBSIZE
,
706 PAGE_SIZE
, 0, &seg
, 1, &rseg
, BUS_DMA_NOWAIT
)) != 0) {
707 aprint_error_dev(&sc
->sc_dev
, "unable to allocate ecbs, error = %d\n",
711 if ((error
= bus_dmamem_map(sc
->sc_dmat
, &seg
, rseg
,
712 ECBSIZE
, (void **)&sc
->sc_ecbs
,
713 BUS_DMA_NOWAIT
|BUS_DMA_COHERENT
)) != 0) {
714 aprint_error_dev(&sc
->sc_dev
, "unable to map ecbs, error = %d\n",
720 * Create and load the DMA map used for the ecbs.
722 if ((error
= bus_dmamap_create(sc
->sc_dmat
, ECBSIZE
,
723 1, ECBSIZE
, 0, BUS_DMA_NOWAIT
, &sc
->sc_dmamap_ecb
)) != 0) {
724 aprint_error_dev(&sc
->sc_dev
, "unable to create ecb DMA map, error = %d\n",
728 if ((error
= bus_dmamap_load(sc
->sc_dmat
, sc
->sc_dmamap_ecb
,
729 sc
->sc_ecbs
, ECBSIZE
, NULL
, BUS_DMA_NOWAIT
)) != 0) {
730 aprint_error_dev(&sc
->sc_dev
, "unable to load ecb DMA map, error = %d\n",
738 * Initialize the ecbs.
740 i
= ahb_create_ecbs(sc
, sc
->sc_ecbs
, AHB_ECB_MAX
);
742 aprint_error_dev(&sc
->sc_dev
, "unable to create ecbs\n");
744 } else if (i
!= AHB_ECB_MAX
) {
745 printf("%s: WARNING: only %d of %d ecbs created\n",
746 device_xname(&sc
->sc_dev
), i
, AHB_ECB_MAX
);
749 sc
->sc_adapter
.adapt_openings
= i
;
755 ahbminphys(struct buf
*bp
)
758 if (bp
->b_bcount
> AHB_MAXXFER
)
759 bp
->b_bcount
= AHB_MAXXFER
;
764 * start a scsi operation given the command and the data address. Also needs
765 * the unit, target and lu.
768 ahb_scsipi_request(struct scsipi_channel
*chan
, scsipi_adapter_req_t req
,
771 struct scsipi_xfer
*xs
;
772 struct scsipi_periph
*periph
;
773 struct ahb_softc
*sc
= (void *)chan
->chan_adapter
->adapt_dev
;
774 bus_dma_tag_t dmat
= sc
->sc_dmat
;
776 int error
, seg
, flags
, s
;
779 case ADAPTER_REQ_RUN_XFER
:
781 periph
= xs
->xs_periph
;
782 flags
= xs
->xs_control
;
784 SC_DEBUG(periph
, SCSIPI_DB2
, ("ahb_scsipi_request\n"));
786 /* Get an ECB to use. */
787 ecb
= ahb_get_ecb(sc
);
790 * This should never happen as we track the resources
794 scsipi_printaddr(periph
);
795 printf("unable to allocate ecb\n");
796 panic("ahb_scsipi_request");
801 ecb
->timeout
= xs
->timeout
;
804 * If it's a reset, we need to do an 'immediate'
805 * command, and store its ecb for later
806 * if there is already an immediate waiting,
809 if (flags
& XS_CTL_RESET
) {
810 ecb
->flags
|= ECB_IMMED
;
811 if (sc
->sc_immed_ecb
) {
812 ahb_free_ecb(sc
, ecb
);
817 sc
->sc_immed_ecb
= ecb
;
820 ahb_send_immed(sc
, AHB_TARG_RESET
, ecb
);
823 if ((flags
& XS_CTL_POLL
) == 0)
827 * If we can't use interrupts, poll on completion
829 if (ahb_poll(sc
, xs
, ecb
->timeout
))
835 * Put all the arguments for the xfer in the ecb
837 if (xs
->cmdlen
> sizeof(ecb
->scsi_cmd
)) {
838 aprint_error_dev(&sc
->sc_dev
, "cmdlen %d too large for ECB\n",
840 xs
->error
= XS_DRIVER_STUFFUP
;
843 ecb
->opcode
= ECB_SCSI_OP
;
844 ecb
->opt1
= ECB_SES
/*| ECB_DSB*/ | ECB_ARS
;
845 ecb
->opt2
= periph
->periph_lun
| ECB_NRB
;
846 memcpy(&ecb
->scsi_cmd
, xs
->cmd
,
847 ecb
->scsi_cmd_length
= xs
->cmdlen
);
848 ecb
->sense_ptr
= sc
->sc_dmamap_ecb
->dm_segs
[0].ds_addr
+
849 AHB_ECB_OFF(ecb
) + offsetof(struct ahb_ecb
, ecb_sense
);
850 ecb
->req_sense_length
= sizeof(ecb
->ecb_sense
);
851 ecb
->status
= sc
->sc_dmamap_ecb
->dm_segs
[0].ds_addr
+
852 AHB_ECB_OFF(ecb
) + offsetof(struct ahb_ecb
, ecb_status
);
853 ecb
->ecb_status
.host_stat
= 0x00;
854 ecb
->ecb_status
.target_stat
= 0x00;
858 * Map the DMA transfer.
861 if (flags
& XS_CTL_DATA_UIO
) {
862 error
= bus_dmamap_load_uio(sc
->sc_dmat
,
863 ecb
->dmamap_xfer
, (struct uio
*)xs
->data
,
868 error
= bus_dmamap_load(sc
->sc_dmat
,
869 ecb
->dmamap_xfer
, xs
->data
, xs
->datalen
,
870 NULL
, BUS_DMA_NOWAIT
);
879 xs
->error
= XS_RESOURCE_SHORTAGE
;
883 xs
->error
= XS_DRIVER_STUFFUP
;
884 aprint_error_dev(&sc
->sc_dev
, "error %d loading DMA map\n",
887 ahb_free_ecb(sc
, ecb
);
892 bus_dmamap_sync(dmat
, ecb
->dmamap_xfer
, 0,
893 ecb
->dmamap_xfer
->dm_mapsize
,
894 (flags
& XS_CTL_DATA_IN
) ? BUS_DMASYNC_PREREAD
:
895 BUS_DMASYNC_PREWRITE
);
898 * Load the hardware scatter/gather map with the
899 * contents of the DMA map.
901 for (seg
= 0; seg
< ecb
->dmamap_xfer
->dm_nsegs
; seg
++) {
902 ecb
->ahb_dma
[seg
].seg_addr
=
903 ecb
->dmamap_xfer
->dm_segs
[seg
].ds_addr
;
904 ecb
->ahb_dma
[seg
].seg_len
=
905 ecb
->dmamap_xfer
->dm_segs
[seg
].ds_len
;
908 ecb
->data_addr
= sc
->sc_dmamap_ecb
->dm_segs
[0].ds_addr
+
910 offsetof(struct ahb_ecb
, ahb_dma
);
911 ecb
->data_length
= ecb
->dmamap_xfer
->dm_nsegs
*
912 sizeof(struct ahb_dma_seg
);
913 ecb
->opt1
|= ECB_S_G
;
914 } else { /* No data xfer, use non S/G values */
915 ecb
->data_addr
= (physaddr
)0;
916 ecb
->data_length
= 0;
918 ecb
->link_addr
= (physaddr
)0;
920 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap_ecb
,
921 AHB_ECB_OFF(ecb
), sizeof(struct ahb_ecb
),
922 BUS_DMASYNC_PREREAD
|BUS_DMASYNC_PREWRITE
);
925 ahb_send_mbox(sc
, OP_START_ECB
, ecb
);
928 if ((flags
& XS_CTL_POLL
) == 0)
932 * If we can't use interrupts, poll on completion
934 if (ahb_poll(sc
, xs
, ecb
->timeout
)) {
936 if (ahb_poll(sc
, xs
, ecb
->timeout
))
941 case ADAPTER_REQ_GROW_RESOURCES
:
942 /* XXX Not supported. */
945 case ADAPTER_REQ_SET_XFER_MODE
:
946 /* XXX How do we do this? */
952 * Function to poll for command completion when in poll mode
955 ahb_poll(struct ahb_softc
*sc
, struct scsipi_xfer
*xs
, int count
)
957 bus_space_tag_t iot
= sc
->sc_iot
;
958 bus_space_handle_t ioh
= sc
->sc_ioh
;
962 * If we had interrupts enabled, would we
963 * have got an interrupt?
965 if (bus_space_read_1(iot
, ioh
, G2STAT
) & G2STAT_INT_PEND
)
967 if (xs
->xs_status
& XS_STS_DONE
)
976 ahb_timeout(void *arg
)
978 struct ahb_ecb
*ecb
= arg
;
979 struct scsipi_xfer
*xs
= ecb
->xs
;
980 struct scsipi_periph
*periph
= xs
->xs_periph
;
981 struct ahb_softc
*sc
=
982 (void *)periph
->periph_channel
->chan_adapter
->adapt_dev
;
985 scsipi_printaddr(periph
);
990 if (ecb
->flags
& ECB_IMMED
) {
992 ecb
->flags
|= ECB_IMMED_FAIL
;
993 /* XXX Must reset! */
997 * If it has been through before, then
998 * a previous abort has failed, don't
1001 if (ecb
->flags
& ECB_ABORT
) {
1002 /* abort timed out */
1004 /* XXX Must reset! */
1006 /* abort the operation that has timed out */
1008 ecb
->xs
->error
= XS_TIMEOUT
;
1009 ecb
->timeout
= AHB_ABORT_TIMEOUT
;
1010 ecb
->flags
|= ECB_ABORT
;
1011 ahb_send_mbox(sc
, OP_ABORT_ECB
, ecb
);