1 /* $NetBSD: sbic.c,v 1.64 2009/03/18 17:06:42 cegger Exp $ */
4 * Copyright (c) 1990 The Regents of the University of California.
7 * This code is derived from software contributed to Berkeley by
8 * Van Jacobson of Lawrence Berkeley Laboratory.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * @(#)scsi.c 7.5 (Berkeley) 5/4/91
38 * Copyright (c) 1994 Christian E. Hopps
40 * This code is derived from software contributed to Berkeley by
41 * Van Jacobson of Lawrence Berkeley Laboratory.
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
46 * 1. Redistributions of source code must retain the above copyright
47 * notice, this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright
49 * notice, this list of conditions and the following disclaimer in the
50 * documentation and/or other materials provided with the distribution.
51 * 3. All advertising materials mentioning features or use of this software
52 * must display the following acknowledgement:
53 * This product includes software developed by the University of
54 * California, Berkeley and its contributors.
55 * 4. Neither the name of the University nor the names of its contributors
56 * may be used to endorse or promote products derived from this software
57 * without specific prior written permission.
59 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
71 * @(#)scsi.c 7.5 (Berkeley) 5/4/91
75 * AMIGA AMD 33C93 scsi adaptor driver
80 #include <sys/cdefs.h>
81 __KERNEL_RCSID(0, "$NetBSD: sbic.c,v 1.64 2009/03/18 17:06:42 cegger Exp $");
83 #include <sys/param.h>
84 #include <sys/systm.h>
85 #include <sys/device.h>
86 #include <sys/kernel.h> /* For hz */
87 #include <sys/disklabel.h>
89 #include <dev/scsipi/scsi_all.h>
90 #include <dev/scsipi/scsipi_all.h>
91 #include <dev/scsipi/scsiconf.h>
92 #include <uvm/uvm_extern.h>
93 #include <machine/cpu.h>
94 #include <amiga/amiga/device.h>
95 #include <amiga/amiga/custom.h>
96 #include <amiga/amiga/isr.h>
97 #include <amiga/dev/dmavar.h>
98 #include <amiga/dev/sbicreg.h>
99 #include <amiga/dev/sbicvar.h>
101 /* These are for bounce buffers */
102 #include <amiga/amiga/cc.h>
103 #include <amiga/dev/zbusvar.h>
105 /* Since I can't find this in any other header files */
106 #define SCSI_PHASE(reg) (reg&0x07)
110 * In u-seconds, primarily for state changes on the SPC.
112 #define SBIC_CMD_WAIT 50000 /* wait per step of 'immediate' cmds */
113 #define SBIC_DATA_WAIT 50000 /* wait per data in/out step */
114 #define SBIC_INIT_WAIT 50000 /* wait per step (both) during init */
116 #define SBIC_WAIT(regs, until, timeo) sbicwait(regs, until, timeo, __LINE__)
118 int sbicicmd(struct sbic_softc
*, int, int, void *, int, void *, int);
119 int sbicgo(struct sbic_softc
*, struct scsipi_xfer
*);
120 int sbicdmaok(struct sbic_softc
*, struct scsipi_xfer
*);
121 int sbicwait(sbic_regmap_t
, char, int , int);
122 int sbiccheckdmap(void *, u_long
, u_long
);
123 int sbicselectbus(struct sbic_softc
*, sbic_regmap_t
, u_char
, u_char
, u_char
);
124 int sbicxfstart(sbic_regmap_t
, int, u_char
, int);
125 int sbicxfout(sbic_regmap_t regs
, int, void *, int);
126 int sbicfromscsiperiod(struct sbic_softc
*, sbic_regmap_t
, int);
127 int sbictoscsiperiod(struct sbic_softc
*, sbic_regmap_t
, int);
128 int sbicpoll(struct sbic_softc
*);
129 int sbicnextstate(struct sbic_softc
*, u_char
, u_char
);
130 int sbicmsgin(struct sbic_softc
*);
131 int sbicxfin(sbic_regmap_t regs
, int, void *);
132 int sbicabort(struct sbic_softc
*, sbic_regmap_t
, const char *);
133 void sbicxfdone(struct sbic_softc
*, sbic_regmap_t
, int);
134 void sbicerror(struct sbic_softc
*, sbic_regmap_t
, u_char
);
135 void sbicstart(struct sbic_softc
*);
136 void sbicreset(struct sbic_softc
*);
137 void sbic_scsidone(struct sbic_acb
*, int);
138 void sbic_sched(struct sbic_softc
*);
139 void sbic_save_ptrs(struct sbic_softc
*, sbic_regmap_t
,int,int);
140 void sbic_load_ptrs(struct sbic_softc
*, sbic_regmap_t
,int,int);
142 void sbicdumpstate(void);
143 void sbic_dump_acb(struct sbic_acb
*);
147 * Synch xfer parameters, and timing conversions
149 int sbic_min_period
= SBIC_SYN_MIN_PERIOD
; /* in cycles = f(ICLK,FSn) */
150 int sbic_max_offset
= SBIC_SYN_MAX_OFFSET
; /* pure number */
152 int sbic_cmd_wait
= SBIC_CMD_WAIT
;
153 int sbic_data_wait
= SBIC_DATA_WAIT
;
154 int sbic_init_wait
= SBIC_INIT_WAIT
;
157 * was broken before.. now if you want this you get it for all drives
158 * on sbic controllers.
160 u_char sbic_inhibit_sync
[8];
161 int sbic_enable_reselect
= 1;
162 int sbic_clock_override
= 0;
164 int sbic_parallel_operations
= 1;
167 sbic_regmap_t debug_sbic_regs
;
168 int sbicdma_ops
= 0; /* total DMA operations */
169 int sbicdma_bounces
= 0; /* number operations using bounce buffer */
170 int sbicdma_hits
= 0; /* number of DMA chains that were contiguous */
171 int sbicdma_misses
= 0; /* number of DMA chains that were not contiguous */
172 int sbicdma_saves
= 0;
173 #define QPRINTF(a) if (sbic_debug > 1) printf a
176 int sbic_dma_debug
= 0;
177 int reselect_debug
= 0;
178 int data_pointer_debug
= 0;
179 u_char debug_asr
, debug_csr
, routine
;
180 void sbictimeout(struct sbic_softc
*dev
);
182 #define CSR_TRACE_SIZE 32
184 #define CSR_TRACE(w,c,a,x) do { \
185 int s_csr_trace = splbio(); \
186 csr_trace[csr_traceptr].whr = (w); csr_trace[csr_traceptr].csr = (c); \
187 csr_trace[csr_traceptr].asr = (a); csr_trace[csr_traceptr].xtn = (x); \
188 dma_cachectl((void *)&csr_trace[csr_traceptr], sizeof(csr_trace[0])); \
189 csr_traceptr = (csr_traceptr + 1) & (CSR_TRACE_SIZE - 1); \
190 /* dma_cachectl((void *)&csr_traceptr, sizeof(csr_traceptr));*/ \
194 int csr_tracesize
= CSR_TRACE_SIZE
;
200 } csr_trace
[CSR_TRACE_SIZE
];
202 #define CSR_TRACE(w,c,a,x)
205 #define SBIC_TRACE_SIZE 0
207 #define SBIC_TRACE(dev) do { \
209 sbic_trace[sbic_traceptr].sp = &s; \
210 sbic_trace[sbic_traceptr].line = __LINE__; \
211 sbic_trace[sbic_traceptr].sr = s; \
212 sbic_trace[sbic_traceptr].csr = csr_traceptr; \
213 dma_cachectl(&sbic_trace[sbic_traceptr], sizeof(sbic_trace[0])); \
214 sbic_traceptr = (sbic_traceptr + 1) & (SBIC_TRACE_SIZE - 1); \
215 dma_cachectl(&sbic_traceptr, sizeof(sbic_traceptr)); \
216 if (dev) dma_cachectl(dev, sizeof(*dev)); \
220 int sbic_tracesize
= SBIC_TRACE_SIZE
;
226 } sbic_trace
[SBIC_TRACE_SIZE
];
228 #define SBIC_TRACE(dev)
233 #define CSR_TRACE(w,c,a,x)
234 #define SBIC_TRACE(dev)
238 * default minphys routine for sbic based controllers
241 sbic_minphys(struct buf
*bp
)
245 * No max transfer at this level.
251 * Save DMA pointers. Take into account partial transfer. Shut down DMA.
254 sbic_save_ptrs(struct sbic_softc
*dev
, sbic_regmap_t regs
, int target
, int lun
)
257 struct sbic_acb
* acb
;
260 if( !dev
->sc_cur
) return;
261 if( !(dev
->sc_flags
& SBICF_INDMA
) ) return; /* DMA not active */
268 GET_SBIC_asr(regs
, asr
);
269 if( asr
& SBIC_ASR_DBR
) {
270 printf("sbic_save_ptrs: asr %02x canceled!\n", asr
);
275 } while( asr
& (SBIC_ASR_BSY
|SBIC_ASR_CIP
) );
277 /* Save important state */
278 /* must be done before dmastop */
279 acb
->sc_dmacmd
= dev
->sc_dmacmd
;
280 SBIC_TC_GET(regs
, count
);
282 /* Shut down DMA ====CAREFUL==== */
283 dev
->sc_dmastop(dev
);
284 dev
->sc_flags
&= ~SBICF_INDMA
;
285 SBIC_TC_PUT(regs
, 0);
288 if(!count
&& sbic_debug
) printf("%dcount0",target
);
289 if(data_pointer_debug
== -1)
290 printf("SBIC saving target %d data pointers from (%p,%x)%xASR:%02x",
291 target
, dev
->sc_cur
->dc_addr
, dev
->sc_cur
->dc_count
,
292 acb
->sc_dmacmd
, asr
);
295 /* Fixup partial xfers */
296 acb
->sc_kv
.dc_addr
+= (dev
->sc_tcnt
- count
);
297 acb
->sc_kv
.dc_count
-= (dev
->sc_tcnt
- count
);
298 acb
->sc_pa
.dc_addr
+= (dev
->sc_tcnt
- count
);
299 acb
->sc_pa
.dc_count
-= ((dev
->sc_tcnt
- count
)>>1);
301 acb
->sc_tcnt
= dev
->sc_tcnt
= count
;
303 if(data_pointer_debug
)
304 printf(" at (%p,%x):%x\n",
305 dev
->sc_cur
->dc_addr
, dev
->sc_cur
->dc_count
,count
);
314 * DOES NOT RESTART DMA!!!
317 sbic_load_ptrs(struct sbic_softc
*dev
, sbic_regmap_t regs
, int target
, int lun
)
320 char* vaddr
, * paddr
;
321 struct sbic_acb
*acb
;
325 if( !acb
->sc_kv
.dc_count
) {
326 /* No data to xfer */
333 dev
->sc_last
= dev
->sc_cur
= &acb
->sc_pa
;
334 dev
->sc_tcnt
= acb
->sc_tcnt
;
335 dev
->sc_dmacmd
= acb
->sc_dmacmd
;
340 if( !dev
->sc_tcnt
) {
341 /* sc_tcnt == 0 implies end of segment */
343 /* do kvm to pa mappings */
344 paddr
= acb
->sc_pa
.dc_addr
=
345 (char *) kvtop(acb
->sc_kv
.dc_addr
);
347 vaddr
= acb
->sc_kv
.dc_addr
;
348 count
= acb
->sc_kv
.dc_count
;
349 for(count
= (PAGE_SIZE
- ((int)vaddr
& PGOFSET
));
350 count
< acb
->sc_kv
.dc_count
351 && (char*)kvtop(vaddr
+ count
+ 4) == paddr
+ count
+ 4;
353 /* If it's all contiguous... */
354 if(count
> acb
->sc_kv
.dc_count
) {
355 count
= acb
->sc_kv
.dc_count
;
364 acb
->sc_tcnt
= count
;
365 acb
->sc_pa
.dc_count
= count
>> 1;
368 if(data_pointer_debug
)
369 printf("DMA recalc:kv(%p,%x)pa(%p,%lx)\n",
378 if(data_pointer_debug
)
379 printf("SBIC restoring target %d data pointers at (%p,%x)%x\n",
380 target
, dev
->sc_cur
->dc_addr
, dev
->sc_cur
->dc_count
,
387 * used by specific sbic controller
389 * it appears that the higher level code does nothing with LUN's
390 * so I will too. I could plug it in, however so could they
391 * in scsi_scsipi_cmd().
394 sbic_scsipi_request(struct scsipi_channel
*chan
, scsipi_adapter_req_t req
,
397 struct scsipi_xfer
*xs
;
398 struct scsipi_periph
*periph
;
399 struct sbic_acb
*acb
;
400 struct sbic_softc
*dev
= (void *)chan
->chan_adapter
->adapt_dev
;
404 case ADAPTER_REQ_RUN_XFER
:
406 periph
= xs
->xs_periph
;
409 flags
= xs
->xs_control
;
411 if (flags
& XS_CTL_DATA_UIO
)
412 panic("sbic: scsi data uio requested");
414 if (dev
->sc_nexus
&& flags
& XS_CTL_POLL
)
415 panic("sbic_scsipi_request: busy");
418 acb
= dev
->free_list
.tqh_first
;
420 TAILQ_REMOVE(&dev
->free_list
, acb
, chain
);
425 scsipi_printaddr(periph
);
426 printf("unable to allocate acb\n");
427 panic("sbic_scsipi_request");
430 acb
->flags
= ACB_ACTIVE
;
431 if (flags
& XS_CTL_DATA_IN
)
432 acb
->flags
|= ACB_DATAIN
;
434 memcpy(&acb
->cmd
, xs
->cmd
, xs
->cmdlen
);
435 acb
->clen
= xs
->cmdlen
;
436 acb
->sc_kv
.dc_addr
= xs
->data
;
437 acb
->sc_kv
.dc_count
= xs
->datalen
;
438 acb
->pa_addr
= xs
->data
? (char *)kvtop(xs
->data
) : 0; /* XXXX check */
440 if (flags
& XS_CTL_POLL
) {
443 * This has major side effects - it locks up the machine
446 dev
->sc_flags
|= SBICF_ICMD
;
451 dev
->sc_stat
[0] = -1;
453 dev
->target
= periph
->periph_target
;
454 dev
->lun
= periph
->periph_lun
;
455 stat
= sbicicmd(dev
, dev
->target
, dev
->lun
,
456 &acb
->cmd
, acb
->clen
,
457 acb
->sc_kv
.dc_addr
, acb
->sc_kv
.dc_count
);
458 } while (dev
->sc_nexus
!= acb
);
459 sbic_scsidone(acb
, stat
);
467 TAILQ_INSERT_TAIL(&dev
->ready_list
, acb
, chain
);
476 * nothing is active, try to start it now.
482 /* TODO: add sbic_poll to do XS_CTL_POLL operations */
484 if (flags
& XS_CTL_POLL
)
489 case ADAPTER_REQ_GROW_RESOURCES
:
492 case ADAPTER_REQ_SET_XFER_MODE
:
498 * attempt to start the next available command
501 sbic_sched(struct sbic_softc
*dev
)
503 struct scsipi_xfer
*xs
;
504 struct scsipi_periph
*periph
;
505 struct sbic_acb
*acb
;
506 int flags
, /*phase,*/ stat
, i
;
510 return; /* a command is current active */
513 for (acb
= dev
->ready_list
.tqh_first
; acb
; acb
= acb
->chain
.tqe_next
) {
514 periph
= acb
->xs
->xs_periph
;
515 i
= periph
->periph_target
;
516 if (!(dev
->sc_tinfo
[i
].lubusy
& (1 << periph
->periph_lun
))) {
517 struct sbic_tinfo
*ti
= &dev
->sc_tinfo
[i
];
519 TAILQ_REMOVE(&dev
->ready_list
, acb
, chain
);
521 ti
= &dev
->sc_tinfo
[periph
->periph_target
];
522 ti
->lubusy
|= (1 << periph
->periph_lun
);
523 acb
->sc_pa
.dc_addr
= acb
->pa_addr
; /* XXXX check */
530 return; /* did not find an available command */
532 dev
->sc_xs
= xs
= acb
->xs
;
533 periph
= xs
->xs_periph
;
534 flags
= xs
->xs_control
;
536 if (flags
& XS_CTL_RESET
)
540 if( data_pointer_debug
> 1 )
541 printf("sbic_sched(%d,%d)\n", periph
->periph_target
,
544 dev
->sc_stat
[0] = -1;
545 dev
->target
= periph
->periph_target
;
546 dev
->lun
= periph
->periph_lun
;
547 if ( flags
& XS_CTL_POLL
|| ( !sbic_parallel_operations
548 && (sbicdmaok(dev
, xs
) == 0)))
549 stat
= sbicicmd(dev
, periph
->periph_target
,
550 periph
->periph_lun
, &acb
->cmd
,
551 acb
->clen
, acb
->sc_kv
.dc_addr
, acb
->sc_kv
.dc_count
);
552 else if (sbicgo(dev
, xs
) == 0 && xs
->error
!= XS_SELTIMEOUT
) {
556 stat
= dev
->sc_stat
[0];
558 sbic_scsidone(acb
, stat
);
563 sbic_scsidone(struct sbic_acb
*acb
, int stat
)
565 struct scsipi_xfer
*xs
;
566 struct scsipi_periph
*periph
;
567 struct sbic_softc
*dev
;
571 periph
= xs
->xs_periph
;
572 dev
= (void *)periph
->periph_channel
->chan_adapter
->adapt_dev
;
575 if (acb
== NULL
|| xs
== NULL
) {
576 printf("sbic_scsidone -- (%d,%d) no scsi_xfer\n",
577 dev
->target
, dev
->lun
);
586 xs
->resid
= 0; /* XXXX */
588 if( data_pointer_debug
> 1 )
589 printf("scsidone: (%d,%d)->(%d,%d)%02x\n",
590 periph
->periph_target
, periph
->periph_lun
,
591 dev
->target
, dev
->lun
, stat
);
592 if( periph
->periph_target
==
593 periph
->periph_channel
->chan_id
)
594 panic("target == hostid");
597 if (xs
->error
== XS_NOERROR
) {
598 if (stat
== SCSI_CHECK
|| stat
== SCSI_BUSY
)
603 * Remove the ACB from whatever queue it's on. We have to do a bit of
604 * a hack to figure out which queue it's on. Note that it is *not*
605 * necessary to cdr down the ready queue, but we must cdr down the
606 * nexus queue and see if it's there, so we can mark the unit as no
607 * longer busy. This code is sickening, but it works.
609 if (acb
== dev
->sc_nexus
) {
610 dev
->sc_nexus
= NULL
;
612 dev
->sc_tinfo
[periph
->periph_target
].lubusy
&=
613 ~(1<<periph
->periph_lun
);
614 if (dev
->ready_list
.tqh_first
)
615 dosched
= 1; /* start next command */
616 } else if (dev
->ready_list
.tqh_last
== &acb
->chain
.tqe_next
) {
617 TAILQ_REMOVE(&dev
->ready_list
, acb
, chain
);
619 register struct sbic_acb
*acb2
;
620 for (acb2
= dev
->nexus_list
.tqh_first
; acb2
;
621 acb2
= acb2
->chain
.tqe_next
) {
623 TAILQ_REMOVE(&dev
->nexus_list
, acb
, chain
);
624 dev
->sc_tinfo
[periph
->periph_target
].lubusy
625 &= ~(1<<periph
->periph_lun
);
631 else if (acb
->chain
.tqe_next
) {
632 TAILQ_REMOVE(&dev
->ready_list
, acb
, chain
);
634 printf("%s: can't find matching acb\n",
635 dev
->sc_dev
.dv_xname
);
641 /* Put it on the free list. */
642 acb
->flags
= ACB_FREE
;
643 TAILQ_INSERT_HEAD(&dev
->free_list
, acb
, chain
);
645 dev
->sc_tinfo
[periph
->periph_target
].cmds
++;
655 sbicdmaok(struct sbic_softc
*dev
, struct scsipi_xfer
*xs
)
657 if (sbic_no_dma
|| !xs
->datalen
|| xs
->datalen
& 0x1 ||
658 (u_int
)xs
->data
& 0x3)
661 * controller supports dma to any addresses?
663 else if ((dev
->sc_flags
& SBICF_BADDMA
) == 0)
666 * this address is ok for DMA?
668 else if (sbiccheckdmap(xs
->data
, xs
->datalen
, dev
->sc_dmamask
) == 0)
671 * we have a bounce buffer?
673 else if (dev
->sc_tinfo
[xs
->xs_periph
->periph_target
].bounce
)
678 else if ((dev
->sc_tinfo
[xs
->xs_periph
->periph_target
].bounce
679 = (char *)alloc_z2mem(MAXPHYS
))) {
680 if (isztwomem(dev
->sc_tinfo
[xs
->xs_periph
->periph_target
].bounce
))
681 printf("alloc ZII target %d bounce pa 0x%x\n",
682 xs
->xs_periph
->periph_target
,
683 (unsigned)kvtop(dev
->sc_tinfo
[xs
->xs_periph
->periph_target
].bounce
));
684 else if (dev
->sc_tinfo
[xs
->xs_periph
->periph_target
].bounce
)
685 printf("alloc CHIP target %d bounce pa %p\n",
686 xs
->xs_periph
->periph_target
,
687 PREP_DMA_MEM(dev
->sc_tinfo
[xs
->xs_periph
->periph_target
].bounce
));
696 sbicwait(sbic_regmap_t regs
, char until
, int timeo
, int line
)
701 SBIC_TRACE((struct sbic_softc
*)0);
703 timeo
= 1000000; /* some large value.. */
705 GET_SBIC_asr(regs
,val
);
706 while ((val
& until
) == 0) {
708 GET_SBIC_csr(regs
, csr
);
709 printf("sbicwait TIMEO @%d with asr=x%x csr=x%x\n",
711 #if defined(DDB) && defined(DEBUG)
714 return(val
); /* Maybe I should abort */
718 GET_SBIC_asr(regs
,val
);
720 SBIC_TRACE((struct sbic_softc
*)0);
725 sbicabort(struct sbic_softc
*dev
, sbic_regmap_t regs
, const char *where
)
729 GET_SBIC_asr(regs
, asr
);
730 GET_SBIC_csr(regs
, csr
);
732 printf ("%s: abort %s: csr = 0x%02x, asr = 0x%02x\n",
733 dev
->sc_dev
.dv_xname
, where
, csr
, asr
);
737 /* Clean up running command */
738 if (dev
->sc_nexus
!= NULL
) {
739 dev
->sc_nexus
->xs
->error
= XS_DRIVER_STUFFUP
;
740 sbic_scsidone(dev
->sc_nexus
, dev
->sc_stat
[0]);
742 while (acb
= dev
->nexus_list
.tqh_first
) {
743 acb
->xs
->error
= XS_DRIVER_STUFFUP
;
744 sbic_scsidone(acb
, -1 /*acb->stat[0]*/);
748 /* Clean up chip itself */
749 if (dev
->sc_flags
& SBICF_SELECTED
) {
750 while( asr
& SBIC_ASR_DBR
) {
751 /* sbic is jammed w/data. need to clear it */
752 /* But we don't know what direction it needs to go */
753 GET_SBIC_data(regs
, asr
);
754 printf("%s: abort %s: clearing data buffer 0x%02x\n",
755 dev
->sc_dev
.dv_xname
, where
, asr
);
756 GET_SBIC_asr(regs
, asr
);
757 if( asr
& SBIC_ASR_DBR
) /* Not the read direction, then */
758 SET_SBIC_data(regs
, asr
);
759 GET_SBIC_asr(regs
, asr
);
762 printf("%s: sbicabort - sending ABORT command\n", dev
->sc_dev
.dv_xname
);
763 SET_SBIC_cmd(regs
, SBIC_CMD_ABORT
);
766 GET_SBIC_asr(regs
, asr
);
767 if (asr
& (SBIC_ASR_BSY
|SBIC_ASR_LCI
)) {
768 /* ok, get more drastic.. */
770 printf("%s: sbicabort - asr %x, trying to reset\n", dev
->sc_dev
.dv_xname
, asr
);
772 dev
->sc_flags
&= ~SBICF_SELECTED
;
775 printf("%s: sbicabort - sending DISC command\n", dev
->sc_dev
.dv_xname
);
776 SET_SBIC_cmd(regs
, SBIC_CMD_DISC
);
779 asr
= SBIC_WAIT (regs
, SBIC_ASR_INT
, 0);
780 GET_SBIC_csr (regs
, csr
);
781 CSR_TRACE('a',csr
,asr
,0);
782 } while ((csr
!= SBIC_CSR_DISC
) && (csr
!= SBIC_CSR_DISC_1
)
783 && (csr
!= SBIC_CSR_CMD_INVALID
));
785 /* lets just hope it worked.. */
786 dev
->sc_flags
&= ~SBICF_SELECTED
;
793 * Initialize driver-private structures
797 sbicinit(struct sbic_softc
*dev
)
801 struct sbic_acb
*acb
;
804 extern u_long scsi_nosync
;
805 extern int shift_nosync
;
809 if ((dev
->sc_flags
& SBICF_ALIVE
) == 0) {
810 TAILQ_INIT(&dev
->ready_list
);
811 TAILQ_INIT(&dev
->nexus_list
);
812 TAILQ_INIT(&dev
->free_list
);
813 callout_init(&dev
->sc_timo_ch
, 0);
814 dev
->sc_nexus
= NULL
;
817 memset(acb
, 0, sizeof(dev
->sc_acb
));
818 for (i
= 0; i
< sizeof(dev
->sc_acb
) / sizeof(*acb
); i
++) {
819 TAILQ_INSERT_TAIL(&dev
->free_list
, acb
, chain
);
822 memset(dev
->sc_tinfo
, 0, sizeof(dev
->sc_tinfo
));
824 /* make sure timeout is really not needed */
825 callout_reset(&dev
->sc_timo_ch
, 30 * hz
,
826 (void *)sbictimeout
, dev
);
829 } else panic("sbic: reinitializing driver!");
831 dev
->sc_flags
|= SBICF_ALIVE
;
832 dev
->sc_flags
&= ~SBICF_SELECTED
;
834 /* initialize inhibit array */
836 inhibit_sync
= (scsi_nosync
>> shift_nosync
) & 0xff;
840 printf("%s: Inhibiting synchronous transfer %02x\n",
841 dev
->sc_dev
.dv_xname
, inhibit_sync
);
843 for (i
= 0; i
< 8; ++i
)
844 if (inhibit_sync
& (1 << i
))
845 sbic_inhibit_sync
[i
] = 1;
852 sbicreset(struct sbic_softc
*dev
)
859 struct sbic_acb
*acb
;
864 if (dev
->sc_flags
& SBICF_ALIVE
) {
865 SET_SBIC_cmd(regs
, SBIC_CMD_ABORT
);
869 SET_SBIC_cmd(regs
, SBIC_CMD_ABORT
);
873 my_id
= dev
->sc_channel
.chan_id
& SBIC_ID_MASK
;
875 /* Enable advanced mode */
876 my_id
|= SBIC_ID_EAF
/*| SBIC_ID_EHP*/ ;
877 SET_SBIC_myid(regs
, my_id
);
880 * Disable interrupts (in dmainit) then reset the chip
882 SET_SBIC_cmd(regs
, SBIC_CMD_RESET
);
884 SBIC_WAIT(regs
, SBIC_ASR_INT
, 0);
885 GET_SBIC_csr(regs
, csr
); /* clears interrupt also */
887 if (dev
->sc_clkfreq
< 110)
888 my_id
|= SBIC_ID_FS_8_10
;
889 else if (dev
->sc_clkfreq
< 160)
890 my_id
|= SBIC_ID_FS_12_15
;
891 else if (dev
->sc_clkfreq
< 210)
892 my_id
|= SBIC_ID_FS_16_20
;
894 SET_SBIC_myid(regs
, my_id
);
897 * Set up various chip parameters
899 SET_SBIC_control(regs
, SBIC_CTL_EDI
| SBIC_CTL_IDI
/* | SBIC_CTL_HSP */
900 | SBIC_MACHINE_DMA_MODE
);
902 * don't allow (re)selection (SBIC_RID_ES)
903 * until we can handle target mode!!
905 SET_SBIC_rselid(regs
, SBIC_RID_ER
);
906 SET_SBIC_syn(regs
, 0); /* asynch for now */
909 * anything else was zeroed by reset
914 if ((dev
->sc_flags
& SBICF_ALIVE
) == 0) {
915 TAILQ_INIT(&dev
->ready_list
);
916 TAILQ_INIT(&dev
->nexus_list
);
917 TAILQ_INIT(&dev
->free_list
);
918 dev
->sc_nexus
= NULL
;
921 memset(acb
, 0, sizeof(dev
->sc_acb
));
922 for (i
= 0; i
< sizeof(dev
->sc_acb
) / sizeof(*acb
); i
++) {
923 TAILQ_INSERT_TAIL(&dev
->free_list
, acb
, chain
);
926 memset(dev
->sc_tinfo
, 0, sizeof(dev
->sc_tinfo
));
928 if (dev
->sc_nexus
!= NULL
) {
929 dev
->sc_nexus
->xs
->error
= XS_DRIVER_STUFFUP
;
930 sbic_scsidone(dev
->sc_nexus
, dev
->sc_stat
[0]);
932 while (acb
= dev
->nexus_list
.tqh_first
) {
933 acb
->xs
->error
= XS_DRIVER_STUFFUP
;
934 sbic_scsidone(acb
, -1 /*acb->stat[0]*/);
938 dev
->sc_flags
|= SBICF_ALIVE
;
940 dev
->sc_flags
&= ~SBICF_SELECTED
;
944 sbicerror(struct sbic_softc
*dev
, sbic_regmap_t regs
, u_char csr
)
946 struct scsipi_xfer
*xs
;
954 if (xs
->xs_control
& XS_CTL_SILENT
)
957 printf("%s: ", dev
->sc_dev
.dv_xname
);
958 printf("csr == 0x%02x\n", csr
); /* XXX */
962 * select the bus, return when selected or error.
965 sbicselectbus(struct sbic_softc
*dev
, sbic_regmap_t regs
, u_char target
,
966 u_char lun
, u_char our_addr
)
971 QPRINTF(("sbicselectbus %d\n", target
));
974 * if we're already selected, return (XXXX panic maybe?)
976 if (dev
->sc_flags
& SBICF_SELECTED
) {
984 SBIC_TC_PUT(regs
, 0);
985 SET_SBIC_selid(regs
, target
);
986 SET_SBIC_timeo(regs
, SBIC_TIMEOUT(250,dev
->sc_clkfreq
));
991 if (dev
->sc_sync
[target
].state
== SYNC_DONE
)
992 SET_SBIC_syn(regs
, SBIC_SYN (dev
->sc_sync
[target
].offset
,
993 dev
->sc_sync
[target
].period
));
995 SET_SBIC_syn(regs
, SBIC_SYN (0, sbic_min_period
));
997 GET_SBIC_asr(regs
, asr
);
998 if( asr
& (SBIC_ASR_INT
|SBIC_ASR_BSY
) ) {
999 /* This means we got ourselves reselected upon */
1000 /* printf("sbicselectbus: INT/BSY asr %02x\n", asr);*/
1008 SET_SBIC_cmd(regs
, SBIC_CMD_SEL_ATN
);
1011 * wait for select (merged from separate function may need
1016 asr
= SBIC_WAIT(regs
, SBIC_ASR_INT
| SBIC_ASR_LCI
, 0);
1017 if (asr
& SBIC_ASR_LCI
) {
1020 printf("sbicselectbus: late LCI asr %02x\n", asr
);
1025 GET_SBIC_csr (regs
, csr
);
1026 CSR_TRACE('s',csr
,asr
,target
);
1027 QPRINTF(("%02x ", csr
));
1028 if( csr
== SBIC_CSR_RSLT_NI
|| csr
== SBIC_CSR_RSLT_IFY
) {
1031 printf("sbicselectbus: reselected asr %02x\n", asr
);
1033 /* We need to handle this now so we don't lock up later */
1034 sbicnextstate(dev
, csr
, asr
);
1038 if( csr
== SBIC_CSR_SLT
|| csr
== SBIC_CSR_SLT_ATN
) {
1039 panic("sbicselectbus: target issued select!");
1042 } while (csr
!= (SBIC_CSR_MIS_2
|MESG_OUT_PHASE
)
1043 && csr
!= (SBIC_CSR_MIS_2
|CMD_PHASE
) && csr
!= SBIC_CSR_SEL_TIMEO
);
1045 /* Enable (or not) reselection */
1046 if(!sbic_enable_reselect
&& dev
->nexus_list
.tqh_first
== NULL
)
1047 SET_SBIC_rselid (regs
, 0);
1049 SET_SBIC_rselid (regs
, SBIC_RID_ER
);
1051 if (csr
== (SBIC_CSR_MIS_2
|CMD_PHASE
)) {
1052 dev
->sc_flags
|= SBICF_SELECTED
; /* device ignored ATN */
1053 GET_SBIC_selid(regs
, id
);
1055 GET_SBIC_tlun(regs
,dev
->lun
);
1056 if( dev
->lun
& SBIC_TLUN_VALID
)
1057 dev
->lun
&= SBIC_TLUN_MASK
;
1060 } else if (csr
== (SBIC_CSR_MIS_2
|MESG_OUT_PHASE
)) {
1062 * Send identify message
1063 * (SCSI-2 requires an identify msg (?))
1065 GET_SBIC_selid(regs
, id
);
1067 GET_SBIC_tlun(regs
,dev
->lun
);
1068 if( dev
->lun
& SBIC_TLUN_VALID
)
1069 dev
->lun
&= SBIC_TLUN_MASK
;
1073 * handle drives that don't want to be asked
1074 * whether to go sync at all.
1076 if (sbic_inhibit_sync
[id
]
1077 && dev
->sc_sync
[id
].state
== SYNC_START
) {
1080 printf("Forcing target %d asynchronous.\n", id
);
1082 dev
->sc_sync
[id
].offset
= 0;
1083 dev
->sc_sync
[id
].period
= sbic_min_period
;
1084 dev
->sc_sync
[id
].state
= SYNC_DONE
;
1088 if (dev
->sc_sync
[id
].state
!= SYNC_START
){
1089 if( dev
->sc_xs
->xs_control
& XS_CTL_POLL
1090 || (dev
->sc_flags
& SBICF_ICMD
)
1091 || !sbic_enable_reselect
)
1092 SEND_BYTE (regs
, MSG_IDENTIFY
| lun
);
1094 SEND_BYTE (regs
, MSG_IDENTIFY_DR
| lun
);
1097 * try to initiate a sync transfer.
1098 * So compose the sync message we're going
1099 * to send to the target
1104 printf("Sending sync request to target %d ... ",
1108 * setup scsi message sync message request
1110 dev
->sc_msg
[0] = MSG_IDENTIFY
| lun
;
1111 dev
->sc_msg
[1] = MSG_EXT_MESSAGE
;
1113 dev
->sc_msg
[3] = MSG_SYNC_REQ
;
1114 dev
->sc_msg
[4] = sbictoscsiperiod(dev
, regs
,
1116 dev
->sc_msg
[5] = sbic_max_offset
;
1118 if (sbicxfstart(regs
, 6, MESG_OUT_PHASE
, sbic_cmd_wait
))
1119 sbicxfout(regs
, 6, dev
->sc_msg
, MESG_OUT_PHASE
);
1121 dev
->sc_sync
[id
].state
= SYNC_SENT
;
1128 asr
= SBIC_WAIT (regs
, SBIC_ASR_INT
, 0);
1129 GET_SBIC_csr (regs
, csr
);
1130 CSR_TRACE('y',csr
,asr
,target
);
1131 QPRINTF(("[%02x]", csr
));
1133 if (sync_debug
&& dev
->sc_sync
[id
].state
== SYNC_SENT
)
1134 printf("csr-result of last msgout: 0x%x\n", csr
);
1137 if (csr
!= SBIC_CSR_SEL_TIMEO
)
1138 dev
->sc_flags
|= SBICF_SELECTED
;
1140 if (csr
== SBIC_CSR_SEL_TIMEO
)
1141 dev
->sc_xs
->error
= XS_SELTIMEOUT
;
1146 return(csr
== SBIC_CSR_SEL_TIMEO
);
1150 sbicxfstart(sbic_regmap_t regs
, int len
, u_char phase
, int wait
)
1157 GET_SBIC_selid (regs
, id
);
1158 id
|= SBIC_SID_FROM_SCSI
;
1159 SET_SBIC_selid (regs
, id
);
1160 SBIC_TC_PUT (regs
, (unsigned)len
);
1162 case DATA_OUT_PHASE
:
1163 case MESG_OUT_PHASE
:
1165 GET_SBIC_selid (regs
, id
);
1166 id
&= ~SBIC_SID_FROM_SCSI
;
1167 SET_SBIC_selid (regs
, id
);
1168 SBIC_TC_PUT (regs
, (unsigned)len
);
1171 SBIC_TC_PUT (regs
, 0);
1173 QPRINTF(("sbicxfstart %d, %d, %d\n", len
, phase
, wait
));
1179 sbicxfout(sbic_regmap_t regs
, int len
, void *bp
, int phase
)
1181 u_char orig_csr
, asr
, *buf
;
1185 wait
= sbic_data_wait
;
1187 QPRINTF(("sbicxfout {%d} %02x %02x %02x %02x %02x "
1188 "%02x %02x %02x %02x %02x\n", len
, buf
[0], buf
[1], buf
[2],
1189 buf
[3], buf
[4], buf
[5], buf
[6], buf
[7], buf
[8], buf
[9]));
1191 GET_SBIC_csr (regs
, orig_csr
);
1192 CSR_TRACE('>',orig_csr
,0,0);
1195 * sigh.. WD-PROTO strikes again.. sending the command in one go
1196 * causes the chip to lock up if talking to certain (misbehaving?)
1197 * targets. Anyway, this procedure should work for all targets, but
1198 * it's slightly slower due to the overhead
1201 SET_SBIC_cmd (regs
, SBIC_CMD_XFER_INFO
);
1202 for (;len
> 0; len
--) {
1203 GET_SBIC_asr (regs
, asr
);
1204 while ((asr
& SBIC_ASR_DBR
) == 0) {
1205 if ((asr
& SBIC_ASR_INT
) || --wait
< 0) {
1208 printf("sbicxfout fail: l%d i%x w%d\n",
1214 GET_SBIC_asr (regs
, asr
);
1217 SET_SBIC_data (regs
, *buf
);
1220 SBIC_TC_GET(regs
, len
);
1221 QPRINTF(("sbicxfout done %d bytes\n", len
));
1223 * this leaves with one csr to be read
1228 /* returns # bytes left to read */
1230 sbicxfin(sbic_regmap_t regs
, int len
, void *bp
)
1234 u_char orig_csr
, csr
, asr
;
1236 wait
= sbic_data_wait
;
1240 GET_SBIC_csr (regs
, orig_csr
);
1241 CSR_TRACE('<',orig_csr
,0,0);
1243 QPRINTF(("sbicxfin %d, csr=%02x\n", len
, orig_csr
));
1246 SET_SBIC_cmd (regs
, SBIC_CMD_XFER_INFO
);
1247 for (;len
> 0; len
--) {
1248 GET_SBIC_asr (regs
, asr
);
1249 if((asr
& SBIC_ASR_PE
)) {
1251 printf("sbicxfin parity error: l%d i%x w%d\n",
1253 /* return ((unsigned long)buf - (unsigned long)bp); */
1259 while ((asr
& SBIC_ASR_DBR
) == 0) {
1260 if ((asr
& SBIC_ASR_INT
) || --wait
< 0) {
1263 QPRINTF(("sbicxfin fail:{%d} %02x %02x %02x %02x %02x %02x "
1264 "%02x %02x %02x %02x\n", len
, obp
[0], obp
[1], obp
[2],
1265 obp
[3], obp
[4], obp
[5], obp
[6], obp
[7], obp
[8], obp
[9]));
1266 printf("sbicxfin fail: l%d i%x w%d\n",
1273 if( ! asr
& SBIC_ASR_BSY
) {
1274 GET_SBIC_csr(regs
, csr
);
1275 CSR_TRACE('<',csr
,asr
,len
);
1276 QPRINTF(("[CSR%02xASR%02x]", csr
, asr
));
1280 GET_SBIC_asr (regs
, asr
);
1283 GET_SBIC_data (regs
, *buf
);
1284 /* QPRINTF(("asr=%02x, csr=%02x, data=%02x\n", asr, csr, *buf));*/
1288 QPRINTF(("sbicxfin {%d} %02x %02x %02x %02x %02x %02x "
1289 "%02x %02x %02x %02x\n", len
, obp
[0], obp
[1], obp
[2],
1290 obp
[3], obp
[4], obp
[5], obp
[6], obp
[7], obp
[8], obp
[9]));
1292 /* this leaves with one csr to be read */
1297 * SCSI 'immediate' command: issue a command to some SCSI device
1298 * and get back an 'immediate' response (i.e., do programmed xfer
1299 * to get the response data). 'cbuf' is a buffer containing a scsi
1300 * command of length clen bytes. 'buf' is a buffer of length 'len'
1301 * bytes for data. The transfer direction is determined by the device
1302 * (i.e., by the scsi bus data xfer phase). If 'len' is zero, the
1303 * command must supply no data.
1306 sbicicmd(struct sbic_softc
*dev
, int target
, int lun
, void *cbuf
, int clen
,
1310 u_char phase
, csr
, asr
;
1312 struct sbic_acb
*acb
;
1314 #define CSR_LOG_BUF_SIZE 0
1315 #if CSR_LOG_BUF_SIZE
1317 int csrbuf
[CSR_LOG_BUF_SIZE
];
1322 regs
= dev
->sc_sbic
;
1323 acb
= dev
->sc_nexus
;
1325 /* Make sure pointers are OK */
1326 dev
->sc_last
= dev
->sc_cur
= &acb
->sc_pa
;
1327 dev
->sc_tcnt
= acb
->sc_tcnt
= 0;
1328 acb
->sc_pa
.dc_count
= 0; /* No DMA */
1329 acb
->sc_kv
.dc_addr
= buf
;
1330 acb
->sc_kv
.dc_count
= len
;
1334 debug_sbic_regs
= regs
; /* store this to allow debug calls */
1335 if( data_pointer_debug
> 1 )
1336 printf("sbicicmd(%d,%d):%d\n", target
, lun
,
1337 acb
->sc_kv
.dc_count
);
1341 * set the sbic into non-DMA mode
1343 SET_SBIC_control(regs
, SBIC_CTL_EDI
| SBIC_CTL_IDI
/*| SBIC_CTL_HSP*/);
1345 dev
->sc_stat
[0] = 0xff;
1346 dev
->sc_msg
[0] = 0xff;
1347 i
= 1; /* pre-load */
1349 /* We're stealing the SCSI bus */
1350 dev
->sc_flags
|= SBICF_ICMD
;
1354 * select the SCSI bus (it's an error if bus isn't free)
1356 if (!( dev
->sc_flags
& SBICF_SELECTED
)
1357 && sbicselectbus(dev
, regs
, target
, lun
, dev
->sc_scsiaddr
)) {
1358 /* printf("sbicicmd: trying to select busy bus!\n"); */
1359 dev
->sc_flags
&= ~SBICF_ICMD
;
1364 * Wait for a phase change (or error) then let the device sequence
1365 * us through the various SCSI phases.
1368 wait
= sbic_cmd_wait
;
1370 GET_SBIC_asr (regs
, asr
);
1371 GET_SBIC_csr (regs
, csr
);
1372 CSR_TRACE('I',csr
,asr
,target
);
1373 QPRINTF((">ASR:%02xCSR:%02x<", asr
, csr
));
1375 #if CSR_LOG_BUF_SIZE
1376 csrbuf
[bufptr
++] = csr
;
1381 case SBIC_CSR_S_XFERRED
:
1383 case SBIC_CSR_DISC_1
:
1384 dev
->sc_flags
&= ~SBICF_SELECTED
;
1385 GET_SBIC_cmd_phase (regs
, phase
);
1386 if (phase
== 0x60) {
1387 GET_SBIC_tlun (regs
, dev
->sc_stat
[0]);
1389 /* break; */ /* Bypass all the state gobldygook */
1392 if(reselect_debug
>1)
1393 printf("sbicicmd: handling disconnect\n");
1395 i
= SBIC_STATE_DISCONNECT
;
1399 case SBIC_CSR_XFERRED
|CMD_PHASE
:
1400 case SBIC_CSR_MIS
|CMD_PHASE
:
1401 case SBIC_CSR_MIS_1
|CMD_PHASE
:
1402 case SBIC_CSR_MIS_2
|CMD_PHASE
:
1403 if (sbicxfstart(regs
, clen
, CMD_PHASE
, sbic_cmd_wait
))
1404 if (sbicxfout(regs
, clen
,
1406 i
= sbicabort(dev
, regs
, "icmd sending cmd");
1408 GET_SBIC_csr(regs
, csr
); /* Lets us reload tcount */
1410 GET_SBIC_asr(regs
, asr
);
1411 CSR_TRACE('I',csr
,asr
,target
);
1412 if( asr
& (SBIC_ASR_BSY
|SBIC_ASR_LCI
|SBIC_ASR_CIP
) )
1413 printf("next: cmd sent asr %02x, csr %02x\n",
1419 case SBIC_CSR_XFERRED
|DATA_OUT_PHASE
:
1420 case SBIC_CSR_XFERRED
|DATA_IN_PHASE
:
1421 case SBIC_CSR_MIS
|DATA_OUT_PHASE
:
1422 case SBIC_CSR_MIS
|DATA_IN_PHASE
:
1423 case SBIC_CSR_MIS_1
|DATA_OUT_PHASE
:
1424 case SBIC_CSR_MIS_1
|DATA_IN_PHASE
:
1425 case SBIC_CSR_MIS_2
|DATA_OUT_PHASE
:
1426 case SBIC_CSR_MIS_2
|DATA_IN_PHASE
:
1427 if (acb
->sc_kv
.dc_count
<= 0)
1428 i
= sbicabort(dev
, regs
, "icmd out of data");
1430 wait
= sbic_data_wait
;
1431 if (sbicxfstart(regs
,
1432 acb
->sc_kv
.dc_count
,
1433 SBIC_PHASE(csr
), wait
))
1437 acb
->sc_kv
.dc_count
,
1438 acb
->sc_kv
.dc_addr
);
1441 acb
->sc_kv
.dc_count
,
1444 acb
->sc_kv
.dc_addr
+=
1445 (acb
->sc_kv
.dc_count
- i
);
1446 acb
->sc_kv
.dc_count
= i
;
1452 case SBIC_CSR_XFERRED
|STATUS_PHASE
:
1453 case SBIC_CSR_MIS
|STATUS_PHASE
:
1454 case SBIC_CSR_MIS_1
|STATUS_PHASE
:
1455 case SBIC_CSR_MIS_2
|STATUS_PHASE
:
1457 * the sbic does the status/cmd-complete reading ok,
1458 * so do this with its hi-level commands.
1462 printf("SBICICMD status phase\n");
1464 SBIC_TC_PUT(regs
, 0);
1465 SET_SBIC_cmd_phase(regs
, 0x46);
1466 SET_SBIC_cmd(regs
, SBIC_CMD_SEL_ATN_XFER
);
1469 #if THIS_IS_A_RESERVED_STATE
1470 case BUS_FREE_PHASE
: /* This is not legal */
1471 if( dev
->sc_stat
[0] != 0xff )
1477 i
= sbicnextstate(dev
, csr
, asr
);
1481 * make sure the last command was taken,
1482 * ie. we're not hunting after an ignored command..
1484 GET_SBIC_asr(regs
, asr
);
1486 /* tapes may take a loooong time.. */
1487 while (asr
& SBIC_ASR_BSY
){
1488 if(asr
& SBIC_ASR_DBR
) {
1489 printf("sbicicmd: Waiting while sbic is jammed, CSR:%02x,ASR:%02x\n",
1494 /* SBIC is jammed */
1495 /* DUNNO which direction */
1496 /* Try old direction */
1497 GET_SBIC_data(regs
,i
);
1498 GET_SBIC_asr(regs
, asr
);
1499 if( asr
& SBIC_ASR_DBR
) /* Wants us to write */
1500 SET_SBIC_data(regs
,i
);
1502 GET_SBIC_asr(regs
, asr
);
1506 * wait for last command to complete
1508 if (asr
& SBIC_ASR_LCI
) {
1509 printf("sbicicmd: last command ignored\n");
1511 else if( i
== 1 ) /* Bsy */
1512 SBIC_WAIT (regs
, SBIC_ASR_INT
, wait
);
1517 } while ( i
> 0 && dev
->sc_stat
[0] == 0xff);
1519 /* Sometimes we need to do an extra read of the CSR */
1520 GET_SBIC_csr(regs
, csr
);
1521 CSR_TRACE('I',csr
,asr
,0xff);
1523 #if CSR_LOG_BUF_SIZE
1524 if(reselect_debug
>1)
1525 for(i
=0; i
<bufptr
; i
++)
1526 printf("CSR:%02x", csrbuf
[i
]);
1530 if(data_pointer_debug
> 1)
1531 printf("sbicicmd done(%d,%d):%d =%d=\n",
1533 acb
->sc_kv
.dc_count
,
1537 QPRINTF(("=STS:%02x=", dev
->sc_stat
[0]));
1538 dev
->sc_flags
&= ~SBICF_ICMD
;
1541 return(dev
->sc_stat
[0]);
1545 * Finish SCSI xfer command: After the completion interrupt from
1546 * a read/write operation, sequence through the final phases in
1547 * programmed i/o. This routine is a lot like sbicicmd except we
1548 * skip (and don't allow) the select, cmd out and data in/out phases.
1551 sbicxfdone(struct sbic_softc
*dev
, sbic_regmap_t regs
, int target
)
1553 u_char phase
, asr
, csr
;
1561 * have the sbic complete on its own
1563 SBIC_TC_PUT(regs
, 0);
1564 SET_SBIC_cmd_phase(regs
, 0x46);
1565 SET_SBIC_cmd(regs
, SBIC_CMD_SEL_ATN_XFER
);
1568 asr
= SBIC_WAIT (regs
, SBIC_ASR_INT
, 0);
1569 GET_SBIC_csr (regs
, csr
);
1570 CSR_TRACE('f',csr
,asr
,target
);
1571 QPRINTF(("%02x:", csr
));
1572 } while ((csr
!= SBIC_CSR_DISC
) && (csr
!= SBIC_CSR_DISC_1
)
1573 && (csr
!= SBIC_CSR_S_XFERRED
));
1575 dev
->sc_flags
&= ~SBICF_SELECTED
;
1577 GET_SBIC_cmd_phase (regs
, phase
);
1578 QPRINTF(("}%02x", phase
));
1580 GET_SBIC_tlun(regs
, dev
->sc_stat
[0]);
1582 sbicerror(dev
, regs
, csr
);
1584 QPRINTF(("=STS:%02x=\n", dev
->sc_stat
[0]));
1594 sbicgo(struct sbic_softc
*dev
, struct scsipi_xfer
*xs
)
1596 int i
, dmaflags
, count
, usedma
;
1597 u_char csr
, asr
, *addr
;
1599 struct sbic_acb
*acb
;
1602 dev
->target
= xs
->xs_periph
->periph_target
;
1603 dev
->lun
= xs
->xs_periph
->periph_lun
;
1604 acb
= dev
->sc_nexus
;
1605 regs
= dev
->sc_sbic
;
1607 usedma
= sbicdmaok(dev
, xs
);
1610 debug_sbic_regs
= regs
; /* store this to allow debug calls */
1611 if( data_pointer_debug
> 1 )
1612 printf("sbicgo(%d,%d)\n", dev
->target
, dev
->lun
);
1616 * set the sbic into DMA mode
1619 SET_SBIC_control(regs
, SBIC_CTL_EDI
| SBIC_CTL_IDI
|
1620 SBIC_MACHINE_DMA_MODE
);
1622 SET_SBIC_control(regs
, SBIC_CTL_EDI
| SBIC_CTL_IDI
);
1626 * select the SCSI bus (it's an error if bus isn't free)
1628 if (sbicselectbus(dev
, regs
, dev
->target
, dev
->lun
,
1629 dev
->sc_scsiaddr
)) {
1630 /* printf("sbicgo: Trying to select busy bus!\n"); */
1632 return(0); /* Not done: needs to be rescheduled */
1634 dev
->sc_stat
[0] = 0xff;
1637 * Calculate DMA chains now
1641 if (acb
->flags
& ACB_DATAIN
)
1642 dmaflags
|= DMAGO_READ
;
1646 * Deal w/bounce buffers.
1649 addr
= acb
->sc_kv
.dc_addr
;
1650 count
= acb
->sc_kv
.dc_count
;
1651 if (count
&& (char *)kvtop(addr
) != acb
->sc_pa
.dc_addr
) { /* XXXX check */
1652 printf("sbic: DMA buffer mapping changed %p->%x\n",
1653 acb
->sc_pa
.dc_addr
, (unsigned)kvtop(addr
));
1660 ++sbicdma_ops
; /* count total DMA operations */
1662 if (count
&& usedma
&& dev
->sc_flags
& SBICF_BADDMA
&&
1663 sbiccheckdmap(addr
, count
, dev
->sc_dmamask
)) {
1665 * need to bounce the DMA.
1667 if (dmaflags
& DMAGO_READ
) {
1668 acb
->flags
|= ACB_BBUF
;
1669 acb
->sc_dmausrbuf
= addr
;
1670 acb
->sc_dmausrlen
= count
;
1671 acb
->sc_usrbufpa
= (u_char
*)kvtop(addr
);
1672 if(!dev
->sc_tinfo
[dev
->target
].bounce
) {
1673 printf("sbicgo: HELP! no bounce allocated for %d\n",
1675 printf("xfer: (%p->%p,%lx)\n", acb
->sc_dmausrbuf
,
1676 acb
->sc_usrbufpa
, acb
->sc_dmausrlen
);
1677 dev
->sc_tinfo
[xs
->xs_periph
->periph_target
].bounce
1678 = (char *)alloc_z2mem(MAXPHYS
);
1679 if (isztwomem(dev
->sc_tinfo
[xs
->xs_periph
->periph_target
].bounce
))
1680 printf("alloc ZII target %d bounce pa 0x%x\n",
1681 xs
->xs_periph
->periph_target
,
1682 (unsigned)kvtop(dev
->sc_tinfo
[xs
->xs_periph
->periph_target
].bounce
));
1683 else if (dev
->sc_tinfo
[xs
->xs_periph
->periph_target
].bounce
)
1684 printf("alloc CHIP target %d bounce pa %p\n",
1685 xs
->xs_periph
->periph_target
,
1686 PREP_DMA_MEM(dev
->sc_tinfo
[xs
->xs_periph
->periph_target
].bounce
));
1688 printf("Allocating %d bounce at %x\n",
1690 (unsigned)kvtop(dev
->sc_tinfo
[dev
->target
].bounce
));
1692 } else { /* write: copy to DMA buffer */
1694 if(data_pointer_debug
)
1695 printf("sbicgo: copying %x bytes to target %d bounce %x\n",
1697 (unsigned)kvtop(dev
->sc_tinfo
[dev
->target
].bounce
));
1699 bcopy (addr
, dev
->sc_tinfo
[dev
->target
].bounce
, count
);
1701 addr
= dev
->sc_tinfo
[dev
->target
].bounce
;/* and use DMA buffer */
1702 acb
->sc_kv
.dc_addr
= addr
;
1704 ++sbicdma_bounces
; /* count number of bounced */
1709 * Allocate the DMA chain
1712 /* Set start KVM addresses */
1714 acb
->sc_kv
.dc_addr
= addr
;
1715 acb
->sc_kv
.dc_count
= count
;
1718 /* Mark end of segment */
1719 acb
->sc_tcnt
= dev
->sc_tcnt
= 0;
1720 acb
->sc_pa
.dc_count
= 0;
1722 sbic_load_ptrs(dev
, regs
, dev
->target
, dev
->lun
);
1724 /* Enable interrupts but don't do any DMA */
1725 dev
->sc_enintr(dev
);
1727 dev
->sc_tcnt
= dev
->sc_dmago(dev
, acb
->sc_pa
.dc_addr
,
1728 acb
->sc_pa
.dc_count
,
1731 dev
->sc_dmatimo
= dev
->sc_tcnt
? 1 : 0;
1734 dev
->sc_dmacmd
= 0; /* Don't use DMA */
1735 dev
->sc_flags
|= SBICF_INDMA
;
1736 /* SBIC_TC_PUT(regs, dev->sc_tcnt); */ /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
1738 sbic_save_ptrs(dev
, regs
, dev
->target
, dev
->lun
);
1741 * push the data cache ( I think this won't work (EH))
1743 #if defined(M68040) || defined(M68060)
1744 if (mmutype
== MMU_68040
&& usedma
&& count
) {
1745 dma_cachectl(addr
, count
);
1746 if (((u_int
)addr
& 0xF) || (((u_int
)addr
+ count
) & 0xF))
1747 dev
->sc_flags
|= SBICF_DCFLUSH
;
1752 * enintr() also enables interrupts for the sbic
1755 if( data_pointer_debug
> 1 )
1756 printf("sbicgo dmago:%d(%p:%lx)\n",
1757 dev
->target
,dev
->sc_cur
->dc_addr
,dev
->sc_tcnt
);
1760 * Hmm - this isn't right: asr and csr haven't been set yet.
1768 * Lets cycle a while then let the interrupt handler take over
1771 GET_SBIC_asr(regs
, asr
);
1773 GET_SBIC_csr(regs
, csr
);
1774 CSR_TRACE('g',csr
,asr
,dev
->target
);
1779 QPRINTF(("go[0x%x]", csr
));
1781 i
= sbicnextstate(dev
, csr
, asr
);
1784 GET_SBIC_asr(regs
, asr
);
1788 if(asr
& SBIC_ASR_LCI
) printf("sbicgo: LCI asr:%02x csr:%02x\n",
1790 } while( i
== SBIC_STATE_RUNNING
1791 && asr
& (SBIC_ASR_INT
|SBIC_ASR_LCI
) );
1793 CSR_TRACE('g',csr
,asr
,i
<<4);
1795 if (i
== SBIC_STATE_DONE
&& dev
->sc_stat
[0] == 0xff) printf("sbicgo: done & stat = 0xff\n");
1796 if (i
== SBIC_STATE_DONE
&& dev
->sc_stat
[0] != 0xff) {
1797 /* if( i == SBIC_STATE_DONE && dev->sc_stat[0] ) { */
1798 /* Did we really finish that fast? */
1806 sbicintr(struct sbic_softc
*dev
)
1812 regs
= dev
->sc_sbic
;
1815 * pending interrupt?
1817 GET_SBIC_asr (regs
, asr
);
1818 if ((asr
& SBIC_ASR_INT
) == 0)
1823 GET_SBIC_csr(regs
, csr
);
1824 CSR_TRACE('i',csr
,asr
,dev
->target
);
1829 QPRINTF(("intr[0x%x]", csr
));
1831 i
= sbicnextstate(dev
, csr
, asr
);
1834 GET_SBIC_asr(regs
, asr
);
1839 if(asr
& SBIC_ASR_LCI
) printf("sbicintr: LCI asr:%02x csr:%02x\n",
1842 } while(i
== SBIC_STATE_RUNNING
&&
1843 asr
& (SBIC_ASR_INT
|SBIC_ASR_LCI
));
1844 CSR_TRACE('i',csr
,asr
,i
<<4);
1850 * Run commands and wait for disconnect
1853 sbicpoll(struct sbic_softc
*dev
)
1860 regs
= dev
->sc_sbic
;
1863 GET_SBIC_asr (regs
, asr
);
1867 GET_SBIC_csr(regs
, csr
);
1868 CSR_TRACE('p',csr
,asr
,dev
->target
);
1873 QPRINTF(("poll[0x%x]", csr
));
1875 i
= sbicnextstate(dev
, csr
, asr
);
1878 GET_SBIC_asr(regs
, asr
);
1879 /* tapes may take a loooong time.. */
1880 while (asr
& SBIC_ASR_BSY
){
1881 if(asr
& SBIC_ASR_DBR
) {
1882 printf("sbipoll: Waiting while sbic is jammed, CSR:%02x,ASR:%02x\n",
1887 /* SBIC is jammed */
1888 /* DUNNO which direction */
1889 /* Try old direction */
1890 GET_SBIC_data(regs
,i
);
1891 GET_SBIC_asr(regs
, asr
);
1892 if( asr
& SBIC_ASR_DBR
) /* Wants us to write */
1893 SET_SBIC_data(regs
,i
);
1895 GET_SBIC_asr(regs
, asr
);
1898 if(asr
& SBIC_ASR_LCI
) printf("sbicpoll: LCI asr:%02x csr:%02x\n",
1900 else if( i
== 1 ) /* BSY */
1901 SBIC_WAIT(regs
, SBIC_ASR_INT
, sbic_cmd_wait
);
1902 } while(i
== SBIC_STATE_RUNNING
);
1903 CSR_TRACE('p',csr
,asr
,i
<<4);
1909 * Handle a single msgin
1913 sbicmsgin(struct sbic_softc
*dev
)
1917 u_char asr
, csr
, *tmpaddr
;
1919 regs
= dev
->sc_sbic
;
1921 dev
->sc_msg
[0] = 0xff;
1922 dev
->sc_msg
[1] = 0xff;
1924 GET_SBIC_asr(regs
, asr
);
1926 if(reselect_debug
>1)
1927 printf("sbicmsgin asr=%02x\n", asr
);
1930 sbic_save_ptrs(dev
, regs
, dev
->target
, dev
->lun
);
1932 GET_SBIC_selid (regs
, csr
);
1933 SET_SBIC_selid (regs
, csr
| SBIC_SID_FROM_SCSI
);
1935 SBIC_TC_PUT(regs
, 0);
1936 tmpaddr
= dev
->sc_msg
;
1939 while( recvlen
-- ) {
1940 GET_SBIC_asr(regs
, asr
);
1941 GET_SBIC_csr(regs
, csr
);
1942 QPRINTF(("sbicmsgin ready to go (csr,asr)=(%02x,%02x)\n",
1945 RECV_BYTE(regs
, *tmpaddr
);
1946 CSR_TRACE('m',csr
,asr
,*tmpaddr
);
1949 * get the command completion interrupt, or we
1950 * can't send a new command (LCI)
1952 SBIC_WAIT(regs
, SBIC_ASR_INT
, 0);
1953 GET_SBIC_csr(regs
, csr
);
1954 CSR_TRACE('X',csr
,asr
,dev
->target
);
1958 GET_SBIC_asr(regs
, asr
);
1960 GET_SBIC_csr(regs
, csr
);
1961 CSR_TRACE('X',csr
,asr
,dev
->target
);
1963 printf("sbicmsgin waiting: csr %02x asr %02x\n", csr
, asr
);
1964 } while( csr
== 0xff );
1967 if(reselect_debug
>1)
1968 printf("sbicmsgin: got %02x csr %02x asr %02x\n",
1969 *tmpaddr
, csr
, asr
);
1972 if( asr
& SBIC_ASR_PE
) {
1973 printf ("Parity error");
1974 /* This code simply does not work. */
1976 SET_SBIC_cmd(regs
, SBIC_CMD_SET_ATN
);
1978 GET_SBIC_asr(regs
, asr
);
1980 SET_SBIC_cmd(regs
, SBIC_CMD_CLR_ACK
);
1982 if( !(asr
& SBIC_ASR_LCI
) )
1983 /* Target wants to send garbled msg*/
1985 printf("--fixing\n");
1986 /* loop until a msgout phase occurs on target */
1987 while(csr
& 0x07 != MESG_OUT_PHASE
) {
1988 while( asr
& SBIC_ASR_BSY
&&
1989 !(asr
& SBIC_ASR_DBR
|SBIC_ASR_INT
) )
1990 GET_SBIC_asr(regs
, asr
);
1991 if( asr
& SBIC_ASR_DBR
)
1992 panic("msgin: jammed again!");
1993 GET_SBIC_csr(regs
, csr
);
1994 CSR_TRACE('e',csr
,asr
,dev
->target
);
1995 if( csr
& 0x07 != MESG_OUT_PHASE
) {
1996 sbicnextstate(dev
, csr
, asr
);
1997 sbic_save_ptrs(dev
, regs
,
2002 /* Should be msg out by now */
2003 SEND_BYTE(regs
, MSG_PARITY_ERROR
);
2012 GET_SBIC_asr(regs
, asr
);
2013 GET_SBIC_csr(regs
, csr
);
2014 CSR_TRACE('X',csr
,asr
,dev
->target
);
2015 QPRINTF(("sbicmsgin pre byte CLR_ACK (csr,asr)=(%02x,%02x)\n",
2017 SET_SBIC_cmd(regs
, SBIC_CMD_CLR_ACK
);
2018 SBIC_WAIT(regs
, SBIC_ASR_INT
, 0);
2023 if(dev
->sc_msg
[0] == 0xff) {
2024 printf("sbicmsgin: sbic swallowed our message\n");
2029 printf("msgin done csr 0x%x asr 0x%x msg 0x%x\n",
2030 csr
, asr
, dev
->sc_msg
[0]);
2033 * test whether this is a reply to our sync
2036 if (MSG_ISIDENTIFY(dev
->sc_msg
[0])) {
2039 /* There is an implied load-ptrs here */
2040 sbic_load_ptrs(dev
, regs
, dev
->target
, dev
->lun
);
2042 /* Got IFFY msg -- ack it */
2043 } else if (dev
->sc_msg
[0] == MSG_REJECT
2044 && dev
->sc_sync
[dev
->target
].state
== SYNC_SENT
) {
2045 QPRINTF(("REJECT of SYN"));
2048 printf("target %d rejected sync, going async\n",
2051 dev
->sc_sync
[dev
->target
].period
= sbic_min_period
;
2052 dev
->sc_sync
[dev
->target
].offset
= 0;
2053 dev
->sc_sync
[dev
->target
].state
= SYNC_DONE
;
2055 SBIC_SYN(dev
->sc_sync
[dev
->target
].offset
,
2056 dev
->sc_sync
[dev
->target
].period
));
2057 } else if ((dev
->sc_msg
[0] == MSG_REJECT
)) {
2058 QPRINTF(("REJECT"));
2060 * we'll never REJECt a REJECT message..
2062 } else if ((dev
->sc_msg
[0] == MSG_SAVE_DATA_PTR
)) {
2063 QPRINTF(("MSG_SAVE_DATA_PTR"));
2065 * don't reject this either.
2067 } else if ((dev
->sc_msg
[0] == MSG_DISCONNECT
)) {
2068 QPRINTF(("DISCONNECT"));
2070 if( reselect_debug
>1 && dev
->sc_msg
[0] == MSG_DISCONNECT
)
2071 printf("sbicmsgin: got disconnect msg %s\n",
2072 (dev
->sc_flags
& SBICF_ICMD
)?"rejecting":"");
2074 if( dev
->sc_flags
& SBICF_ICMD
) {
2075 /* We're in immediate mode. Prevent disconnects. */
2076 /* prepare to reject the message, NACK */
2077 SET_SBIC_cmd(regs
, SBIC_CMD_SET_ATN
);
2080 } else if (dev
->sc_msg
[0] == MSG_CMD_COMPLETE
) {
2081 QPRINTF(("CMD_COMPLETE"));
2082 /* !! KLUDGE ALERT !! quite a few drives don't seem to
2083 * really like the current way of sending the
2084 * sync-handshake together with the ident-message, and
2085 * they react by sending command-complete and
2086 * disconnecting right after returning the valid sync
2087 * handshake. So, all I can do is reselect the drive,
2088 * and hope it won't disconnect again. I don't think
2089 * this is valid behavior, but I can't help fixing a
2090 * problem that apparently exists.
2092 * Note: we should not get here on `normal' command
2093 * completion, as that condition is handled by the
2094 * high-level sel&xfer resume command used to walk
2095 * thru status/cc-phase.
2100 printf ("GOT MSG %d! target %d acting weird.."
2101 " waiting for disconnect...\n",
2102 dev
->sc_msg
[0], dev
->target
);
2104 /* Check to see if sbic is handling this */
2105 GET_SBIC_asr(regs
, asr
);
2106 if(asr
& SBIC_ASR_BSY
)
2107 return SBIC_STATE_RUNNING
;
2109 /* Let's try this: Assume it works and set status to 00 */
2110 dev
->sc_stat
[0] = 0;
2111 } else if (dev
->sc_msg
[0] == MSG_EXT_MESSAGE
2112 && tmpaddr
== &dev
->sc_msg
[1]) {
2113 QPRINTF(("ExtMSG\n"));
2114 /* Read in whole extended message */
2115 SET_SBIC_cmd(regs
, SBIC_CMD_CLR_ACK
);
2116 SBIC_WAIT(regs
, SBIC_ASR_INT
, 0);
2117 GET_SBIC_asr(regs
, asr
);
2118 GET_SBIC_csr(regs
, csr
);
2119 QPRINTF(("CLR ACK asr %02x, csr %02x\n", asr
, csr
));
2120 RECV_BYTE(regs
, *tmpaddr
);
2121 CSR_TRACE('x',csr
,asr
,*tmpaddr
);
2122 /* Wait for command completion IRQ */
2123 SBIC_WAIT(regs
, SBIC_ASR_INT
, 0);
2124 recvlen
= *tmpaddr
++;
2125 QPRINTF(("Recving ext msg, asr %02x csr %02x len %02x\n",
2126 asr
, csr
, recvlen
));
2127 } else if (dev
->sc_msg
[0] == MSG_EXT_MESSAGE
&& dev
->sc_msg
[1] == 3
2128 && dev
->sc_msg
[2] == MSG_SYNC_REQ
) {
2130 dev
->sc_sync
[dev
->target
].period
=
2131 sbicfromscsiperiod(dev
,
2132 regs
, dev
->sc_msg
[3]);
2133 dev
->sc_sync
[dev
->target
].offset
= dev
->sc_msg
[4];
2134 dev
->sc_sync
[dev
->target
].state
= SYNC_DONE
;
2136 SBIC_SYN(dev
->sc_sync
[dev
->target
].offset
,
2137 dev
->sc_sync
[dev
->target
].period
));
2138 printf("%s: target %d now synchronous,"
2139 " period=%dns, offset=%d.\n",
2140 dev
->sc_dev
.dv_xname
, dev
->target
,
2141 dev
->sc_msg
[3] * 4, dev
->sc_msg
[4]);
2144 if (sbic_debug
|| sync_debug
)
2145 printf ("sbicmsgin: Rejecting message 0x%02x\n",
2148 /* prepare to reject the message, NACK */
2149 SET_SBIC_cmd(regs
, SBIC_CMD_SET_ATN
);
2154 GET_SBIC_asr(regs
, asr
);
2155 GET_SBIC_csr(regs
, csr
);
2156 CSR_TRACE('X',csr
,asr
,dev
->target
);
2157 QPRINTF(("sbicmsgin pre CLR_ACK (csr,asr)=(%02x,%02x)%d\n",
2158 csr
, asr
, recvlen
));
2159 SET_SBIC_cmd(regs
, SBIC_CMD_CLR_ACK
);
2160 SBIC_WAIT(regs
, SBIC_ASR_INT
, 0);
2163 while((csr
== SBIC_CSR_MSGIN_W_ACK
)
2164 || (SBIC_PHASE(csr
) == MESG_IN_PHASE
));
2169 QPRINTF(("sbicmsgin finished: csr %02x, asr %02x\n",csr
, asr
));
2171 /* Should still have one CSR to read */
2172 return SBIC_STATE_RUNNING
;
2185 sbicnextstate(struct sbic_softc
*dev
, u_char csr
, u_char asr
)
2188 struct sbic_acb
*acb
;
2189 int i
, newtarget
, newlun
, wait
;
2196 regs
= dev
->sc_sbic
;
2197 acb
= dev
->sc_nexus
;
2199 QPRINTF(("next[%02x,%02x]",asr
,csr
));
2202 case SBIC_CSR_XFERRED
|CMD_PHASE
:
2203 case SBIC_CSR_MIS
|CMD_PHASE
:
2204 case SBIC_CSR_MIS_1
|CMD_PHASE
:
2205 case SBIC_CSR_MIS_2
|CMD_PHASE
:
2206 sbic_save_ptrs(dev
, regs
, dev
->target
, dev
->lun
);
2207 if (sbicxfstart(regs
, acb
->clen
, CMD_PHASE
, sbic_cmd_wait
))
2208 if (sbicxfout(regs
, acb
->clen
,
2209 &acb
->cmd
, CMD_PHASE
))
2213 case SBIC_CSR_XFERRED
|STATUS_PHASE
:
2214 case SBIC_CSR_MIS
|STATUS_PHASE
:
2215 case SBIC_CSR_MIS_1
|STATUS_PHASE
:
2216 case SBIC_CSR_MIS_2
|STATUS_PHASE
:
2218 * this should be the normal i/o completion case.
2219 * get the status & cmd complete msg then let the
2220 * device driver look at what happened.
2222 sbicxfdone(dev
,regs
,dev
->target
);
2224 * check for overlapping cache line, flush if so
2226 #if defined(M68040) || defined(M68060)
2227 if (dev
->sc_flags
& SBICF_DCFLUSH
) {
2229 printf("sbic: 68040/68060 DMA cache flush needs"
2231 dev
->sc_xs
->data
, dev
->sc_xs
->datalen
);
2236 if( data_pointer_debug
> 1 )
2237 printf("next dmastop: %d(%p:%lx)\n",
2238 dev
->target
,dev
->sc_cur
->dc_addr
,dev
->sc_tcnt
);
2239 dev
->sc_dmatimo
= 0;
2241 dev
->sc_dmastop(dev
); /* was dmafree */
2242 if (acb
->flags
& ACB_BBUF
) {
2243 if ((u_char
*)kvtop(acb
->sc_dmausrbuf
) != acb
->sc_usrbufpa
)
2244 printf("%s: WARNING - buffer mapping changed %p->%x\n",
2245 dev
->sc_dev
.dv_xname
, acb
->sc_usrbufpa
,
2246 (unsigned)kvtop(acb
->sc_dmausrbuf
));
2248 if(data_pointer_debug
)
2249 printf("sbicgo:copying %lx bytes from target %d bounce %x\n",
2252 (unsigned)kvtop(dev
->sc_tinfo
[dev
->target
].bounce
));
2254 bcopy(dev
->sc_tinfo
[dev
->target
].bounce
,
2258 dev
->sc_flags
&= ~(SBICF_INDMA
| SBICF_DCFLUSH
);
2259 sbic_scsidone(acb
, dev
->sc_stat
[0]);
2261 return SBIC_STATE_DONE
;
2263 case SBIC_CSR_XFERRED
|DATA_OUT_PHASE
:
2264 case SBIC_CSR_XFERRED
|DATA_IN_PHASE
:
2265 case SBIC_CSR_MIS
|DATA_OUT_PHASE
:
2266 case SBIC_CSR_MIS
|DATA_IN_PHASE
:
2267 case SBIC_CSR_MIS_1
|DATA_OUT_PHASE
:
2268 case SBIC_CSR_MIS_1
|DATA_IN_PHASE
:
2269 case SBIC_CSR_MIS_2
|DATA_OUT_PHASE
:
2270 case SBIC_CSR_MIS_2
|DATA_IN_PHASE
:
2271 if( dev
->sc_xs
->xs_control
& XS_CTL_POLL
|| dev
->sc_flags
& SBICF_ICMD
2272 || acb
->sc_dmacmd
== 0 ) {
2274 SET_SBIC_control(regs
, SBIC_CTL_EDI
| SBIC_CTL_IDI
);
2275 if (acb
->sc_kv
.dc_count
<= 0) {
2276 printf("sbicnextstate:xfer count %d asr%x csr%x\n",
2277 acb
->sc_kv
.dc_count
, asr
, csr
);
2280 wait
= sbic_data_wait
;
2281 if( sbicxfstart(regs
,
2282 acb
->sc_kv
.dc_count
,
2283 SBIC_PHASE(csr
), wait
)) {
2284 if( SBIC_PHASE(csr
) == DATA_IN_PHASE
)
2287 acb
->sc_kv
.dc_count
,
2288 acb
->sc_kv
.dc_addr
);
2291 acb
->sc_kv
.dc_count
,
2295 acb
->sc_kv
.dc_addr
+=
2296 (acb
->sc_kv
.dc_count
- i
);
2297 acb
->sc_kv
.dc_count
= i
;
2299 if (acb
->sc_kv
.dc_count
<= 0) {
2300 printf("sbicnextstate:xfer count %d asr%x csr%x\n",
2301 acb
->sc_kv
.dc_count
, asr
, csr
);
2305 * do scatter-gather DMA
2306 * hacking the controller chip, ouch..
2308 SET_SBIC_control(regs
, SBIC_CTL_EDI
| SBIC_CTL_IDI
|
2309 SBIC_MACHINE_DMA_MODE
);
2311 * set next DMA addr and dec count
2314 SBIC_TC_GET(regs
, tcnt
);
2315 dev
->sc_cur
->dc_count
-= ((dev
->sc_tcnt
- tcnt
) >> 1);
2316 dev
->sc_cur
->dc_addr
+= (dev
->sc_tcnt
- tcnt
);
2317 dev
->sc_tcnt
= acb
->sc_tcnt
= tcnt
;
2319 sbic_save_ptrs(dev
, regs
, dev
->target
, dev
->lun
);
2320 sbic_load_ptrs(dev
, regs
, dev
->target
, dev
->lun
);
2323 if( data_pointer_debug
> 1 )
2324 printf("next dmanext: %d(%p:%lx)\n",
2325 dev
->target
,dev
->sc_cur
->dc_addr
,
2327 dev
->sc_dmatimo
= 1;
2329 dev
->sc_tcnt
= dev
->sc_dmanext(dev
);
2330 SBIC_TC_PUT(regs
, (unsigned)dev
->sc_tcnt
);
2331 SET_SBIC_cmd(regs
, SBIC_CMD_XFER_INFO
);
2332 dev
->sc_flags
|= SBICF_INDMA
;
2336 case SBIC_CSR_XFERRED
|MESG_IN_PHASE
:
2337 case SBIC_CSR_MIS
|MESG_IN_PHASE
:
2338 case SBIC_CSR_MIS_1
|MESG_IN_PHASE
:
2339 case SBIC_CSR_MIS_2
|MESG_IN_PHASE
:
2341 return sbicmsgin(dev
);
2343 case SBIC_CSR_MSGIN_W_ACK
:
2344 SET_SBIC_cmd(regs
, SBIC_CMD_CLR_ACK
); /* Dunno what I'm ACKing */
2345 printf("Acking unknown msgin CSR:%02x",csr
);
2348 case SBIC_CSR_XFERRED
|MESG_OUT_PHASE
:
2349 case SBIC_CSR_MIS
|MESG_OUT_PHASE
:
2350 case SBIC_CSR_MIS_1
|MESG_OUT_PHASE
:
2351 case SBIC_CSR_MIS_2
|MESG_OUT_PHASE
:
2354 printf ("sending REJECT msg to last msg.\n");
2357 sbic_save_ptrs(dev
, regs
, dev
->target
, dev
->lun
);
2359 * should only get here on reject,
2360 * since it's always US that
2361 * initiate a sync transfer
2363 SEND_BYTE(regs
, MSG_REJECT
);
2365 if( asr
& (SBIC_ASR_BSY
|SBIC_ASR_LCI
|SBIC_ASR_CIP
) )
2366 printf("next: REJECT sent asr %02x\n", asr
);
2368 return SBIC_STATE_RUNNING
;
2371 case SBIC_CSR_DISC_1
:
2372 dev
->sc_flags
&= ~(SBICF_INDMA
|SBICF_SELECTED
);
2374 /* Try to schedule another target */
2376 if(reselect_debug
>1)
2377 printf("sbicnext target %d disconnected\n", dev
->target
);
2379 TAILQ_INSERT_HEAD(&dev
->nexus_list
, acb
, chain
);
2380 ++dev
->sc_tinfo
[dev
->target
].dconns
;
2381 dev
->sc_nexus
= NULL
;
2384 if( acb
->xs
->xs_control
& XS_CTL_POLL
2385 || (dev
->sc_flags
& SBICF_ICMD
)
2386 || !sbic_parallel_operations
) {
2388 return SBIC_STATE_DISCONNECT
;
2392 return SBIC_STATE_DISCONNECT
;
2394 case SBIC_CSR_RSLT_NI
:
2395 case SBIC_CSR_RSLT_IFY
:
2396 GET_SBIC_rselid(regs
, newtarget
);
2397 /* check SBIC_RID_SIV? */
2398 newtarget
&= SBIC_RID_MASK
;
2399 if (csr
== SBIC_CSR_RSLT_IFY
) {
2400 /* Read IFY msg to avoid lockup */
2401 GET_SBIC_data(regs
, newlun
);
2403 newlun
&= SBIC_TLUN_MASK
;
2404 CSR_TRACE('r',csr
,asr
,newtarget
);
2406 /* Need to get IFY message */
2407 for (newlun
= 256; newlun
; --newlun
) {
2408 GET_SBIC_asr(regs
, asr
);
2409 if (asr
& SBIC_ASR_INT
)
2413 newlun
= 0; /* XXXX */
2414 if ((asr
& SBIC_ASR_INT
) == 0) {
2417 printf("RSLT_NI - no IFFY message? asr %x\n", asr
);
2420 GET_SBIC_csr(regs
,csr
);
2421 CSR_TRACE('n',csr
,asr
,newtarget
);
2422 if (csr
== (SBIC_CSR_MIS
| MESG_IN_PHASE
) ||
2423 csr
== (SBIC_CSR_MIS_1
| MESG_IN_PHASE
) ||
2424 csr
== (SBIC_CSR_MIS_2
| MESG_IN_PHASE
)) {
2426 newlun
= dev
->sc_msg
[0] & 7;
2428 printf("RSLT_NI - not MESG_IN_PHASE %x\n",
2434 if(reselect_debug
>1 || (reselect_debug
&& csr
==SBIC_CSR_RSLT_NI
))
2435 printf("sbicnext: reselect %s from targ %d lun %d\n",
2436 csr
== SBIC_CSR_RSLT_NI
? "NI" : "IFY",
2439 if (dev
->sc_nexus
) {
2441 if (reselect_debug
> 1)
2442 printf("%s: reselect %s with active command\n",
2443 dev
->sc_dev
.dv_xname
,
2444 csr
== SBIC_CSR_RSLT_NI
? "NI" : "IFY");
2449 TAILQ_INSERT_HEAD(&dev
->ready_list
, dev
->sc_nexus
, chain
);
2450 dev
->sc_tinfo
[dev
->target
].lubusy
&= ~(1 << dev
->lun
);
2451 dev
->sc_nexus
= NULL
;
2454 /* Reload sync values for this target */
2455 if (dev
->sc_sync
[newtarget
].state
== SYNC_DONE
)
2456 SET_SBIC_syn(regs
, SBIC_SYN (dev
->sc_sync
[newtarget
].offset
,
2457 dev
->sc_sync
[newtarget
].period
));
2459 SET_SBIC_syn(regs
, SBIC_SYN (0, sbic_min_period
));
2460 for (acb
= dev
->nexus_list
.tqh_first
; acb
;
2461 acb
= acb
->chain
.tqe_next
) {
2462 if (acb
->xs
->xs_periph
->periph_target
!= newtarget
||
2463 acb
->xs
->xs_periph
->periph_lun
!= newlun
)
2465 TAILQ_REMOVE(&dev
->nexus_list
, acb
, chain
);
2466 dev
->sc_nexus
= acb
;
2467 dev
->sc_xs
= acb
->xs
;
2468 dev
->sc_flags
|= SBICF_SELECTED
;
2469 dev
->target
= newtarget
;
2474 printf("%s: reselect %s targ %d not in nexus_list %p\n",
2475 dev
->sc_dev
.dv_xname
,
2476 csr
== SBIC_CSR_RSLT_NI
? "NI" : "IFY", newtarget
,
2477 &dev
->nexus_list
.tqh_first
);
2478 panic("bad reselect in sbic");
2480 if (csr
== SBIC_CSR_RSLT_IFY
)
2481 SET_SBIC_cmd(regs
, SBIC_CMD_CLR_ACK
);
2487 * Something unexpected happened -- deal with it.
2489 printf("sbicnextstate: aborting csr %02x asr %02x\n", csr
, asr
);
2494 if( data_pointer_debug
> 1 )
2495 printf("next dmastop: %d(%p:%lx)\n",
2496 dev
->target
,dev
->sc_cur
->dc_addr
,dev
->sc_tcnt
);
2497 dev
->sc_dmatimo
= 0;
2499 dev
->sc_dmastop(dev
);
2500 SET_SBIC_control(regs
, SBIC_CTL_EDI
| SBIC_CTL_IDI
);
2501 sbicerror(dev
, regs
, csr
);
2502 sbicabort(dev
, regs
, "next");
2503 if (dev
->sc_flags
& SBICF_INDMA
) {
2505 * check for overlapping cache line, flush if so
2507 #if defined(M68040) || defined(M68060)
2508 if (dev
->sc_flags
& SBICF_DCFLUSH
) {
2510 printf("sbic: 68040/060 DMA cache flush needs"
2512 dev
->sc_xs
->data
, dev
->sc_xs
->datalen
);
2517 ~(SBICF_INDMA
| SBICF_DCFLUSH
);
2519 if( data_pointer_debug
> 1 )
2520 printf("next dmastop: %d(%p:%lx)\n",
2521 dev
->target
,dev
->sc_cur
->dc_addr
,dev
->sc_tcnt
);
2522 dev
->sc_dmatimo
= 0;
2524 dev
->sc_dmastop(dev
);
2525 sbic_scsidone(acb
, -1);
2528 return SBIC_STATE_ERROR
;
2532 return(SBIC_STATE_RUNNING
);
2537 * Check if DMA can not be used with specified buffer
2541 sbiccheckdmap(void *bp
, u_long len
, u_long mask
)
2553 phy_buf
= kvtop(buffer
);
2554 if (len
< (phy_len
= PAGE_SIZE
- ((int) buffer
& PGOFSET
)))
2565 sbictoscsiperiod(struct sbic_softc
*dev
, sbic_regmap_t regs
, int a
)
2570 * cycle = DIV / (2*CLK)
2572 * best we can do is 200ns at 20 MHz, 2 cycles
2575 GET_SBIC_myid(regs
,fs
);
2576 fs
= (fs
>>6) + 2; /* DIV */
2577 fs
= (fs
* 10000) / (dev
->sc_clkfreq
<<1); /* Cycle, in ns */
2578 if (a
< 2) a
= 8; /* map to Cycles */
2579 return ((fs
*a
)>>2); /* in 4 ns units */
2583 sbicfromscsiperiod(struct sbic_softc
*dev
, sbic_regmap_t regs
, int p
)
2585 register unsigned int fs
, ret
;
2587 /* Just the inverse of the above */
2589 GET_SBIC_myid(regs
,fs
);
2590 fs
= (fs
>>6) + 2; /* DIV */
2591 fs
= (fs
* 10000) / (dev
->sc_clkfreq
<<1); /* Cycle, in ns */
2593 ret
= p
<< 2; /* in ns units */
2594 ret
= ret
/ fs
; /* in Cycles */
2595 if (ret
< sbic_min_period
)
2596 return(sbic_min_period
);
2598 /* verify rounding */
2599 if (sbictoscsiperiod(dev
, regs
, ret
) < p
)
2601 return (ret
>= 8) ? 0 : ret
;
2611 GET_SBIC_asr(debug_sbic_regs
,asr
);
2612 GET_SBIC_csr(debug_sbic_regs
,csr
);
2613 printf("%s: asr:csr(%02x:%02x)->(%02x:%02x)\n",
2614 (routine
==1)?"sbicgo":
2615 (routine
==2)?"sbicintr":
2616 (routine
==3)?"sbicicmd":
2617 (routine
==4)?"sbicnext":"unknown",
2618 debug_asr
, debug_csr
, asr
, csr
);
2623 sbictimeout(struct sbic_softc
*dev
)
2628 if (dev
->sc_dmatimo
) {
2629 if (dev
->sc_dmatimo
> 1) {
2630 printf("%s: DMA timeout #%d\n",
2631 dev
->sc_dev
.dv_xname
, dev
->sc_dmatimo
- 1);
2632 GET_SBIC_asr(dev
->sc_sbic
, asr
);
2633 if( asr
& SBIC_ASR_INT
) {
2634 /* We need to service a missed IRQ */
2635 printf("Servicing a missed int:(%02x,%02x)->(%02x,?)\n",
2636 debug_asr
, debug_csr
, asr
);
2644 callout_reset(&dev
->sc_timo_ch
, 30 * hz
,
2645 (void *)sbictimeout
, dev
);
2649 sbic_dump_acb(struct sbic_acb
*acb
)
2651 u_char
*b
= (u_char
*) &acb
->cmd
;
2654 printf("acb@%p ", acb
);
2655 if (acb
->xs
== NULL
) {
2656 printf("<unused>\n");
2659 printf("(%d:%d) flags %2x clen %2d cmd ",
2660 acb
->xs
->xs_periph
->periph_target
,
2661 acb
->xs
->xs_periph
->periph_lun
, acb
->flags
, acb
->clen
);
2662 for (i
= acb
->clen
; i
; --i
)
2663 printf(" %02x", *b
++);
2665 printf(" xs: %8p data %8p:%04x ", acb
->xs
, acb
->xs
->data
,
2667 printf("va %8p:%04x ", acb
->sc_kv
.dc_addr
, acb
->sc_kv
.dc_count
);
2668 printf("pa %8p:%04x tcnt %lx\n", acb
->sc_pa
.dc_addr
, acb
->sc_pa
.dc_count
,
2673 sbic_dump(struct sbic_softc
*dev
)
2677 struct sbic_acb
*acb
;
2682 regs
= dev
->sc_sbic
;
2684 printf("csr trace: ");
2687 printf("%c%02x%02x%02x ", csr_trace
[i
].whr
,
2688 csr_trace
[i
].csr
, csr_trace
[i
].asr
, csr_trace
[i
].xtn
);
2689 switch(csr_trace
[i
].whr
) {
2691 printf("go "); break;
2693 printf("select "); break;
2695 printf("select+ "); break;
2697 printf("intr "); break;
2699 printf("finish "); break;
2701 printf("out "); break;
2703 printf("in "); break;
2705 printf("msgin "); break;
2707 printf("msginx "); break;
2709 printf("msginX "); break;
2711 printf("reselect "); break;
2713 printf("icmd "); break;
2715 printf("abort "); break;
2719 switch(csr_trace
[i
].csr
) {
2721 printf("INITIATOR"); break;
2723 printf("S_XFERRED"); break;
2725 printf("MSGIN_ACK"); break;
2727 printf("DISC"); break;
2729 printf("SEL_TIMEO"); break;
2731 printf("RSLT_NI"); break;
2733 printf("RSLT_IFY"); break;
2735 printf("DISC_1"); break;
2736 case 0x18: case 0x19: case 0x1a:
2737 case 0x1b: case 0x1e: case 0x1f:
2738 case 0x28: case 0x29: case 0x2a:
2739 case 0x2b: case 0x2e: case 0x2f:
2740 case 0x48: case 0x49: case 0x4a:
2741 case 0x4b: case 0x4e: case 0x4f:
2742 case 0x88: case 0x89: case 0x8a:
2743 case 0x8b: case 0x8e: case 0x8f:
2744 switch(csr_trace
[i
].csr
& 0xf0) {
2746 printf("DONE_"); break;
2748 printf("STOP_"); break;
2750 printf("ERR_"); break;
2752 printf("REQ_"); break;
2754 switch(csr_trace
[i
].csr
& 7) {
2756 printf("DATA_OUT"); break;
2758 printf("DATA_IN"); break;
2760 printf("CMD"); break;
2762 printf("STATUS"); break;
2764 printf("MSG_OUT"); break;
2766 printf("MSG_IN"); break;
2768 printf("invld phs");
2771 default: printf("****"); break;
2773 if (csr_trace
[i
].asr
& SBIC_ASR_INT
)
2775 if (csr_trace
[i
].asr
& SBIC_ASR_LCI
)
2777 if (csr_trace
[i
].asr
& SBIC_ASR_BSY
)
2779 if (csr_trace
[i
].asr
& SBIC_ASR_CIP
)
2782 i
= (i
+ 1) & (CSR_TRACE_SIZE
- 1);
2783 } while (i
!= csr_traceptr
);
2785 GET_SBIC_asr(regs
, asr
);
2786 if ((asr
& SBIC_ASR_INT
) == 0)
2787 GET_SBIC_csr(regs
, csr
);
2790 printf("%s@%p regs %p/%p asr %x csr %x\n", dev
->sc_dev
.dv_xname
,
2791 dev
, regs
.sbic_asr_p
, regs
.sbic_value_p
, asr
, csr
);
2792 if ((acb
= dev
->free_list
.tqh_first
)) {
2793 printf("Free list:\n");
2796 acb
= acb
->chain
.tqe_next
;
2799 if ((acb
= dev
->ready_list
.tqh_first
)) {
2800 printf("Ready list:\n");
2803 acb
= acb
->chain
.tqe_next
;
2806 if ((acb
= dev
->nexus_list
.tqh_first
)) {
2807 printf("Nexus list:\n");
2810 acb
= acb
->chain
.tqe_next
;
2813 if (dev
->sc_nexus
) {
2815 sbic_dump_acb(dev
->sc_nexus
);
2817 printf("sc_xs %p targ %d lun %d flags %x tcnt %lx dmacmd %x mask %lx\n",
2818 dev
->sc_xs
, dev
->target
, dev
->lun
, dev
->sc_flags
, dev
->sc_tcnt
,
2819 dev
->sc_dmacmd
, dev
->sc_dmamask
);
2820 for (i
= 0; i
< 8; ++i
) {
2821 if (dev
->sc_tinfo
[i
].cmds
> 2) {
2822 printf("tgt %d: cmds %d disc %d lubusy %x\n",
2823 i
, dev
->sc_tinfo
[i
].cmds
,
2824 dev
->sc_tinfo
[i
].dconns
,
2825 dev
->sc_tinfo
[i
].lubusy
);