1 /* $FreeBSD: src/sys/dev/ncv/ncr53c500.c,v 1.1.2.4 2001/12/17 13:30:18 non Exp $ */
2 /* $DragonFly: src/sys/dev/disk/ncv/ncr53c500.c,v 1.12 2006/12/22 23:26:16 swildner Exp $ */
3 /* $NecBSD: ncr53c500.c,v 1.30.12.3 2001/06/26 07:31:41 honda Exp $ */
8 #define NCV_IO_CONTROL_FLAGS (0)
11 * [NetBSD for NEC PC-98 series]
12 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
13 * NetBSD/pc98 porting staff. All rights reserved.
14 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
15 * Naofumi HONDA. All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 * 3. The name of the author may not be used to endorse or promote products
26 * derived from this software without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
29 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
32 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
33 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
34 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
46 #include <sys/queue.h>
47 #include <sys/malloc.h>
48 #include <sys/errno.h>
50 #include <sys/thread2.h>
52 #include <machine/clock.h>
53 #include <machine/cpu.h>
56 #include <machine/physio_proc.h>
58 #include <bus/cam/scsi/scsi_low.h>
60 #include "ncr53c500reg.h"
61 #include "ncr53c500hw.h"
62 #include "ncr53c500var.h"
64 #include "ncr53c500hwtab.h"
66 #define NCV_MAX_DATA_SIZE (64 * 1024)
67 #define NCV_DELAY_MAX (2 * 1000 * 1000)
68 #define NCV_DELAY_INTERVAL (1)
69 #define NCV_PADDING_SIZE (32)
71 /***************************************************
73 ***************************************************/
74 #define NCV_READ_INTERRUPTS_DRIVEN 0x0001
75 #define NCV_WRITE_INTERRUPTS_DRIVEN 0x0002
76 #define NCV_ENABLE_FAST_SCSI 0x0010
77 #define NCV_FAST_INTERRUPTS 0x0100
79 u_int ncv_io_control = NCV_IO_CONTROL_FLAGS;
80 int ncv_data_read_bytes = 4096;
81 int ncv_data_write_bytes = 4096;
83 /***************************************************
85 ***************************************************/
88 #endif /* NCV_DEBUG */
95 #endif /* NCV_STATICS */
97 /***************************************************
99 ***************************************************/
100 extern struct cfdriver ncv_cd;
102 /**************************************************************
104 **************************************************************/
106 static void ncv_pio_read (struct ncv_softc *, u_int8_t *, u_int);
107 static void ncv_pio_write (struct ncv_softc *, u_int8_t *, u_int);
108 static int ncv_msg (struct ncv_softc *, struct targ_info *, u_int);
109 static int ncv_reselected (struct ncv_softc *);
110 static int ncv_disconnected (struct ncv_softc *, struct targ_info *);
112 static __inline void ncvhw_set_count (bus_space_tag_t, bus_space_handle_t, int);
113 static __inline u_int ncvhw_get_count (bus_space_tag_t, bus_space_handle_t);
114 static __inline void ncvhw_select_register_0 (bus_space_tag_t, bus_space_handle_t, struct ncv_hw *);
115 static __inline void ncvhw_select_register_1 (bus_space_tag_t, bus_space_handle_t, struct ncv_hw *);
116 static __inline void ncvhw_fpush (bus_space_tag_t, bus_space_handle_t, u_int8_t *, int);
118 static void ncv_pdma_end (struct ncv_softc *sc, struct targ_info *);
119 static int ncv_world_start (struct ncv_softc *, int);
120 static void ncvhw_bus_reset (struct ncv_softc *);
121 static void ncvhw_reset (bus_space_tag_t, bus_space_handle_t, struct ncv_hw *);
122 static int ncvhw_check (bus_space_tag_t, bus_space_handle_t, struct ncv_hw *);
123 static void ncvhw_init (bus_space_tag_t, bus_space_handle_t, struct ncv_hw *);
124 static int ncvhw_start_selection (struct ncv_softc *sc, struct slccb *);
125 static void ncvhw_attention (struct ncv_softc *);
126 static int ncv_ccb_nexus_establish (struct ncv_softc *);
127 static int ncv_lun_nexus_establish (struct ncv_softc *);
128 static int ncv_target_nexus_establish (struct ncv_softc *);
129 static int ncv_targ_init (struct ncv_softc *, struct targ_info *, int);
130 static int ncv_catch_intr (struct ncv_softc *);
131 #ifdef NCV_POWER_CONTROL
132 static int ncvhw_power (struct ncv_softc *, u_int);
133 #endif /* NCV_POWER_CONTROL */
134 static __inline void ncv_setup_and_start_pio (struct ncv_softc *, u_int);
136 struct scsi_low_funcs ncv_funcs = {
137 SC_LOW_INIT_T ncv_world_start,
138 SC_LOW_BUSRST_T ncvhw_bus_reset,
139 SC_LOW_TARG_INIT_T ncv_targ_init,
140 SC_LOW_LUN_INIT_T NULL,
142 SC_LOW_SELECT_T ncvhw_start_selection,
143 SC_LOW_NEXUS_T ncv_lun_nexus_establish,
144 SC_LOW_NEXUS_T ncv_ccb_nexus_establish,
146 SC_LOW_ATTEN_T ncvhw_attention,
147 SC_LOW_MSG_T ncv_msg,
149 SC_LOW_TIMEOUT_T NULL,
150 SC_LOW_POLL_T ncvintr,
152 NULL, /* SC_LOW_POWER_T ncvhw_power, */
155 /**************************************************************
157 **************************************************************/
159 ncvhw_select_register_0(bus_space_tag_t iot, bus_space_handle_t ioh,
163 bus_space_write_1(iot, ioh, cr0_cfg4, hw->hw_cfg4);
167 ncvhw_select_register_1(bus_space_tag_t iot, bus_space_handle_t ioh,
171 bus_space_write_1(iot, ioh, cr1_cfg5, hw->hw_cfg5);
175 ncvhw_fpush(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t *buf,
180 for (ptr = 0; ptr < len; ptr ++)
181 bus_space_write_1(iot, ioh, cr0_sfifo, buf[ptr]);
185 ncvhw_set_count(bus_space_tag_t iot, bus_space_handle_t ioh, int count)
188 bus_space_write_1(iot, ioh, cr0_tclsb, (u_int8_t) count);
189 bus_space_write_1(iot, ioh, cr0_tcmsb, (u_int8_t) (count >> NBBY));
190 bus_space_write_1(iot, ioh, cr0_tchsb, (u_int8_t) (count >> (NBBY * 2)));
193 static __inline u_int
194 ncvhw_get_count(bus_space_tag_t iot, bus_space_handle_t ioh)
198 count = (u_int) bus_space_read_1(iot, ioh, cr0_tclsb);
199 count |= ((u_int) bus_space_read_1(iot, ioh, cr0_tcmsb)) << NBBY;
200 count |= ((u_int) bus_space_read_1(iot, ioh, cr0_tchsb)) << (NBBY * 2);
205 ncvhw_check(bus_space_tag_t iot, bus_space_handle_t ioh, struct ncv_hw *hw)
209 ncvhw_select_register_0(iot, ioh, hw);
210 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP | CMD_DMA);
211 if (bus_space_read_1(iot, ioh, cr0_cmd) != (CMD_NOP | CMD_DMA))
214 kprintf("ncv: cr0_cmd CMD_NOP|CMD_DMA failed\n");
215 #endif /* NCV_DEBUG */
219 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP);
220 if (bus_space_read_1(iot, ioh, cr0_cmd) != CMD_NOP)
223 kprintf("ncv: cr0_cmd CMD_NOP failed\n");
224 #endif /* NCV_DEBUG */
229 ncvhw_reset(iot, ioh, hw);
230 ncvhw_init(iot, ioh, hw);
233 ncvhw_select_register_0(iot, ioh, hw);
234 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH);
235 bus_space_write_1(iot, ioh, cr0_cmd, CMD_RSTSCSI);
236 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP | CMD_DMA);
237 SCSI_LOW_DELAY(100 * 1000);
240 bus_space_read_1(iot, ioh, cr0_stat);
241 stat = bus_space_read_1(iot, ioh, cr0_istat);
242 SCSI_LOW_DELAY(1000);
244 if (((stat & INTR_SBR) == 0) ||
245 (bus_space_read_1(iot, ioh, cr0_istat) & INTR_SBR))
248 kprintf("ncv: cr0_istat SCSI BUS RESET failed\n");
249 #endif /* NCV_DEBUG */
257 ncvhw_reset(bus_space_tag_t iot, bus_space_handle_t ioh,
261 ncvhw_select_register_0(iot, ioh, hw);
263 /* dummy cmd twice */
264 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP);
265 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP);
268 bus_space_write_1(iot, ioh, cr0_cmd, CMD_RSTCHIP);
270 /* again dummy cmd twice */
271 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP);
272 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP);
276 ncvhw_init(bus_space_tag_t iot, bus_space_handle_t ioh,
280 ncvhw_select_register_0(iot, ioh, hw);
281 bus_space_write_1(iot, ioh, cr0_clk, hw->hw_clk);
282 bus_space_write_1(iot, ioh, cr0_srtout, SEL_TOUT);
283 bus_space_write_1(iot, ioh, cr0_period, 0);
284 bus_space_write_1(iot, ioh, cr0_offs, 0);
286 bus_space_write_1(iot, ioh, cr0_cfg1, hw->hw_cfg1);
287 bus_space_write_1(iot, ioh, cr0_cfg2, hw->hw_cfg2);
288 bus_space_write_1(iot, ioh, cr0_cfg3, hw->hw_cfg3);
289 bus_space_write_1(iot, ioh, cr0_tchsb, 0);
291 ncvhw_select_register_1(iot, ioh, hw);
292 bus_space_write_1(iot, ioh, cr1_fstat, 0x0);
293 bus_space_write_1(iot, ioh, cr1_pflag, 0x0);
294 bus_space_write_1(iot, ioh, cr1_atacmd, ATACMD_ENGAGE);
296 ncvhw_select_register_0(iot, ioh, hw);
299 #ifdef NCV_POWER_CONTROL
301 ncvhw_power(struct ncv_softc *sc, u_int flags)
303 struct scsi_low_softc *slp = &sc->sc_sclow;
304 bus_space_tag_t iot = sc->sc_iot;
305 bus_space_handle_t ioh = sc->sc_ioh;
307 if (flags == SCSI_LOW_POWDOWN)
309 kprintf("%s power down\n", slp->sl_xname);
310 ncvhw_select_register_1(iot, ioh, &sc->sc_hw);
311 bus_space_write_1(iot, ioh, cr1_atacmd, ATACMD_POWDOWN);
315 switch (sc->sc_rstep)
318 kprintf("%s resume step O\n", slp->sl_xname);
319 ncvhw_select_register_1(iot, ioh, &sc->sc_hw);
320 bus_space_write_1(iot, ioh, cr1_atacmd, ATACMD_ENGAGE);
324 kprintf("%s resume step I\n", slp->sl_xname);
325 ncvhw_reset(iot, ioh, &sc->sc_hw);
326 ncvhw_init(iot, ioh, &sc->sc_hw);
333 #endif /* NCV_POWER_CONTROL */
335 /**************************************************************
337 **************************************************************/
339 ncvhw_attention(struct ncv_softc *sc)
342 bus_space_write_1(sc->sc_iot, sc->sc_ioh, cr0_cmd, CMD_SETATN);
347 ncvhw_bus_reset(struct ncv_softc *sc)
349 bus_space_tag_t iot = sc->sc_iot;
350 bus_space_handle_t ioh = sc->sc_ioh;
352 ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
353 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH);
354 bus_space_write_1(iot, ioh, cr0_cmd, CMD_RSTSCSI);
355 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP | CMD_DMA);
359 ncvhw_start_selection(struct ncv_softc *sc, struct slccb *cb)
361 struct scsi_low_softc *slp = &sc->sc_sclow;
362 bus_space_tag_t iot = sc->sc_iot;
363 bus_space_handle_t ioh = sc->sc_ioh;
364 struct targ_info *ti = cb->ti;
369 sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000;
371 if (scsi_low_is_msgout_continue(ti, SCSI_LOW_MSG_IDENTIFY) == 0)
375 flags = SCSI_LOW_MSGOUT_UNIFY | SCSI_LOW_MSGOUT_INIT;
377 else if (scsi_low_is_msgout_continue(ti,
378 SCSI_LOW_MSG_IDENTIFY | SCSI_LOW_MSG_SIMPLE_QTAG) == 0)
382 flags = SCSI_LOW_MSGOUT_UNIFY | SCSI_LOW_MSGOUT_INIT;
388 flags = SCSI_LOW_MSGOUT_INIT;
391 ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
392 if ((bus_space_read_1(iot, ioh, cr0_stat) & STAT_INT) != 0)
393 return SCSI_LOW_START_FAIL;
395 ncv_target_nexus_establish(sc);
397 len = scsi_low_msgout(slp, ti, flags);
398 if (sc->sc_selstop == 0)
399 scsi_low_cmd(slp, ti);
402 if ((bus_space_read_1(iot, ioh, cr0_stat) & STAT_INT) != 0)
405 return SCSI_LOW_START_FAIL;
408 bus_space_write_1(iot, ioh, cr0_dstid, ti->ti_id);
409 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH);
410 ncvhw_fpush(iot, ioh, ti->ti_msgoutstr, len);
411 if (sc->sc_selstop == 0)
413 ncvhw_fpush(iot, ioh,
414 slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen);
416 bus_space_write_1(iot, ioh, cr0_cmd, cmd);
419 SCSI_LOW_SETUP_PHASE(ti, PH_SELSTART);
420 return SCSI_LOW_START_OK;
424 ncv_world_start(struct ncv_softc *sc, int fdone)
426 struct scsi_low_softc *slp = &sc->sc_sclow;
427 bus_space_tag_t iot = sc->sc_iot;
428 bus_space_handle_t ioh = sc->sc_ioh;
431 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0)
432 sc->sc_hw.hw_cfg1 |= C1_PARENB;
434 sc->sc_hw.hw_cfg1 &= ~C1_PARENB;
436 ncvhw_reset(iot, ioh, &sc->sc_hw);
437 ncvhw_init(iot, ioh, &sc->sc_hw);
439 scsi_low_bus_reset(slp);
441 ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
442 bus_space_read_1(sc->sc_iot, sc->sc_ioh, cr0_stat);
443 stat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, cr0_istat);
444 SCSI_LOW_DELAY(1000);
446 if (((stat & INTR_SBR) == 0) ||
447 (bus_space_read_1(sc->sc_iot, sc->sc_ioh, cr0_istat) & INTR_SBR))
450 SOFT_INTR_REQUIRED(slp);
455 ncv_msg(struct ncv_softc *sc, struct targ_info *ti, u_int msg)
457 bus_space_tag_t iot = sc->sc_iot;
458 bus_space_handle_t ioh = sc->sc_ioh;
459 struct ncv_targ_info *nti = (void *) ti;
460 u_int hwcycle, period;
462 if ((msg & SCSI_LOW_MSG_WIDE) != 0)
464 if (ti->ti_width != SCSI_LOW_BUS_WIDTH_8)
466 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
472 if ((msg & SCSI_LOW_MSG_SYNCH) == 0)
475 period = ti->ti_maxsynch.period;
476 hwcycle = (sc->sc_hw.hw_clk == 0) ? 40 : (5 * sc->sc_hw.hw_clk);
477 hwcycle = 1000 / hwcycle;
479 if (period < 200 / 4 && period >= 100 / 4)
480 nti->nti_reg_cfg3 |= sc->sc_hw.hw_cfg3_fscsi;
482 nti->nti_reg_cfg3 &= ~sc->sc_hw.hw_cfg3_fscsi;
484 period = ((period * 40 / hwcycle) + 5) / 10;
485 nti->nti_reg_period = period & 0x1f;
486 nti->nti_reg_offset = ti->ti_maxsynch.offset;
488 bus_space_write_1(iot, ioh, cr0_period, nti->nti_reg_period);
489 bus_space_write_1(iot, ioh, cr0_offs, nti->nti_reg_offset);
490 bus_space_write_1(iot, ioh, cr0_cfg3, nti->nti_reg_cfg3);
495 ncv_targ_init(struct ncv_softc *sc, struct targ_info *ti, int action)
497 struct ncv_targ_info *nti = (void *) ti;
499 if (action == SCSI_LOW_INFO_ALLOC || action == SCSI_LOW_INFO_REVOKE)
501 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
502 ti->ti_maxsynch.period = sc->sc_hw.hw_mperiod;
503 ti->ti_maxsynch.offset = sc->sc_hw.hw_moffset;
505 nti->nti_reg_cfg3 = sc->sc_hw.hw_cfg3;
506 nti->nti_reg_period = 0;
507 nti->nti_reg_offset = 0;
512 /**************************************************************
513 * General probe attach
514 **************************************************************/
515 static int ncv_setup_img (struct ncv_hw *, u_int, int);
518 ncv_setup_img(struct ncv_hw *hw, u_int dvcfg, int hostid)
521 if (NCV_CLKFACTOR(dvcfg) > CLK_35M_F)
523 kprintf("ncv: invalid dvcfg flags\n");
527 if (NCV_C5IMG(dvcfg) != 0)
529 hw->hw_cfg5 = NCV_C5IMG(dvcfg);
530 hw->hw_clk = NCV_CLKFACTOR(dvcfg);
532 if ((ncv_io_control & NCV_ENABLE_FAST_SCSI) != 0 &&
533 (NCV_SPECIAL(dvcfg) & NCVHWCFG_MAX10M) != 0)
534 hw->hw_mperiod = 100 / 4;
536 if (NCV_SPECIAL(dvcfg) & NCVHWCFG_FIFOBUG)
537 hw->hw_cfg3_fclk = 0x04;
539 if (NCV_SPECIAL(dvcfg) & NCVHWCFG_SCSI1)
540 hw->hw_cfg2 &= ~C2_SCSI2;
542 if (NCV_SPECIAL(dvcfg) & NCVHWCFG_SLOW)
543 hw->hw_cfg1 |= C1_SLOW;
546 /* setup configuration image 3 */
547 if (hw->hw_clk != CLK_40M_F && hw->hw_clk <= CLK_25M_F)
548 hw->hw_cfg3 &= ~hw->hw_cfg3_fclk;
550 hw->hw_cfg3 |= hw->hw_cfg3_fclk;
552 /* setup configuration image 1 */
553 hw->hw_cfg1 = (hw->hw_cfg1 & 0xf0) | hostid;
558 ncvprobesubr(bus_space_tag_t iot, bus_space_handle_t ioh, u_int dvcfg,
563 hwtab = ncv_template;
564 if (ncv_setup_img(&hwtab, dvcfg, hsid))
566 if (ncvhw_check(iot, ioh, &hwtab) != 0)
573 ncvprint(void *aux, const char *name)
577 kprintf("%s: scsibus ", name);
582 ncvattachsubr(struct ncv_softc *sc)
584 struct scsi_low_softc *slp = &sc->sc_sclow;
587 sc->sc_hw = ncv_template;
588 ncv_setup_img(&sc->sc_hw, slp->sl_cfgflags, slp->sl_hostid);
589 slp->sl_funcs = &ncv_funcs;
590 slp->sl_flags |= HW_READ_PADDING;
591 sc->sc_tmaxcnt = SCSI_LOW_MIN_TOUT * 1000 * 1000; /* default */
593 (void) scsi_low_attach(slp, 0, NCV_NTARGETS, NCV_NLUNS,
594 sizeof(struct ncv_targ_info), 0);
597 /**************************************************************
599 **************************************************************/
601 ncv_setup_and_start_pio(struct ncv_softc *sc, u_int reqlen)
603 bus_space_tag_t iot = sc->sc_iot;
604 bus_space_handle_t ioh = sc->sc_ioh;
606 ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
607 ncvhw_set_count(iot, ioh, reqlen);
608 bus_space_write_1(iot, ioh, cr0_cmd, CMD_TRANS | CMD_DMA);
610 ncvhw_select_register_1(iot, ioh, &sc->sc_hw);
611 bus_space_write_1(iot, ioh, cr1_fstat, FIFO_EN);
615 ncv_pdma_end(struct ncv_softc *sc, struct targ_info *ti)
617 struct scsi_low_softc *slp = &sc->sc_sclow;
618 bus_space_tag_t iot = sc->sc_iot;
619 bus_space_handle_t ioh = sc->sc_ioh;
622 slp->sl_flags &= ~HW_PDMASTART;
623 if (slp->sl_Qnexus == NULL)
625 slp->sl_error |= PDMAERR;
629 if (ti->ti_phase == PH_DATA)
631 len = ncvhw_get_count(sc->sc_iot, sc->sc_ioh);
632 if (slp->sl_scp.scp_direction == SCSI_LOW_WRITE)
633 len += (bus_space_read_1(sc->sc_iot, sc->sc_ioh,
634 cr0_sffl) & CR0_SFFLR_BMASK);
636 if ((u_int) len <= (u_int) sc->sc_sdatalen)
638 if ((slp->sl_scp.scp_direction == SCSI_LOW_READ) &&
639 sc->sc_tdatalen != len)
642 len = sc->sc_sdatalen - len;
643 if ((u_int) len > (u_int) slp->sl_scp.scp_datalen)
646 slp->sl_scp.scp_data += len;
647 slp->sl_scp.scp_datalen -= len;
652 if ((slp->sl_error & PDMAERR) == 0)
654 kprintf("%s: stragne cnt hw 0x%x soft 0x%x\n",
656 slp->sl_scp.scp_datalen);
658 slp->sl_error |= PDMAERR;
660 scsi_low_data_finish(slp);
664 kprintf("%s: data phase miss\n", slp->sl_xname);
665 slp->sl_error |= PDMAERR;
669 ncvhw_select_register_1(iot, ioh, &sc->sc_hw);
670 bus_space_write_1(iot, ioh, cr1_fstat, 0);
671 ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
675 ncv_pio_read(struct ncv_softc *sc, u_int8_t *buf, u_int reqlen)
677 struct scsi_low_softc *slp = &sc->sc_sclow;
678 bus_space_tag_t iot = sc->sc_iot;
679 bus_space_handle_t ioh = sc->sc_ioh;
683 ncv_setup_and_start_pio(sc, reqlen);
684 slp->sl_flags |= HW_PDMASTART;
685 sc->sc_sdatalen = reqlen;
686 tout = sc->sc_tmaxcnt;
688 while (reqlen >= FIFO_F_SZ && tout -- > 0)
690 fstat = bus_space_read_1(iot, ioh, cr1_fstat);
691 if (fstat == (u_int8_t) -1)
695 #define NCV_FAST32_ACCESS
696 #ifdef NCV_FAST32_ACCESS
697 bus_space_read_multi_4(iot, ioh, cr1_fdata,
698 (u_int32_t *) buf, FIFO_F_SZ / 4);
699 #else /* !NCV_FAST32_ACCESS */
700 bus_space_read_multi_2(iot, ioh, cr1_fdata,
701 (u_int16_t *) buf, FIFO_F_SZ / 2);
702 #endif /* !NCV_FAST32_ACCESS */
708 if (fstat & FIFO_BRK)
715 while (reqlen > 0 && tout -- > 0)
717 fstat = bus_space_read_1(iot, ioh, cr1_fstat);
718 if ((fstat & FIFO_E) == 0)
720 *buf++ = bus_space_read_1(iot, ioh, cr1_fdata);
725 if (fstat & FIFO_BRK)
733 ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
734 sc->sc_tdatalen = reqlen;
738 ncv_pio_write(struct ncv_softc *sc, u_int8_t *buf, u_int reqlen)
740 struct scsi_low_softc *slp = &sc->sc_sclow;
741 bus_space_tag_t iot = sc->sc_iot;
742 bus_space_handle_t ioh = sc->sc_ioh;
746 ncv_setup_and_start_pio(sc, reqlen);
747 sc->sc_sdatalen = reqlen;
748 tout = sc->sc_tmaxcnt;
749 slp->sl_flags |= HW_PDMASTART;
751 while (reqlen >= FIFO_F_SZ && tout -- > 0)
753 fstat = bus_space_read_1(iot, ioh, cr1_fstat);
754 if (fstat & FIFO_BRK)
757 if ((fstat & FIFO_E) != 0)
759 #ifdef NCV_FAST32_ACCESS
760 bus_space_write_multi_4(iot, ioh, cr1_fdata,
761 (u_int32_t *) buf, FIFO_F_SZ / 4);
762 #else /* !NCV_FAST32_ACCESS */
763 bus_space_write_multi_2(iot, ioh, cr1_fdata,
764 (u_int16_t *) buf, FIFO_F_SZ / 2);
765 #endif /* !NCV_FAST32_ACCESS */
775 while (reqlen > 0 && tout -- > 0)
777 fstat = bus_space_read_1(iot, ioh, cr1_fstat);
778 if (fstat & FIFO_BRK)
781 if ((fstat & FIFO_F) == 0) /* fifo not full */
783 bus_space_write_1(iot, ioh, cr1_fdata, *buf++);
793 ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
796 /**************************************************************
797 * disconnect & reselect (HW low)
798 **************************************************************/
800 ncv_reselected(struct ncv_softc *sc)
802 struct scsi_low_softc *slp = &sc->sc_sclow;
803 bus_space_tag_t iot = sc->sc_iot;
804 bus_space_handle_t ioh = sc->sc_ioh;
805 struct targ_info *ti;
808 if ((bus_space_read_1(iot, ioh, cr0_sffl) & CR0_SFFLR_BMASK) != 2)
810 kprintf("%s illegal fifo bytes\n", slp->sl_xname);
811 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, "chip confused");
815 sid = (u_int) bus_space_read_1(iot, ioh, cr0_sfifo);
816 sid &= ~(1 << slp->sl_hostid);
818 ti = scsi_low_reselected((struct scsi_low_softc *) sc, sid);
823 ncv_statics.reselect ++;
824 #endif /* NCV_STATICS */
825 bus_space_write_1(iot, ioh, cr0_dstid, sid);
830 ncv_disconnected(struct ncv_softc *sc, struct targ_info *ti)
832 struct scsi_low_softc *slp = &sc->sc_sclow;
833 bus_space_tag_t iot = sc->sc_iot;
834 bus_space_handle_t ioh = sc->sc_ioh;
836 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH);
837 bus_space_write_1(iot, ioh, cr0_cmd, CMD_ENSEL);
840 ncv_statics.disconnect ++;
841 #endif /* NCV_STATICS */
843 scsi_low_disconnected(slp, ti);
847 /**************************************************************
849 **************************************************************/
851 ncv_target_nexus_establish(struct ncv_softc *sc)
853 struct scsi_low_softc *slp = &sc->sc_sclow;
854 struct targ_info *ti = slp->sl_Tnexus;
855 struct ncv_targ_info *nti = (void *) ti;
856 bus_space_tag_t iot = sc->sc_iot;
857 bus_space_handle_t ioh = sc->sc_ioh;
859 bus_space_write_1(iot, ioh, cr0_period, nti->nti_reg_period);
860 bus_space_write_1(iot, ioh, cr0_offs, nti->nti_reg_offset);
861 bus_space_write_1(iot, ioh, cr0_cfg3, nti->nti_reg_cfg3);
866 ncv_lun_nexus_establish(struct ncv_softc *sc)
873 ncv_ccb_nexus_establish(struct ncv_softc *sc)
875 struct scsi_low_softc *slp = &sc->sc_sclow;
876 struct slccb *cb = slp->sl_Qnexus;
878 sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000;
883 ncv_catch_intr(struct ncv_softc *sc)
885 bus_space_tag_t iot = sc->sc_iot;
886 bus_space_handle_t ioh = sc->sc_ioh;
890 for (wc = 0; wc < NCV_DELAY_MAX / NCV_DELAY_INTERVAL; wc ++)
892 status = bus_space_read_1(iot, ioh, cr0_stat);
893 if ((status & STAT_INT) != 0)
896 SCSI_LOW_DELAY(NCV_DELAY_INTERVAL);
904 struct ncv_softc *sc = arg;
905 struct scsi_low_softc *slp = &sc->sc_sclow;
906 bus_space_tag_t iot = sc->sc_iot;
907 bus_space_handle_t ioh = sc->sc_ioh;
908 struct targ_info *ti;
909 struct physio_proc *pp;
913 u_int8_t regv, status, ireason;
916 if (slp->sl_flags & HW_INACTIVE)
919 /********************************************
921 ********************************************/
922 ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
923 status = bus_space_read_1(iot, ioh, cr0_stat);
924 if ((status & STAT_INT) == 0 || status == (u_int8_t) -1)
927 ireason = bus_space_read_1(iot, ioh, cr0_istat);
928 if ((ireason & INTR_SBR) != 0)
932 /* avoid power off hangup */
933 val = bus_space_read_1(iot, ioh, cr0_cfg1);
934 bus_space_write_1(iot, ioh, cr0_cfg1, val | C1_SRR);
937 scsi_low_restart(slp, SCSI_LOW_RESTART_SOFT,
938 "bus reset (power off?)");
942 /********************************************
944 ********************************************/
948 scsi_low_print(slp, NULL);
949 kprintf("%s st %x ist %x\n\n", slp->sl_xname,
953 SCSI_LOW_DEBUGGER("ncv");
956 #endif /* NCV_DEBUG */
958 /********************************************
959 * Reselect or Disconnect or Nexus check
960 ********************************************/
962 if (ireason == INTR_RESELECT)
964 if (ncv_reselected(sc) == EJUSTRETURN)
969 if ((ti = slp->sl_Tnexus) == NULL)
973 if ((status & (STAT_PE | STAT_GE)) != 0)
975 slp->sl_error |= PARITYERR;
976 if ((status & PHASE_MASK) == MESSAGE_IN_PHASE)
977 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
979 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ERROR, 1);
980 derror = SCSI_LOW_DATA_PE;
983 if ((ireason & (INTR_DIS | INTR_ILL)) != 0)
985 if ((ireason & INTR_ILL) == 0)
986 return ncv_disconnected(sc, ti);
988 slp->sl_error |= FATALIO;
989 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, "illegal cmd");
993 /********************************************
994 * Internal scsi phase
995 ********************************************/
996 switch (ti->ti_phase)
999 scsi_low_arbit_win(slp);
1000 SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED);
1002 if (sc->sc_selstop == 0)
1005 * Here scsi phases expected are
1007 * MSGIN : target wants to disconnect the host.
1008 * STATUSIN : immediate command completed.
1009 * CMD PHASE : command out failed
1010 * MSGOUT : identify command failed.
1012 if ((status & PHASE_MASK) != MESSAGE_OUT_PHASE)
1017 if ((status & PHASE_MASK) != MESSAGE_OUT_PHASE)
1019 if ((ireason & INTR_FC) != 0)
1021 SCSI_LOW_ASSERT_ATN(slp);
1024 SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT);
1028 ncv_target_nexus_establish(sc);
1029 if ((status & PHASE_MASK) != MESSAGE_IN_PHASE)
1031 kprintf("%s: unexpected phase after reselect\n",
1033 slp->sl_error |= FATALIO;
1034 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 1);
1040 if ((slp->sl_flags & HW_PDMASTART) != 0)
1042 ncv_pdma_end(sc, ti);
1047 /********************************************
1048 * Scsi phase sequencer
1049 ********************************************/
1050 switch (status & PHASE_MASK)
1052 case DATA_OUT_PHASE: /* data out */
1053 SCSI_LOW_SETUP_PHASE(ti, PH_DATA);
1054 if (scsi_low_data(slp, ti, &bp, SCSI_LOW_WRITE) != 0)
1056 scsi_low_attention(slp);
1059 pp = physio_proc_enter(bp);
1060 if (slp->sl_scp.scp_datalen <= 0)
1062 if ((ireason & INTR_BS) == 0)
1065 if ((slp->sl_error & PDMAERR) == 0)
1066 kprintf("%s: data underrun\n", slp->sl_xname);
1067 slp->sl_error |= PDMAERR;
1069 if ((slp->sl_flags & HW_WRITE_PADDING) != 0)
1071 u_int8_t padding[NCV_PADDING_SIZE];
1073 SCSI_LOW_BZERO(padding, sizeof(padding));
1074 ncv_pio_write(sc, padding, sizeof(padding));
1078 kprintf("%s: write padding required\n",
1084 len = slp->sl_scp.scp_datalen;
1085 if ((ncv_io_control & NCV_WRITE_INTERRUPTS_DRIVEN) != 0)
1087 if (len > ncv_data_write_bytes)
1088 len = ncv_data_write_bytes;
1090 ncv_pio_write(sc, slp->sl_scp.scp_data, len);
1092 physio_proc_leave(pp);
1095 case DATA_IN_PHASE: /* data in */
1096 SCSI_LOW_SETUP_PHASE(ti, PH_DATA);
1097 if (scsi_low_data(slp, ti, &bp, SCSI_LOW_READ) != 0)
1099 scsi_low_attention(slp);
1102 pp = physio_proc_enter(bp);
1103 if (slp->sl_scp.scp_datalen <= 0)
1105 if ((ireason & INTR_BS) == 0)
1108 if ((slp->sl_error & PDMAERR) == 0)
1109 kprintf("%s: data overrun\n", slp->sl_xname);
1110 slp->sl_error |= PDMAERR;
1112 if ((slp->sl_flags & HW_READ_PADDING) != 0)
1114 u_int8_t padding[NCV_PADDING_SIZE];
1116 ncv_pio_read(sc, padding, sizeof(padding));
1120 kprintf("%s: read padding required\n",
1127 len = slp->sl_scp.scp_datalen;
1128 if ((ncv_io_control & NCV_READ_INTERRUPTS_DRIVEN) != 0)
1130 if (len > ncv_data_read_bytes)
1131 len = ncv_data_read_bytes;
1133 ncv_pio_read(sc, slp->sl_scp.scp_data, len);
1135 physio_proc_leave(pp);
1138 case COMMAND_PHASE: /* cmd out */
1139 SCSI_LOW_SETUP_PHASE(ti, PH_CMD);
1140 if (scsi_low_cmd(slp, ti) != 0)
1142 scsi_low_attention(slp);
1145 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH);
1146 ncvhw_fpush(iot, ioh,
1147 slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen);
1148 bus_space_write_1(iot, ioh, cr0_cmd, CMD_TRANS);
1151 case STATUS_PHASE: /* status in */
1152 SCSI_LOW_SETUP_PHASE(ti, PH_STAT);
1153 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH);
1154 bus_space_write_1(iot, ioh, cr0_cmd, CMD_ICCS);
1161 case MESSAGE_OUT_PHASE: /* msg out */
1162 SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT);
1163 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH);
1165 flags = SCSI_LOW_MSGOUT_UNIFY;
1166 if (ti->ti_ophase != ti->ti_phase)
1167 flags |= SCSI_LOW_MSGOUT_INIT;
1168 len = scsi_low_msgout(slp, ti, flags);
1170 if (len > 1 && slp->sl_atten == 0)
1172 scsi_low_attention(slp);
1175 ncvhw_fpush(iot, ioh, ti->ti_msgoutstr, len);
1176 bus_space_write_1(iot, ioh, cr0_cmd, CMD_TRANS);
1177 SCSI_LOW_DEASSERT_ATN(slp);
1180 case MESSAGE_IN_PHASE: /* msg in */
1181 SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
1183 len = bus_space_read_1(iot, ioh, cr0_sffl) & CR0_SFFLR_BMASK;
1184 if (sc->sc_compseq != 0)
1187 if ((ireason & INTR_FC) && len == 2)
1189 regv = bus_space_read_1(iot, ioh, cr0_sfifo);
1190 scsi_low_statusin(slp, ti, regv | derror);
1195 slp->sl_error |= FATALIO;
1196 scsi_low_assert_msg(slp, ti,
1197 SCSI_LOW_MSG_ABORT, 1);
1198 bus_space_write_1(sc->sc_iot, sc->sc_ioh,
1199 cr0_cmd, CMD_MSGOK);
1203 else if (ireason & INTR_BS)
1205 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH);
1206 bus_space_write_1(iot, ioh, cr0_cmd, CMD_TRANS);
1207 if ((ncv_io_control & NCV_FAST_INTERRUPTS) != 0)
1209 if (ncv_catch_intr(sc) == 0)
1215 if ((ireason & INTR_FC) && len == 1)
1217 regv = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
1219 if (scsi_low_msgin(slp, ti, regv | derror) == 0)
1221 if (scsi_low_is_msgout_continue(ti, 0) != 0)
1223 scsi_low_attention(slp);
1226 bus_space_write_1(sc->sc_iot, sc->sc_ioh, cr0_cmd,
1228 if ((ncv_io_control & NCV_FAST_INTERRUPTS) != 0)
1231 * clear a pending interrupt and sync with
1239 slp->sl_error |= FATALIO;
1240 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 1);
1241 bus_space_write_1(sc->sc_iot, sc->sc_ioh, cr0_cmd,