1 /* $NetBSD: sbic.c,v 1.14 2009/03/18 10:22:22 cegger Exp $ */
4 * Copyright (c) 2001 Richard Earnshaw
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the company nor the name of the author may be used to
13 * endorse or promote products derived from this software without specific
14 * prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * POSSIBILITY OF SUCH DAMAGE.
28 * Copyright (c) 1990 The Regents of the University of California.
29 * All rights reserved.
31 * This code is derived from software contributed to Berkeley by
32 * Van Jacobson of Lawrence Berkeley Laboratory.
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions
37 * 1. Redistributions of source code must retain the above copyright
38 * notice, this list of conditions and the following disclaimer.
39 * 2. Redistributions in binary form must reproduce the above copyright
40 * notice, this list of conditions and the following disclaimer in the
41 * documentation and/or other materials provided with the distribution.
42 * 3. Neither the name of the University nor the names of its contributors
43 * may be used to endorse or promote products derived from this software
44 * without specific prior written permission.
46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * Copyright (c) 1994 Christian E. Hopps
60 * This code is derived from software contributed to Berkeley by
61 * Van Jacobson of Lawrence Berkeley Laboratory.
63 * Redistribution and use in source and binary forms, with or without
64 * modification, are permitted provided that the following conditions
66 * 1. Redistributions of source code must retain the above copyright
67 * notice, this list of conditions and the following disclaimer.
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in the
70 * documentation and/or other materials provided with the distribution.
71 * 3. All advertising materials mentioning features or use of this software
72 * must display the following acknowledgement:
73 * This product includes software developed by the University of
74 * California, Berkeley and its contributors.
75 * 4. Neither the name of the University nor the names of its contributors
76 * may be used to endorse or promote products derived from this software
77 * without specific prior written permission.
79 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
80 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
81 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
82 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
83 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
84 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
85 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
86 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
87 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
88 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
91 * from: sbic.c,v 1.21 1996/01/07 22:01:54
95 * WD 33C93 scsi adaptor driver
100 * The UPROTECTED_CSR code is bogus. It can read the csr (SCSI Status
101 * register) at times when an interrupt may be pending. Doing this will
102 * clear the interrupt, so we won't see it at times when we really need
105 #define UNPROTECTED_CSR
111 /* #define SBIC_DEBUG(a) a */
115 #include <sys/param.h>
117 __KERNEL_RCSID(0, "$NetBSD: sbic.c,v 1.14 2009/03/18 10:22:22 cegger Exp $");
119 #include <sys/systm.h>
120 #include <sys/callout.h>
121 #include <sys/kernel.h> /* For hz */
122 #include <sys/device.h>
125 #include <uvm/uvm_extern.h>
127 #include <machine/bus.h>
128 #include <machine/intr.h>
130 #include <dev/scsipi/scsi_all.h>
131 #include <dev/scsipi/scsipi_all.h>
132 #include <dev/scsipi/scsiconf.h>
134 #include <acorn32/podulebus/sbicreg.h>
135 #include <acorn32/podulebus/sbicvar.h>
139 * In u-seconds, primarily for state changes on the SPC.
141 #define SBIC_CMD_WAIT 50000 /* wait per step of 'immediate' cmds */
142 #define SBIC_DATA_WAIT 50000 /* wait per data in/out step */
143 #define SBIC_INIT_WAIT 50000 /* wait per step (both) during init */
145 #define SBIC_WAIT(regs, until, timeo) sbicwait(regs, until, timeo, __LINE__)
147 static int sbicicmd (struct sbic_softc
*, int, int,
149 static int sbicgo (struct sbic_softc
*, struct scsipi_xfer
*);
150 static int sbicwait (sbic_regmap_p
, char, int , int);
151 static int sbicselectbus (struct sbic_softc
*, sbic_regmap_p
, u_char
,
153 static int sbicxfstart (sbic_regmap_p
, int, u_char
, int);
154 static int sbicxfout (sbic_regmap_p regs
, int, void *, int);
155 static int sbicfromscsiperiod (struct sbic_softc
*, sbic_regmap_p
, int);
156 static int sbictoscsiperiod (struct sbic_softc
*, sbic_regmap_p
, int);
157 static int sbicpoll (struct sbic_softc
*);
158 static int sbicnextstate (struct sbic_softc
*, u_char
, u_char
);
159 static int sbicmsgin (struct sbic_softc
*);
160 static int sbicxfin (sbic_regmap_p regs
, int, void *);
161 static int sbicabort (struct sbic_softc
*, sbic_regmap_p
, const char *);
162 static void sbicxfdone (struct sbic_softc
*, sbic_regmap_p
, int);
163 static void sbicerror (struct sbic_softc
*, sbic_regmap_p
, u_char
);
164 static void sbicreset (struct sbic_softc
*);
165 static void sbic_scsidone (struct sbic_acb
*, int);
166 static void sbic_sched (struct sbic_softc
*);
167 static void sbic_save_ptrs (struct sbic_softc
*, sbic_regmap_p
);
170 * Synch xfer parameters, and timing conversions
172 int sbic_min_period
= SBIC_SYN_MIN_PERIOD
; /* in cycles = f(ICLK,FSn) */
173 int sbic_max_offset
= SBIC_SYN_MAX_OFFSET
; /* pure number */
175 int sbic_cmd_wait
= SBIC_CMD_WAIT
;
176 int sbic_data_wait
= SBIC_DATA_WAIT
;
177 int sbic_init_wait
= SBIC_INIT_WAIT
;
180 * was broken before.. now if you want this you get it for all drives
181 * on sbic controllers.
183 u_char sbic_inhibit_sync
[8];
184 int sbic_enable_reselect
= 1;
185 int sbic_clock_override
= 0;
186 int sbic_no_dma
= 1; /* was 0 */
187 int sbic_parallel_operations
= 1;
190 sbic_regmap_p debug_sbic_regs
;
191 int sbicdma_ops
= 0; /* total DMA operations */
192 int sbicdma_saves
= 0;
193 #define QPRINTF(a) if (sbic_debug > 1) printf a
194 #define DBGPRINTF(x,p) if (p) printf x
198 int sbic_dma_debug
= 0;
199 int reselect_debug
= 0;
200 int data_pointer_debug
= 0;
201 u_char debug_asr
, debug_csr
, routine
;
203 void sbicdumpstate (void);
204 void sbictimeout (struct sbic_softc
*);
205 void sbic_dump (struct sbic_softc
*);
206 void sbic_dump_acb (struct sbic_acb
*);
208 #define CSR_TRACE_SIZE 32
210 #define CSR_TRACE(w,c,a,x) do { \
212 csr_trace[csr_traceptr].whr = (w); csr_trace[csr_traceptr].csr = (c); \
213 csr_trace[csr_traceptr].asr = (a); csr_trace[csr_traceptr].xtn = (x); \
214 csr_traceptr = (csr_traceptr + 1) & (CSR_TRACE_SIZE - 1); \
218 int csr_tracesize
= CSR_TRACE_SIZE
;
224 } csr_trace
[CSR_TRACE_SIZE
];
229 #define SBIC_TRACE_SIZE 0
231 #define SBIC_TRACE(dev) do { \
233 sbic_trace[sbic_traceptr].sp = &s; \
234 sbic_trace[sbic_traceptr].line = __LINE__; \
235 sbic_trace[sbic_traceptr].sr = s; \
236 sbic_trace[sbic_traceptr].csr = csr_traceptr; \
237 sbic_traceptr = (sbic_traceptr + 1) & (SBIC_TRACE_SIZE - 1); \
241 int sbic_tracesize
= SBIC_TRACE_SIZE
;
247 } sbic_trace
[SBIC_TRACE_SIZE
];
249 #define SBIC_TRACE(dev)
254 #define DBGPRINTF(x,p)
261 #define SBIC_DEBUG(x)
265 * default minphys routine for sbic based controllers
268 sbic_minphys(struct buf
*bp
)
271 * No max transfer at this level.
277 * Save DMA pointers. Take into account partial transfer. Shut down DMA.
280 sbic_save_ptrs(struct sbic_softc
*dev
, sbic_regmap_p regs
)
283 struct sbic_acb
* acb
;
286 if (!(dev
->sc_flags
& SBICF_INDMA
))
287 return; /* DMA not active */
298 GET_SBIC_asr(regs
, asr
);
299 if (asr
& SBIC_ASR_DBR
) {
300 printf("sbic_save_ptrs: asr %02x canceled!\n", asr
);
305 } while (asr
& (SBIC_ASR_BSY
| SBIC_ASR_CIP
));
307 /* Save important state */
308 /* must be done before dmastop */
309 SBIC_TC_GET(regs
, count
);
311 /* Shut down DMA ====CAREFUL==== */
312 dev
->sc_dmastop(dev
->sc_dmah
, dev
->sc_dmat
, acb
);
313 dev
->sc_flags
&= ~SBICF_INDMA
;
318 SBIC_TC_GET(regs
, count2
);
320 panic("sbic_save_ptrs: DMA was still active(%d,%d)",
324 /* Note where we got to before stopping. We need this to resume
326 acb
->offset
+= acb
->sc_tcnt
- count
;
327 SBIC_TC_PUT(regs
, 0);
329 DBGPRINTF(("SBIC saving tgt %d data pointers: Offset now %d ASR:%02x",
330 dev
->target
, acb
->offset
, asr
), data_pointer_debug
>= 1);
334 DBG(sbicdma_saves
++);
340 * used by specific sbic controller
342 * it appears that the higher level code does nothing with LUN's
343 * so I will too. I could plug it in, however so could they
344 * in scsi_scsi_cmd().
347 sbic_scsi_request(struct scsipi_channel
*chan
,
348 scsipi_adapter_req_t req
, void *arg
)
350 struct scsipi_xfer
*xs
;
351 struct sbic_acb
*acb
;
352 struct sbic_softc
*dev
= (void *)chan
->chan_adapter
->adapt_dev
;
353 struct scsipi_periph
*periph
;
357 case ADAPTER_REQ_RUN_XFER
:
359 periph
= xs
->xs_periph
;
361 flags
= xs
->xs_control
;
363 if (flags
& XS_CTL_DATA_UIO
)
364 panic("sbic: scsi data uio requested");
366 if (dev
->sc_nexus
&& (flags
& XS_CTL_POLL
))
367 panic("sbic_scsicmd: busy");
370 acb
= dev
->free_list
.tqh_first
;
372 TAILQ_REMOVE(&dev
->free_list
, acb
, chain
);
376 DBG(printf("sbic_scsicmd: unable to queue request for "
377 "target %d\n", periph
->periph_target
));
378 #if defined(DDB) && defined(DEBUG)
381 xs
->error
= XS_RESOURCE_SHORTAGE
;
387 acb
->flags
= ACB_ACTIVE
;
388 if (flags
& XS_CTL_DATA_IN
)
389 acb
->flags
|= ACB_DATAIN
;
391 memcpy(&acb
->cmd
, xs
->cmd
, xs
->cmdlen
);
392 acb
->clen
= xs
->cmdlen
;
393 acb
->data
= xs
->data
;
394 acb
->datalen
= xs
->datalen
;
396 QPRINTF(("sbic_scsi_request: Cmd %02x (len %d), Data %p(%d)\n",
397 (unsigned) acb
->cmd
.opcode
, acb
->clen
, xs
->data
,
399 if (flags
& XS_CTL_POLL
) {
402 * This has major side effects -- it locks up the
406 dev
->sc_flags
|= SBICF_ICMD
;
408 while (dev
->sc_nexus
)
411 dev
->sc_stat
[0] = -1;
412 dev
->target
= periph
->periph_target
;
413 dev
->lun
= periph
->periph_lun
;
414 stat
= sbicicmd(dev
, periph
->periph_target
,
415 periph
->periph_lun
, acb
);
416 } while (dev
->sc_nexus
!= acb
);
418 sbic_scsidone(acb
, stat
);
425 TAILQ_INSERT_TAIL(&dev
->ready_list
, acb
, chain
);
434 * Nothing is active, try to start it now.
440 /* TODO: add sbic_poll to do XS_CTL_POLL operations */
443 case ADAPTER_REQ_GROW_RESOURCES
:
444 case ADAPTER_REQ_SET_XFER_MODE
:
445 /* XXX Not supported. */
451 * attempt to start the next available command
454 sbic_sched(struct sbic_softc
*dev
)
456 struct scsipi_xfer
*xs
;
457 struct scsipi_periph
*periph
;
458 struct sbic_acb
*acb
;
459 int flags
, /*phase,*/ stat
, i
;
463 return; /* a command is current active */
466 for (acb
= dev
->ready_list
.tqh_first
; acb
; acb
= acb
->chain
.tqe_next
) {
467 periph
= acb
->xs
->xs_periph
;
468 i
= periph
->periph_target
;
469 if (!(dev
->sc_tinfo
[i
].lubusy
& (1 << periph
->periph_lun
))) {
470 struct sbic_tinfo
*ti
= &dev
->sc_tinfo
[i
];
472 TAILQ_REMOVE(&dev
->ready_list
, acb
, chain
);
474 periph
= acb
->xs
->xs_periph
;
475 ti
= &dev
->sc_tinfo
[periph
->periph_target
];
476 ti
->lubusy
|= (1 << periph
->periph_lun
);
483 return; /* did not find an available command */
486 periph
= xs
->xs_periph
;
487 flags
= xs
->xs_control
;
489 if (flags
& XS_CTL_RESET
)
492 DBGPRINTF(("sbic_sched(%d,%d)\n", periph
->periph_target
,
493 periph
->periph_lun
), data_pointer_debug
> 1);
494 DBG(if (data_pointer_debug
> 1) sbic_dump_acb(acb
));
495 dev
->sc_stat
[0] = -1;
496 dev
->target
= periph
->periph_target
;
497 dev
->lun
= periph
->periph_lun
;
499 /* Decide if we can use DMA for this transfer. */
500 if ((flags
& XS_CTL_POLL
) == 0
502 && dev
->sc_dmaok(dev
->sc_dmah
, dev
->sc_dmat
, acb
))
503 acb
->flags
|= ACB_DMA
;
505 if ((flags
& XS_CTL_POLL
) ||
506 (!sbic_parallel_operations
&& (acb
->flags
& ACB_DMA
) == 0))
507 stat
= sbicicmd(dev
, periph
->periph_target
,
508 periph
->periph_lun
, acb
);
509 else if (sbicgo(dev
, xs
) == 0 && xs
->error
!= XS_SELTIMEOUT
) {
513 stat
= dev
->sc_stat
[0];
515 sbic_scsidone(acb
, stat
);
520 sbic_scsidone(struct sbic_acb
*acb
, int stat
)
522 struct scsipi_xfer
*xs
;
523 struct scsipi_periph
*periph
;
524 struct sbic_softc
*dev
;
529 periph
= xs
->xs_periph
;
530 dev
= (void *)periph
->periph_channel
->chan_adapter
->adapt_dev
;
533 if (acb
== NULL
|| xs
== NULL
) {
534 printf("sbic_scsidone -- (%d,%d) no scsipi_xfer\n",
535 dev
->target
, dev
->lun
);
543 DBGPRINTF(("scsidone: (%d,%d)->(%d,%d)%02x acbfl=%x\n",
544 periph
->periph_target
, periph
->periph_lun
,
545 dev
->target
, dev
->lun
, stat
, acb
->flags
),
546 data_pointer_debug
> 1);
547 DBG(if (xs
->xs_periph
->periph_target
== dev
->sc_channel
.chan_id
)
548 panic("target == hostid"));
552 if (xs
->error
== XS_NOERROR
) {
553 if (stat
== SCSI_CHECK
|| stat
== SCSI_BUSY
)
558 * Remove the ACB from whatever queue it's on. We have to do a bit of
559 * a hack to figure out which queue it's on. Note that it is *not*
560 * necessary to cdr down the ready queue, but we must cdr down the
561 * nexus queue and see if it's there, so we can mark the unit as no
562 * longer busy. This code is sickening, but it works.
564 if (acb
== dev
->sc_nexus
) {
565 dev
->sc_nexus
= NULL
;
566 dev
->sc_tinfo
[periph
->periph_target
].lubusy
&=
567 ~(1 << periph
->periph_lun
);
568 if (dev
->ready_list
.tqh_first
)
569 dosched
= 1; /* start next command */
570 } else if (dev
->ready_list
.tqh_last
== &acb
->chain
.tqe_next
) {
571 TAILQ_REMOVE(&dev
->ready_list
, acb
, chain
);
573 register struct sbic_acb
*acb2
;
574 for (acb2
= dev
->nexus_list
.tqh_first
; acb2
;
575 acb2
= acb2
->chain
.tqe_next
) {
577 TAILQ_REMOVE(&dev
->nexus_list
, acb
, chain
);
578 dev
->sc_tinfo
[periph
->periph_target
].lubusy
579 &= ~(1 << periph
->periph_lun
);
585 else if (acb
->chain
.tqe_next
) {
586 TAILQ_REMOVE(&dev
->ready_list
, acb
, chain
);
588 printf("%s: can't find matching acb\n",
589 device_xname(&dev
->sc_dev
));
595 /* Put it on the free list. */
596 acb
->flags
= ACB_FREE
;
597 TAILQ_INSERT_HEAD(&dev
->free_list
, acb
, chain
);
599 dev
->sc_tinfo
[periph
->periph_target
].cmds
++;
609 sbicwait(sbic_regmap_p regs
, char until
, int timeo
, int line
)
614 SBIC_TRACE((struct sbic_softc
*)0);
616 timeo
= 1000000; /* some large value.. */
618 GET_SBIC_asr(regs
,val
);
619 while ((val
& until
) == 0) {
621 GET_SBIC_csr(regs
, csr
);
622 printf("sbicwait TIMEO @%d with asr=x%x csr=x%x\n",
624 #if defined(DDB) && defined(DEBUG)
627 return val
; /* Maybe I should abort */
631 GET_SBIC_asr(regs
,val
);
633 SBIC_TRACE((struct sbic_softc
*)0);
638 sbicabort(struct sbic_softc
*dev
, sbic_regmap_p regs
, const char *where
)
642 GET_SBIC_asr(regs
, asr
);
643 GET_SBIC_csr(regs
, csr
);
645 printf ("%s: abort %s: csr = 0x%02x, asr = 0x%02x\n",
646 device_xname(&dev
->sc_dev
), where
, csr
, asr
);
650 /* Clean up running command */
651 if (dev
->sc_nexus
!= NULL
) {
652 dev
->sc_nexus
->xs
->error
= XS_DRIVER_STUFFUP
;
653 sbic_scsidone(dev
->sc_nexus
, dev
->sc_stat
[0]);
655 while (acb
= dev
->nexus_list
.tqh_first
) {
656 acb
->xs
->error
= XS_DRIVER_STUFFUP
;
657 sbic_scsidone(acb
, -1 /*acb->stat[0]*/);
661 /* Clean up chip itself */
662 if (dev
->sc_flags
& SBICF_SELECTED
) {
663 while (asr
& SBIC_ASR_DBR
) {
664 /* sbic is jammed w/data. need to clear it */
665 /* But we don't know what direction it needs to go */
666 GET_SBIC_data(regs
, asr
);
667 printf("%s: abort %s: clearing data buffer 0x%02x\n",
668 device_xname(&dev
->sc_dev
), where
, asr
);
669 GET_SBIC_asr(regs
, asr
);
670 /* Not the read direction, then */
671 if (asr
& SBIC_ASR_DBR
)
672 SET_SBIC_data(regs
, asr
);
673 GET_SBIC_asr(regs
, asr
);
676 printf("%s: sbicabort - sending ABORT command\n",
677 device_xname(&dev
->sc_dev
));
678 SET_SBIC_cmd(regs
, SBIC_CMD_ABORT
);
681 GET_SBIC_asr(regs
, asr
);
682 if (asr
& (SBIC_ASR_BSY
| SBIC_ASR_LCI
)) {
683 /* ok, get more drastic.. */
685 printf("%s: sbicabort - asr %x, trying to reset\n",
686 device_xname(&dev
->sc_dev
), asr
);
688 dev
->sc_flags
&= ~SBICF_SELECTED
;
691 printf("%s: sbicabort - sending DISC command\n",
692 device_xname(&dev
->sc_dev
));
693 SET_SBIC_cmd(regs
, SBIC_CMD_DISC
);
696 asr
= SBIC_WAIT (regs
, SBIC_ASR_INT
, 0);
697 GET_SBIC_csr (regs
, csr
);
698 CSR_TRACE('a',csr
,asr
,0);
699 } while ((csr
!= SBIC_CSR_DISC
) && (csr
!= SBIC_CSR_DISC_1
)
700 && (csr
!= SBIC_CSR_CMD_INVALID
));
702 /* lets just hope it worked.. */
703 dev
->sc_flags
&= ~SBICF_SELECTED
;
710 * Initialize driver-private structures
714 sbicinit(struct sbic_softc
*dev
)
720 struct sbic_acb
*acb
;
723 extern u_long scsi_nosync
;
724 extern int shift_nosync
;
726 SBIC_DEBUG(printf("sbicinit:\n"));
728 regs
= &dev
->sc_sbicp
;
730 if ((dev
->sc_flags
& SBICF_ALIVE
) == 0) {
731 TAILQ_INIT(&dev
->ready_list
);
732 TAILQ_INIT(&dev
->nexus_list
);
733 TAILQ_INIT(&dev
->free_list
);
734 callout_init(&dev
->sc_timo_ch
, 0);
735 dev
->sc_nexus
= NULL
;
737 memset(acb
, 0, sizeof(dev
->sc_acb
));
739 SBIC_DEBUG(printf("sbicinit: %d\n", __LINE__
));
741 for (i
= 0; i
< sizeof(dev
->sc_acb
) / sizeof(*acb
); i
++) {
742 TAILQ_INSERT_TAIL(&dev
->free_list
, acb
, chain
);
745 memset(dev
->sc_tinfo
, 0, sizeof(dev
->sc_tinfo
));
746 /* make sure timeout is really not needed */
747 DBG(callout_reset(&dev
->sc_timo_ch
, 30 * hz
,
748 (void *)sbictimeout
, dev
));
750 panic("sbic: reinitializing driver!");
752 SBIC_DEBUG(printf("sbicinit: %d\n", __LINE__
));
754 dev
->sc_flags
|= SBICF_ALIVE
;
755 dev
->sc_flags
&= ~SBICF_SELECTED
;
757 /* initialize inhibit array */
760 SBIC_DEBUG(printf("sbicinit: %d\n", __LINE__
));
762 inhibit_sync
= (scsi_nosync
>> shift_nosync
) & 0xff;
765 DBGPRINTF(("%s: Inhibiting synchronous transfer %02x\n",
766 device_xname(&dev
->sc_dev
), inhibit_sync
), inhibit_sync
);
768 for (i
= 0; i
< 8; ++i
)
769 if (inhibit_sync
& (1 << i
))
770 sbic_inhibit_sync
[i
] = 1;
773 SBIC_DEBUG(printf("sbicinit: %d\n", __LINE__
));
780 sbicreset(struct sbic_softc
*dev
)
786 /* struct sbic_acb *acb;*/
788 SBIC_DEBUG(printf("sbicreset: %d\n", __LINE__
));
790 regs
= &dev
->sc_sbicp
;
792 SBIC_DEBUG(printf("sbicreset: regs = %08x\n", regs
));
795 if (dev
->sc_flags
& SBICF_ALIVE
) {
796 SET_SBIC_cmd(regs
, SBIC_CMD_ABORT
);
800 SET_SBIC_cmd(regs
, SBIC_CMD_ABORT
);
802 SBIC_DEBUG(printf("sbicreset: %d\n", __LINE__
));
806 SBIC_DEBUG(printf("sbicreset: %d\n", __LINE__
));
809 my_id
= dev
->sc_channel
.chan_id
& SBIC_ID_MASK
;
811 /* Enable advanced mode */
812 my_id
|= SBIC_ID_EAF
/*| SBIC_ID_EHP*/ ;
813 SET_SBIC_myid(regs
, my_id
);
815 SBIC_DEBUG(printf("sbicreset: %d\n", __LINE__
));
818 * Disable interrupts (in dmainit) then reset the chip
820 SET_SBIC_cmd(regs
, SBIC_CMD_RESET
);
822 SBIC_WAIT(regs
, SBIC_ASR_INT
, 0);
823 GET_SBIC_csr(regs
, csr
); /* clears interrupt also */
825 if (dev
->sc_clkfreq
< 110)
826 my_id
|= SBIC_ID_FS_8_10
;
827 else if (dev
->sc_clkfreq
< 160)
828 my_id
|= SBIC_ID_FS_12_15
;
829 else if (dev
->sc_clkfreq
< 210)
830 my_id
|= SBIC_ID_FS_16_20
;
832 SET_SBIC_myid(regs
, my_id
);
834 SBIC_DEBUG(printf("sbicreset: %d\n", __LINE__
));
837 * Set up various chip parameters
839 SET_SBIC_control(regs
, SBIC_CTL_EDI
| SBIC_CTL_IDI
/* | SBIC_CTL_HSP */
842 * don't allow (re)selection (SBIC_RID_ES)
843 * until we can handle target mode!!
845 SET_SBIC_rselid(regs
, SBIC_RID_ER
);
846 SET_SBIC_syn(regs
, 0); /* asynch for now */
849 * anything else was zeroed by reset
854 if ((dev
->sc_flags
& SBICF_ALIVE
) == 0) {
855 TAILQ_INIT(&dev
->ready_list
);
856 TAILQ_INIT(&dev
->nexus_list
);
857 TAILQ_INIT(&dev
->free_list
);
858 dev
->sc_nexus
= NULL
;
860 memset(acb
, 0, sizeof(dev
->sc_acb
));
861 for (i
= 0; i
< sizeof(dev
->sc_acb
) / sizeof(*acb
); i
++) {
862 TAILQ_INSERT_TAIL(&dev
->free_list
, acb
, chain
);
865 memset(dev
->sc_tinfo
, 0, sizeof(dev
->sc_tinfo
));
867 if (dev
->sc_nexus
!= NULL
) {
868 dev
->sc_nexus
->xs
->error
= XS_DRIVER_STUFFUP
;
869 sbic_scsidone(dev
->sc_nexus
, dev
->sc_stat
[0]);
871 while (acb
= dev
->nexus_list
.tqh_first
) {
872 acb
->xs
->error
= XS_DRIVER_STUFFUP
;
873 sbic_scsidone(acb
, -1 /*acb->stat[0]*/);
877 dev
->sc_flags
|= SBICF_ALIVE
;
879 dev
->sc_flags
&= ~SBICF_SELECTED
;
883 sbicerror(struct sbic_softc
*dev
, sbic_regmap_p regs
, u_char csr
)
886 if (dev
->sc_nexus
== NULL
)
889 if (dev
->sc_nexus
->xs
->xs_control
& XS_CTL_SILENT
)
892 printf("%s: ", device_xname(&dev
->sc_dev
));
893 printf("csr == 0x%02x\n", csr
); /* XXX */
897 * select the bus, return when selected or error.
900 sbicselectbus(struct sbic_softc
*dev
, sbic_regmap_p regs
, u_char target
,
901 u_char lun
, u_char our_addr
)
906 QPRINTF(("sbicselectbus %d\n", target
));
909 * if we're already selected, return (XXXX panic maybe?)
911 if (dev
->sc_flags
& SBICF_SELECTED
) {
919 SBIC_TC_PUT(regs
, 0);
920 SET_SBIC_selid(regs
, target
);
921 SET_SBIC_timeo(regs
, SBIC_TIMEOUT(250,dev
->sc_clkfreq
));
926 if (dev
->sc_sync
[target
].state
== SYNC_DONE
)
927 SET_SBIC_syn(regs
, SBIC_SYN (dev
->sc_sync
[target
].offset
,
928 dev
->sc_sync
[target
].period
));
930 SET_SBIC_syn(regs
, SBIC_SYN (0, sbic_min_period
));
932 GET_SBIC_asr(regs
, asr
);
933 if (asr
& (SBIC_ASR_INT
| SBIC_ASR_BSY
)) {
934 /* This means we got ourselves reselected upon */
935 /* printf("sbicselectbus: INT/BSY asr %02x\n", asr);*/
943 SET_SBIC_cmd(regs
, SBIC_CMD_SEL_ATN
);
946 * wait for select (merged from separate function may need
951 asr
= SBIC_WAIT(regs
, SBIC_ASR_INT
| SBIC_ASR_LCI
, 0);
952 if (asr
& SBIC_ASR_LCI
) {
954 DBGPRINTF(("sbicselectbus: late LCI asr %02x\n", asr
),
960 GET_SBIC_csr (regs
, csr
);
961 CSR_TRACE('s',csr
,asr
,target
);
962 QPRINTF(("%02x ", csr
));
963 if (csr
== SBIC_CSR_RSLT_NI
|| csr
== SBIC_CSR_RSLT_IFY
) {
965 DBGPRINTF(("sbicselectbus: reselected asr %02x\n",
966 asr
), reselect_debug
);
968 /* We need to handle this now so we don't lock
970 sbicnextstate(dev
, csr
, asr
);
974 if (csr
== SBIC_CSR_SLT
|| csr
== SBIC_CSR_SLT_ATN
) {
975 panic("sbicselectbus: target issued select!");
978 } while (csr
!= (SBIC_CSR_MIS_2
| MESG_OUT_PHASE
) &&
979 csr
!= (SBIC_CSR_MIS_2
| CMD_PHASE
) &&
980 csr
!= SBIC_CSR_SEL_TIMEO
);
982 /* Enable (or not) reselection */
983 if (!sbic_enable_reselect
&& dev
->nexus_list
.tqh_first
== NULL
)
984 SET_SBIC_rselid (regs
, 0);
986 SET_SBIC_rselid (regs
, SBIC_RID_ER
);
988 if (csr
== (SBIC_CSR_MIS_2
| CMD_PHASE
)) {
989 dev
->sc_flags
|= SBICF_SELECTED
; /* device ignored ATN */
990 GET_SBIC_selid(regs
, id
);
992 GET_SBIC_tlun(regs
,dev
->lun
);
993 if (dev
->lun
& SBIC_TLUN_VALID
)
994 dev
->lun
&= SBIC_TLUN_MASK
;
997 } else if (csr
== (SBIC_CSR_MIS_2
| MESG_OUT_PHASE
)) {
999 * Send identify message
1000 * (SCSI-2 requires an identify msg (?))
1002 GET_SBIC_selid(regs
, id
);
1004 GET_SBIC_tlun(regs
,dev
->lun
);
1005 if (dev
->lun
& SBIC_TLUN_VALID
)
1006 dev
->lun
&= SBIC_TLUN_MASK
;
1010 * handle drives that don't want to be asked
1011 * whether to go sync at all.
1013 if (sbic_inhibit_sync
[id
]
1014 && dev
->sc_sync
[id
].state
== SYNC_START
) {
1015 DBGPRINTF(("Forcing target %d asynchronous.\n", id
),
1018 dev
->sc_sync
[id
].offset
= 0;
1019 dev
->sc_sync
[id
].period
= sbic_min_period
;
1020 dev
->sc_sync
[id
].state
= SYNC_DONE
;
1024 if (dev
->sc_sync
[id
].state
!= SYNC_START
){
1025 if ((dev
->sc_nexus
->xs
->xs_control
& XS_CTL_POLL
)
1026 || (dev
->sc_flags
& SBICF_ICMD
)
1027 || !sbic_enable_reselect
)
1028 SEND_BYTE(regs
, MSG_IDENTIFY
| lun
);
1030 SEND_BYTE(regs
, MSG_IDENTIFY_DR
| lun
);
1033 * try to initiate a sync transfer.
1034 * So compose the sync message we're going
1035 * to send to the target
1038 DBGPRINTF(("Sending sync request to target %d ... ",
1042 * setup scsi message sync message request
1044 dev
->sc_msg
[0] = MSG_IDENTIFY
| lun
;
1045 dev
->sc_msg
[1] = MSG_EXT_MESSAGE
;
1047 dev
->sc_msg
[3] = MSG_SYNC_REQ
;
1048 dev
->sc_msg
[4] = sbictoscsiperiod(dev
, regs
,
1050 dev
->sc_msg
[5] = sbic_max_offset
;
1052 if (sbicxfstart(regs
, 6, MESG_OUT_PHASE
,
1054 sbicxfout(regs
, 6, dev
->sc_msg
,
1057 dev
->sc_sync
[id
].state
= SYNC_SENT
;
1059 DBGPRINTF(("sent\n"), sync_debug
);
1062 asr
= SBIC_WAIT (regs
, SBIC_ASR_INT
, 0);
1063 GET_SBIC_csr (regs
, csr
);
1064 CSR_TRACE('y',csr
,asr
,target
);
1065 QPRINTF(("[%02x]", csr
));
1067 DBGPRINTF(("csr-result of last msgout: 0x%x\n", csr
),
1068 sync_debug
&& dev
->sc_sync
[id
].state
== SYNC_SENT
);
1070 if (csr
!= SBIC_CSR_SEL_TIMEO
)
1071 dev
->sc_flags
|= SBICF_SELECTED
;
1073 if (csr
== SBIC_CSR_SEL_TIMEO
)
1074 dev
->sc_nexus
->xs
->error
= XS_SELTIMEOUT
;
1079 return csr
== SBIC_CSR_SEL_TIMEO
;
1083 sbicxfstart(sbic_regmap_p regs
, int len
, u_char phase
, int wait
)
1090 GET_SBIC_selid (regs
, id
);
1091 id
|= SBIC_SID_FROM_SCSI
;
1092 SET_SBIC_selid (regs
, id
);
1093 SBIC_TC_PUT (regs
, (unsigned)len
);
1095 case DATA_OUT_PHASE
:
1096 case MESG_OUT_PHASE
:
1098 GET_SBIC_selid (regs
, id
);
1099 id
&= ~SBIC_SID_FROM_SCSI
;
1100 SET_SBIC_selid (regs
, id
);
1101 SBIC_TC_PUT (regs
, (unsigned)len
);
1104 SBIC_TC_PUT (regs
, 0);
1106 QPRINTF(("sbicxfstart %d, %d, %d\n", len
, phase
, wait
));
1112 sbicxfout(sbic_regmap_p regs
, int len
, void *bp
, int phase
)
1114 #ifdef UNPROTECTED_CSR
1122 wait
= sbic_data_wait
;
1124 QPRINTF(("sbicxfout {%d} %02x %02x %02x %02x %02x "
1125 "%02x %02x %02x %02x %02x\n", len
, buf
[0], buf
[1], buf
[2],
1126 buf
[3], buf
[4], buf
[5], buf
[6], buf
[7], buf
[8], buf
[9]));
1128 #ifdef UNPROTECTED_CSR
1129 GET_SBIC_csr (regs
, orig_csr
);
1130 CSR_TRACE('>',orig_csr
,0,0);
1134 * sigh.. WD-PROTO strikes again.. sending the command in one go
1135 * causes the chip to lock up if talking to certain (misbehaving?)
1136 * targets. Anyway, this procedure should work for all targets, but
1137 * it's slightly slower due to the overhead
1140 SET_SBIC_cmd (regs
, SBIC_CMD_XFER_INFO
);
1141 for (;len
> 0; len
--) {
1142 GET_SBIC_asr (regs
, asr
);
1143 while ((asr
& SBIC_ASR_DBR
) == 0) {
1144 if ((asr
& SBIC_ASR_INT
) || --wait
< 0) {
1146 DBGPRINTF(("sbicxfout fail: l%d i%x w%d\n",
1147 len
, asr
, wait
), sbic_debug
);
1152 GET_SBIC_asr (regs
, asr
);
1155 SET_SBIC_data (regs
, *buf
);
1158 SBIC_TC_GET(regs
, len
);
1159 QPRINTF(("sbicxfout done %d bytes\n", len
));
1161 * this leaves with one csr to be read
1166 /* returns # bytes left to read */
1168 sbicxfin(sbic_regmap_p regs
, int len
, void *bp
)
1173 #ifdef UNPROTECTED_CSR
1174 u_char orig_csr
, csr
;
1178 wait
= sbic_data_wait
;
1182 #ifdef UNPROTECTED_CSR
1183 GET_SBIC_csr (regs
, orig_csr
);
1184 CSR_TRACE('<',orig_csr
,0,0);
1186 QPRINTF(("sbicxfin %d, csr=%02x\n", len
, orig_csr
));
1190 SET_SBIC_cmd (regs
, SBIC_CMD_XFER_INFO
);
1191 for (;len
> 0; len
--) {
1192 GET_SBIC_asr (regs
, asr
);
1193 if ((asr
& SBIC_ASR_PE
)) {
1194 DBG(printf("sbicxfin parity error: l%d i%x w%d\n",
1196 #if defined(DDB) && defined(DEBUG)
1199 DBG(return ((unsigned long)buf
- (unsigned long)bp
));
1201 while ((asr
& SBIC_ASR_DBR
) == 0) {
1202 if ((asr
& SBIC_ASR_INT
) || --wait
< 0) {
1204 DBG(if (sbic_debug
) {
1205 QPRINTF(("sbicxfin fail:{%d} %02x %02x %02x %02x %02x %02x "
1206 "%02x %02x %02x %02x\n", len
, obp
[0], obp
[1], obp
[2],
1207 obp
[3], obp
[4], obp
[5], obp
[6], obp
[7], obp
[8], obp
[9]));
1208 printf("sbicxfin fail: l%d i%x w%d\n", len
, asr
, wait
); });
1213 #ifdef UNPROTECTED_CSR
1214 if (!(asr
& SBIC_ASR_BSY
)) {
1215 GET_SBIC_csr(regs
, csr
);
1216 CSR_TRACE('<',csr
,asr
,len
);
1217 QPRINTF(("[CSR%02xASR%02x]", csr
, asr
));
1222 GET_SBIC_asr (regs
, asr
);
1225 GET_SBIC_data (regs
, *buf
);
1226 /* QPRINTF(("asr=%02x, csr=%02x, data=%02x\n", asr, csr, *buf));*/
1230 QPRINTF(("sbicxfin {%d} %02x %02x %02x %02x %02x %02x "
1231 "%02x %02x %02x %02x\n", len
, obp
[0], obp
[1], obp
[2],
1232 obp
[3], obp
[4], obp
[5], obp
[6], obp
[7], obp
[8], obp
[9]));
1234 /* this leaves with one csr to be read */
1239 * SCSI 'immediate' command: issue a command to some SCSI device
1240 * and get back an 'immediate' response (i.e., do programmed xfer
1241 * to get the response data). 'cbuf' is a buffer containing a scsi
1242 * command of length clen bytes. 'buf' is a buffer of length 'len'
1243 * bytes for data. The transfer direction is determined by the device
1244 * (i.e., by the scsi bus data xfer phase). If 'len' is zero, the
1245 * command must supply no data.
1248 sbicicmd(struct sbic_softc
*dev
, int target
, int lun
, struct sbic_acb
*acb
)
1251 u_char phase
, csr
, asr
;
1253 /* int newtarget, cmd_sent, parity_err;*/
1261 #define CSR_LOG_BUF_SIZE 0
1262 #if CSR_LOG_BUF_SIZE
1264 int csrbuf
[CSR_LOG_BUF_SIZE
];
1274 regs
= &dev
->sc_sbicp
;
1279 DBG(debug_sbic_regs
= regs
); /* store this to allow debug calls */
1280 DBGPRINTF(("sbicicmd(%d,%d):%d\n", target
, lun
, len
),
1281 data_pointer_debug
> 1);
1284 * set the sbic into non-DMA mode
1286 SET_SBIC_control(regs
, SBIC_CTL_EDI
| SBIC_CTL_IDI
/*| SBIC_CTL_HSP*/);
1288 dev
->sc_stat
[0] = 0xff;
1289 dev
->sc_msg
[0] = 0xff;
1290 i
= 1; /* pre-load */
1292 /* We're stealing the SCSI bus */
1293 dev
->sc_flags
|= SBICF_ICMD
;
1297 * select the SCSI bus (it's an error if bus isn't free)
1299 if (!(dev
->sc_flags
& SBICF_SELECTED
)
1300 && sbicselectbus(dev
, regs
, target
, lun
,
1301 dev
->sc_scsiaddr
)) {
1302 /*printf("sbicicmd trying to select busy bus!\n");*/
1303 dev
->sc_flags
&= ~SBICF_ICMD
;
1308 * Wait for a phase change (or error) then let the
1309 * device sequence us through the various SCSI phases.
1312 wait
= sbic_cmd_wait
;
1314 GET_SBIC_asr (regs
, asr
);
1315 GET_SBIC_csr (regs
, csr
);
1316 CSR_TRACE('I',csr
,asr
,target
);
1317 QPRINTF((">ASR:%02xCSR:%02x<", asr
, csr
));
1319 #if CSR_LOG_BUF_SIZE
1320 csrbuf
[bufptr
++] = csr
;
1325 case SBIC_CSR_S_XFERRED
:
1327 case SBIC_CSR_DISC_1
:
1328 dev
->sc_flags
&= ~SBICF_SELECTED
;
1329 GET_SBIC_cmd_phase (regs
, phase
);
1330 if (phase
== 0x60) {
1331 GET_SBIC_tlun (regs
, dev
->sc_stat
[0]);
1333 /* break;*/ /* Bypass all the state gobldygook */
1335 DBGPRINTF(("sbicicmd: handling disconnect\n"),
1336 reselect_debug
> 1);
1338 i
= SBIC_STATE_DISCONNECT
;
1342 case SBIC_CSR_XFERRED
| CMD_PHASE
:
1343 case SBIC_CSR_MIS
| CMD_PHASE
:
1344 case SBIC_CSR_MIS_1
| CMD_PHASE
:
1345 case SBIC_CSR_MIS_2
| CMD_PHASE
:
1346 if (sbicxfstart(regs
, clen
, CMD_PHASE
, sbic_cmd_wait
))
1347 if (sbicxfout(regs
, clen
,
1349 i
= sbicabort(dev
, regs
,
1350 "icmd sending cmd");
1352 GET_SBIC_csr(regs
, csr
); /* Lets us reload tcount */
1354 GET_SBIC_asr(regs
, asr
);
1355 CSR_TRACE('I',csr
,asr
,target
);
1356 if (asr
& (SBIC_ASR_BSY
| SBIC_ASR_LCI
| SBIC_ASR_CIP
))
1357 printf("next: cmd sent asr %02x, csr %02x\n",
1363 case SBIC_CSR_XFERRED
| DATA_OUT_PHASE
:
1364 case SBIC_CSR_XFERRED
| DATA_IN_PHASE
:
1365 case SBIC_CSR_MIS
| DATA_OUT_PHASE
:
1366 case SBIC_CSR_MIS
| DATA_IN_PHASE
:
1367 case SBIC_CSR_MIS_1
| DATA_OUT_PHASE
:
1368 case SBIC_CSR_MIS_1
| DATA_IN_PHASE
:
1369 case SBIC_CSR_MIS_2
| DATA_OUT_PHASE
:
1370 case SBIC_CSR_MIS_2
| DATA_IN_PHASE
:
1371 if (acb
->datalen
<= 0)
1372 i
= sbicabort(dev
, regs
, "icmd out of data");
1374 wait
= sbic_data_wait
;
1375 if (sbicxfstart(regs
, acb
->datalen
,
1376 SBIC_PHASE(csr
), wait
))
1379 i
= sbicxfin(regs
, acb
->datalen
, acb
->data
);
1381 i
= sbicxfout(regs
, acb
->datalen
, acb
->data
,
1383 acb
->data
+= acb
->datalen
- i
;
1390 case SBIC_CSR_XFERRED
| STATUS_PHASE
:
1391 case SBIC_CSR_MIS
| STATUS_PHASE
:
1392 case SBIC_CSR_MIS_1
| STATUS_PHASE
:
1393 case SBIC_CSR_MIS_2
| STATUS_PHASE
:
1395 * the sbic does the status/cmd-complete reading ok,
1396 * so do this with its hi-level commands.
1398 DBGPRINTF(("SBICICMD status phase\n"), sbic_debug
);
1400 SBIC_TC_PUT(regs
, 0);
1401 SET_SBIC_cmd_phase(regs
, 0x46);
1402 SET_SBIC_cmd(regs
, SBIC_CMD_SEL_ATN_XFER
);
1405 #if THIS_IS_A_RESERVED_STATE
1406 case BUS_FREE_PHASE
: /* This is not legal */
1407 if (dev
->sc_stat
[0] != 0xff)
1413 i
= sbicnextstate(dev
, csr
, asr
);
1417 * make sure the last command was taken,
1418 * ie. we're not hunting after an ignored command..
1420 GET_SBIC_asr(regs
, asr
);
1422 /* tapes may take a loooong time.. */
1423 while (asr
& SBIC_ASR_BSY
){
1424 if (asr
& SBIC_ASR_DBR
) {
1425 printf("sbicicmd: Waiting while sbic is "
1426 "jammed, CSR:%02x,ASR:%02x\n",
1431 /* SBIC is jammed */
1432 /* DUNNO which direction */
1433 /* Try old direction */
1434 GET_SBIC_data(regs
,i
);
1435 GET_SBIC_asr(regs
, asr
);
1436 if (asr
& SBIC_ASR_DBR
) /* Wants us to write */
1437 SET_SBIC_data(regs
,i
);
1439 GET_SBIC_asr(regs
, asr
);
1443 * wait for last command to complete
1445 if (asr
& SBIC_ASR_LCI
) {
1446 printf("sbicicmd: last command ignored\n");
1448 else if (i
== 1) /* Bsy */
1449 SBIC_WAIT(regs
, SBIC_ASR_INT
, wait
);
1454 } while (i
> 0 && dev
->sc_stat
[0] == 0xff);
1456 /* Sometimes we need to do an extra read of the CSR */
1457 GET_SBIC_csr(regs
, csr
);
1458 CSR_TRACE('I',csr
,asr
,0xff);
1460 #if CSR_LOG_BUF_SIZE
1461 if (reselect_debug
> 1)
1462 for (i
= 0; i
< bufptr
; i
++)
1463 printf("CSR:%02x", csrbuf
[i
]);
1466 DBGPRINTF(("sbicicmd done(%d,%d):%d =%d=\n",
1470 data_pointer_debug
> 1);
1472 QPRINTF(("=STS:%02x=", dev
->sc_stat
[0]));
1473 dev
->sc_flags
&= ~SBICF_ICMD
;
1476 return dev
->sc_stat
[0];
1480 * Finish SCSI xfer command: After the completion interrupt from
1481 * a read/write operation, sequence through the final phases in
1482 * programmed i/o. This routine is a lot like sbicicmd except we
1483 * skip (and don't allow) the select, cmd out and data in/out phases.
1486 sbicxfdone(struct sbic_softc
*dev
, sbic_regmap_p regs
, int target
)
1488 u_char phase
, asr
, csr
;
1496 * have the sbic complete on its own
1498 SBIC_TC_PUT(regs
, 0);
1499 SET_SBIC_cmd_phase(regs
, 0x46);
1500 SET_SBIC_cmd(regs
, SBIC_CMD_SEL_ATN_XFER
);
1503 asr
= SBIC_WAIT (regs
, SBIC_ASR_INT
, 0);
1504 GET_SBIC_csr (regs
, csr
);
1505 CSR_TRACE('f',csr
,asr
,target
);
1506 QPRINTF(("%02x:", csr
));
1507 } while ((csr
!= SBIC_CSR_DISC
) && (csr
!= SBIC_CSR_DISC_1
)
1508 && (csr
!= SBIC_CSR_S_XFERRED
));
1510 dev
->sc_flags
&= ~SBICF_SELECTED
;
1512 GET_SBIC_cmd_phase (regs
, phase
);
1513 QPRINTF(("}%02x", phase
));
1515 GET_SBIC_tlun(regs
, dev
->sc_stat
[0]);
1517 sbicerror(dev
, regs
, csr
);
1519 QPRINTF(("=STS:%02x=\n", dev
->sc_stat
[0]));
1529 sbicgo(struct sbic_softc
*dev
, struct scsipi_xfer
*xs
)
1532 /* int dmaflags, count; */
1535 u_char asr
= 0, csr
= 0;
1538 struct sbic_acb
*acb
;
1541 dev
->target
= xs
->xs_periph
->periph_target
;
1542 dev
->lun
= xs
->xs_periph
->periph_lun
;
1543 acb
= dev
->sc_nexus
;
1544 regs
= &dev
->sc_sbicp
;
1546 usedma
= acb
->flags
& ACB_DMA
;
1549 DBG(debug_sbic_regs
= regs
); /* store this to allow debug calls */
1550 DBGPRINTF(("sbicgo(%d,%d)\n", dev
->target
, dev
->lun
),
1551 data_pointer_debug
> 1);
1554 * set the sbic into DMA mode
1557 SET_SBIC_control(regs
,
1558 SBIC_CTL_EDI
| SBIC_CTL_IDI
| dev
->sc_dmamode
);
1560 SET_SBIC_control(regs
, SBIC_CTL_EDI
| SBIC_CTL_IDI
);
1564 * select the SCSI bus (it's an error if bus isn't free)
1566 if (sbicselectbus(dev
, regs
, dev
->target
, dev
->lun
,
1567 dev
->sc_scsiaddr
)) {
1568 /* printf("sbicgo: Trying to select busy bus!\n"); */
1570 /* Not done: may need to be rescheduled */
1573 dev
->sc_stat
[0] = 0xff;
1576 * Allocate the DMA chain
1579 /* Mark end of segment */
1583 /* Enable interrupts */
1584 dev
->sc_enintr(dev
);
1590 /* Note, this does not start DMA */
1591 tcnt
= dev
->sc_dmasetup(dev
->sc_dmah
, dev
->sc_dmat
, acb
,
1592 (acb
->flags
& ACB_DATAIN
) != 0);
1594 DBG(dev
->sc_dmatimo
= tcnt
? 1 : 0);
1595 DBG(++sbicdma_ops
); /* count total DMA operations */
1601 * enintr() also enables interrupts for the sbic
1603 DBG(debug_asr
= asr
);
1604 DBG(debug_csr
= csr
);
1607 * Lets cycle a while then let the interrupt handler take over
1610 GET_SBIC_asr(regs
, asr
);
1612 GET_SBIC_csr(regs
, csr
);
1613 CSR_TRACE('g', csr
, asr
, dev
->target
);
1615 DBG(debug_csr
= csr
);
1618 QPRINTF(("go[0x%x]", csr
));
1620 i
= sbicnextstate(dev
, csr
, asr
);
1623 GET_SBIC_asr(regs
, asr
);
1625 DBG(debug_asr
= asr
);
1627 if (asr
& SBIC_ASR_LCI
)
1628 printf("sbicgo: LCI asr:%02x csr:%02x\n", asr
, csr
);
1629 } while (i
== SBIC_STATE_RUNNING
&&
1630 (asr
& (SBIC_ASR_INT
| SBIC_ASR_LCI
)));
1632 CSR_TRACE('g',csr
,asr
,i
<<4);
1634 if (i
== SBIC_STATE_DONE
&& dev
->sc_stat
[0] == 0xff)
1635 printf("sbicgo: done & stat = 0xff\n");
1636 if (i
== SBIC_STATE_DONE
&& dev
->sc_stat
[0] != 0xff) {
1637 /* if (i == SBIC_STATE_DONE && dev->sc_stat[0]) { */
1638 /* Did we really finish that fast? */
1646 sbicintr(struct sbic_softc
*dev
)
1650 /* u_char *tmpaddr;*/
1651 /* struct sbic_acb *acb;*/
1653 /* int newtarget, newlun;*/
1656 regs
= &dev
->sc_sbicp
;
1659 * pending interrupt?
1661 GET_SBIC_asr (regs
, asr
);
1662 if ((asr
& SBIC_ASR_INT
) == 0)
1667 GET_SBIC_csr(regs
, csr
);
1668 CSR_TRACE('i',csr
,asr
,dev
->target
);
1670 DBG(debug_csr
= csr
);
1673 QPRINTF(("intr[0x%x]", csr
));
1675 i
= sbicnextstate(dev
, csr
, asr
);
1678 GET_SBIC_asr(regs
, asr
);
1680 DBG(debug_asr
= asr
);
1683 if (asr
& SBIC_ASR_LCI
)
1684 printf("sbicintr: LCI asr:%02x csr:%02x\n", asr
, csr
);
1686 } while (i
== SBIC_STATE_RUNNING
&&
1687 (asr
& (SBIC_ASR_INT
| SBIC_ASR_LCI
)));
1688 CSR_TRACE('i', csr
, asr
, i
<< 4);
1694 * Run commands and wait for disconnect
1697 sbicpoll(struct sbic_softc
*dev
)
1701 /* struct sbic_pending* pendp;*/
1706 regs
= &dev
->sc_sbicp
;
1709 GET_SBIC_asr (regs
, asr
);
1711 DBG(debug_asr
= asr
);
1713 GET_SBIC_csr(regs
, csr
);
1714 CSR_TRACE('p', csr
, asr
, dev
->target
);
1716 DBG(debug_csr
= csr
);
1719 QPRINTF(("poll[0x%x]", csr
));
1721 i
= sbicnextstate(dev
, csr
, asr
);
1724 GET_SBIC_asr(regs
, asr
);
1725 /* tapes may take a loooong time.. */
1726 while (asr
& SBIC_ASR_BSY
){
1727 if (asr
& SBIC_ASR_DBR
) {
1728 printf("sbipoll: Waiting while sbic is "
1729 "jammed, CSR:%02x,ASR:%02x\n",
1734 /* SBIC is jammed */
1735 /* DUNNO which direction */
1736 /* Try old direction */
1737 GET_SBIC_data(regs
,i
);
1738 GET_SBIC_asr(regs
, asr
);
1739 if (asr
& SBIC_ASR_DBR
) /* Wants us to write */
1740 SET_SBIC_data(regs
,i
);
1742 GET_SBIC_asr(regs
, asr
);
1745 if (asr
& SBIC_ASR_LCI
)
1746 printf("sbicpoll: LCI asr:%02x csr:%02x\n", asr
, csr
);
1747 else if (i
== 1) /* BSY */
1748 SBIC_WAIT(regs
, SBIC_ASR_INT
, sbic_cmd_wait
);
1749 } while (i
== SBIC_STATE_RUNNING
);
1750 CSR_TRACE('p', csr
, asr
, i
<< 4);
1756 * Handle a single msgin
1760 sbicmsgin(struct sbic_softc
*dev
)
1764 u_char asr
, csr
, *tmpaddr
;
1766 regs
= &dev
->sc_sbicp
;
1768 dev
->sc_msg
[0] = 0xff;
1769 dev
->sc_msg
[1] = 0xff;
1771 GET_SBIC_asr(regs
, asr
);
1773 DBGPRINTF(("sbicmsgin asr=%02x\n", asr
), reselect_debug
> 1);
1775 sbic_save_ptrs(dev
, regs
);
1777 GET_SBIC_selid (regs
, csr
);
1778 SET_SBIC_selid (regs
, csr
| SBIC_SID_FROM_SCSI
);
1780 SBIC_TC_PUT(regs
, 0);
1781 tmpaddr
= dev
->sc_msg
;
1785 GET_SBIC_asr(regs
, asr
);
1786 GET_SBIC_csr(regs
, csr
);
1787 QPRINTF(("sbicmsgin ready to go (csr,asr)=(%02x,%02x)\n",
1790 RECV_BYTE(regs
, *tmpaddr
);
1791 CSR_TRACE('m', csr
, asr
, *tmpaddr
);
1794 * get the command completion interrupt, or we
1795 * can't send a new command (LCI)
1797 SBIC_WAIT(regs
, SBIC_ASR_INT
, 0);
1798 GET_SBIC_csr(regs
, csr
);
1799 CSR_TRACE('X', csr
, asr
, dev
->target
);
1803 GET_SBIC_asr(regs
, asr
);
1805 GET_SBIC_csr(regs
, csr
);
1806 CSR_TRACE('X', csr
, asr
, dev
->target
);
1808 printf("sbicmsgin waiting: csr %02x "
1809 "asr %02x\n", csr
, asr
);
1810 } while (csr
== 0xff);
1813 DBGPRINTF(("sbicmsgin: got %02x csr %02x asr %02x\n",
1814 *tmpaddr
, csr
, asr
), reselect_debug
> 1);
1817 if (asr
& SBIC_ASR_PE
) {
1818 printf("Parity error");
1819 /* This code simply does not work. */
1821 SET_SBIC_cmd(regs
, SBIC_CMD_SET_ATN
);
1823 GET_SBIC_asr(regs
, asr
);
1825 SET_SBIC_cmd(regs
, SBIC_CMD_CLR_ACK
);
1827 if (!(asr
& SBIC_ASR_LCI
))
1828 /* Target wants to send garbled msg*/
1830 printf("--fixing\n");
1831 /* loop until a msgout phase occurs on
1833 while ((csr
& 0x07) != MESG_OUT_PHASE
) {
1834 while ((asr
& SBIC_ASR_BSY
) &&
1836 (SBIC_ASR_DBR
| SBIC_ASR_INT
)))
1837 GET_SBIC_asr(regs
, asr
);
1838 if (asr
& SBIC_ASR_DBR
)
1839 panic("msgin: jammed again!");
1840 GET_SBIC_csr(regs
, csr
);
1841 CSR_TRACE('e', csr
, asr
, dev
->target
);
1842 if ((csr
& 0x07) != MESG_OUT_PHASE
) {
1843 sbicnextstate(dev
, csr
, asr
);
1844 sbic_save_ptrs(dev
, regs
);
1847 /* Should be msg out by now */
1848 SEND_BYTE(regs
, MSG_PARITY_ERROR
);
1857 GET_SBIC_asr(regs
, asr
);
1858 GET_SBIC_csr(regs
, csr
);
1859 CSR_TRACE('X',csr
,asr
,dev
->target
);
1860 QPRINTF(("sbicmsgin pre byte CLR_ACK (csr,asr)=(%02x,%02x)\n",
1862 SET_SBIC_cmd(regs
, SBIC_CMD_CLR_ACK
);
1863 SBIC_WAIT(regs
, SBIC_ASR_INT
, 0);
1868 if (dev
->sc_msg
[0] == 0xff) {
1869 printf("sbicmsgin: sbic swallowed our message\n");
1873 DBGPRINTF(("msgin done csr 0x%x asr 0x%x msg 0x%x\n",
1874 csr
, asr
, dev
->sc_msg
[0]), sync_debug
);
1877 * test whether this is a reply to our sync
1880 if (MSG_ISIDENTIFY(dev
->sc_msg
[0])) {
1882 /* Got IFFY msg -- ack it */
1883 } else if (dev
->sc_msg
[0] == MSG_REJECT
1884 && dev
->sc_sync
[dev
->target
].state
== SYNC_SENT
) {
1885 QPRINTF(("REJECT of SYN"));
1887 DBGPRINTF(("target %d rejected sync, going async\n",
1888 dev
->target
), sync_debug
);
1890 dev
->sc_sync
[dev
->target
].period
= sbic_min_period
;
1891 dev
->sc_sync
[dev
->target
].offset
= 0;
1892 dev
->sc_sync
[dev
->target
].state
= SYNC_DONE
;
1894 SBIC_SYN(dev
->sc_sync
[dev
->target
].offset
,
1895 dev
->sc_sync
[dev
->target
].period
));
1896 } else if ((dev
->sc_msg
[0] == MSG_REJECT
)) {
1897 QPRINTF(("REJECT"));
1899 * we'll never REJECt a REJECT message..
1901 } else if ((dev
->sc_msg
[0] == MSG_SAVE_DATA_PTR
)) {
1902 QPRINTF(("MSG_SAVE_DATA_PTR"));
1904 * don't reject this either.
1906 } else if ((dev
->sc_msg
[0] == MSG_DISCONNECT
)) {
1907 QPRINTF(("DISCONNECT"));
1909 DBGPRINTF(("sbicmsgin: got disconnect msg %s\n",
1910 (dev
->sc_flags
& SBICF_ICMD
) ? "rejecting" : ""),
1911 reselect_debug
> 1 &&
1912 dev
->sc_msg
[0] == MSG_DISCONNECT
);
1914 if (dev
->sc_flags
& SBICF_ICMD
) {
1915 /* We're in immediate mode. Prevent
1917 /* prepare to reject the message, NACK */
1918 SET_SBIC_cmd(regs
, SBIC_CMD_SET_ATN
);
1921 } else if (dev
->sc_msg
[0] == MSG_CMD_COMPLETE
) {
1922 QPRINTF(("CMD_COMPLETE"));
1923 /* !! KLUDGE ALERT !! quite a few drives don't seem to
1924 * really like the current way of sending the
1925 * sync-handshake together with the ident-message, and
1926 * they react by sending command-complete and
1927 * disconnecting right after returning the valid sync
1928 * handshake. So, all I can do is reselect the drive,
1929 * and hope it won't disconnect again. I don't think
1930 * this is valid behavior, but I can't help fixing a
1931 * problem that apparently exists.
1933 * Note: we should not get here on `normal' command
1934 * completion, as that condition is handled by the
1935 * high-level sel&xfer resume command used to walk
1936 * thru status/cc-phase.
1939 DBGPRINTF(("GOT MSG %d! target %d acting weird.."
1940 " waiting for disconnect...\n",
1941 dev
->sc_msg
[0], dev
->target
), sync_debug
);
1943 /* Check to see if sbic is handling this */
1944 GET_SBIC_asr(regs
, asr
);
1945 if (asr
& SBIC_ASR_BSY
)
1946 return SBIC_STATE_RUNNING
;
1948 /* Let's try this: Assume it works and set
1950 dev
->sc_stat
[0] = 0;
1951 } else if (dev
->sc_msg
[0] == MSG_EXT_MESSAGE
1952 && tmpaddr
== &dev
->sc_msg
[1]) {
1953 QPRINTF(("ExtMSG\n"));
1954 /* Read in whole extended message */
1955 SET_SBIC_cmd(regs
, SBIC_CMD_CLR_ACK
);
1956 SBIC_WAIT(regs
, SBIC_ASR_INT
, 0);
1957 GET_SBIC_asr(regs
, asr
);
1958 GET_SBIC_csr(regs
, csr
);
1959 QPRINTF(("CLR ACK asr %02x, csr %02x\n", asr
, csr
));
1960 RECV_BYTE(regs
, *tmpaddr
);
1961 CSR_TRACE('x',csr
,asr
,*tmpaddr
);
1962 /* Wait for command completion IRQ */
1963 SBIC_WAIT(regs
, SBIC_ASR_INT
, 0);
1964 recvlen
= *tmpaddr
++;
1965 QPRINTF(("Recving ext msg, asr %02x csr %02x len %02x\n",
1966 asr
, csr
, recvlen
));
1967 } else if (dev
->sc_msg
[0] == MSG_EXT_MESSAGE
&&
1968 dev
->sc_msg
[1] == 3 &&
1969 dev
->sc_msg
[2] == MSG_SYNC_REQ
) {
1971 dev
->sc_sync
[dev
->target
].period
=
1972 sbicfromscsiperiod(dev
,
1973 regs
, dev
->sc_msg
[3]);
1974 dev
->sc_sync
[dev
->target
].offset
= dev
->sc_msg
[4];
1975 dev
->sc_sync
[dev
->target
].state
= SYNC_DONE
;
1977 SBIC_SYN(dev
->sc_sync
[dev
->target
].offset
,
1978 dev
->sc_sync
[dev
->target
].period
));
1979 printf("%s: target %d now synchronous,"
1980 " period=%dns, offset=%d.\n",
1981 device_xname(&dev
->sc_dev
), dev
->target
,
1982 dev
->sc_msg
[3] * 4, dev
->sc_msg
[4]);
1985 DBGPRINTF(("sbicmsgin: Rejecting message 0x%02x\n",
1986 dev
->sc_msg
[0]), sbic_debug
|| sync_debug
);
1988 /* prepare to reject the message, NACK */
1989 SET_SBIC_cmd(regs
, SBIC_CMD_SET_ATN
);
1994 GET_SBIC_asr(regs
, asr
);
1995 GET_SBIC_csr(regs
, csr
);
1996 CSR_TRACE('X',csr
,asr
,dev
->target
);
1997 QPRINTF(("sbicmsgin pre CLR_ACK (csr,asr)=(%02x,%02x)%d\n",
1998 csr
, asr
, recvlen
));
1999 SET_SBIC_cmd(regs
, SBIC_CMD_CLR_ACK
);
2000 SBIC_WAIT(regs
, SBIC_ASR_INT
, 0);
2003 while ((csr
== SBIC_CSR_MSGIN_W_ACK
) ||
2004 (SBIC_PHASE(csr
) == MESG_IN_PHASE
));
2006 while (recvlen
> 0);
2009 QPRINTF(("sbicmsgin finished: csr %02x, asr %02x\n",csr
, asr
));
2011 /* Should still have one CSR to read */
2012 return SBIC_STATE_RUNNING
;
2025 sbicnextstate(struct sbic_softc
*dev
, u_char csr
, u_char asr
)
2028 struct sbic_acb
*acb
;
2030 int newtarget
, newlun
, wait
;
2034 regs
= &dev
->sc_sbicp
;
2035 acb
= dev
->sc_nexus
;
2037 QPRINTF(("next[%02x,%02x]",asr
,csr
));
2040 case SBIC_CSR_XFERRED
| CMD_PHASE
:
2041 case SBIC_CSR_MIS
| CMD_PHASE
:
2042 case SBIC_CSR_MIS_1
| CMD_PHASE
:
2043 case SBIC_CSR_MIS_2
| CMD_PHASE
:
2044 sbic_save_ptrs(dev
, regs
);
2045 if (sbicxfstart(regs
, acb
->clen
, CMD_PHASE
, sbic_cmd_wait
))
2046 if (sbicxfout(regs
, acb
->clen
,
2047 &acb
->cmd
, CMD_PHASE
))
2051 case SBIC_CSR_XFERRED
| STATUS_PHASE
:
2052 case SBIC_CSR_MIS
| STATUS_PHASE
:
2053 case SBIC_CSR_MIS_1
| STATUS_PHASE
:
2054 case SBIC_CSR_MIS_2
| STATUS_PHASE
:
2056 * this should be the normal i/o completion case.
2057 * get the status & cmd complete msg then let the
2058 * device driver look at what happened.
2060 sbicxfdone(dev
,regs
,dev
->target
);
2062 if (acb
->flags
& ACB_DMA
) {
2063 DBG(dev
->sc_dmatimo
= 0);
2065 dev
->sc_dmafinish(dev
->sc_dmah
, dev
->sc_dmat
, acb
);
2067 dev
->sc_flags
&= ~SBICF_INDMA
;
2069 sbic_scsidone(acb
, dev
->sc_stat
[0]);
2071 return SBIC_STATE_DONE
;
2073 case SBIC_CSR_XFERRED
| DATA_OUT_PHASE
:
2074 case SBIC_CSR_XFERRED
| DATA_IN_PHASE
:
2075 case SBIC_CSR_MIS
| DATA_OUT_PHASE
:
2076 case SBIC_CSR_MIS
| DATA_IN_PHASE
:
2077 case SBIC_CSR_MIS_1
| DATA_OUT_PHASE
:
2078 case SBIC_CSR_MIS_1
| DATA_IN_PHASE
:
2079 case SBIC_CSR_MIS_2
| DATA_OUT_PHASE
:
2080 case SBIC_CSR_MIS_2
| DATA_IN_PHASE
:
2084 if ((acb
->xs
->xs_control
& XS_CTL_POLL
) ||
2085 (dev
->sc_flags
& SBICF_ICMD
) ||
2086 (acb
->flags
& ACB_DMA
) == 0) {
2088 SET_SBIC_control(regs
, SBIC_CTL_EDI
| SBIC_CTL_IDI
);
2089 if (acb
->datalen
<= 0) {
2090 printf("sbicnextstate:xfer count %d asr%x csr%x\n",
2091 acb
->datalen
, asr
, csr
);
2094 wait
= sbic_data_wait
;
2095 if (sbicxfstart(regs
, acb
->datalen
,
2096 SBIC_PHASE(csr
), wait
)) {
2097 if (SBIC_PHASE(csr
) == DATA_IN_PHASE
)
2099 i
= sbicxfin(regs
, acb
->datalen
,
2102 i
= sbicxfout(regs
, acb
->datalen
,
2103 acb
->data
, SBIC_PHASE(csr
));
2105 acb
->data
+= acb
->datalen
- i
;
2108 /* Transfer = using DMA */
2110 * do scatter-gather dma
2111 * hacking the controller chip, ouch..
2113 SET_SBIC_control(regs
,
2114 SBIC_CTL_EDI
| SBIC_CTL_IDI
| dev
->sc_dmamode
);
2116 * set next dma addr and dec count
2118 sbic_save_ptrs(dev
, regs
);
2120 if (acb
->offset
>= acb
->datalen
) {
2121 printf("sbicnextstate:xfer offset %d asr%x csr%x\n",
2122 acb
->offset
, asr
, csr
);
2125 DBGPRINTF(("next dmanext: %d(offset %d)\n",
2126 dev
->target
, acb
->offset
),
2127 data_pointer_debug
> 1);
2128 DBG(dev
->sc_dmatimo
= 1);
2131 dev
->sc_dmanext(dev
->sc_dmah
, dev
->sc_dmat
,
2133 DBGPRINTF(("dmanext transfering %ld bytes\n",
2134 acb
->sc_tcnt
), data_pointer_debug
);
2135 SBIC_TC_PUT(regs
, (unsigned)acb
->sc_tcnt
);
2136 SET_SBIC_cmd(regs
, SBIC_CMD_XFER_INFO
);
2137 dev
->sc_flags
|= SBICF_INDMA
;
2141 case SBIC_CSR_XFERRED
| MESG_IN_PHASE
:
2142 case SBIC_CSR_MIS
| MESG_IN_PHASE
:
2143 case SBIC_CSR_MIS_1
| MESG_IN_PHASE
:
2144 case SBIC_CSR_MIS_2
| MESG_IN_PHASE
:
2146 return sbicmsgin(dev
);
2148 case SBIC_CSR_MSGIN_W_ACK
:
2149 /* Dunno what I'm ACKing */
2150 SET_SBIC_cmd(regs
, SBIC_CMD_CLR_ACK
);
2151 printf("Acking unknown msgin CSR:%02x",csr
);
2154 case SBIC_CSR_XFERRED
| MESG_OUT_PHASE
:
2155 case SBIC_CSR_MIS
| MESG_OUT_PHASE
:
2156 case SBIC_CSR_MIS_1
| MESG_OUT_PHASE
:
2157 case SBIC_CSR_MIS_2
| MESG_OUT_PHASE
:
2159 DBGPRINTF(("sending REJECT msg to last msg.\n"), sync_debug
);
2161 sbic_save_ptrs(dev
, regs
);
2163 * Should only get here on reject, since it's always
2164 * US that initiate a sync transfer.
2166 SEND_BYTE(regs
, MSG_REJECT
);
2168 if (asr
& (SBIC_ASR_BSY
| SBIC_ASR_LCI
| SBIC_ASR_CIP
))
2169 printf("next: REJECT sent asr %02x\n", asr
);
2171 return SBIC_STATE_RUNNING
;
2174 case SBIC_CSR_DISC_1
:
2175 dev
->sc_flags
&= ~(SBICF_INDMA
| SBICF_SELECTED
);
2177 /* Try to schedule another target */
2178 DBGPRINTF(("sbicnext target %d disconnected\n", dev
->target
),
2179 reselect_debug
> 1);
2181 TAILQ_INSERT_HEAD(&dev
->nexus_list
, acb
, chain
);
2182 ++dev
->sc_tinfo
[dev
->target
].dconns
;
2183 dev
->sc_nexus
= NULL
;
2185 if ((acb
->xs
->xs_control
& XS_CTL_POLL
)
2186 || (dev
->sc_flags
& SBICF_ICMD
)
2187 || (!sbic_parallel_operations
)) {
2189 return SBIC_STATE_DISCONNECT
;
2193 return SBIC_STATE_DISCONNECT
;
2195 case SBIC_CSR_RSLT_NI
:
2196 case SBIC_CSR_RSLT_IFY
:
2197 GET_SBIC_rselid(regs
, newtarget
);
2198 /* check SBIC_RID_SIV? */
2199 newtarget
&= SBIC_RID_MASK
;
2200 if (csr
== SBIC_CSR_RSLT_IFY
) {
2201 /* Read IFY msg to avoid lockup */
2202 GET_SBIC_data(regs
, newlun
);
2204 newlun
&= SBIC_TLUN_MASK
;
2205 CSR_TRACE('r',csr
,asr
,newtarget
);
2207 /* Need to get IFY message */
2208 for (newlun
= 256; newlun
; --newlun
) {
2209 GET_SBIC_asr(regs
, asr
);
2210 if (asr
& SBIC_ASR_INT
)
2214 newlun
= 0; /* XXXX */
2215 if ((asr
& SBIC_ASR_INT
) == 0) {
2217 DBGPRINTF(("RSLT_NI - no IFFY message? asr %x\n",
2218 asr
), reselect_debug
);
2221 GET_SBIC_csr(regs
,csr
);
2222 CSR_TRACE('n',csr
,asr
,newtarget
);
2223 if ((csr
== (SBIC_CSR_MIS
| MESG_IN_PHASE
)) ||
2224 (csr
== (SBIC_CSR_MIS_1
| MESG_IN_PHASE
)) ||
2225 (csr
== (SBIC_CSR_MIS_2
| MESG_IN_PHASE
))) {
2227 newlun
= dev
->sc_msg
[0] & 7;
2229 printf("RSLT_NI - not MESG_IN_PHASE %x\n",
2235 DBGPRINTF(("sbicnext: reselect %s from targ %d lun %d\n",
2236 csr
== SBIC_CSR_RSLT_NI
? "NI" : "IFY",
2238 reselect_debug
> 1 ||
2239 (reselect_debug
&& csr
== SBIC_CSR_RSLT_NI
));
2241 if (dev
->sc_nexus
) {
2242 DBGPRINTF(("%s: reselect %s with active command\n",
2243 device_xname(&dev
->sc_dev
),
2244 csr
== SBIC_CSR_RSLT_NI
? "NI" : "IFY"),
2245 reselect_debug
> 1);
2246 #if defined(DDB) && defined (DEBUG)
2250 TAILQ_INSERT_HEAD(&dev
->ready_list
, dev
->sc_nexus
,
2252 dev
->sc_tinfo
[dev
->target
].lubusy
&= ~(1 << dev
->lun
);
2253 dev
->sc_nexus
= NULL
;
2255 /* Reload sync values for this target */
2256 if (dev
->sc_sync
[newtarget
].state
== SYNC_DONE
)
2258 SBIC_SYN(dev
->sc_sync
[newtarget
].offset
,
2259 dev
->sc_sync
[newtarget
].period
));
2261 SET_SBIC_syn(regs
, SBIC_SYN (0, sbic_min_period
));
2262 for (acb
= dev
->nexus_list
.tqh_first
; acb
;
2263 acb
= acb
->chain
.tqe_next
) {
2264 if (acb
->xs
->xs_periph
->periph_target
!= newtarget
||
2265 acb
->xs
->xs_periph
->periph_lun
!= newlun
)
2267 TAILQ_REMOVE(&dev
->nexus_list
, acb
, chain
);
2268 dev
->sc_nexus
= acb
;
2269 dev
->sc_flags
|= SBICF_SELECTED
;
2270 dev
->target
= newtarget
;
2275 printf("%s: reselect %s targ %d not in nexus_list %p\n",
2276 device_xname(&dev
->sc_dev
),
2277 csr
== SBIC_CSR_RSLT_NI
? "NI" : "IFY", newtarget
,
2278 &dev
->nexus_list
.tqh_first
);
2279 panic("bad reselect in sbic");
2281 if (csr
== SBIC_CSR_RSLT_IFY
)
2282 SET_SBIC_cmd(regs
, SBIC_CMD_CLR_ACK
);
2288 * Something unexpected happened -- deal with it.
2290 printf("sbicnextstate: aborting csr %02x asr %02x\n", csr
,
2295 DBG(dev
->sc_dmatimo
= 0);
2297 if (dev
->sc_flags
& SBICF_INDMA
) {
2298 dev
->sc_dmafinish(dev
->sc_dmah
, dev
->sc_dmat
, acb
);
2299 dev
->sc_flags
&= ~SBICF_INDMA
;
2300 DBG(dev
->sc_dmatimo
= 0);
2302 SET_SBIC_control(regs
, SBIC_CTL_EDI
| SBIC_CTL_IDI
);
2303 sbicerror(dev
, regs
, csr
);
2304 sbicabort(dev
, regs
, "next");
2305 sbic_scsidone(acb
, -1);
2307 return SBIC_STATE_ERROR
;
2311 return SBIC_STATE_RUNNING
;
2315 sbictoscsiperiod(struct sbic_softc
*dev
, sbic_regmap_p regs
, int a
)
2320 * cycle = DIV / (2*CLK)
2322 * best we can do is 200ns at 20 MHz, 2 cycles
2325 GET_SBIC_myid(regs
,fs
);
2326 fs
= (fs
>> 6) + 2; /* DIV */
2327 fs
= (fs
* 10000) / (dev
->sc_clkfreq
<< 1); /* Cycle, in ns */
2329 a
= 8; /* map to Cycles */
2330 return (fs
* a
) >> 2; /* in 4 ns units */
2334 sbicfromscsiperiod(struct sbic_softc
*dev
, sbic_regmap_p regs
, int p
)
2336 register unsigned int fs
, ret
;
2338 /* Just the inverse of the above */
2340 GET_SBIC_myid(regs
, fs
);
2341 fs
= (fs
>> 6) + 2; /* DIV */
2342 fs
= (fs
* 10000) / (dev
->sc_clkfreq
<< 1); /* Cycle, in ns */
2344 ret
= p
<< 2; /* in ns units */
2345 ret
= ret
/ fs
; /* in Cycles */
2346 if (ret
< sbic_min_period
)
2347 return sbic_min_period
;
2349 /* verify rounding */
2350 if (sbictoscsiperiod(dev
, regs
, ret
) < p
)
2352 return (ret
>= 8) ? 0 : ret
;
2362 GET_SBIC_asr(debug_sbic_regs
,asr
);
2363 GET_SBIC_csr(debug_sbic_regs
,csr
);
2364 printf("%s: asr:csr(%02x:%02x)->(%02x:%02x)\n",
2365 (routine
== 1) ? "sbicgo" :
2366 (routine
== 2) ? "sbicintr" :
2367 (routine
== 3) ? "sbicicmd" :
2368 (routine
== 4) ? "sbicnext" : "unknown",
2369 debug_asr
, debug_csr
, asr
, csr
);
2374 sbictimeout(struct sbic_softc
*dev
)
2379 if (dev
->sc_dmatimo
) {
2380 if (dev
->sc_dmatimo
> 1) {
2381 printf("%s: DMA timeout #%d\n",
2382 device_xname(&dev
->sc_dev
), dev
->sc_dmatimo
- 1);
2383 GET_SBIC_asr(&dev
->sc_sbicp
, asr
);
2384 if (asr
& SBIC_ASR_INT
) {
2385 /* We need to service a missed IRQ */
2386 printf("Servicing a missed int:(%02x,%02x)->(%02x,?)\n",
2387 debug_asr
, debug_csr
, asr
);
2395 callout_reset(&dev
->sc_timo_ch
, 30 * hz
,
2396 (void *)sbictimeout
, dev
);
2400 sbic_dump_acb(struct sbic_acb
*acb
)
2402 u_char
*b
= (u_char
*) &acb
->cmd
;
2405 printf("acb@%p ", acb
);
2406 if (acb
->xs
== NULL
) {
2407 printf("<unused>\n");
2410 printf("(%d:%d) flags %2x clen %2d cmd ",
2411 acb
->xs
->xs_periph
->periph_target
,
2412 acb
->xs
->xs_periph
->periph_lun
, acb
->flags
, acb
->clen
);
2413 for (i
= acb
->clen
; i
; --i
)
2414 printf(" %02x", *b
++);
2416 printf(" xs: %8p data %8p:%04x ", acb
->xs
, acb
->xs
->data
,
2418 printf("tcnt %lx\n", acb
->sc_tcnt
);
2422 sbic_dump(struct sbic_softc
*dev
)
2426 struct sbic_acb
*acb
;
2431 regs
= &dev
->sc_sbicp
;
2433 printf("csr trace: ");
2436 printf("%c%02x%02x%02x ", csr_trace
[i
].whr
,
2437 csr_trace
[i
].csr
, csr_trace
[i
].asr
, csr_trace
[i
].xtn
);
2438 switch(csr_trace
[i
].whr
) {
2440 printf("go "); break;
2442 printf("select "); break;
2444 printf("select+ "); break;
2446 printf("intr "); break;
2448 printf("finish "); break;
2450 printf("out "); break;
2452 printf("in "); break;
2454 printf("msgin "); break;
2456 printf("msginx "); break;
2458 printf("msginX "); break;
2460 printf("reselect "); break;
2462 printf("icmd "); break;
2464 printf("abort "); break;
2468 switch(csr_trace
[i
].csr
) {
2470 printf("INITIATOR"); break;
2472 printf("S_XFERRED"); break;
2474 printf("MSGIN_ACK"); break;
2476 printf("DISC"); break;
2478 printf("SEL_TIMEO"); break;
2480 printf("RSLT_NI"); break;
2482 printf("RSLT_IFY"); break;
2484 printf("DISC_1"); break;
2485 case 0x18: case 0x19: case 0x1a:
2486 case 0x1b: case 0x1e: case 0x1f:
2487 case 0x28: case 0x29: case 0x2a:
2488 case 0x2b: case 0x2e: case 0x2f:
2489 case 0x48: case 0x49: case 0x4a:
2490 case 0x4b: case 0x4e: case 0x4f:
2491 case 0x88: case 0x89: case 0x8a:
2492 case 0x8b: case 0x8e: case 0x8f:
2493 switch(csr_trace
[i
].csr
& 0xf0) {
2495 printf("DONE_"); break;
2497 printf("STOP_"); break;
2499 printf("ERR_"); break;
2501 printf("REQ_"); break;
2503 switch(csr_trace
[i
].csr
& 7) {
2505 printf("DATA_OUT"); break;
2507 printf("DATA_IN"); break;
2509 printf("CMD"); break;
2511 printf("STATUS"); break;
2513 printf("MSG_OUT"); break;
2515 printf("MSG_IN"); break;
2517 printf("invld phs");
2520 default: printf("****"); break;
2522 if (csr_trace
[i
].asr
& SBIC_ASR_INT
)
2524 if (csr_trace
[i
].asr
& SBIC_ASR_LCI
)
2526 if (csr_trace
[i
].asr
& SBIC_ASR_BSY
)
2528 if (csr_trace
[i
].asr
& SBIC_ASR_CIP
)
2531 i
= (i
+ 1) & (CSR_TRACE_SIZE
- 1);
2532 } while (i
!= csr_traceptr
);
2534 GET_SBIC_asr(regs
, asr
);
2535 if ((asr
& SBIC_ASR_INT
) == 0)
2536 GET_SBIC_csr(regs
, csr
);
2539 printf("%s@%p regs %p asr %x csr %x\n", device_xname(&dev
->sc_dev
),
2540 dev
, regs
, asr
, csr
);
2541 if ((acb
= dev
->free_list
.tqh_first
)) {
2542 printf("Free list:\n");
2545 acb
= acb
->chain
.tqe_next
;
2548 if ((acb
= dev
->ready_list
.tqh_first
)) {
2549 printf("Ready list:\n");
2552 acb
= acb
->chain
.tqe_next
;
2555 if ((acb
= dev
->nexus_list
.tqh_first
)) {
2556 printf("Nexus list:\n");
2559 acb
= acb
->chain
.tqe_next
;
2562 if (dev
->sc_nexus
) {
2564 sbic_dump_acb(dev
->sc_nexus
);
2566 printf("targ %d lun %d flags %x\n",
2567 dev
->target
, dev
->lun
, dev
->sc_flags
);
2568 for (i
= 0; i
< 8; ++i
) {
2569 if (dev
->sc_tinfo
[i
].cmds
> 2) {
2570 printf("tgt %d: cmds %d disc %d lubusy %x\n",
2571 i
, dev
->sc_tinfo
[i
].cmds
,
2572 dev
->sc_tinfo
[i
].dconns
,
2573 dev
->sc_tinfo
[i
].lubusy
);