1 /* $NetBSD: scsi_1185.c,v 1.18 2005/12/11 12:18:24 christos Exp $ */
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
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 * from: $Hdr: scsi_1185.c,v 4.300 91/06/09 06:22:20 root Rel41 $ SONY
36 * @(#)scsi_1185.c 8.1 (Berkeley) 6/11/93
40 * Copyright (c) 1989- by SONY Corporation.
45 * SCSI bus low level common routines
50 * DMAC_WAIT --- DMAC_0266 wo tukau-baai, DMAC mata-wa SCSI-chip ni
51 * tuzukete access suru-baai,
52 * kanarazu wait wo ireru-beshi !
55 #include <sys/cdefs.h>
56 __KERNEL_RCSID(0, "$NetBSD: scsi_1185.c,v 1.18 2005/12/11 12:18:24 christos Exp $");
58 #include <sys/param.h>
59 #include <sys/systm.h>
60 #include <sys/device.h>
62 #include <uvm/uvm_extern.h>
64 #include <dev/scsipi/scsi_all.h>
65 #include <dev/scsipi/scsipi_all.h>
66 #include <dev/scsipi/scsiconf.h>
68 #include <machine/cpu.h>
69 #include <machine/intr.h>
70 #include <machine/machConst.h>
72 #include <mips/cache.h>
74 #include <newsmips/dev/screg_1185.h>
75 #include <newsmips/dev/scsireg.h>
80 # include <newsmips/dev/dmac_0448.h>
86 #define ABORT_SYNCTR_MES_FROM_TARGET
89 #define DMAC_MAP_INIT /* for nws-3700 parity error */
90 #define APAD_ALWAYS_ON
92 #define CHECK_LOOP_CNT 60
93 #define RSL_LOOP_CNT 60
96 # define MAP_OVER_ACCESS /* for nws-3700 parity error */
101 #ifdef NOT_SUPPORT_SYNCTR
102 # define MAX_OFFSET_BYTES 0
104 # define MAX_OFFSET_BYTES MAX_OFFSET
107 #define act_point spoint
108 #define act_trcnt stcnt
110 #define act_offset soffset
112 #define splscsi splsc
114 #if defined(__mips__) && defined(CPU_SINGLE)
115 #define nops(x) { int __i; for (__i = 0; __i < (x); __i++) ; }
118 #define DMAC_WAIT0 DMAC_WAIT
122 static int dmac_map_init
= 0;
126 * command flag status
133 #define SEL_TIMEOUT_VALUE 0x7a
135 void sc_send(struct sc_scb
*, int, int);
137 void scsi_hardreset(void);
138 void scsi_chipreset(struct sc_softc
*);
139 void scsi_softreset(struct sc_softc
*);
140 int sc_busy(struct sc_softc
*, int);
142 static int WAIT_STATR_BITCLR(int);
143 static int WAIT_STATR_BITSET(int);
144 static void SET_CMD(struct sc_softc
*, int);
145 static void SET_CNT(int);
146 static int GET_CNT(void);
147 static void GET_INTR(uint8_t *, uint8_t *);
148 static void sc_start(struct sc_softc
*);
149 static void sc_resel(struct sc_softc
*);
150 static void sc_discon(struct sc_softc
*);
151 static void sc_pmatch(struct sc_softc
*);
152 static void flush_fifo(struct sc_softc
*);
153 static void sc_cout(struct sc_softc
*, struct sc_chan_stat
*);
154 static void sc_min(struct sc_softc
*, struct sc_chan_stat
*);
155 static void sc_mout(struct sc_softc
*, struct sc_chan_stat
*);
156 static void sc_sin(struct sc_softc
*, volatile struct sc_chan_stat
*);
157 static void sc_dio(struct sc_softc
*, volatile struct sc_chan_stat
*);
158 static void sc_dio_pad(struct sc_softc
*, volatile struct sc_chan_stat
*);
159 static void print_scsi_stat(struct sc_softc
*);
160 static void append_wb(struct sc_softc
*, struct sc_chan_stat
*);
161 static struct sc_chan_stat
*get_wb_chan(struct sc_softc
*);
162 static int release_wb(struct sc_softc
*);
163 static void adjust_transfer(struct sc_softc
*, struct sc_chan_stat
*);
164 static void clean_k2dcache(struct sc_scb
*);
166 extern void sc_done(struct sc_scb
*);
167 extern paddr_t
kvtophys(vaddr_t
);
169 #if defined(__mips__) && defined(CPU_SINGLE)
170 #define dma_reset(x) do { \
171 int __s = splscsi(); \
172 dmac_gsel = (x); dmac_cctl = DM_RST; dmac_cctl = 0; \
174 } while (/* CONSTCOND */ 0)
178 WAIT_STATR_BITCLR(int bitmask
)
187 if (iloop
++ > CHECK_LOOP_CNT
)
189 } while (dummy
& bitmask
);
194 WAIT_STATR_BITSET(int bitmask
)
203 if (iloop
++ > CHECK_LOOP_CNT
)
205 } while ((dummy
& bitmask
) == 0);
210 SET_CMD(struct sc_softc
*sc
, int CMD
)
213 (void)WAIT_STATR_BITCLR(R0_CIP
);
223 sc_tclow
= COUNT
& 0xff;
225 sc_tcmid
= (COUNT
>> 8) & 0xff;
227 sc_tchi
= (COUNT
>> 16) & 0xff;
238 COUNT
+= (sc_tcmid
<< 8) & 0xff00;
240 COUNT
+= (sc_tchi
<< 16) & 0xff0000;
246 GET_INTR(uint8_t *DATA1
, uint8_t *DATA2
)
249 (void)WAIT_STATR_BITCLR(R0_CIP
);
250 while (sc_statr
& R0_MIRQ
) {
261 sc_send(struct sc_scb
*scb
, int chan
, int ie
)
263 struct sc_softc
*sc
= scb
->scb_softc
;
264 struct sc_chan_stat
*cs
;
265 struct scsipi_xfer
*xs
;
269 cs
= &sc
->chan_stat
[chan
];
272 p
= (uint8_t *)xs
->cmd
;
273 if (cs
->scb
!= NULL
) {
274 printf("SCSI%d: sc_send() NOT NULL cs->sc\n", chan
);
275 printf("ie=0x%x scb=%p cs->sc=%p\n", ie
, scb
, cs
->scb
);
277 for (i
= 0; i
< 6; i
++)
278 printf(" 0x%x", *p
++);
280 panic("SCSI soft error");
284 if (p
[0] == SCOP_RESET
&& p
[1] == SCOP_RESET
) {
286 * SCSI bus reset command procedure
287 * (vender unique by Sony Corp.)
297 scb
->istatus
= INST_EP
;
303 if (scb
->sc_map
&& (scb
->sc_map
->mp_pages
> 0)) {
307 scb
->sc_coffset
= scb
->sc_map
->mp_offset
& PGOFSET
;
308 if (scb
->sc_map
->mp_pages
> NSCMAP
) {
309 printf("SCSI%d: map table overflow\n", chan
);
310 scb
->istatus
= INST_EP
|INST_LB
|INST_PRE
;
317 scb
->sc_coffset
= (u_int
)scb
->sc_cpoint
& PGOFSET
;
326 sc
->perr_flag
[chan
] = 0;
327 sc
->mout_flag
[chan
] = 0;
328 sc
->min_cnt
[chan
] = 0;
330 sc
->sel_stat
[chan
] = SEL_WAIT
;
336 * SCSI start up routine
339 sc_start(struct sc_softc
*sc
)
341 struct sc_chan_stat
*cs
;
346 cs
= get_wb_chan(sc
);
347 if ((cs
== NULL
) || (sc
->ipc
>= 0))
350 if (sc
->sel_stat
[chan
] != SEL_WAIT
) {
356 sc
->sel_stat
[chan
] = SEL_START
;
360 if (dummy
& (R4_MBSY
|R4_MSEL
)) {
361 sc
->sel_stat
[chan
] = SEL_WAIT
;
366 * send SELECT with ATN command
372 if (dummy
& R0_CIP
) {
373 sc
->sel_stat
[chan
] = SEL_WAIT
;
376 sc_idenr
= (chan
<< SC_TG_SHIFT
) | SC_OWNID
;
380 sc_intok1
= Ra_STO
|Ra_ARBF
;
382 sc_intok1
= Ra_STO
|Ra_RSL
|Ra_ARBF
;
384 sc_intok1
= Ra_STO
|Ra_RSL
|Ra_ARBF
;
388 * BUGFIX for signal reflection on BSY
391 sc_intok2
= Rb_FNC
|Rb_SRST
|Rb_PHC
|Rb_SPE
;
396 if (dummy
& (R4_MBSY
|R4_MSEL
)) {
397 sc
->sel_stat
[chan
] = SEL_WAIT
;
400 SET_CMD(sc
, SCMD_SEL_ATN
);
407 * SCSI interrupt service routine
416 struct sc_chan_stat
*cs
;
417 uint8_t s_int1
, s_int2
;
419 sc
= device_lookup_private(&sc_cd
, 0); /* XXX */
423 #if defined(CHECK_MRQ) && defined(news3400)
424 while (dmac_gstat
& CH_MRQ(CH_SCSI
))
428 for (iloop
= 0; iloop
< 100; iloop
++) {
431 if ((dummy
& R0_CIP
) == 0)
436 * get SCSI interrupt request
438 while (sc_statr
& R0_MIRQ
) {
444 sc
->int_stat1
|= s_int1
;
445 sc
->int_stat2
|= s_int2
;
448 if (sc
->int_stat2
& R3_SRST
) {
450 * RST signal is drived
452 sc
->int_stat2
&= ~R3_SRST
;
457 if ((sc
->ipc
< 0) && (sc
->wrc
<= 0) && (sc
->wbc
<= 0)) {
463 cs
= get_wb_chan(sc
);
467 if (cs
&& (sc
->sel_stat
[chan
] == SEL_START
) &&
468 (sc
->lastcmd
== SCMD_SEL_ATN
)) {
470 * Check the result of SELECTION command
472 if (sc
->int_stat1
& R2_RSL
) {
477 sc
->sel_stat
[chan
] = SEL_RSLD
;
480 * Ghost RESELECTION ???
482 sc
->int_stat1
&= ~R2_RSL
;
485 if (sc
->int_stat1
& R2_ARBF
) {
489 sc
->int_stat1
&= ~R2_ARBF
;
490 sc
->sel_stat
[chan
] = SEL_ARBF
;
492 if (sc
->int_stat1
& R2_STO
) {
496 sc
->int_stat1
&= ~R2_STO
;
497 if ((sc
->int_stat2
&(R3_PHC
|R3_RMSG
)) !=
500 sc
->ip
= &sc
->chan_stat
[chan
];
501 sc
->sel_stat
[chan
] = SEL_TIMEOUT
;
502 sc
->chan_stat
[chan
].scb
->istatus
509 * SELECTION command done
511 switch (sc
->sel_stat
[chan
]) {
514 if ((sc
->int_stat2
& R3_FNC
) == 0)
519 sc_intok2
= Rb_FNC
|Rb_DCNT
|Rb_SRST
|Rb_PHC
|Rb_SPE
;
521 sc
->ip
= &sc
->chan_stat
[chan
];
522 sc
->ip
->scb
->istatus
|= INST_IP
;
525 sc
->sel_stat
[chan
] = SEL_SUCCESS
;
527 #ifndef NOT_SUPPORT_SYNCTR
528 sc_syncr
= sc
->sync_tr
[chan
];
547 sc
->sel_stat
[chan
] = SEL_WAIT
;
550 if ((sc
->int_stat1
& R2_RSL
) == 0)
551 sc
->int_stat2
&= ~R3_FNC
;
554 if (sc
->ip
!= NULL
) {
556 * check In Process channel's request
558 if (sc
->dma_stat
!= OFF
) {
560 * adjust pointer & counter
562 adjust_transfer(sc
, sc
->ip
);
564 if (sc
->int_stat2
& R3_SPE
) {
571 sc
->int_stat2
&= ~R3_SPE
;
572 sc
->perr_flag
[sc
->ip
->chan_num
] = 1;
576 if (sc
->int_stat2
& R3_DCNT
) {
581 sc
->int_stat2
&= ~R3_DCNT
;
584 if ((sc
->ipc
>= 0) && (sc
->sel_stat
[sc
->ipc
] == SEL_RSL_WAIT
)) {
585 sc
->sel_stat
[sc
->ipc
] = SEL_RSLD
;
587 sc
->int_stat1
|= R2_RSL
;
589 if (sc
->int_stat1
& R2_RSL
) {
594 sc
->int_stat1
&= ~R2_RSL
;
595 if (sc
->sel_stat
[sc
->ipc
] == SEL_RSL_WAIT
)
600 if ((sc
->ipc
>= 0) && (sc
->ipc
!= SC_OWNID
) &&
601 (sc
->sel_stat
[sc
->ipc
] == SEL_SUCCESS
)) {
602 if (sc
->int_stat2
& R3_PHC
) {
606 sc
->int_stat2
&= ~(R3_PHC
|R3_RMSG
);
608 } else if (sc
->int_stat2
& R3_RMSG
) {
612 if (sc
->min_flag
> 0) {
613 sc
->int_stat2
&= ~(R3_PHC
|R3_RMSG
);
617 else if (sc
->dma_stat
!= OFF
) {
620 if ((dummy
& (R4_MMSG
|R4_MCD
|R4_MREQ
)) == R4_MREQ
) {
622 * still DATA transfer phase
624 sc_dio_pad(sc
, sc
->ip
);
627 else if (sc
->ip
->comflg
== CF_SEND
) {
630 if ((dummy
& SC_PMASK
) == COM_OUT
) {
638 if (sc
->int_stat2
& (R3_PHC
|R3_RMSG
))
642 if ((sc
->int_stat1
& (R2_STO
|R2_RSL
|R2_ARBF
))
643 || (sc
->int_stat2
& (R3_DCNT
|R3_SRST
|R3_PHC
|R3_SPE
))) {
655 * SCSI bus reset routine
656 * scsi_hardreset() is occered a reset interrupt.
657 * And call scsi_softreset().
668 sc
= device_lookup_private(&sc_cd
, 0); /* XXX */
675 SET_CMD(sc
, SCMD_AST_RST
); /* assert RST signal */
678 if (dmac_map_init
== 0) {
680 for (i
= 0; i
< NDMACMAP
; i
++) {
681 # if defined(__mips__) && defined(CPU_SINGLE)
683 dmac_ctag
= (uint8_t)i
;
684 dmac_cmap
= (uint16_t)0;
694 * I/O port (sc_ioptr) bit assign
696 * Rf_PRT3 - <reserved>
697 * Rf_PRT2 - <reserved>
698 * Rf_PRT1 out Floppy Disk Density control
699 * Rf_PRT0 out Floppy Disk Eject control
703 scsi_chipreset(struct sc_softc
*sc
)
710 #if defined(__mips__) && defined(CPU_SINGLE)
712 dmac_cwid
= 4; /* initialize DMAC SCSI chan */
713 *(volatile uint8_t *)PINTEN
|= DMA_INTEN
;
716 sc_envir
= 0; /* 1/4 clock */
718 save_ioptr
= sc_ioptr
;
720 sc
->lastcmd
= SCMD_CHIP_RST
;
721 sc_comr
= SCMD_CHIP_RST
; /* reset chip */
723 (void)WAIT_STATR_BITCLR(R0_CIP
);
725 * SCMD_CHIP_RST command reset all register
726 * except sc_statr<7:6> & sc_cmonr.
727 * So, bit R0_MIRQ & R3_FNC will be not set.
732 sc_intok1
= Ra_STO
|Ra_RSL
|Ra_ARBF
;
734 sc_intok2
= Rb_FNC
|Rb_SRST
|Rb_PHC
|Rb_SPE
|Rb_RMSG
;
737 sc_ioptr
= save_ioptr
;
740 sc_moder
= Rc_TMSL
; /* RST drive time = 25.5 us */
745 sc_moder
= Rc_SPHI
; /* selection timeout = 252 ms */
747 sc_timer
= SEL_TIMEOUT_VALUE
;
752 SET_CMD(sc
, SCMD_ENB_SEL
); /* enable reselection */
755 sc
->int_stat1
&= ~R2_RSL
; /* ignore RSL inter request */
761 scsi_softreset(struct sc_softc
*sc
)
763 struct sc_chan_stat
*cs
;
765 /* int (*handler)(); */
776 for (i
= 0; i
< NTARGET
; ++i
) {
779 cs
= &sc
->chan_stat
[i
];
781 #ifndef NOT_SUPPORT_SYNCTR
782 sc
->sync_tr
[i
] = 0; /* asynchronous mode */
784 sc
->sel_stat
[i
] = SEL_WAIT
;
785 if (cs
->scb
!= NULL
) {
786 struct sc_scb
*scb
= cs
->scb
;
788 if ((cs
->scb
->istatus
& INST_EP
) == 0)
789 cs
->scb
->istatus
= (INST_EP
|INST_HE
);
794 if (cs
->intr_flg
== SCSI_INTEN
) {
795 intrcnt
[SCSI_INTR
]++;
797 handler
= scintsw
[i
].sci_inthandler
;
799 (*handler
)(scintsw
[i
].sci_ctlr
);
808 * RESELECTION interrupt service routine
809 * ( RESELECTION phase )
812 sc_resel(struct sc_softc
*sc
)
814 struct sc_chan_stat
*cs
;
820 chan
= (sc_idenr
& R6_SID_MASK
) >> SC_TG_SHIFT
;
822 if (chan
== SC_OWNID
)
827 if (statr
& R0_CIP
) {
828 if (sc
->lastcmd
== SCMD_SEL_ATN
) {
830 * SELECTION command dead lock ?
831 * save interrupt request
833 while (sc_statr
& R0_MIRQ
) {
835 sc
->int_stat1
|= sc_intrq1
;
837 sc
->int_stat2
|= sc_intrq2
;
844 cs
= &sc
->chan_stat
[chan
];
845 if (cs
->scb
== NULL
) {
849 if ((cs
->scb
->istatus
& INST_WR
) == 0) {
862 sc_intok2
= Rb_FNC
|Rb_DCNT
|Rb_SRST
|Rb_PHC
|Rb_SPE
;
866 while ((sc
->int_stat2
& R3_FNC
) == 0) {
870 if (iloop
++ > RSL_LOOP_CNT
) {
871 sc
->sel_stat
[chan
] = SEL_RSL_WAIT
;
874 GET_INTR(&sc
->int_stat1
, &sc
->int_stat2
);
876 sc
->int_stat2
&= ~R3_FNC
;
878 sc
->sel_stat
[chan
] = SEL_SUCCESS
;
883 cs
->scb
->istatus
|= INST_IP
;
884 cs
->scb
->istatus
&= ~INST_WR
;
886 #ifndef NOT_SUPPORT_SYNCTR
887 sc_syncr
= sc
->sync_tr
[chan
];
893 * DISCONNECT interrupt service routine
894 * ( Target disconnect / job done )
897 sc_discon(struct sc_softc
*sc
)
899 struct sc_chan_stat
*cs
;
900 /* int (*handler)(); */
904 * Signal reflection on BSY has occurred.
905 * Not Bus Free Phase, ignore.
907 * But, CXD1185Q reset INIT bit of sc_statr.
908 * So, can't issue Transfer Information command.
910 * What shall we do ? Bus reset ?
912 if ((sc
->int_stat2
& R3_DCNT
) && ((sc_intok2
& Rb_DCNT
) == 0))
915 sc_intok2
= Rb_FNC
|Rb_SRST
|Rb_PHC
|Rb_SPE
;
921 if (dummy
& R4_MATN
) {
922 SET_CMD(sc
, SCMD_NGT_ATN
);
923 (void) WAIT_STATR_BITSET(R0_MIRQ
);
924 GET_INTR(&sc
->int_stat1
, &sc
->int_stat2
); /* clear interrupt */
927 if ((sc
->int_stat1
& R2_RSL
) == 0)
928 sc
->int_stat2
&= ~R3_FNC
;
931 if ((cs
== NULL
) || (sc
->ipc
< 0))
934 if ((sc
->sel_stat
[cs
->chan_num
] != SEL_SUCCESS
)
935 && (sc
->sel_stat
[cs
->chan_num
] != SEL_TIMEOUT
))
936 printf("%s: eh!\n", __func__
);
939 * indicate abnormal terminate
941 if ((cs
->scb
->istatus
& (INST_EP
|INST_WR
)) == 0)
942 cs
->scb
->istatus
|= (INST_EP
|INST_PRE
|INST_LB
);
944 cs
->scb
->istatus
&= ~INST_IP
;
950 if ((cs
->scb
->istatus
& INST_WR
) == 0) {
951 struct sc_scb
*scb
= cs
->scb
;
953 if (sc
->perr_flag
[cs
->chan_num
] > 0)
954 cs
->scb
->istatus
|= INST_EP
|INST_PRE
;
959 if (cs
->intr_flg
== SCSI_INTEN
) {
960 intrcnt
[SCSI_INTR
]++;
962 handler
= scintsw
[cs
->chan_num
].sci_inthandler
;
964 (*handler
)(scintsw
[cs
->chan_num
].sci_ctlr
);
975 * SCSI phase match interrupt service routine
978 sc_pmatch(struct sc_softc
*sc
)
980 struct sc_chan_stat
*cs
;
985 sc
->int_stat2
&= ~R3_FNC
; /* XXXXXXXX */
991 #if defined(__mips__) && defined(CPU_SINGLE)
994 phase
= sc_cmonr
& SC_PMASK
;
1000 phase
= cmonr
& SC_PMASK
;
1001 if (phase
== phase2
) {
1002 if ((phase
== DAT_IN
) || (phase
== DAT_OUT
))
1004 else if (cmonr
& R4_MREQ
)
1013 if (phase
== COM_OUT
) {
1015 if (cs
->comflg
!= CF_SEND
)
1016 cs
->comflg
= CF_SET
;
1019 cs
->comflg
= CF_ENOUGH
;
1020 sc_intok2
&= ~Rb_FNC
;
1021 if (phase
== MES_IN
) {
1043 printf("SCSI%d: unknown phase\n", cs
->chan_num
);
1052 flush_fifo(struct sc_softc
*sc
)
1060 if (dummy
& R5_FIFOREM
) {
1064 SET_CMD(sc
, SCMD_FLSH_FIFO
);
1070 } while (dummy
& R0_CIP
);
1071 GET_INTR(&tmp0
, &tmp
); /* clear interrupt */
1072 } while ((tmp
& R3_FNC
) == 0);
1077 * SCSI command send routine
1080 sc_cout(struct sc_softc
*sc
, struct sc_chan_stat
*cs
)
1086 struct scsipi_xfer
*xs
;
1088 if (cs
->comflg
== CF_SET
) {
1089 struct sc_scb
*scb
= cs
->scb
;
1091 cs
->comflg
= CF_SEND
;
1096 cdb_bytes
= xs
->cmdlen
;
1098 switch (xs
->cmd
->opcode
& CMD_TYPEMASK
) {
1106 sc_intok2
|= Rb_FNC
;
1111 * set Active pointers
1113 sc
->act_cmd_pointer
= (char *)xs
->cmd
;
1114 cs
->act_trcnt
= scb
->sc_ctrnscnt
;
1115 cs
->act_point
= scb
->sc_cpoint
;
1116 cs
->act_tag
= scb
->sc_ctag
;
1117 cs
->act_offset
= scb
->sc_coffset
;
1125 if ((dummy
& SC_PMASK
) != COM_OUT
)
1129 if (statr
& R0_MIRQ
)
1131 } while ((dummy
& R4_MREQ
) == 0);
1134 if (statr
& R0_MIRQ
)
1140 SET_CMD(sc
, SCMD_TR_INFO
|R0_TRBE
);
1142 for (iloop
= 0; iloop
< cdb_bytes
; iloop
++) {
1146 if ((dummy
& SC_PMASK
) != COM_OUT
)
1148 } while ((dummy
& R4_MREQ
) == 0);
1151 if (statr
& R0_MIRQ
)
1153 sc_datr
= *sc
->act_cmd_pointer
++;
1157 } while ((dummy
& R4_MACK
) != 0);
1161 #define GET_MIN_COUNT 127
1164 * SCSI message accept routine
1167 sc_min(struct sc_softc
*sc
, struct sc_chan_stat
*cs
)
1169 struct sc_scb
*scb
= cs
->scb
;
1170 struct scsipi_xfer
*xs
= scb
->xs
;
1173 sc_intok2
= Rb_FNC
|Rb_DCNT
|Rb_SRST
|Rb_PHC
|Rb_SPE
|Rb_RMSG
;
1176 if (sc
->min_flag
== 1)
1181 if ((dummy
& R4_MREQ
) == 0) {
1182 printf("sc_min: !REQ cmonr=%x\n", dummy
);
1183 print_scsi_stat(sc
);
1188 /* retry_cmd_issue: */
1189 sc
->int_stat2
&= ~R3_FNC
;
1190 SET_CMD(sc
, SCMD_TR_INFO
);
1195 } while (dummy
& R0_CIP
);
1196 GET_INTR(&sc
->int_stat1
, &sc
->int_stat2
); /* clear interrupt */
1197 } while ((sc
->int_stat2
& R3_FNC
) == 0);
1198 sc
->int_stat2
&= ~R3_FNC
;
1201 if (dummy
& R5_FIE
) {
1205 if (dummy
& R5_FIE
) {
1208 if ((dummy
& R0_INIT
) == 0) {
1210 * CXD1185 detect BSY false
1217 dummy
= sc_datr
; /* get message byte */
1220 if (sc
->min_cnt
[cs
->chan_num
] == 0) {
1221 scb
->message
= scb
->identify
;
1222 if (dummy
== MSG_EXTND
) {
1223 /* Extended Message */
1224 sc
->min_cnt
[cs
->chan_num
] = GET_MIN_COUNT
;
1225 sc
->min_point
[cs
->chan_num
] = scb
->msgbuf
;
1226 memset(scb
->msgbuf
, 0, 8);
1227 *sc
->min_point
[cs
->chan_num
]++ = dummy
;
1229 switch ((dummy
& MSG_IDENT
)? MSG_IDENT
: dummy
) {
1232 scb
->istatus
|= INST_EP
;
1236 #ifndef NOT_SUPPORT_SYNCTR
1237 if (sc
->mout_flag
[cs
->chan_num
] == MOUT_SYNC_TR
)
1238 sc
->sync_tr
[cs
->chan_num
] = 0;
1249 * restore the saved value to Active pointers
1251 sc
->act_cmd_pointer
= (char *)xs
->cmd
;
1252 cs
->act_trcnt
= scb
->sc_ctrnscnt
;
1253 cs
->act_point
= scb
->sc_cpoint
;
1254 cs
->act_tag
= scb
->sc_ctag
;
1255 cs
->act_offset
= scb
->sc_coffset
;
1260 * save Active pointers
1262 scb
->sc_ctrnscnt
= cs
->act_trcnt
;
1263 scb
->sc_ctag
= cs
->act_tag
;
1264 scb
->sc_coffset
= cs
->act_offset
;
1265 scb
->sc_cpoint
= cs
->act_point
;
1269 scb
->istatus
|= INST_WR
;
1274 scb
->message
= MSG_MREJ
;
1275 SET_CMD(sc
, SCMD_AST_ATN
);
1276 printf("SCSI%d:sc_min() Unknown mes=0x%x, \n",
1277 cs
->chan_num
, dummy
);
1281 *sc
->min_point
[cs
->chan_num
]++ = dummy
;
1282 if (sc
->min_cnt
[cs
->chan_num
] == GET_MIN_COUNT
)
1283 sc
->min_cnt
[cs
->chan_num
] = dummy
;
1285 sc
->min_cnt
[cs
->chan_num
]--;
1286 if (sc
->min_cnt
[cs
->chan_num
] <= 0) {
1287 #ifdef ABORT_SYNCTR_MES_FROM_TARGET
1288 if ((scb
->msgbuf
[2] == 0x01) &&
1289 (sc
->mout_flag
[cs
->chan_num
] == MOUT_SYNC_TR
)) {
1291 if (scb
->msgbuf
[2] == 0x01) {
1295 * receive Synchronous transfer message reply
1296 * calculate transfer period val
1297 * tpm * 4/1000 us = 4/16 * (tpv + 1)
1299 #define TPM2TPV(tpm) (((tpm)*16 + 999) / 1000 - 1)
1300 #ifndef NOT_SUPPORT_SYNCTR
1301 i
= scb
->msgbuf
[3]; /* get tpm */
1302 i
= TPM2TPV(i
) << 4;
1303 if (scb
->msgbuf
[4] == 0)
1304 sc
->sync_tr
[cs
->chan_num
] = 0;
1306 sc
->sync_tr
[cs
->chan_num
] =
1308 #endif /* !NOT_SUPPORT_SYNCTR */
1310 scb
->message
= MSG_MREJ
;
1311 SET_CMD(sc
, SCMD_AST_ATN
); /* assert ATN */
1315 SET_CMD(sc
, SCMD_NGT_ACK
);
1319 * SCSI message send routine
1322 sc_mout(struct sc_softc
*sc
, struct sc_chan_stat
*cs
)
1324 struct sc_scb
*scb
= cs
->scb
;
1334 if (sc
->mout_flag
[cs
->chan_num
] == 0) {
1335 sc
->mout_flag
[cs
->chan_num
] = MOUT_IDENTIFY
;
1336 if (scb
->message
!= 0) {
1337 sc_intok2
= Rb_FNC
|Rb_DCNT
|Rb_SRST
|Rb_PHC
|Rb_SPE
|Rb_RMSG
;
1339 if ((scb
->message
== MSG_EXTND
)
1340 && (scb
->msgbuf
[2] == 0x01)) {
1343 scb
->msgbuf
[3] = MIN_TP
;
1344 if (scb
->msgbuf
[4] > MAX_OFFSET_BYTES
)
1345 scb
->msgbuf
[4] = MAX_OFFSET_BYTES
;
1346 sc
->mout_flag
[cs
->chan_num
] = MOUT_SYNC_TR
;
1353 SET_CMD(sc
, SCMD_TR_INFO
|R0_TRBE
);
1354 sc_datr
= scb
->identify
;
1356 for (iloop
= 1; iloop
< cnt
; iloop
++) {
1363 if ((dummy
& R4_MBSY
) == 0)
1367 } while (dummy
& R0_CIP
);
1370 GET_INTR(&tmp0
, &tmp
); /* clear interrupt */
1371 if ((tmp
& R3_FNC
) == 0) {
1372 (void) WAIT_STATR_BITSET(R0_MIRQ
);
1373 GET_INTR(&tmp0
, &tmp
); /* clear interrupt */
1379 if ((dummy
& R4_MBSY
) == 0)
1381 } while ((dummy
& R4_MREQ
) == 0);
1382 SET_CMD(sc
, SCMD_NGT_ATN
);
1383 (void)WAIT_STATR_BITCLR(R0_CIP
);
1384 GET_INTR(&tmp0
, &tmp
); /* clear interrupt */
1388 if ((dummy
& R4_MREQ
) == 0) {
1389 printf("sc_mout: !REQ cmonr=%x\n", dummy
);
1390 print_scsi_stat(sc
);
1395 SET_CMD(sc
, SCMD_TR_INFO
);
1401 if (dummy
& R4_MATN
) {
1402 SET_CMD(sc
, SCMD_NGT_ATN
);
1403 (void) WAIT_STATR_BITCLR(R0_CIP
);
1404 GET_INTR(&tmp0
, &tmp
); /* clear interrupt */
1411 if (iloop
++ > CHECK_LOOP_CNT
)
1413 } while ((dummy
& R4_MREQ
) == 0);
1414 SET_CMD(sc
, SCMD_TR_INFO
);
1415 sc_datr
= scb
->identify
;
1421 if (dummy
& R4_MATN
) {
1422 SET_CMD(sc
, SCMD_NGT_ATN
);
1423 (void) WAIT_STATR_BITCLR(R0_CIP
);
1424 GET_INTR(&tmp0
, &tmp
); /* clear interrupt */
1429 if ((dummy
& R4_MREQ
) == 0) {
1430 printf("sc_mout: !REQ cmonr=%x\n", dummy
);
1431 print_scsi_stat(sc
);
1436 SET_CMD(sc
, SCMD_TR_INFO
);
1437 sc_datr
= scb
->message
;
1443 * SCSI status accept routine
1446 sc_sin(struct sc_softc
*sc
, volatile struct sc_chan_stat
*cs
)
1455 if ((dummy
& R4_MREQ
) == 0) {
1456 printf("sc_sin: !REQ cmonr=%x\n", dummy
);
1457 print_scsi_stat(sc
);
1462 sc_intok2
= Rb_FNC
|Rb_DCNT
|Rb_SRST
|Rb_PHC
|Rb_SPE
|Rb_RMSG
;
1465 SET_CMD(sc
, SCMD_TR_INFO
);
1467 (void)WAIT_STATR_BITCLR(R0_CIP
);
1469 sc
->int_stat2
&= ~R3_FNC
;
1472 if (iloop
++ > CHECK_LOOP_CNT
)
1474 GET_INTR(&sc
->int_stat1
, &sc
->int_stat2
); /* clear interrupt */
1475 } while ((sc
->int_stat2
& R3_FNC
) == 0);
1476 sc
->int_stat2
&= ~R3_FNC
;
1478 cs
->scb
->tstatus
= sc_datr
; /* get status byte */
1483 * SCSI data in/out routine
1486 sc_dio(struct sc_softc
*sc
, volatile struct sc_chan_stat
*cs
)
1494 struct scsipi_xfer
*xs
;
1499 sc_intok2
= Rb_FNC
|Rb_DCNT
|Rb_SRST
|Rb_PHC
|Rb_SPE
;
1502 if (cs
->act_trcnt
<= 0) {
1507 switch (xs
->cmd
->opcode
) {
1513 i
= (cs
->act_trcnt
+ DEV_BSIZE
-1) / DEV_BSIZE
;
1523 sc
->pad_cnt
[cs
->chan_num
] = i
- cs
->act_trcnt
;
1525 phase
= sc_cmonr
& SC_PMASK
;
1527 if (phase
== DAT_IN
) {
1528 if (sc_syncr
== OFF
) {
1534 #if defined(__mips__) && defined(CPU_SINGLE)
1535 SET_CMD(sc
, SCMD_TR_INFO
|R0_DMA
|R0_TRBE
);
1538 #if defined(__mips__) && defined(CPU_SINGLE)
1539 dmac_gsel
= CH_SCSI
;
1540 dmac_ctrcl
= (uint8_t)(cs
->act_trcnt
& 0xff);
1541 dmac_ctrcm
= (uint8_t)((cs
->act_trcnt
>> 8) & 0xff);
1542 dmac_ctrch
= (uint8_t)((cs
->act_trcnt
>> 16) & 0x0f);
1543 dmac_cofsh
= (uint8_t)((cs
->act_offset
>> 8) & 0xf);
1544 dmac_cofsl
= (uint8_t)(cs
->act_offset
& 0xff);
1548 if (scb
->sc_map
&& (scb
->sc_map
->mp_pages
> 0)) {
1550 * Set DMAC map entry from map table
1552 pages
= scb
->sc_map
->mp_pages
;
1553 for (i
= cs
->act_tag
; i
< pages
; i
++) {
1554 if ((pfn
= scb
->sc_map
->mp_addr
[i
]) == 0)
1555 panic("SCSI:sc_dma() zero entry");
1556 #if defined(__mips__) && defined(CPU_SINGLE)
1557 dmac_gsel
= CH_SCSI
;
1558 dmac_ctag
= (uint8_t)tag
++;
1559 dmac_cmap
= (uint16_t)pfn
;
1562 #ifdef MAP_OVER_ACCESS
1563 # if defined(__mips__) && defined(CPU_SINGLE)
1564 dmac_gsel
= CH_SCSI
;
1565 dmac_ctag
= (uint8_t)tag
++;
1566 dmac_cmap
= (uint16_t)pfn
;
1571 * Set DMAC map entry from logical address
1573 pfn
= kvtophys((vaddr_t
)cs
->act_point
) >> PGSHIFT
;
1574 pages
= (cs
->act_trcnt
>> PGSHIFT
) + 2;
1575 for (i
= 0; i
< pages
; i
++) {
1576 #if defined(__mips__) && defined(CPU_SINGLE)
1577 dmac_gsel
= CH_SCSI
;
1578 dmac_ctag
= (uint8_t)tag
++;
1579 dmac_cmap
= (uint8_t)pfn
+ i
;
1584 #if defined(__mips__) && defined(CPU_SINGLE)
1585 dmac_gsel
= CH_SCSI
;
1589 if (phase
== DAT_IN
) {
1590 sc
->dma_stat
= SC_DMAC_RD
;
1591 #if defined(__mips__) && defined(CPU_SINGLE)
1593 * auto pad flag is always on
1595 dmac_gsel
= CH_SCSI
;
1596 dmac_cctl
= DM_MODE
|DM_APAD
;
1598 dmac_cctl
= DM_MODE
|DM_APAD
|DM_ENABLE
;
1602 else if (phase
== DAT_OUT
) {
1603 sc
->dma_stat
= SC_DMAC_WR
;
1604 #if defined(__mips__) && defined(CPU_SINGLE)
1605 dmac_gsel
= CH_SCSI
;
1606 dmac_cctl
= DM_APAD
;
1608 dmac_cctl
= DM_APAD
|DM_ENABLE
;
1611 /* DMAC start on mem->I/O */
1615 #define MAX_TR_CNT24 ((1 << 24) -1)
1617 sc_dio_pad(struct sc_softc
*sc
, volatile struct sc_chan_stat
*cs
)
1621 if (cs
->act_trcnt
>= 0)
1625 SET_CNT(MAX_TR_CNT24
);
1626 SET_CMD(sc
, SCMD_TR_PAD
|R0_TRBE
);
1627 dummy
= sc_cmonr
& SC_PMASK
;
1629 if (dummy
== DAT_IN
)
1630 dummy
= sc_datr
; /* get data */
1632 sc_datr
= 0; /* send data */
1636 print_scsi_stat(struct sc_softc
*sc
)
1639 printf("ipc=%d wrc=%d wbc=%d\n", sc
->ipc
, sc
->wrc
, sc
->wbc
);
1643 * return 0 if it was done. Or retun TRUE if it is busy.
1646 sc_busy(struct sc_softc
*sc
, int chan
)
1649 return (int)sc
->chan_stat
[chan
].scb
;
1654 * append channel into Waiting Bus_free queue
1657 append_wb(struct sc_softc
*sc
, struct sc_chan_stat
*cs
)
1661 s
= splclock(); /* inhibit process switch */
1662 if (sc
->wbq_actf
== NULL
)
1665 sc
->wbq_actl
->wb_next
= cs
;
1667 cs
->scb
->istatus
= INST_WAIT
;
1673 * get channel from Waiting Bus_free queue
1675 struct sc_chan_stat
*
1676 get_wb_chan(struct sc_softc
*sc
)
1678 struct sc_chan_stat
*cs
;
1681 s
= splclock(); /* inhibit process switch */
1683 if (cs
&& cs
->chan_num
== SC_OWNID
) /* needed? */
1690 * release channel from Waiting Bus_free queue
1693 release_wb(struct sc_softc
*sc
)
1695 struct sc_chan_stat
*cs
;
1699 s
= splclock(); /* inhibit process switch */
1700 if (sc
->wbq_actf
== NULL
) {
1704 sc
->wbq_actf
= cs
->wb_next
;
1706 if (sc
->wbq_actl
== cs
)
1707 sc
->wbq_actl
= NULL
;
1708 cs
->scb
->istatus
&= ~INST_WAIT
;
1716 adjust_transfer(struct sc_softc
*sc
, struct sc_chan_stat
*cs
)
1718 struct sc_scb
*scb
= cs
->scb
;
1720 u_int offset
, sent_byte
;
1722 if (sc
->pad_start
) {
1726 # if defined(__mips__) && defined(CPU_SINGLE)
1727 remain_cnt
= GET_CNT();
1728 remain_cnt
-= sc
->pad_cnt
[cs
->chan_num
];
1729 if (sc
->dma_stat
== SC_DMAC_WR
) {
1731 * adjust counter in the FIFO
1733 remain_cnt
+= sc_ffstr
& R5_FIFOREM
;
1738 sent_byte
= scb
->sc_ctrnscnt
- remain_cnt
;
1739 cs
->act_trcnt
= remain_cnt
;
1741 offset
= scb
->sc_coffset
+ sent_byte
;
1742 cs
->act_tag
+= (offset
>> PGSHIFT
);
1743 cs
->act_offset
= offset
& PGOFSET
;
1744 if ((scb
->sc_map
== NULL
) || (scb
->sc_map
->mp_pages
<= 0))
1745 cs
->act_point
+= sent_byte
;
1750 clean_k2dcache(struct sc_scb
*scb
)
1752 struct sc_map
*sc_map
= scb
->sc_map
;
1756 pa
= kvtophys((vaddr_t
)scb
->msgbuf
);
1757 mips_dcache_wbinv_range_index(MIPS_PHYS_TO_KSEG0(pa
),
1758 sizeof(scb
->msgbuf
));
1760 if (MACH_IS_USPACE(scb
->sc_cpoint
))
1761 panic("clean_k2dcache: user address is not supported");
1763 if (MACH_IS_CACHED(scb
->sc_cpoint
)) {
1764 mips_dcache_wbinv_range_index((vaddr_t
)scb
->sc_cpoint
,
1770 pages
= sc_map
->mp_pages
;
1771 for (i
= 0; i
< pages
; i
++) {
1772 pa
= sc_map
->mp_addr
[i
] << PGSHIFT
;
1773 mips_dcache_wbinv_range_index(MIPS_PHYS_TO_KSEG0(pa
),