1 /* $NecBSD: ncr53c500.c,v 1.30.12.3 2001/06/26 07:31:41 honda Exp $ */
6 #define NCV_IO_CONTROL_FLAGS (0)
9 * [NetBSD for NEC PC-98 series]
10 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
11 * NetBSD/pc98 porting staff. All rights reserved.
12 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
13 * Naofumi HONDA. All rights reserved.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
30 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
39 #include <sys/cdefs.h>
40 __FBSDID("$FreeBSD$");
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
47 #include <sys/queue.h>
48 #include <sys/malloc.h>
49 #include <sys/errno.h>
51 #include <machine/cpu.h>
52 #include <machine/bus.h>
54 #include <compat/netbsd/dvcfg.h>
56 #include <cam/scsi/scsi_low.h>
58 #include <dev/ncv/ncr53c500reg.h>
59 #include <dev/ncv/ncr53c500hw.h>
60 #include <dev/ncv/ncr53c500var.h>
62 #include <dev/ncv/ncr53c500hwtab.h>
64 #define NCV_MAX_DATA_SIZE (64 * 1024)
65 #define NCV_DELAY_MAX (2 * 1000 * 1000)
66 #define NCV_DELAY_INTERVAL (1)
67 #define NCV_PADDING_SIZE (32)
69 /***************************************************
71 ***************************************************/
72 #define NCV_READ_INTERRUPTS_DRIVEN 0x0001
73 #define NCV_WRITE_INTERRUPTS_DRIVEN 0x0002
74 #define NCV_ENABLE_FAST_SCSI 0x0010
75 #define NCV_FAST_INTERRUPTS 0x0100
77 u_int ncv_io_control = NCV_IO_CONTROL_FLAGS;
78 int ncv_data_read_bytes = 4096;
79 int ncv_data_write_bytes = 4096;
81 /***************************************************
83 ***************************************************/
86 #endif /* NCV_DEBUG */
89 static struct ncv_statics {
93 #endif /* NCV_STATICS */
95 /***************************************************
97 ***************************************************/
98 extern struct cfdriver ncv_cd;
100 /**************************************************************
102 **************************************************************/
104 static void ncv_pio_read(struct ncv_softc *, u_int8_t *, u_int);
105 static void ncv_pio_write(struct ncv_softc *, u_int8_t *, u_int);
106 static int ncv_msg(struct ncv_softc *, struct targ_info *, u_int);
107 static int ncv_reselected(struct ncv_softc *);
108 static int ncv_disconnected(struct ncv_softc *, struct targ_info *);
110 static __inline void ncvhw_set_count(bus_space_tag_t, bus_space_handle_t, int);
111 static __inline u_int ncvhw_get_count(bus_space_tag_t, bus_space_handle_t);
112 static __inline void ncvhw_select_register_0(bus_space_tag_t, bus_space_handle_t, struct ncv_hw *);
113 static __inline void ncvhw_select_register_1(bus_space_tag_t, bus_space_handle_t, struct ncv_hw *);
114 static __inline void ncvhw_fpush(bus_space_tag_t, bus_space_handle_t, u_int8_t *, int);
116 static void ncv_pdma_end(struct ncv_softc *sc, struct targ_info *);
117 static int ncv_world_start(struct ncv_softc *, int);
118 static void ncvhw_bus_reset(struct ncv_softc *);
119 static void ncvhw_reset(bus_space_tag_t, bus_space_handle_t, struct ncv_hw *);
120 static int ncvhw_check(bus_space_tag_t, bus_space_handle_t, struct ncv_hw *);
121 static void ncvhw_init(bus_space_tag_t, bus_space_handle_t, struct ncv_hw *);
122 static int ncvhw_start_selection(struct ncv_softc *sc, struct slccb *);
123 static void ncvhw_attention(struct ncv_softc *);
124 static int ncv_ccb_nexus_establish(struct ncv_softc *);
125 static int ncv_lun_nexus_establish(struct ncv_softc *);
126 static int ncv_target_nexus_establish(struct ncv_softc *);
127 static int ncv_targ_init(struct ncv_softc *, struct targ_info *, int);
128 static int ncv_catch_intr(struct ncv_softc *);
129 #ifdef NCV_POWER_CONTROL
130 static int ncvhw_power(struct ncv_softc *, u_int);
131 #endif /* NCV_POWER_CONTROL */
132 static __inline void ncv_setup_and_start_pio(struct ncv_softc *, u_int);
134 struct scsi_low_funcs ncv_funcs = {
135 SC_LOW_INIT_T ncv_world_start,
136 SC_LOW_BUSRST_T ncvhw_bus_reset,
137 SC_LOW_TARG_INIT_T ncv_targ_init,
138 SC_LOW_LUN_INIT_T NULL,
140 SC_LOW_SELECT_T ncvhw_start_selection,
141 SC_LOW_NEXUS_T ncv_lun_nexus_establish,
142 SC_LOW_NEXUS_T ncv_ccb_nexus_establish,
144 SC_LOW_ATTEN_T ncvhw_attention,
145 SC_LOW_MSG_T ncv_msg,
147 SC_LOW_TIMEOUT_T NULL,
148 SC_LOW_POLL_T ncvintr,
150 NULL, /* SC_LOW_POWER_T ncvhw_power, */
153 /**************************************************************
155 **************************************************************/
157 ncvhw_select_register_0(iot, ioh, hw)
159 bus_space_handle_t ioh;
163 bus_space_write_1(iot, ioh, cr0_cfg4, hw->hw_cfg4);
167 ncvhw_select_register_1(iot, ioh, hw)
169 bus_space_handle_t ioh;
173 bus_space_write_1(iot, ioh, cr1_cfg5, hw->hw_cfg5);
177 ncvhw_fpush(iot, ioh, buf, len)
179 bus_space_handle_t ioh;
185 for (ptr = 0; ptr < len; ptr ++)
186 bus_space_write_1(iot, ioh, cr0_sfifo, buf[ptr]);
190 ncvhw_set_count(iot, ioh, count)
192 bus_space_handle_t ioh;
196 bus_space_write_1(iot, ioh, cr0_tclsb, (u_int8_t) count);
197 bus_space_write_1(iot, ioh, cr0_tcmsb, (u_int8_t) (count >> NBBY));
198 bus_space_write_1(iot, ioh, cr0_tchsb, (u_int8_t) (count >> (NBBY * 2)));
201 static __inline u_int
202 ncvhw_get_count(iot, ioh)
204 bus_space_handle_t ioh;
208 count = (u_int) bus_space_read_1(iot, ioh, cr0_tclsb);
209 count |= ((u_int) bus_space_read_1(iot, ioh, cr0_tcmsb)) << NBBY;
210 count |= ((u_int) bus_space_read_1(iot, ioh, cr0_tchsb)) << (NBBY * 2);
215 ncvhw_check(iot, ioh, hw)
217 bus_space_handle_t ioh;
222 ncvhw_select_register_0(iot, ioh, hw);
223 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP | CMD_DMA);
224 if (bus_space_read_1(iot, ioh, cr0_cmd) != (CMD_NOP | CMD_DMA))
227 printf("ncv: cr0_cmd CMD_NOP|CMD_DMA failed\n");
228 #endif /* NCV_DEBUG */
232 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP);
233 if (bus_space_read_1(iot, ioh, cr0_cmd) != CMD_NOP)
236 printf("ncv: cr0_cmd CMD_NOP failed\n");
237 #endif /* NCV_DEBUG */
242 ncvhw_reset(iot, ioh, hw);
243 ncvhw_init(iot, ioh, hw);
246 ncvhw_select_register_0(iot, ioh, hw);
247 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH);
248 bus_space_write_1(iot, ioh, cr0_cmd, CMD_RSTSCSI);
249 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP | CMD_DMA);
253 bus_space_read_1(iot, ioh, cr0_stat);
254 stat = bus_space_read_1(iot, ioh, cr0_istat);
257 if (((stat & INTR_SBR) == 0) ||
258 (bus_space_read_1(iot, ioh, cr0_istat) & INTR_SBR))
261 printf("ncv: cr0_istat SCSI BUS RESET failed\n");
262 #endif /* NCV_DEBUG */
270 ncvhw_reset(iot, ioh, hw)
272 bus_space_handle_t ioh;
276 ncvhw_select_register_0(iot, ioh, hw);
278 /* dummy cmd twice */
279 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP);
280 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP);
283 bus_space_write_1(iot, ioh, cr0_cmd, CMD_RSTCHIP);
285 /* again dummy cmd twice */
286 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP);
287 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP);
291 ncvhw_init(iot, ioh, hw)
293 bus_space_handle_t ioh;
297 ncvhw_select_register_0(iot, ioh, hw);
298 bus_space_write_1(iot, ioh, cr0_clk, hw->hw_clk);
299 bus_space_write_1(iot, ioh, cr0_srtout, SEL_TOUT);
300 bus_space_write_1(iot, ioh, cr0_period, 0);
301 bus_space_write_1(iot, ioh, cr0_offs, 0);
303 bus_space_write_1(iot, ioh, cr0_cfg1, hw->hw_cfg1);
304 bus_space_write_1(iot, ioh, cr0_cfg2, hw->hw_cfg2);
305 bus_space_write_1(iot, ioh, cr0_cfg3, hw->hw_cfg3);
306 bus_space_write_1(iot, ioh, cr0_tchsb, 0);
308 ncvhw_select_register_1(iot, ioh, hw);
309 bus_space_write_1(iot, ioh, cr1_fstat, 0x0);
310 bus_space_write_1(iot, ioh, cr1_pflag, 0x0);
311 bus_space_write_1(iot, ioh, cr1_atacmd, ATACMD_ENGAGE);
313 ncvhw_select_register_0(iot, ioh, hw);
316 #ifdef NCV_POWER_CONTROL
318 ncvhw_power(sc, flags)
319 struct ncv_softc *sc;
322 struct scsi_low_softc *slp = &sc->sc_sclow;
323 bus_space_tag_t iot = sc->sc_iot;
324 bus_space_handle_t ioh = sc->sc_ioh;
326 if (flags == SCSI_LOW_POWDOWN)
328 device_printf(slp->sl_dev, "power down\n");
329 ncvhw_select_register_1(iot, ioh, &sc->sc_hw);
330 bus_space_write_1(iot, ioh, cr1_atacmd, ATACMD_POWDOWN);
334 switch (sc->sc_rstep)
337 device_printf(slp->sl_dev, "resume step O\n");
338 ncvhw_select_register_1(iot, ioh, &sc->sc_hw);
339 bus_space_write_1(iot, ioh, cr1_atacmd, ATACMD_ENGAGE);
343 device_printf(slp->sl_dev, "resume step I\n");
344 ncvhw_reset(iot, ioh, &sc->sc_hw);
345 ncvhw_init(iot, ioh, &sc->sc_hw);
352 #endif /* NCV_POWER_CONTROL */
354 /**************************************************************
356 **************************************************************/
359 struct ncv_softc *sc;
362 bus_space_write_1(sc->sc_iot, sc->sc_ioh, cr0_cmd, CMD_SETATN);
368 struct ncv_softc *sc;
370 bus_space_tag_t iot = sc->sc_iot;
371 bus_space_handle_t ioh = sc->sc_ioh;
373 ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
374 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH);
375 bus_space_write_1(iot, ioh, cr0_cmd, CMD_RSTSCSI);
376 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP | CMD_DMA);
380 ncvhw_start_selection(sc, cb)
381 struct ncv_softc *sc;
384 struct scsi_low_softc *slp = &sc->sc_sclow;
385 bus_space_tag_t iot = sc->sc_iot;
386 bus_space_handle_t ioh = sc->sc_ioh;
387 struct targ_info *ti = cb->ti;
392 sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000;
394 if (scsi_low_is_msgout_continue(ti, SCSI_LOW_MSG_IDENTIFY) == 0)
398 flags = SCSI_LOW_MSGOUT_UNIFY | SCSI_LOW_MSGOUT_INIT;
400 else if (scsi_low_is_msgout_continue(ti,
401 SCSI_LOW_MSG_IDENTIFY | SCSI_LOW_MSG_SIMPLE_QTAG) == 0)
405 flags = SCSI_LOW_MSGOUT_UNIFY | SCSI_LOW_MSGOUT_INIT;
411 flags = SCSI_LOW_MSGOUT_INIT;
414 ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
415 if ((bus_space_read_1(iot, ioh, cr0_stat) & STAT_INT) != 0)
416 return SCSI_LOW_START_FAIL;
418 ncv_target_nexus_establish(sc);
420 len = scsi_low_msgout(slp, ti, flags);
421 if (sc->sc_selstop == 0)
422 scsi_low_cmd(slp, ti);
425 if ((bus_space_read_1(iot, ioh, cr0_stat) & STAT_INT) != 0)
428 return SCSI_LOW_START_FAIL;
431 bus_space_write_1(iot, ioh, cr0_dstid, ti->ti_id);
432 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH);
433 ncvhw_fpush(iot, ioh, ti->ti_msgoutstr, len);
434 if (sc->sc_selstop == 0)
436 ncvhw_fpush(iot, ioh,
437 slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen);
439 bus_space_write_1(iot, ioh, cr0_cmd, cmd);
442 SCSI_LOW_SETUP_PHASE(ti, PH_SELSTART);
443 return SCSI_LOW_START_OK;
447 ncv_world_start(sc, fdone)
448 struct ncv_softc *sc;
451 struct scsi_low_softc *slp = &sc->sc_sclow;
452 bus_space_tag_t iot = sc->sc_iot;
453 bus_space_handle_t ioh = sc->sc_ioh;
456 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0)
457 sc->sc_hw.hw_cfg1 |= C1_PARENB;
459 sc->sc_hw.hw_cfg1 &= ~C1_PARENB;
461 ncvhw_reset(iot, ioh, &sc->sc_hw);
462 ncvhw_init(iot, ioh, &sc->sc_hw);
464 scsi_low_bus_reset(slp);
466 ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
467 bus_space_read_1(sc->sc_iot, sc->sc_ioh, cr0_stat);
468 stat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, cr0_istat);
471 if (((stat & INTR_SBR) == 0) ||
472 (bus_space_read_1(sc->sc_iot, sc->sc_ioh, cr0_istat) & INTR_SBR))
480 struct ncv_softc *sc;
481 struct targ_info *ti;
484 bus_space_tag_t iot = sc->sc_iot;
485 bus_space_handle_t ioh = sc->sc_ioh;
486 struct ncv_targ_info *nti = (void *) ti;
487 u_int hwcycle, period;
489 if ((msg & SCSI_LOW_MSG_WIDE) != 0)
491 if (ti->ti_width != SCSI_LOW_BUS_WIDTH_8)
493 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
499 if ((msg & SCSI_LOW_MSG_SYNCH) == 0)
502 period = ti->ti_maxsynch.period;
503 hwcycle = (sc->sc_hw.hw_clk == 0) ? 40 : (5 * sc->sc_hw.hw_clk);
504 hwcycle = 1000 / hwcycle;
506 if (period < 200 / 4 && period >= 100 / 4)
507 nti->nti_reg_cfg3 |= sc->sc_hw.hw_cfg3_fscsi;
509 nti->nti_reg_cfg3 &= ~sc->sc_hw.hw_cfg3_fscsi;
511 period = ((period * 40 / hwcycle) + 5) / 10;
512 nti->nti_reg_period = period & 0x1f;
513 nti->nti_reg_offset = ti->ti_maxsynch.offset;
515 bus_space_write_1(iot, ioh, cr0_period, nti->nti_reg_period);
516 bus_space_write_1(iot, ioh, cr0_offs, nti->nti_reg_offset);
517 bus_space_write_1(iot, ioh, cr0_cfg3, nti->nti_reg_cfg3);
522 ncv_targ_init(sc, ti, action)
523 struct ncv_softc *sc;
524 struct targ_info *ti;
527 struct ncv_targ_info *nti = (void *) ti;
529 if (action == SCSI_LOW_INFO_ALLOC || action == SCSI_LOW_INFO_REVOKE)
531 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
532 ti->ti_maxsynch.period = sc->sc_hw.hw_mperiod;
533 ti->ti_maxsynch.offset = sc->sc_hw.hw_moffset;
535 nti->nti_reg_cfg3 = sc->sc_hw.hw_cfg3;
536 nti->nti_reg_period = 0;
537 nti->nti_reg_offset = 0;
542 /**************************************************************
543 * General probe attach
544 **************************************************************/
545 static int ncv_setup_img(struct ncv_hw *, u_int, int);
548 ncv_setup_img(hw, dvcfg, hostid)
554 if (NCV_CLKFACTOR(dvcfg) > CLK_35M_F)
556 printf("ncv: invalid dvcfg flags\n");
560 if (NCV_C5IMG(dvcfg) != 0)
562 hw->hw_cfg5 = NCV_C5IMG(dvcfg);
563 hw->hw_clk = NCV_CLKFACTOR(dvcfg);
565 if ((ncv_io_control & NCV_ENABLE_FAST_SCSI) != 0 &&
566 (NCV_SPECIAL(dvcfg) & NCVHWCFG_MAX10M) != 0)
567 hw->hw_mperiod = 100 / 4;
569 if (NCV_SPECIAL(dvcfg) & NCVHWCFG_FIFOBUG)
570 hw->hw_cfg3_fclk = 0x04;
572 if (NCV_SPECIAL(dvcfg) & NCVHWCFG_SCSI1)
573 hw->hw_cfg2 &= ~C2_SCSI2;
575 if (NCV_SPECIAL(dvcfg) & NCVHWCFG_SLOW)
576 hw->hw_cfg1 |= C1_SLOW;
579 /* setup configuration image 3 */
580 if (hw->hw_clk != CLK_40M_F && hw->hw_clk <= CLK_25M_F)
581 hw->hw_cfg3 &= ~hw->hw_cfg3_fclk;
583 hw->hw_cfg3 |= hw->hw_cfg3_fclk;
585 /* setup configuration image 1 */
586 hw->hw_cfg1 = (hw->hw_cfg1 & 0xf0) | hostid;
591 ncvprobesubr(iot, ioh, dvcfg, hsid)
593 bus_space_handle_t ioh;
599 hwtab = ncv_template;
600 if (ncv_setup_img(&hwtab, dvcfg, hsid))
602 if (ncvhw_check(iot, ioh, &hwtab) != 0)
610 struct ncv_softc *sc;
612 struct scsi_low_softc *slp = &sc->sc_sclow;
615 sc->sc_hw = ncv_template;
616 ncv_setup_img(&sc->sc_hw, slp->sl_cfgflags, slp->sl_hostid);
617 slp->sl_funcs = &ncv_funcs;
618 slp->sl_flags |= HW_READ_PADDING;
619 sc->sc_tmaxcnt = SCSI_LOW_MIN_TOUT * 1000 * 1000; /* default */
621 (void) scsi_low_attach(slp, 0, NCV_NTARGETS, NCV_NLUNS,
622 sizeof(struct ncv_targ_info), 0);
625 /**************************************************************
627 **************************************************************/
629 ncv_setup_and_start_pio(sc, reqlen)
630 struct ncv_softc *sc;
633 bus_space_tag_t iot = sc->sc_iot;
634 bus_space_handle_t ioh = sc->sc_ioh;
636 ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
637 ncvhw_set_count(iot, ioh, reqlen);
638 bus_space_write_1(iot, ioh, cr0_cmd, CMD_TRANS | CMD_DMA);
640 ncvhw_select_register_1(iot, ioh, &sc->sc_hw);
641 bus_space_write_1(iot, ioh, cr1_fstat, FIFO_EN);
646 struct ncv_softc *sc;
647 struct targ_info *ti;
649 struct scsi_low_softc *slp = &sc->sc_sclow;
650 bus_space_tag_t iot = sc->sc_iot;
651 bus_space_handle_t ioh = sc->sc_ioh;
654 slp->sl_flags &= ~HW_PDMASTART;
655 if (slp->sl_Qnexus == NULL)
657 slp->sl_error |= PDMAERR;
661 if (ti->ti_phase == PH_DATA)
663 len = ncvhw_get_count(sc->sc_iot, sc->sc_ioh);
664 if (slp->sl_scp.scp_direction == SCSI_LOW_WRITE)
665 len += (bus_space_read_1(sc->sc_iot, sc->sc_ioh,
666 cr0_sffl) & CR0_SFFLR_BMASK);
668 if ((u_int) len <= (u_int) sc->sc_sdatalen)
670 if ((slp->sl_scp.scp_direction == SCSI_LOW_READ) &&
671 sc->sc_tdatalen != len)
674 len = sc->sc_sdatalen - len;
675 if ((u_int) len > (u_int) slp->sl_scp.scp_datalen)
678 slp->sl_scp.scp_data += len;
679 slp->sl_scp.scp_datalen -= len;
684 if ((slp->sl_error & PDMAERR) == 0)
686 device_printf(slp->sl_dev,
687 "strange cnt hw 0x%x soft 0x%x\n", len,
688 slp->sl_scp.scp_datalen);
690 slp->sl_error |= PDMAERR;
692 scsi_low_data_finish(slp);
696 device_printf(slp->sl_dev, "data phase miss\n");
697 slp->sl_error |= PDMAERR;
701 ncvhw_select_register_1(iot, ioh, &sc->sc_hw);
702 bus_space_write_1(iot, ioh, cr1_fstat, 0);
703 ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
707 ncv_pio_read(sc, buf, reqlen)
708 struct ncv_softc *sc;
712 struct scsi_low_softc *slp = &sc->sc_sclow;
713 bus_space_tag_t iot = sc->sc_iot;
714 bus_space_handle_t ioh = sc->sc_ioh;
716 register u_int8_t fstat;
718 ncv_setup_and_start_pio(sc, reqlen);
719 slp->sl_flags |= HW_PDMASTART;
720 sc->sc_sdatalen = reqlen;
721 tout = sc->sc_tmaxcnt;
723 while (reqlen >= FIFO_F_SZ && tout -- > 0)
725 fstat = bus_space_read_1(iot, ioh, cr1_fstat);
726 if (fstat == (u_int8_t) -1)
730 #define NCV_FAST32_ACCESS
731 #ifdef NCV_FAST32_ACCESS
732 bus_space_read_multi_4(iot, ioh, cr1_fdata,
733 (u_int32_t *) buf, FIFO_F_SZ / 4);
734 #else /* !NCV_FAST32_ACCESS */
735 bus_space_read_multi_2(iot, ioh, cr1_fdata,
736 (u_int16_t *) buf, FIFO_F_SZ / 2);
737 #endif /* !NCV_FAST32_ACCESS */
743 if (fstat & FIFO_BRK)
750 while (reqlen > 0 && tout -- > 0)
752 fstat = bus_space_read_1(iot, ioh, cr1_fstat);
753 if ((fstat & FIFO_E) == 0)
755 *buf++ = bus_space_read_1(iot, ioh, cr1_fdata);
760 if (fstat & FIFO_BRK)
768 ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
769 sc->sc_tdatalen = reqlen;
773 ncv_pio_write(sc, buf, reqlen)
774 struct ncv_softc *sc;
778 struct scsi_low_softc *slp = &sc->sc_sclow;
779 bus_space_tag_t iot = sc->sc_iot;
780 bus_space_handle_t ioh = sc->sc_ioh;
782 register u_int8_t fstat;
784 ncv_setup_and_start_pio(sc, reqlen);
785 sc->sc_sdatalen = reqlen;
786 tout = sc->sc_tmaxcnt;
787 slp->sl_flags |= HW_PDMASTART;
789 while (reqlen >= FIFO_F_SZ && tout -- > 0)
791 fstat = bus_space_read_1(iot, ioh, cr1_fstat);
792 if (fstat & FIFO_BRK)
795 if ((fstat & FIFO_E) != 0)
797 #ifdef NCV_FAST32_ACCESS
798 bus_space_write_multi_4(iot, ioh, cr1_fdata,
799 (u_int32_t *) buf, FIFO_F_SZ / 4);
800 #else /* !NCV_FAST32_ACCESS */
801 bus_space_write_multi_2(iot, ioh, cr1_fdata,
802 (u_int16_t *) buf, FIFO_F_SZ / 2);
803 #endif /* !NCV_FAST32_ACCESS */
813 while (reqlen > 0 && tout -- > 0)
815 fstat = bus_space_read_1(iot, ioh, cr1_fstat);
816 if (fstat & FIFO_BRK)
819 if ((fstat & FIFO_F) == 0) /* fifo not full */
821 bus_space_write_1(iot, ioh, cr1_fdata, *buf++);
831 ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
834 /**************************************************************
835 * disconnect & reselect (HW low)
836 **************************************************************/
839 struct ncv_softc *sc;
841 struct scsi_low_softc *slp = &sc->sc_sclow;
842 bus_space_tag_t iot = sc->sc_iot;
843 bus_space_handle_t ioh = sc->sc_ioh;
844 struct targ_info *ti;
847 if ((bus_space_read_1(iot, ioh, cr0_sffl) & CR0_SFFLR_BMASK) != 2)
849 device_printf(slp->sl_dev, "illegal fifo bytes\n");
850 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, "chip confused");
854 sid = (u_int) bus_space_read_1(iot, ioh, cr0_sfifo);
855 sid &= ~(1 << slp->sl_hostid);
857 ti = scsi_low_reselected((struct scsi_low_softc *) sc, sid);
862 ncv_statics.reselect ++;
863 #endif /* NCV_STATICS */
864 bus_space_write_1(iot, ioh, cr0_dstid, sid);
869 ncv_disconnected(sc, ti)
870 struct ncv_softc *sc;
871 struct targ_info *ti;
873 struct scsi_low_softc *slp = &sc->sc_sclow;
874 bus_space_tag_t iot = sc->sc_iot;
875 bus_space_handle_t ioh = sc->sc_ioh;
877 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH);
878 bus_space_write_1(iot, ioh, cr0_cmd, CMD_ENSEL);
881 ncv_statics.disconnect ++;
882 #endif /* NCV_STATICS */
884 scsi_low_disconnected(slp, ti);
888 /**************************************************************
890 **************************************************************/
892 ncv_target_nexus_establish(sc)
893 struct ncv_softc *sc;
895 struct scsi_low_softc *slp = &sc->sc_sclow;
896 struct targ_info *ti = slp->sl_Tnexus;
897 struct ncv_targ_info *nti = (void *) ti;
898 bus_space_tag_t iot = sc->sc_iot;
899 bus_space_handle_t ioh = sc->sc_ioh;
901 bus_space_write_1(iot, ioh, cr0_period, nti->nti_reg_period);
902 bus_space_write_1(iot, ioh, cr0_offs, nti->nti_reg_offset);
903 bus_space_write_1(iot, ioh, cr0_cfg3, nti->nti_reg_cfg3);
908 ncv_lun_nexus_establish(sc)
909 struct ncv_softc *sc;
916 ncv_ccb_nexus_establish(sc)
917 struct ncv_softc *sc;
919 struct scsi_low_softc *slp = &sc->sc_sclow;
920 struct slccb *cb = slp->sl_Qnexus;
922 sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000;
928 struct ncv_softc *sc;
930 bus_space_tag_t iot = sc->sc_iot;
931 bus_space_handle_t ioh = sc->sc_ioh;
933 register u_int8_t status;
935 for (wc = 0; wc < NCV_DELAY_MAX / NCV_DELAY_INTERVAL; wc ++)
937 status = bus_space_read_1(iot, ioh, cr0_stat);
938 if ((status & STAT_INT) != 0)
941 DELAY(NCV_DELAY_INTERVAL);
950 struct ncv_softc *sc = arg;
951 struct scsi_low_softc *slp = &sc->sc_sclow;
952 bus_space_tag_t iot = sc->sc_iot;
953 bus_space_handle_t ioh = sc->sc_ioh;
954 struct targ_info *ti;
958 u_int8_t regv, status, ireason;
961 if (slp->sl_flags & HW_INACTIVE)
964 /********************************************
966 ********************************************/
967 ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
968 status = bus_space_read_1(iot, ioh, cr0_stat);
969 if ((status & STAT_INT) == 0 || status == (u_int8_t) -1)
972 ireason = bus_space_read_1(iot, ioh, cr0_istat);
973 if ((ireason & INTR_SBR) != 0)
977 /* avoid power off hangup */
978 val = bus_space_read_1(iot, ioh, cr0_cfg1);
979 bus_space_write_1(iot, ioh, cr0_cfg1, val | C1_SRR);
982 scsi_low_restart(slp, SCSI_LOW_RESTART_SOFT,
983 "bus reset (power off?)");
987 /********************************************
989 ********************************************/
993 scsi_low_print(slp, NULL);
994 device_printf(slp->sl_dev, "st %x ist %x\n\n",
998 kdb_enter(KDB_WHY_CAM, "ncv");
1001 #endif /* NCV_DEBUG */
1003 /********************************************
1004 * Reselect or Disconnect or Nexus check
1005 ********************************************/
1007 if (ireason == INTR_RESELECT)
1009 if (ncv_reselected(sc) == EJUSTRETURN)
1014 if ((ti = slp->sl_Tnexus) == NULL)
1018 if ((status & (STAT_PE | STAT_GE)) != 0)
1020 slp->sl_error |= PARITYERR;
1021 if ((status & PHASE_MASK) == MESSAGE_IN_PHASE)
1022 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
1024 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ERROR, 1);
1025 derror = SCSI_LOW_DATA_PE;
1028 if ((ireason & (INTR_DIS | INTR_ILL)) != 0)
1030 if ((ireason & INTR_ILL) == 0)
1031 return ncv_disconnected(sc, ti);
1033 slp->sl_error |= FATALIO;
1034 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, "illegal cmd");
1038 /********************************************
1039 * Internal scsi phase
1040 ********************************************/
1041 switch (ti->ti_phase)
1044 scsi_low_arbit_win(slp);
1045 SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED);
1047 if (sc->sc_selstop == 0)
1050 * Here scsi phases expected are
1052 * MSGIN : target wants to disconnect the host.
1053 * STATUSIN : immediate command completed.
1054 * CMD PHASE : command out failed
1055 * MSGOUT : identify command failed.
1057 if ((status & PHASE_MASK) != MESSAGE_OUT_PHASE)
1062 if ((status & PHASE_MASK) != MESSAGE_OUT_PHASE)
1064 if ((ireason & INTR_FC) != 0)
1066 SCSI_LOW_ASSERT_ATN(slp);
1069 SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT);
1073 ncv_target_nexus_establish(sc);
1074 if ((status & PHASE_MASK) != MESSAGE_IN_PHASE)
1076 device_printf(slp->sl_dev,
1077 "unexpected phase after reselect\n");
1078 slp->sl_error |= FATALIO;
1079 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 1);
1085 if ((slp->sl_flags & HW_PDMASTART) != 0)
1087 ncv_pdma_end(sc, ti);
1092 /********************************************
1093 * Scsi phase sequencer
1094 ********************************************/
1095 switch (status & PHASE_MASK)
1097 case DATA_OUT_PHASE: /* data out */
1098 SCSI_LOW_SETUP_PHASE(ti, PH_DATA);
1099 if (scsi_low_data(slp, ti, &bp, SCSI_LOW_WRITE) != 0)
1101 scsi_low_attention(slp);
1104 if (slp->sl_scp.scp_datalen <= 0)
1106 if ((ireason & INTR_BS) == 0)
1109 if ((slp->sl_error & PDMAERR) == 0)
1110 device_printf(slp->sl_dev, "data underrun\n");
1111 slp->sl_error |= PDMAERR;
1113 if ((slp->sl_flags & HW_WRITE_PADDING) != 0)
1115 u_int8_t padding[NCV_PADDING_SIZE];
1117 bzero(padding, sizeof(padding));
1118 ncv_pio_write(sc, padding, sizeof(padding));
1122 device_printf(slp->sl_dev,
1123 "write padding required\n");
1128 len = slp->sl_scp.scp_datalen;
1129 if ((ncv_io_control & NCV_WRITE_INTERRUPTS_DRIVEN) != 0)
1131 if (len > ncv_data_write_bytes)
1132 len = ncv_data_write_bytes;
1134 ncv_pio_write(sc, slp->sl_scp.scp_data, len);
1138 case DATA_IN_PHASE: /* data in */
1139 SCSI_LOW_SETUP_PHASE(ti, PH_DATA);
1140 if (scsi_low_data(slp, ti, &bp, SCSI_LOW_READ) != 0)
1142 scsi_low_attention(slp);
1145 if (slp->sl_scp.scp_datalen <= 0)
1147 if ((ireason & INTR_BS) == 0)
1150 if ((slp->sl_error & PDMAERR) == 0)
1151 device_printf(slp->sl_dev, "data overrun\n");
1152 slp->sl_error |= PDMAERR;
1154 if ((slp->sl_flags & HW_READ_PADDING) != 0)
1156 u_int8_t padding[NCV_PADDING_SIZE];
1158 ncv_pio_read(sc, padding, sizeof(padding));
1162 device_printf(slp->sl_dev,
1163 "read padding required\n");
1169 len = slp->sl_scp.scp_datalen;
1170 if ((ncv_io_control & NCV_READ_INTERRUPTS_DRIVEN) != 0)
1172 if (len > ncv_data_read_bytes)
1173 len = ncv_data_read_bytes;
1175 ncv_pio_read(sc, slp->sl_scp.scp_data, len);
1179 case COMMAND_PHASE: /* cmd out */
1180 SCSI_LOW_SETUP_PHASE(ti, PH_CMD);
1181 if (scsi_low_cmd(slp, ti) != 0)
1183 scsi_low_attention(slp);
1186 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH);
1187 ncvhw_fpush(iot, ioh,
1188 slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen);
1189 bus_space_write_1(iot, ioh, cr0_cmd, CMD_TRANS);
1192 case STATUS_PHASE: /* status in */
1193 SCSI_LOW_SETUP_PHASE(ti, PH_STAT);
1194 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH);
1195 bus_space_write_1(iot, ioh, cr0_cmd, CMD_ICCS);
1202 case MESSAGE_OUT_PHASE: /* msg out */
1203 SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT);
1204 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH);
1206 flags = SCSI_LOW_MSGOUT_UNIFY;
1207 if (ti->ti_ophase != ti->ti_phase)
1208 flags |= SCSI_LOW_MSGOUT_INIT;
1209 len = scsi_low_msgout(slp, ti, flags);
1211 if (len > 1 && slp->sl_atten == 0)
1213 scsi_low_attention(slp);
1216 ncvhw_fpush(iot, ioh, ti->ti_msgoutstr, len);
1217 bus_space_write_1(iot, ioh, cr0_cmd, CMD_TRANS);
1218 SCSI_LOW_DEASSERT_ATN(slp);
1221 case MESSAGE_IN_PHASE: /* msg in */
1222 SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
1224 len = bus_space_read_1(iot, ioh, cr0_sffl) & CR0_SFFLR_BMASK;
1225 if (sc->sc_compseq != 0)
1228 if ((ireason & INTR_FC) && len == 2)
1230 regv = bus_space_read_1(iot, ioh, cr0_sfifo);
1231 scsi_low_statusin(slp, ti, regv | derror);
1236 slp->sl_error |= FATALIO;
1237 scsi_low_assert_msg(slp, ti,
1238 SCSI_LOW_MSG_ABORT, 1);
1239 bus_space_write_1(sc->sc_iot, sc->sc_ioh,
1240 cr0_cmd, CMD_MSGOK);
1244 else if (ireason & INTR_BS)
1246 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH);
1247 bus_space_write_1(iot, ioh, cr0_cmd, CMD_TRANS);
1248 if ((ncv_io_control & NCV_FAST_INTERRUPTS) != 0)
1250 if (ncv_catch_intr(sc) == 0)
1256 if ((ireason & INTR_FC) && len == 1)
1258 regv = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
1260 if (scsi_low_msgin(slp, ti, regv | derror) == 0)
1262 if (scsi_low_is_msgout_continue(ti, 0) != 0)
1264 scsi_low_attention(slp);
1267 bus_space_write_1(sc->sc_iot, sc->sc_ioh, cr0_cmd,
1269 if ((ncv_io_control & NCV_FAST_INTERRUPTS) != 0)
1272 * clear a pending interrupt and sync with
1280 slp->sl_error |= FATALIO;
1281 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 1);
1282 bus_space_write_1(sc->sc_iot, sc->sc_ioh, cr0_cmd,