1 /* $NetBSD: btl.c,v 1.23 2009/11/27 03:23:04 rmind Exp $ */
2 /* NetBSD: bt.c,v 1.10 1996/05/12 23:51:54 mycroft Exp */
7 #define notyet /* XXX - #undef this, if this driver does actually work */
10 * Copyright (c) 1994, 1996 Charles M. Hannum. All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by Charles M. Hannum.
23 * 4. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 * Originally written by Julian Elischer (julian@tfs.com)
40 * for TRW Financial Systems for use under the MACH(2.5) operating system.
42 * TRW Financial Systems, in accordance with their agreement with Carnegie
43 * Mellon University, makes this software available to CMU to distribute
44 * or use in any manner that they see fit as long as this message is kept with
45 * the software. For this reason TFS also grants any other persons or
46 * organisations permission to use or modify this software.
48 * TFS supplies this software to be publicly redistributed
49 * on the understanding that TFS is not responsible for the correct
50 * functioning of this software in any circumstances.
53 #include <sys/cdefs.h>
54 __KERNEL_RCSID(0, "$NetBSD: btl.c,v 1.23 2009/11/27 03:23:04 rmind Exp $");
56 #include <sys/types.h>
57 #include <sys/param.h>
58 #include <sys/systm.h>
59 #include <sys/kernel.h>
60 #include <sys/errno.h>
61 #include <sys/malloc.h>
62 #include <sys/ioctl.h>
63 #include <sys/device.h>
67 #include <machine/intr.h>
68 #include <machine/pio.h>
70 #include <arc/dti/desktech.h>
72 #include <dev/scsipi/scsi_all.h>
73 #include <dev/scsipi/scsipi_all.h>
74 #include <dev/scsipi/scsiconf.h>
76 #include <dev/isa/isavar.h>
77 #include <arc/dti/btlreg.h>
78 #include <arc/dti/btlvar.h>
81 #define Debugger() panic("should call debugger here (bt742a.c)")
86 * these could be bigger but we need the bt_softc to fit on a single page..
88 #define BT_MBX_SIZE 32 /* mail box size (MAX 255 MBxs) */
89 /* don't need that many really */
90 #define BT_CCB_MAX 32 /* store up to 32 CCBs at one time */
91 #define CCB_HASH_SIZE 32 /* hash table size for phystokv */
92 #define CCB_HASH_SHIFT 9
93 #define CCB_HASH(x) ((((long)(x))>>CCB_HASH_SHIFT) & (CCB_HASH_SIZE - 1))
95 #define bt_nextmbx(wmb, mbx, mbio) \
96 if ((wmb) == &(mbx)->mbio[BT_MBX_SIZE - 1]) \
97 (wmb) = &(mbx)->mbio[0]; \
102 struct bt_mbx_out mbo
[BT_MBX_SIZE
];
103 struct bt_mbx_in mbi
[BT_MBX_SIZE
];
104 struct bt_mbx_out
*cmbo
; /* Collection Mail Box out */
105 struct bt_mbx_out
*tmbo
; /* Target Mail Box out */
106 struct bt_mbx_in
*tmbi
; /* Target Mail Box in */
109 #define KVTOPHYS(x) (*btl_conf->bc_kvtophys)((int)(x))
110 #define PHYSTOKV(x) (*btl_conf->bc_phystokv)((int)(x))
122 struct bt_mbx
*sc_mbx
; /* all our mailboxes */
123 #define wmbx (sc->sc_mbx)
124 struct bt_ccb
*sc_ccbhash
[CCB_HASH_SIZE
];
125 TAILQ_HEAD(, bt_ccb
) sc_free_ccb
, sc_waiting_ccb
;
126 TAILQ_HEAD(, bt_buf
) sc_free_buf
;
127 int sc_numccbs
, sc_mbofull
;
129 int sc_scsi_dev
; /* adapters scsi id */
130 struct scsipi_link sc_link
; /* prototype for devs */
131 struct scsipi_adapter sc_adapter
;
138 int bt_cmd(int, struct bt_softc
*, int, u_char
*, int, u_char
*);
139 integrate
void bt_finish_ccbs(struct bt_softc
*);
141 integrate
void bt_reset_ccb(struct bt_softc
*, struct bt_ccb
*);
142 void bt_free_ccb(struct bt_softc
*, struct bt_ccb
*);
143 integrate
void bt_init_ccb(struct bt_softc
*, struct bt_ccb
*);
144 struct bt_ccb
*bt_get_ccb(struct bt_softc
*, int);
145 struct bt_ccb
*bt_ccb_phys_kv(struct bt_softc
*, u_long
);
146 void bt_queue_ccb(struct bt_softc
*, struct bt_ccb
*);
147 void bt_collect_mbo(struct bt_softc
*);
148 void bt_start_ccbs(struct bt_softc
*);
149 void bt_done(struct bt_softc
*, struct bt_ccb
*);
150 int bt_find(struct isa_attach_args
*, struct bt_softc
*);
151 void bt_init(struct bt_softc
*);
152 void bt_inquire_setup_information(struct bt_softc
*);
153 void btminphys(struct buf
*);
154 int bt_scsi_cmd(struct scsipi_xfer
*);
155 int bt_poll(struct bt_softc
*, struct scsipi_xfer
*, int);
156 void bt_timeout(void *arg
);
157 void bt_free_buf(struct bt_softc
*, struct bt_buf
*);
158 struct bt_buf
* bt_get_buf(struct bt_softc
*, int);
160 /* the below structure is so we have a default dev struct for out link struct */
161 struct scsipi_device bt_dev
= {
162 NULL
, /* Use default error handler */
163 NULL
, /* have a queue, served by this */
164 NULL
, /* have no async handler */
165 NULL
, /* Use default 'done' routine */
168 static int btprobe(device_t
, cfdata_t
, void *);
169 static void btattach(device_t
, device_t
, void *);
171 CFATTACH_DECL_NEW(btl
, sizeof(struct bt_softc
),
172 btprobe
, btattach
, NULL
, NULL
);
174 #define BT_RESET_TIMEOUT 2000 /* time to wait for reset (mSec) */
175 #define BT_ABORT_TIMEOUT 2000 /* time to wait for abort (mSec) */
177 struct btl_config
*btl_conf
= NULL
;
180 * bt_cmd(iobase, sc, icnt, ibuf, ocnt, obuf)
182 * Activate Adapter command
183 * icnt: number of args (outbound bytes including opcode)
184 * ibuf: argument buffer
185 * ocnt: number of expected returned bytes
186 * obuf: result buffer
187 * wait: number of seconds to wait for response
189 * Performs an adapter command through the ports. Not to be confused with a
190 * scsi command, which is read in via the DMA; one of the adapter commands
191 * tells it to read in a scsi command.
194 bt_cmd(int iobase
, struct bt_softc
*sc
, int icnt
, int ocnt
, u_char
*ibuf
,
201 u_char opcode
= ibuf
[0];
204 name
= device_xname(sc
->sc_dev
);
209 * Calculate a reasonable timeout for the command.
212 case BT_INQUIRE_DEVICES
:
221 * Wait for the adapter to go idle, unless it's one of
222 * the commands which don't need this
224 if (opcode
!= BT_MBO_INTR_EN
) {
225 for (i
= 20000; i
; i
--) { /* 1 sec? */
226 sts
= isa_inb(iobase
+ BT_STAT_PORT
);
227 if (sts
& BT_STAT_IDLE
)
232 printf("%s: bt_cmd, host not idle(0x%x)\n",
238 * Now that it is idle, if we expect output, preflush the
239 * queue feeding to us.
242 while ((isa_inb(iobase
+ BT_STAT_PORT
)) & BT_STAT_DF
)
243 isa_inb(iobase
+ BT_DATA_PORT
);
246 * Output the command and the number of arguments given
247 * for each byte, first check the port is empty.
250 for (i
= wait
; i
; i
--) {
251 sts
= isa_inb(iobase
+ BT_STAT_PORT
);
252 if (!(sts
& BT_STAT_CDF
))
257 if (opcode
!= BT_INQUIRE_REVISION
&&
258 opcode
!= BT_INQUIRE_REVISION_3
)
259 printf("%s: bt_cmd, cmd/data port full\n", name
);
260 isa_outb(iobase
+ BT_CTRL_PORT
, BT_CTRL_SRST
);
263 isa_outb(iobase
+ BT_CMD_PORT
, *ibuf
++);
266 * If we expect input, loop that many times, each time,
267 * looking for the data register to have valid data
270 for (i
= wait
; i
; i
--) {
271 sts
= isa_inb(iobase
+ BT_STAT_PORT
);
272 if (sts
& BT_STAT_DF
)
277 if (opcode
!= BT_INQUIRE_REVISION
&&
278 opcode
!= BT_INQUIRE_REVISION_3
)
279 printf("%s: bt_cmd, cmd/data port empty %d\n",
281 isa_outb(iobase
+ BT_CTRL_PORT
, BT_CTRL_SRST
);
284 *obuf
++ = isa_inb(iobase
+ BT_DATA_PORT
);
287 * Wait for the board to report a finished instruction.
288 * We may get an extra interrupt for the HACC signal, but this is
291 if (opcode
!= BT_MBO_INTR_EN
) {
292 for (i
= 20000; i
; i
--) { /* 1 sec? */
293 sts
= isa_inb(iobase
+ BT_INTR_PORT
);
294 /* XXX Need to save this in the interrupt handler? */
295 if (sts
& BT_INTR_HACC
)
300 printf("%s: bt_cmd, host not finished(0x%x)\n",
305 isa_outb(iobase
+ BT_CTRL_PORT
, BT_CTRL_IRST
);
310 * Check if the device can be found at the port given
311 * and if so, set it up ready for further work
312 * as an argument, takes the isa_device structure from
316 btprobe(device_t parent
, cfdata_t cf
, void *aux
)
318 struct isa_attach_args
*ia
= aux
;
321 if (ia
->ia_iobase
== IOBASEUNK
)
325 if (btl_conf
== NULL
)
328 /* See if there is a unit at this location. */
329 if (bt_find(ia
, NULL
) != 0)
334 /* IRQ and DRQ set by bt_find(). */
339 * Attach all the sub-devices we can find
342 btattach(device_t parent
, device_t self
, void *aux
)
344 struct isa_attach_args
*ia
= aux
;
345 struct bt_softc
*sc
= device_private(self
);
354 if (bt_find(ia
, sc
) != 0)
355 panic("btattach: bt_find of %s failed", self
->dv_xname
);
356 sc
->sc_iobase
= ia
->ia_iobase
;
361 (*btl_conf
->bc_bouncemem
)(&bouncebase
, &bouncesize
);
362 bouncearea
= bouncebase
+ sizeof(struct bt_mbx
);
363 sc
->sc_mbx
= (struct bt_mbx
*)bouncebase
;
365 bt_inquire_setup_information(sc
);
367 TAILQ_INIT(&sc
->sc_free_ccb
);
368 TAILQ_INIT(&sc
->sc_free_buf
);
369 TAILQ_INIT(&sc
->sc_waiting_ccb
);
374 while (sc
->sc_numccbs
< BT_CCB_MAX
) {
375 ccb
= (struct bt_ccb
*)bouncearea
;
376 bouncearea
+= sizeof(struct bt_ccb
);
377 bt_init_ccb(sc
, ccb
);
378 TAILQ_INSERT_HEAD(&sc
->sc_free_ccb
, ccb
, chain
);
382 * fill up with bufs's
384 while ((bouncearea
+ sizeof(struct bt_buf
)) < bouncebase
+ bouncesize
) {
385 buf
= (struct bt_buf
*)bouncearea
;
386 bouncearea
+= sizeof(struct bt_buf
);
387 TAILQ_INSERT_HEAD(&sc
->sc_free_buf
, buf
, chain
);
391 * Fill in the adapter.
393 sc
->sc_adapter
.scsipi_cmd
= bt_scsi_cmd
;
394 sc
->sc_adapter
.scsipi_minphys
= btminphys
;
396 * fill in the prototype scsipi_link.
398 sc
->sc_link
.scsipi_scsi
.channel
= SCSI_CHANNEL_ONLY_ONE
;
399 sc
->sc_link
.adapter_softc
= sc
;
400 sc
->sc_link
.scsipi_scsi
.adapter_target
= sc
->sc_scsi_dev
;
401 sc
->sc_link
.adapter
= &sc
->sc_adapter
;
402 sc
->sc_link
.device
= &bt_dev
;
403 sc
->sc_link
.openings
= 1;
404 sc
->sc_link
.scsipi_scsi
.max_target
= 7;
405 sc
->sc_link
.scsipi_scsi
.max_lun
= 7;
406 sc
->sc_link
.type
= BUS_SCSI
;
408 sc
->sc_ih
= isa_intr_establish(ia
->ia_ic
, sc
->sc_irq
, IST_EDGE
,
409 IPL_BIO
, btintr
, sc
);
412 * ask the adapter what subunits are present
414 config_found(self
, &sc
->sc_link
, scsiprint
);
418 bt_finish_ccbs(struct bt_softc
*sc
)
420 struct bt_mbx_in
*wmbi
;
426 if (wmbi
->stat
== BT_MBI_FREE
) {
427 for (i
= 0; i
< BT_MBX_SIZE
; i
++) {
428 if (wmbi
->stat
!= BT_MBI_FREE
) {
429 printf("%s: mbi not in round-robin order\n",
430 device_xname(sc
->sc_dev
));
433 bt_nextmbx(wmbi
, wmbx
, mbi
);
436 printf("%s: mbi interrupt with no full mailboxes\n",
437 device_xname(sc
->sc_dev
));
444 ccb
= bt_ccb_phys_kv(sc
, phystol(wmbi
->ccb_addr
));
446 printf("%s: bad mbi ccb pointer; skipping\n",
447 device_xname(sc
->sc_dev
));
453 u_char
*cp
= (u_char
*) &ccb
->scsi_cmd
;
454 printf("op=%x %x %x %x %x %x\n",
455 cp
[0], cp
[1], cp
[2], cp
[3], cp
[4], cp
[5]);
456 printf("stat %x for mbi addr = 0x%08x, ",
458 printf("ccb addr = 0x%x\n", ccb
);
462 switch (wmbi
->stat
) {
465 if ((ccb
->flags
& CCB_ABORT
) != 0) {
467 * If we already started an abort, wait for it
468 * to complete before clearing the CCB. We
469 * could instead just clear CCB_SENDING, but
470 * what if the mailbox was already received?
471 * The worst that happens here is that we clear
472 * the CCB a bit later than we need to. BFD.
481 * Even if the CCB wasn't found, we clear it anyway.
482 * See preceding comment.
487 printf("%s: bad mbi status %02x; skipping\n",
488 device_xname(sc
->sc_dev
), wmbi
->stat
);
492 callout_stop(&ccb
->xs
->xs_callout
);
496 wmbi
->stat
= BT_MBI_FREE
;
497 bt_nextmbx(wmbi
, wmbx
, mbi
);
498 } while (wmbi
->stat
!= BT_MBI_FREE
);
504 * Catch an interrupt from the adaptor
509 struct bt_softc
*sc
= arg
;
510 int iobase
= sc
->sc_iobase
;
514 printf("%s: btintr ", device_xname(sc
->sc_dev
));
518 * First acknowlege the interrupt, Then if it's not telling about
519 * a completed operation just return.
521 sts
= isa_inb(iobase
+ BT_INTR_PORT
);
522 if ((sts
& BT_INTR_ANYINTR
) == 0)
524 isa_outb(iobase
+ BT_CTRL_PORT
, BT_CTRL_IRST
);
527 /* Make sure we clear CCB_SENDING before finishing a CCB. */
531 /* Mail box out empty? */
532 if (sts
& BT_INTR_MBOA
) {
533 struct bt_toggle toggle
;
535 toggle
.cmd
.opcode
= BT_MBO_INTR_EN
;
536 toggle
.cmd
.enable
= 0;
537 bt_cmd(iobase
, sc
, sizeof(toggle
.cmd
), (u_char
*)&toggle
.cmd
, 0,
542 /* Mail box in full? */
543 if (sts
& BT_INTR_MBIF
)
550 bt_reset_ccb(struct bt_softc
*sc
, struct bt_ccb
*ccb
)
557 * A ccb is put onto the free list.
560 bt_free_ccb(struct bt_softc
*sc
, struct bt_ccb
*ccb
)
566 bt_reset_ccb(sc
, ccb
);
567 TAILQ_INSERT_HEAD(&sc
->sc_free_ccb
, ccb
, chain
);
570 * If there were none, wake anybody waiting for one to come free,
571 * starting with queued entries.
573 if (ccb
->chain
.tqe_next
== 0)
574 wakeup(&sc
->sc_free_ccb
);
580 * A buf is put onto the free list.
583 bt_free_buf(struct bt_softc
*sc
, struct bt_buf
*buf
)
589 TAILQ_INSERT_HEAD(&sc
->sc_free_buf
, buf
, chain
);
593 * If there were none, wake anybody waiting for one to come free,
594 * starting with queued entries.
596 if (buf
->chain
.tqe_next
== 0)
597 wakeup(&sc
->sc_free_buf
);
603 bt_init_ccb(struct bt_softc
*sc
, struct bt_ccb
*ccb
)
607 memset(ccb
, 0, sizeof(struct bt_ccb
));
609 * put in the phystokv hash table
610 * Never gets taken out.
612 ccb
->hashkey
= KVTOPHYS(ccb
);
613 hashnum
= CCB_HASH(ccb
->hashkey
);
614 ccb
->nexthash
= sc
->sc_ccbhash
[hashnum
];
615 sc
->sc_ccbhash
[hashnum
] = ccb
;
616 bt_reset_ccb(sc
, ccb
);
622 * If there are none, either return an error or sleep.
625 bt_get_ccb(struct bt_softc
*sc
, int nosleep
)
633 * If we can and have to, sleep waiting for one to come free.
636 ccb
= sc
->sc_free_ccb
.tqh_first
;
638 TAILQ_REMOVE(&sc
->sc_free_ccb
, ccb
, chain
);
643 tsleep(&sc
->sc_free_ccb
, PRIBIO
, "btccb", 0);
646 ccb
->flags
|= CCB_ALLOC
;
656 * If there are none, either return an error or sleep.
659 bt_get_buf(struct bt_softc
*sc
, int nosleep
)
667 * If we can and have to, sleep waiting for one to come free.
670 buf
= sc
->sc_free_buf
.tqh_first
;
672 TAILQ_REMOVE(&sc
->sc_free_buf
, buf
, chain
);
678 tsleep(&sc
->sc_free_buf
, PRIBIO
, "btbuf", 0);
687 * Given a physical address, find the ccb that it corresponds to.
690 bt_ccb_phys_kv(struct bt_softc
*sc
, u_long ccb_phys
)
692 int hashnum
= CCB_HASH(ccb_phys
);
693 struct bt_ccb
*ccb
= sc
->sc_ccbhash
[hashnum
];
696 if (ccb
->hashkey
== ccb_phys
)
704 * Queue a CCB to be sent to the controller, and send it if possible.
707 bt_queue_ccb(struct bt_softc
*sc
, struct bt_ccb
*ccb
)
710 TAILQ_INSERT_TAIL(&sc
->sc_waiting_ccb
, ccb
, chain
);
715 * Garbage collect mailboxes that are no longer in use.
718 bt_collect_mbo(struct bt_softc
*sc
)
720 struct bt_mbx_out
*wmbo
; /* Mail Box Out pointer */
724 while (sc
->sc_mbofull
> 0) {
725 if (wmbo
->cmd
!= BT_MBO_FREE
)
729 ccb
= bt_ccb_phys_kv(sc
, phystol(wmbo
->ccb_addr
));
730 ccb
->flags
&= ~CCB_SENDING
;
734 bt_nextmbx(wmbo
, wmbx
, mbo
);
741 * Send as many CCBs as we have empty mailboxes for.
744 bt_start_ccbs(struct bt_softc
*sc
)
746 int iobase
= sc
->sc_iobase
;
747 struct bt_mbx_out
*wmbo
; /* Mail Box Out pointer */
752 while ((ccb
= sc
->sc_waiting_ccb
.tqh_first
) != NULL
) {
753 if (sc
->sc_mbofull
>= BT_MBX_SIZE
) {
755 if (sc
->sc_mbofull
>= BT_MBX_SIZE
) {
756 struct bt_toggle toggle
;
758 toggle
.cmd
.opcode
= BT_MBO_INTR_EN
;
759 toggle
.cmd
.enable
= 1;
760 bt_cmd(iobase
, sc
, sizeof(toggle
.cmd
),
761 (u_char
*)&toggle
.cmd
, 0, (u_char
*)0);
766 TAILQ_REMOVE(&sc
->sc_waiting_ccb
, ccb
, chain
);
768 ccb
->flags
|= CCB_SENDING
;
771 /* Link ccb to mbo. */
772 ltophys(KVTOPHYS(ccb
), wmbo
->ccb_addr
);
773 if (ccb
->flags
& CCB_ABORT
)
774 wmbo
->cmd
= BT_MBO_ABORT
;
776 wmbo
->cmd
= BT_MBO_START
;
778 /* Tell the card to poll immediately. */
779 isa_outb(iobase
+ BT_CMD_PORT
, BT_START_SCSI
);
781 if ((ccb
->xs
->xs_control
& XS_CTL_POLL
) == 0)
782 callout_reset(&ccb
->xs
->xs_callout
,
783 mstohz(ccb
->timeout
), bt_timeout
, ccb
);
786 bt_nextmbx(wmbo
, wmbx
, mbo
);
793 * We have a ccb which has been processed by the
794 * adaptor, now we look to see how the operation
795 * went. Wake up the owner if waiting
798 bt_done(struct bt_softc
*sc
, struct bt_ccb
*ccb
)
800 struct scsi_sense_data
*s1
, *s2
;
801 struct scsipi_xfer
*xs
= ccb
->xs
;
803 u_long thiskv
, thisbounce
;
804 int bytes_this_page
, datalen
;
805 struct bt_scat_gath
*sg
;
808 SC_DEBUG(xs
->sc_link
, SDEV_DB2
, ("bt_done\n"));
810 * Otherwise, put the results of the operation
811 * into the xfer and call whoever started it
814 if (ccb
->flags
& CCB_SENDING
) {
815 printf("%s: exiting ccb still in transit!\n",
816 device_xname(sc
->sc_dev
));
821 if ((ccb
->flags
& CCB_ALLOC
) == 0) {
822 printf("%s: exiting ccb not allocated!\n",
823 device_xname(sc
->sc_dev
));
827 if (xs
->error
== XS_NOERROR
) {
828 if (ccb
->host_stat
!= BT_OK
) {
829 switch (ccb
->host_stat
) {
830 case BT_SEL_TIMEOUT
: /* No response */
831 xs
->error
= XS_SELTIMEOUT
;
833 default: /* Other scsi protocol messes */
834 printf("%s: host_stat %x\n",
835 device_xname(sc
->sc_dev
), ccb
->host_stat
);
836 xs
->error
= XS_DRIVER_STUFFUP
;
839 } else if (ccb
->target_stat
!= SCSI_OK
) {
840 switch (ccb
->target_stat
) {
842 s1
= &ccb
->scsi_sense
;
843 s2
= &xs
->sense
.scsi_sense
;
845 xs
->error
= XS_SENSE
;
851 printf("%s: target_stat %x\n",
852 device_xname(sc
->sc_dev
), ccb
->target_stat
);
853 xs
->error
= XS_DRIVER_STUFFUP
;
860 if((datalen
= xs
->datalen
) != 0) {
861 thiskv
= (int)xs
->data
;
863 seg
= phystol(ccb
->data_length
) / sizeof(struct bt_scat_gath
);
866 thisbounce
= PHYSTOKV(phystol(sg
->seg_addr
));
867 bytes_this_page
= phystol(sg
->seg_len
);
868 if(xs
->xs_control
& XS_CTL_DATA_IN
) {
869 memcpy((void *)thiskv
, (void *)thisbounce
, bytes_this_page
);
871 bt_free_buf(sc
, (struct bt_buf
*)thisbounce
);
872 thiskv
+= bytes_this_page
;
873 datalen
-= bytes_this_page
;
880 bt_free_ccb(sc
, ccb
);
881 xs
->xs_status
|= XS_STS_DONE
;
886 * Find the board and find it's irq/drq
889 bt_find(struct isa_attach_args
*ia
, struct bt_softc
*sc
)
891 int iobase
= ia
->ia_iobase
;
894 struct bt_extended_inquire inquire
;
895 struct bt_config config
;
899 /* Check something is at the ports we need to access */
900 sts
= isa_inb(iobase
+ BHA_STAT_PORT
);
906 * reset board, If it doesn't respond, assume
907 * that it's not there.. good for the probe
910 isa_outb(iobase
+ BT_CTRL_PORT
, BT_CTRL_HRST
| BT_CTRL_SRST
);
913 for (i
= BT_RESET_TIMEOUT
; i
; i
--) {
914 sts
= isa_inb(iobase
+ BT_STAT_PORT
);
915 if (sts
== (BT_STAT_IDLE
| BT_STAT_INIT
))
922 printf("bt_find: No answer from buslogic board\n");
929 * The BusLogic cards implement an Adaptec 1542 (aha)-compatible
930 * interface. The native bha interface is not compatible with
931 * an aha. 1542. We need to ensure that we never match an
932 * Adaptec 1542. We must also avoid sending Adaptec-compatible
933 * commands to a real bha, lest it go into 1542 emulation mode.
934 * (On an indirect bus like ISA, we should always probe for BusLogic
935 * interfaces before Adaptec interfaces).
939 * Make sure we don't match an AHA-1542A or AHA-1542B, by checking
940 * for an extended-geometry register. The 1542[AB] don't have one.
942 sts
= isa_inb(iobase
+ BT_EXTGEOM_PORT
);
948 * Check that we actually know how to use this board.
951 memset(&inquire
, 0, sizeof inquire
);
952 inquire
.cmd
.opcode
= BT_INQUIRE_EXTENDED
;
953 inquire
.cmd
.len
= sizeof(inquire
.reply
);
954 i
= bt_cmd(iobase
, sc
, sizeof(inquire
.cmd
), (u_char
*)&inquire
.cmd
,
955 sizeof(inquire
.reply
), (u_char
*)&inquire
.reply
);
959 * Some 1542Cs (CP, perhaps not CF, may depend on firmware rev)
960 * have the extended-geometry register and also respond to
961 * BHA_INQUIRE_EXTENDED. Make sure we never match such cards,
962 * by checking the size of the reply is what a BusLogic card returns.
964 if (i
) { /* XXX - this doesn't really check the size. ??? see bha.c */
966 printf("bt_find: board returned %d instead of %d to %s\n",
967 i
, sizeof(inquire
.reply
), "INQUIRE_EXTENDED");
972 /* OK, we know we've found a buslogic adaptor. */
975 switch (inquire
.reply
.bus_type
) {
976 case BT_BUS_TYPE_24BIT
:
977 case BT_BUS_TYPE_32BIT
:
979 case BT_BUS_TYPE_MCA
:
980 /* We don't grok MicroChannel (yet). */
983 printf("bt_find: illegal bus type %c\n", inquire
.reply
.bus_type
);
988 * Assume we have a board at this stage setup DMA channel from
989 * jumpers and save int level
992 config
.cmd
.opcode
= BT_INQUIRE_CONFIG
;
993 bt_cmd(iobase
, sc
, sizeof(config
.cmd
), (u_char
*)&config
.cmd
,
994 sizeof(config
.reply
), (u_char
*)&config
.reply
);
995 switch (config
.reply
.chan
) {
1012 printf("bt_find: illegal drq setting %x\n", config
.reply
.chan
);
1016 switch (config
.reply
.intr
) {
1036 printf("bt_find: illegal irq setting %x\n", config
.reply
.intr
);
1041 /* who are we on the scsi bus? */
1042 sc
->sc_scsi_dev
= config
.reply
.scsi_dev
;
1044 sc
->sc_iobase
= iobase
;
1048 if (ia
->ia_irq
== IRQUNK
)
1050 else if (ia
->ia_irq
!= irq
)
1052 if (ia
->ia_drq
== DRQUNK
)
1054 else if (ia
->ia_drq
!= drq
)
1062 * Start the board, ready for normal operation
1065 bt_init(struct bt_softc
*sc
)
1067 int iobase
= sc
->sc_iobase
;
1068 struct bt_devices devices
;
1069 struct bt_setup setup
;
1070 struct bt_mailbox mailbox
;
1071 struct bt_period period
;
1074 /* Enable round-robin scheme - appeared at firmware rev. 3.31. */
1075 if (strcmp(sc
->sc_firmware
, "3.31") >= 0) {
1076 struct bt_toggle toggle
;
1078 toggle
.cmd
.opcode
= BT_ROUND_ROBIN
;
1079 toggle
.cmd
.enable
= 1;
1080 bt_cmd(iobase
, sc
, sizeof(toggle
.cmd
), (u_char
*)&toggle
.cmd
,
1084 /* Inquire Installed Devices (to force synchronous negotiation). */
1085 devices
.cmd
.opcode
= BT_INQUIRE_DEVICES
;
1086 bt_cmd(iobase
, sc
, sizeof(devices
.cmd
), (u_char
*)&devices
.cmd
,
1087 sizeof(devices
.reply
), (u_char
*)&devices
.reply
);
1089 /* Obtain setup information from. */
1090 setup
.cmd
.opcode
= BT_INQUIRE_SETUP
;
1091 setup
.cmd
.len
= sizeof(setup
.reply
);
1092 bt_cmd(iobase
, sc
, sizeof(setup
.cmd
), (u_char
*)&setup
.cmd
,
1093 sizeof(setup
.reply
), (u_char
*)&setup
.reply
);
1095 printf("%s: %s, %s\n",
1096 device_xname(sc
->sc_dev
),
1097 setup
.reply
.sync_neg
? "sync" : "async",
1098 setup
.reply
.parity
? "parity" : "no parity");
1100 for (i
= 0; i
< 8; i
++)
1101 period
.reply
.period
[i
] = setup
.reply
.sync
[i
].period
* 5 + 20;
1103 if (sc
->sc_firmware
[0] >= '3') {
1104 period
.cmd
.opcode
= BT_INQUIRE_PERIOD
;
1105 period
.cmd
.len
= sizeof(period
.reply
);
1106 bt_cmd(iobase
, sc
, sizeof(period
.cmd
), (u_char
*)&period
.cmd
,
1107 sizeof(period
.reply
), (u_char
*)&period
.reply
);
1110 for (i
= 0; i
< 8; i
++) {
1111 if (!setup
.reply
.sync
[i
].valid
||
1112 (!setup
.reply
.sync
[i
].offset
&& !setup
.reply
.sync
[i
].period
))
1114 printf("%s targ %d: sync, offset %d, period %dnsec\n",
1115 device_xname(sc
->sc_dev
), i
,
1116 setup
.reply
.sync
[i
].offset
, period
.reply
.period
[i
] * 10);
1120 * Set up initial mail box for round-robin operation.
1122 for (i
= 0; i
< BT_MBX_SIZE
; i
++) {
1123 wmbx
->mbo
[i
].cmd
= BT_MBO_FREE
;
1124 wmbx
->mbi
[i
].stat
= BT_MBI_FREE
;
1126 wmbx
->cmbo
= wmbx
->tmbo
= &wmbx
->mbo
[0];
1127 wmbx
->tmbi
= &wmbx
->mbi
[0];
1130 /* Initialize mail box. */
1131 mailbox
.cmd
.opcode
= BT_MBX_INIT_EXTENDED
;
1132 mailbox
.cmd
.nmbx
= BT_MBX_SIZE
;
1133 ltophys(KVTOPHYS(wmbx
), mailbox
.cmd
.addr
);
1134 bt_cmd(iobase
, sc
, sizeof(mailbox
.cmd
), (u_char
*)&mailbox
.cmd
,
1139 bt_inquire_setup_information(struct bt_softc
*sc
)
1141 int iobase
= sc
->sc_iobase
;
1142 struct bt_model model
;
1143 struct bt_revision revision
;
1144 struct bt_digit digit
;
1148 * Get the firmware revision.
1150 p
= sc
->sc_firmware
;
1151 revision
.cmd
.opcode
= BT_INQUIRE_REVISION
;
1152 bt_cmd(iobase
, sc
, sizeof(revision
.cmd
), (u_char
*)&revision
.cmd
,
1153 sizeof(revision
.reply
), (u_char
*)&revision
.reply
);
1154 *p
++ = revision
.reply
.firm_revision
;
1156 *p
++ = revision
.reply
.firm_version
;
1157 digit
.cmd
.opcode
= BT_INQUIRE_REVISION_3
;
1158 bt_cmd(iobase
, sc
, sizeof(digit
.cmd
), (u_char
*)&digit
.cmd
,
1159 sizeof(digit
.reply
), (u_char
*)&digit
.reply
);
1160 *p
++ = digit
.reply
.digit
;
1161 if (revision
.reply
.firm_revision
>= '3' ||
1162 (revision
.reply
.firm_revision
== '3' && revision
.reply
.firm_version
>= '3')) {
1163 digit
.cmd
.opcode
= BT_INQUIRE_REVISION_4
;
1164 bt_cmd(iobase
, sc
, sizeof(digit
.cmd
), (u_char
*)&digit
.cmd
,
1165 sizeof(digit
.reply
), (u_char
*)&digit
.reply
);
1166 *p
++ = digit
.reply
.digit
;
1168 while (p
> sc
->sc_firmware
&& (p
[-1] == ' ' || p
[-1] == '\0'))
1173 * Get the model number.
1175 if (revision
.reply
.firm_revision
>= '3') {
1177 model
.cmd
.opcode
= BT_INQUIRE_MODEL
;
1178 model
.cmd
.len
= sizeof(model
.reply
);
1179 bt_cmd(iobase
, sc
, sizeof(model
.cmd
), (u_char
*)&model
.cmd
,
1180 sizeof(model
.reply
), (u_char
*)&model
.reply
);
1181 *p
++ = model
.reply
.id
[0];
1182 *p
++ = model
.reply
.id
[1];
1183 *p
++ = model
.reply
.id
[2];
1184 *p
++ = model
.reply
.id
[3];
1185 while (p
> sc
->sc_model
&& (p
[-1] == ' ' || p
[-1] == '\0'))
1187 *p
++ = model
.reply
.version
[0];
1188 *p
++ = model
.reply
.version
[1];
1189 while (p
> sc
->sc_model
&& (p
[-1] == ' ' || p
[-1] == '\0'))
1193 strcpy(sc
->sc_model
, "542B");
1195 printf(": model BT-%s, firmware %s\n", sc
->sc_model
, sc
->sc_firmware
);
1199 btminphys(struct buf
*bp
)
1202 if (bp
->b_bcount
> ((BT_NSEG
- 1) << PGSHIFT
))
1203 bp
->b_bcount
= ((BT_NSEG
- 1) << PGSHIFT
);
1208 * start a scsi operation given the command and the data address. Also needs
1209 * the unit, target and lu.
1212 bt_scsi_cmd(struct scsipi_xfer
*xs
)
1214 struct scsipi_link
*sc_link
= xs
->sc_link
;
1215 struct bt_softc
*sc
= sc_link
->adapter_softc
;
1217 struct bt_scat_gath
*sg
;
1218 int seg
; /* scatter gather seg being worked on */
1219 u_long thiskv
, thisbounce
;
1220 int bytes_this_page
, datalen
, control
;
1223 SC_DEBUG(sc_link
, SDEV_DB2
, ("bt_scsi_cmd\n"));
1225 * get a ccb to use. If the transfer
1226 * is from a buf (possibly from interrupt time)
1227 * then we can't allow it to sleep
1229 control
= xs
->xs_control
;
1230 if ((ccb
= bt_get_ccb(sc
, control
& XS_CTL_NOSLEEP
)) == NULL
) {
1231 xs
->error
= XS_DRIVER_STUFFUP
;
1232 return TRY_AGAIN_LATER
;
1235 ccb
->timeout
= xs
->timeout
;
1238 * Put all the arguments for the xfer in the ccb
1240 if (control
& XS_CTL_RESET
) {
1241 ccb
->opcode
= BT_RESET_CCB
;
1242 ccb
->scsi_cmd_length
= 0;
1244 /* can't use S/G if zero length */
1245 if (xs
->cmdlen
> sizeof(ccb
->scsi_cmd
)) {
1246 printf("%s: cmdlen %d too large for CCB\n",
1247 device_xname(sc
->sc_dev
), xs
->cmdlen
);
1248 xs
->error
= XS_DRIVER_STUFFUP
;
1249 bt_free_ccb(sc
, ccb
);
1252 ccb
->opcode
= (xs
->datalen
? BT_INIT_SCAT_GATH_CCB
1253 : BT_INITIATOR_CCB
);
1254 memcpy(&ccb
->scsi_cmd
, xs
->cmd
,
1255 ccb
->scsi_cmd_length
= xs
->cmdlen
);
1259 sg
= ccb
->scat_gath
;
1262 * Set up the scatter-gather block.
1264 SC_DEBUG(sc_link
, SDEV_DB4
,
1265 ("%d @0x%x:- ", xs
->datalen
, xs
->data
));
1267 datalen
= xs
->datalen
;
1268 thiskv
= (int)xs
->data
;
1270 while (datalen
&& seg
< BT_NSEG
) {
1272 /* put in the base address of a buf */
1273 thisbounce
= (u_long
)
1274 bt_get_buf(sc
, control
& XS_CTL_NOSLEEP
);
1277 ltophys(KVTOPHYS(thisbounce
), sg
->seg_addr
);
1278 bytes_this_page
= min(sizeof(struct bt_buf
), datalen
);
1279 if (control
& XS_CTL_DATA_OUT
) {
1280 memcpy((void *)thisbounce
, (void *)thiskv
, bytes_this_page
);
1282 thiskv
+= bytes_this_page
;
1283 datalen
-= bytes_this_page
;
1285 ltophys(bytes_this_page
, sg
->seg_len
);
1289 SC_DEBUGN(sc_link
, SDEV_DB4
, ("\n"));
1291 printf("%s: bt_scsi_cmd, out of bufs %d of %d left.\n",
1292 device_xname(sc
->sc_dev
), datalen
, xs
->datalen
);
1295 ltophys(KVTOPHYS(ccb
->scat_gath
), ccb
->data_addr
);
1296 ltophys(seg
* sizeof(struct bt_scat_gath
), ccb
->data_length
);
1297 } else { /* No data xfer, use non S/G values */
1298 ltophys(0, ccb
->data_addr
);
1299 ltophys(0, ccb
->data_length
);
1304 ccb
->target
= sc_link
->scsipi_scsi
.target
;
1305 ccb
->lun
= sc_link
->scsipi_scsi
.lun
;
1306 ltophys(KVTOPHYS(&ccb
->scsi_sense
), ccb
->sense_ptr
);
1307 ccb
->req_sense_length
= sizeof(ccb
->scsi_sense
);
1308 ccb
->host_stat
= 0x00;
1309 ccb
->target_stat
= 0x00;
1311 ltophys(0, ccb
->link_addr
);
1314 bt_queue_ccb(sc
, ccb
);
1318 * Usually return SUCCESSFULLY QUEUED
1320 SC_DEBUG(sc_link
, SDEV_DB3
, ("cmd_sent\n"));
1321 if ((control
& XS_CTL_POLL
) == 0)
1322 return SUCCESSFULLY_QUEUED
;
1325 * If we can't use interrupts, poll on completion
1327 if (bt_poll(sc
, xs
, ccb
->timeout
)) {
1329 if (bt_poll(sc
, xs
, ccb
->timeout
))
1335 sg
= ccb
->scat_gath
;
1337 thisbounce
= PHYSTOKV(phystol(sg
->seg_addr
));
1338 bt_free_buf(sc
, (struct bt_buf
*)thisbounce
);
1342 xs
->error
= XS_DRIVER_STUFFUP
;
1343 bt_free_ccb(sc
, ccb
);
1344 return TRY_AGAIN_LATER
;
1348 * Poll a particular unit, looking for a particular xs
1351 bt_poll(struct bt_softc
*sc
, struct scsipi_xfer
*xs
, int count
)
1353 int iobase
= sc
->sc_iobase
;
1355 /* timeouts are in msec, so we loop in 1000 usec cycles */
1358 * If we had interrupts enabled, would we
1359 * have got an interrupt?
1361 if (isa_inb(iobase
+ BT_INTR_PORT
) & BT_INTR_ANYINTR
)
1363 if (xs
->xs_status
& XS_STS_DONE
)
1365 delay(1000); /* only happens in boot so ok */
1372 bt_timeout(void *arg
)
1374 struct bt_ccb
*ccb
= arg
;
1375 struct scsipi_xfer
*xs
= ccb
->xs
;
1376 struct scsipi_link
*sc_link
= xs
->sc_link
;
1377 struct bt_softc
*sc
= sc_link
->adapter_softc
;
1380 scsi_print_addr(sc_link
);
1381 printf("timed out");
1387 * If the ccb's mbx is not free, then the board has gone Far East?
1390 if (ccb
->flags
& CCB_SENDING
) {
1391 printf("%s: not taking commands!\n", device_xname(sc
->sc_dev
));
1397 * If it has been through before, then
1398 * a previous abort has failed, don't
1401 if (ccb
->flags
& CCB_ABORT
) {
1402 /* abort timed out */
1404 /* XXX Must reset! */
1406 /* abort the operation that has timed out */
1408 ccb
->xs
->error
= XS_TIMEOUT
;
1409 ccb
->timeout
= BT_ABORT_TIMEOUT
;
1410 ccb
->flags
|= CCB_ABORT
;
1411 bt_queue_ccb(sc
, ccb
);