1/* $NecBSD: ncr53c500.c,v 1.30.12.3 2001/06/26 07:31:41 honda Exp $ */ 2/* $NetBSD$ */ 3 4#define NCV_DEBUG 5#define NCV_STATICS 6#define NCV_IO_CONTROL_FLAGS (0) 7 8/*- 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. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 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. 25 * 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. 37 */ 38 39#include <sys/cdefs.h> 40__FBSDID("$FreeBSD$"); 41 42#include <sys/param.h> 43#include <sys/systm.h> 44#include <sys/kernel.h> 45#include <sys/bio.h> 46#include <sys/buf.h> 47#include <sys/queue.h> 48#include <sys/malloc.h> 49#include <sys/errno.h> 50 51#include <machine/cpu.h> 52#include <machine/bus.h> 53 54#include <compat/netbsd/dvcfg.h> 55 56#include <cam/scsi/scsi_low.h> 57 58#include <dev/ncv/ncr53c500reg.h> 59#include <dev/ncv/ncr53c500hw.h> 60#include <dev/ncv/ncr53c500var.h> 61 62#include <dev/ncv/ncr53c500hwtab.h> 63 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) 68 69/*************************************************** 70 * IO control 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 76 77u_int ncv_io_control = NCV_IO_CONTROL_FLAGS; 78int ncv_data_read_bytes = 4096; 79int ncv_data_write_bytes = 4096; 80 81/*************************************************** 82 * DEBUG 83 ***************************************************/ 84#ifdef NCV_DEBUG 85static int ncv_debug; 86#endif /* NCV_DEBUG */ 87 88#ifdef NCV_STATICS 89static struct ncv_statics { 90 int disconnect; 91 int reselect; 92} ncv_statics; 93#endif /* NCV_STATICS */ 94 95/*************************************************** 96 * DEVICE STRUCTURE 97 ***************************************************/ 98extern struct cfdriver ncv_cd; 99 100/************************************************************** 101 * DECLARE 102 **************************************************************/ 103/* static */ 104static void ncv_pio_read(struct ncv_softc *, u_int8_t *, u_int); 105static void ncv_pio_write(struct ncv_softc *, u_int8_t *, u_int); 106static int ncv_msg(struct ncv_softc *, struct targ_info *, u_int); 107static int ncv_reselected(struct ncv_softc *); 108static int ncv_disconnected(struct ncv_softc *, struct targ_info *); 109 110static __inline void ncvhw_set_count(bus_space_tag_t, bus_space_handle_t, int); 111static __inline u_int ncvhw_get_count(bus_space_tag_t, bus_space_handle_t); 112static __inline void ncvhw_select_register_0(bus_space_tag_t, bus_space_handle_t, struct ncv_hw *); 113static __inline void ncvhw_select_register_1(bus_space_tag_t, bus_space_handle_t, struct ncv_hw *); 114static __inline void ncvhw_fpush(bus_space_tag_t, bus_space_handle_t, u_int8_t *, int); 115 116static void ncv_pdma_end(struct ncv_softc *sc, struct targ_info *); 117static int ncv_world_start(struct ncv_softc *, int); 118static void ncvhw_bus_reset(struct ncv_softc *); 119static void ncvhw_reset(bus_space_tag_t, bus_space_handle_t, struct ncv_hw *); 120static int ncvhw_check(bus_space_tag_t, bus_space_handle_t, struct ncv_hw *); 121static void ncvhw_init(bus_space_tag_t, bus_space_handle_t, struct ncv_hw *); 122static int ncvhw_start_selection(struct ncv_softc *sc, struct slccb *); 123static void ncvhw_attention(struct ncv_softc *); 124static int ncv_ccb_nexus_establish(struct ncv_softc *); 125static int ncv_lun_nexus_establish(struct ncv_softc *); 126static int ncv_target_nexus_establish(struct ncv_softc *); 127static int ncv_targ_init(struct ncv_softc *, struct targ_info *, int); 128static int ncv_catch_intr(struct ncv_softc *); 129#ifdef NCV_POWER_CONTROL 130static int ncvhw_power(struct ncv_softc *, u_int); 131#endif /* NCV_POWER_CONTROL */ 132static __inline void ncv_setup_and_start_pio(struct ncv_softc *, u_int); 133 134struct 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, 139 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, 143 144 SC_LOW_ATTEN_T ncvhw_attention, 145 SC_LOW_MSG_T ncv_msg, 146 147 SC_LOW_TIMEOUT_T NULL, 148 SC_LOW_POLL_T ncvintr, 149 150 NULL, /* SC_LOW_POWER_T ncvhw_power, */ 151}; 152 153/************************************************************** 154 * hwfuncs 155 **************************************************************/ 156static __inline void 157ncvhw_select_register_0(iot, ioh, hw) 158 bus_space_tag_t iot; 159 bus_space_handle_t ioh; 160 struct ncv_hw *hw; 161{ 162 163 bus_space_write_1(iot, ioh, cr0_cfg4, hw->hw_cfg4); 164} 165 166static __inline void 167ncvhw_select_register_1(iot, ioh, hw) 168 bus_space_tag_t iot; 169 bus_space_handle_t ioh; 170 struct ncv_hw *hw; 171{ 172 173 bus_space_write_1(iot, ioh, cr1_cfg5, hw->hw_cfg5); 174} 175 176static __inline void 177ncvhw_fpush(iot, ioh, buf, len) 178 bus_space_tag_t iot; 179 bus_space_handle_t ioh; 180 u_int8_t *buf; 181 int len; 182{ 183 int ptr; 184 185 for (ptr = 0; ptr < len; ptr ++) 186 bus_space_write_1(iot, ioh, cr0_sfifo, buf[ptr]); 187} 188 189static __inline void 190ncvhw_set_count(iot, ioh, count) 191 bus_space_tag_t iot; 192 bus_space_handle_t ioh; 193 int count; 194{ 195 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))); 199} 200 201static __inline u_int 202ncvhw_get_count(iot, ioh) 203 bus_space_tag_t iot; 204 bus_space_handle_t ioh; 205{ 206 u_int count; 207 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); 211 return count; 212} 213 214static int 215ncvhw_check(iot, ioh, hw) 216 bus_space_tag_t iot; 217 bus_space_handle_t ioh; 218 struct ncv_hw *hw; 219{ 220 u_int8_t stat; 221 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)) 225 { 226#ifdef NCV_DEBUG 227 printf("ncv: cr0_cmd CMD_NOP|CMD_DMA failed\n"); 228#endif /* NCV_DEBUG */ 229 return ENODEV; 230 } 231 232 bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP); 233 if (bus_space_read_1(iot, ioh, cr0_cmd) != CMD_NOP) 234 { 235#ifdef NCV_DEBUG 236 printf("ncv: cr0_cmd CMD_NOP failed\n"); 237#endif /* NCV_DEBUG */ 238 return ENODEV; 239 } 240 241 /* hardware reset */ 242 ncvhw_reset(iot, ioh, hw); 243 ncvhw_init(iot, ioh, hw); 244 245 /* bus reset */ 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); 250 DELAY(100 * 1000); 251 252 /* check response */ 253 bus_space_read_1(iot, ioh, cr0_stat); 254 stat = bus_space_read_1(iot, ioh, cr0_istat); 255 DELAY(1000); 256 257 if (((stat & INTR_SBR) == 0) || 258 (bus_space_read_1(iot, ioh, cr0_istat) & INTR_SBR)) 259 { 260#ifdef NCV_DEBUG 261 printf("ncv: cr0_istat SCSI BUS RESET failed\n"); 262#endif /* NCV_DEBUG */ 263 return ENODEV; 264 } 265 266 return 0; 267} 268 269static void 270ncvhw_reset(iot, ioh, hw) 271 bus_space_tag_t iot; 272 bus_space_handle_t ioh; 273 struct ncv_hw *hw; 274{ 275 276 ncvhw_select_register_0(iot, ioh, hw); 277 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); 281 282 /* chip reset */ 283 bus_space_write_1(iot, ioh, cr0_cmd, CMD_RSTCHIP); 284 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); 288} 289 290static void 291ncvhw_init(iot, ioh, hw) 292 bus_space_tag_t iot; 293 bus_space_handle_t ioh; 294 struct ncv_hw *hw; 295{ 296 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); 302 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); 307 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); 312 313 ncvhw_select_register_0(iot, ioh, hw); 314} 315 316#ifdef NCV_POWER_CONTROL 317static int 318ncvhw_power(sc, flags) 319 struct ncv_softc *sc; 320 u_int flags; 321{ 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; 325 326 if (flags == SCSI_LOW_POWDOWN) 327 { 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); 331 } 332 else 333 { 334 switch (sc->sc_rstep) 335 { 336 case 0: 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); 340 break; 341 342 case 1: 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); 346 break; 347 } 348 } 349 350 return 0; 351} 352#endif /* NCV_POWER_CONTROL */ 353 354/************************************************************** 355 * scsi low interface 356 **************************************************************/ 357static void 358ncvhw_attention(sc) 359 struct ncv_softc *sc; 360{ 361 362 bus_space_write_1(sc->sc_iot, sc->sc_ioh, cr0_cmd, CMD_SETATN); 363 DELAY(10); 364} 365 366static void 367ncvhw_bus_reset(sc) 368 struct ncv_softc *sc; 369{ 370 bus_space_tag_t iot = sc->sc_iot; 371 bus_space_handle_t ioh = sc->sc_ioh; 372 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); 377} 378 379static int 380ncvhw_start_selection(sc, cb) 381 struct ncv_softc *sc; 382 struct slccb *cb; 383{ 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; 388 int s, len; 389 u_int flags; 390 u_int8_t cmd; 391 392 sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000; 393 sc->sc_compseq = 0; 394 if (scsi_low_is_msgout_continue(ti, SCSI_LOW_MSG_IDENTIFY) == 0) 395 { 396 cmd = CMD_SELATN; 397 sc->sc_selstop = 0; 398 flags = SCSI_LOW_MSGOUT_UNIFY | SCSI_LOW_MSGOUT_INIT; 399 } 400 else if (scsi_low_is_msgout_continue(ti, 401 SCSI_LOW_MSG_IDENTIFY | SCSI_LOW_MSG_SIMPLE_QTAG) == 0) 402 { 403 cmd = CMD_SELATN3; 404 sc->sc_selstop = 0; 405 flags = SCSI_LOW_MSGOUT_UNIFY | SCSI_LOW_MSGOUT_INIT; 406 } 407 else 408 { 409 cmd = CMD_SELATNS; 410 sc->sc_selstop = 1; 411 flags = SCSI_LOW_MSGOUT_INIT; 412 } 413 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; 417 418 ncv_target_nexus_establish(sc); 419 420 len = scsi_low_msgout(slp, ti, flags); 421 if (sc->sc_selstop == 0) 422 scsi_low_cmd(slp, ti); 423 424 s = splhigh(); 425 if ((bus_space_read_1(iot, ioh, cr0_stat) & STAT_INT) != 0) 426 { 427 splx(s); 428 return SCSI_LOW_START_FAIL; 429 } 430 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) 435 { 436 ncvhw_fpush(iot, ioh, 437 slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen); 438 } 439 bus_space_write_1(iot, ioh, cr0_cmd, cmd); 440 splx(s); 441 442 SCSI_LOW_SETUP_PHASE(ti, PH_SELSTART); 443 return SCSI_LOW_START_OK; 444} 445 446static int 447ncv_world_start(sc, fdone) 448 struct ncv_softc *sc; 449 int fdone; 450{ 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; 454 u_int8_t stat; 455 456 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0) 457 sc->sc_hw.hw_cfg1 |= C1_PARENB; 458 else 459 sc->sc_hw.hw_cfg1 &= ~C1_PARENB; 460 461 ncvhw_reset(iot, ioh, &sc->sc_hw); 462 ncvhw_init(iot, ioh, &sc->sc_hw); 463 464 scsi_low_bus_reset(slp); 465 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); 469 DELAY(1000); 470 471 if (((stat & INTR_SBR) == 0) || 472 (bus_space_read_1(sc->sc_iot, sc->sc_ioh, cr0_istat) & INTR_SBR)) 473 return ENODEV; 474 475 return 0; 476} 477 478static int 479ncv_msg(sc, ti, msg) 480 struct ncv_softc *sc; 481 struct targ_info *ti; 482 u_int msg; 483{ 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; 488 489 if ((msg & SCSI_LOW_MSG_WIDE) != 0) 490 { 491 if (ti->ti_width != SCSI_LOW_BUS_WIDTH_8) 492 { 493 ti->ti_width = SCSI_LOW_BUS_WIDTH_8; 494 return EINVAL; 495 } 496 return 0; 497 } 498 499 if ((msg & SCSI_LOW_MSG_SYNCH) == 0) 500 return 0; 501 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; 505 506 if (period < 200 / 4 && period >= 100 / 4) 507 nti->nti_reg_cfg3 |= sc->sc_hw.hw_cfg3_fscsi; 508 else 509 nti->nti_reg_cfg3 &= ~sc->sc_hw.hw_cfg3_fscsi; 510 511 period = ((period * 40 / hwcycle) + 5) / 10; 512 nti->nti_reg_period = period & 0x1f; 513 nti->nti_reg_offset = ti->ti_maxsynch.offset; 514 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); 518 return 0; 519} 520 521static int 522ncv_targ_init(sc, ti, action) 523 struct ncv_softc *sc; 524 struct targ_info *ti; 525 int action; 526{ 527 struct ncv_targ_info *nti = (void *) ti; 528 529 if (action == SCSI_LOW_INFO_ALLOC || action == SCSI_LOW_INFO_REVOKE) 530 { 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; 534 535 nti->nti_reg_cfg3 = sc->sc_hw.hw_cfg3; 536 nti->nti_reg_period = 0; 537 nti->nti_reg_offset = 0; 538 } 539 return 0; 540} 541 542/************************************************************** 543 * General probe attach 544 **************************************************************/ 545static int ncv_setup_img(struct ncv_hw *, u_int, int); 546 547static int 548ncv_setup_img(hw, dvcfg, hostid) 549 struct ncv_hw *hw; 550 u_int dvcfg; 551 int hostid; 552{ 553 554 if (NCV_CLKFACTOR(dvcfg) > CLK_35M_F) 555 { 556 printf("ncv: invalid dvcfg flags\n"); 557 return EINVAL; 558 } 559 560 if (NCV_C5IMG(dvcfg) != 0) 561 { 562 hw->hw_cfg5 = NCV_C5IMG(dvcfg); 563 hw->hw_clk = NCV_CLKFACTOR(dvcfg); 564 565 if ((ncv_io_control & NCV_ENABLE_FAST_SCSI) != 0 && 566 (NCV_SPECIAL(dvcfg) & NCVHWCFG_MAX10M) != 0) 567 hw->hw_mperiod = 100 / 4; 568 569 if (NCV_SPECIAL(dvcfg) & NCVHWCFG_FIFOBUG) 570 hw->hw_cfg3_fclk = 0x04; 571 572 if (NCV_SPECIAL(dvcfg) & NCVHWCFG_SCSI1) 573 hw->hw_cfg2 &= ~C2_SCSI2; 574 575 if (NCV_SPECIAL(dvcfg) & NCVHWCFG_SLOW) 576 hw->hw_cfg1 |= C1_SLOW; 577 } 578 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; 582 else 583 hw->hw_cfg3 |= hw->hw_cfg3_fclk; 584 585 /* setup configuration image 1 */ 586 hw->hw_cfg1 = (hw->hw_cfg1 & 0xf0) | hostid; 587 return 0; 588} 589 590int 591ncvprobesubr(iot, ioh, dvcfg, hsid) 592 bus_space_tag_t iot; 593 bus_space_handle_t ioh; 594 u_int dvcfg; 595 int hsid; 596{ 597 struct ncv_hw hwtab; 598 599 hwtab = ncv_template; 600 if (ncv_setup_img(&hwtab, dvcfg, hsid)) 601 return 0; 602 if (ncvhw_check(iot, ioh, &hwtab) != 0) 603 return 0; 604 605 return 1; 606} 607 608void 609ncvattachsubr(sc) 610 struct ncv_softc *sc; 611{ 612 struct scsi_low_softc *slp = &sc->sc_sclow; 613 614 printf("\n"); 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 */ 620 621 (void) scsi_low_attach(slp, 0, NCV_NTARGETS, NCV_NLUNS, 622 sizeof(struct ncv_targ_info), 0); 623} 624 625/************************************************************** 626 * PDMA 627 **************************************************************/ 628static __inline void 629ncv_setup_and_start_pio(sc, reqlen) 630 struct ncv_softc *sc; 631 u_int reqlen; 632{ 633 bus_space_tag_t iot = sc->sc_iot; 634 bus_space_handle_t ioh = sc->sc_ioh; 635 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); 639 640 ncvhw_select_register_1(iot, ioh, &sc->sc_hw); 641 bus_space_write_1(iot, ioh, cr1_fstat, FIFO_EN); 642} 643 644static void 645ncv_pdma_end(sc, ti) 646 struct ncv_softc *sc; 647 struct targ_info *ti; 648{ 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; 652 int len; 653 654 slp->sl_flags &= ~HW_PDMASTART; 655 if (slp->sl_Qnexus == NULL) 656 { 657 slp->sl_error |= PDMAERR; 658 goto out; 659 } 660 661 if (ti->ti_phase == PH_DATA) 662 { 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); 667 668 if ((u_int) len <= (u_int) sc->sc_sdatalen) 669 { 670 if ((slp->sl_scp.scp_direction == SCSI_LOW_READ) && 671 sc->sc_tdatalen != len) 672 goto bad; 673 674 len = sc->sc_sdatalen - len; 675 if ((u_int) len > (u_int) slp->sl_scp.scp_datalen) 676 goto bad; 677 678 slp->sl_scp.scp_data += len; 679 slp->sl_scp.scp_datalen -= len; 680 } 681 else 682 { 683bad: 684 if ((slp->sl_error & PDMAERR) == 0) 685 { 686 device_printf(slp->sl_dev, 687 "strange cnt hw 0x%x soft 0x%x\n", len, 688 slp->sl_scp.scp_datalen); 689 } 690 slp->sl_error |= PDMAERR; 691 } 692 scsi_low_data_finish(slp); 693 } 694 else 695 { 696 device_printf(slp->sl_dev, "data phase miss\n"); 697 slp->sl_error |= PDMAERR; 698 } 699 700out: 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); 704} 705 706static void 707ncv_pio_read(sc, buf, reqlen) 708 struct ncv_softc *sc; 709 u_int8_t *buf; 710 u_int reqlen; 711{ 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; 715 int tout; 716 register u_int8_t fstat; 717 718 ncv_setup_and_start_pio(sc, reqlen); 719 slp->sl_flags |= HW_PDMASTART; 720 sc->sc_sdatalen = reqlen; 721 tout = sc->sc_tmaxcnt; 722 723 while (reqlen >= FIFO_F_SZ && tout -- > 0) 724 { 725 fstat = bus_space_read_1(iot, ioh, cr1_fstat); 726 if (fstat == (u_int8_t) -1) 727 goto out; 728 if (fstat & FIFO_F) 729 { 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 */ 738 buf += FIFO_F_SZ; 739 reqlen -= FIFO_F_SZ; 740 } 741 else 742 { 743 if (fstat & FIFO_BRK) 744 break; 745 746 DELAY(1); 747 } 748 } 749 750 while (reqlen > 0 && tout -- > 0) 751 { 752 fstat = bus_space_read_1(iot, ioh, cr1_fstat); 753 if ((fstat & FIFO_E) == 0) 754 { 755 *buf++ = bus_space_read_1(iot, ioh, cr1_fdata); 756 reqlen --; 757 } 758 else 759 { 760 if (fstat & FIFO_BRK) 761 break; 762 763 DELAY(1); 764 } 765 } 766 767out: 768 ncvhw_select_register_0(iot, ioh, &sc->sc_hw); 769 sc->sc_tdatalen = reqlen; 770} 771 772static void 773ncv_pio_write(sc, buf, reqlen) 774 struct ncv_softc *sc; 775 u_int8_t *buf; 776 u_int reqlen; 777{ 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; 781 int tout; 782 register u_int8_t fstat; 783 784 ncv_setup_and_start_pio(sc, reqlen); 785 sc->sc_sdatalen = reqlen; 786 tout = sc->sc_tmaxcnt; 787 slp->sl_flags |= HW_PDMASTART; 788 789 while (reqlen >= FIFO_F_SZ && tout -- > 0) 790 { 791 fstat = bus_space_read_1(iot, ioh, cr1_fstat); 792 if (fstat & FIFO_BRK) 793 goto done; 794 795 if ((fstat & FIFO_E) != 0) 796 { 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 */ 804 buf += FIFO_F_SZ; 805 reqlen -= FIFO_F_SZ; 806 } 807 else 808 { 809 DELAY(1); 810 } 811 } 812 813 while (reqlen > 0 && tout -- > 0) 814 { 815 fstat = bus_space_read_1(iot, ioh, cr1_fstat); 816 if (fstat & FIFO_BRK) 817 break; 818 819 if ((fstat & FIFO_F) == 0) /* fifo not full */ 820 { 821 bus_space_write_1(iot, ioh, cr1_fdata, *buf++); 822 reqlen --; 823 } 824 else 825 { 826 DELAY(1); 827 } 828 } 829 830done: 831 ncvhw_select_register_0(iot, ioh, &sc->sc_hw); 832} 833 834/************************************************************** 835 * disconnect & reselect (HW low) 836 **************************************************************/ 837static int 838ncv_reselected(sc) 839 struct ncv_softc *sc; 840{ 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; 845 u_int sid; 846 847 if ((bus_space_read_1(iot, ioh, cr0_sffl) & CR0_SFFLR_BMASK) != 2) 848 { 849 device_printf(slp->sl_dev, "illegal fifo bytes\n"); 850 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, "chip confused"); 851 return EJUSTRETURN; 852 } 853 854 sid = (u_int) bus_space_read_1(iot, ioh, cr0_sfifo); 855 sid &= ~(1 << slp->sl_hostid); 856 sid = ffs(sid) - 1; 857 ti = scsi_low_reselected((struct scsi_low_softc *) sc, sid); 858 if (ti == NULL) 859 return EJUSTRETURN; 860 861#ifdef NCV_STATICS 862 ncv_statics.reselect ++; 863#endif /* NCV_STATICS */ 864 bus_space_write_1(iot, ioh, cr0_dstid, sid); 865 return 0; 866} 867 868static int 869ncv_disconnected(sc, ti) 870 struct ncv_softc *sc; 871 struct targ_info *ti; 872{ 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; 876 877 bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); 878 bus_space_write_1(iot, ioh, cr0_cmd, CMD_ENSEL); 879 880#ifdef NCV_STATICS 881 ncv_statics.disconnect ++; 882#endif /* NCV_STATICS */ 883 884 scsi_low_disconnected(slp, ti); 885 return 1; 886} 887 888/************************************************************** 889 * SEQUENCER 890 **************************************************************/ 891static int 892ncv_target_nexus_establish(sc) 893 struct ncv_softc *sc; 894{ 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; 900 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); 904 return 0; 905} 906 907static int 908ncv_lun_nexus_establish(sc) 909 struct ncv_softc *sc; 910{ 911 912 return 0; 913} 914 915static int 916ncv_ccb_nexus_establish(sc) 917 struct ncv_softc *sc; 918{ 919 struct scsi_low_softc *slp = &sc->sc_sclow; 920 struct slccb *cb = slp->sl_Qnexus; 921 922 sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000; 923 return 0; 924} 925 926static int 927ncv_catch_intr(sc) 928 struct ncv_softc *sc; 929{ 930 bus_space_tag_t iot = sc->sc_iot; 931 bus_space_handle_t ioh = sc->sc_ioh; 932 int wc; 933 register u_int8_t status; 934 935 for (wc = 0; wc < NCV_DELAY_MAX / NCV_DELAY_INTERVAL; wc ++) 936 { 937 status = bus_space_read_1(iot, ioh, cr0_stat); 938 if ((status & STAT_INT) != 0) 939 return 0; 940 941 DELAY(NCV_DELAY_INTERVAL); 942 } 943 return EJUSTRETURN; 944} 945 946int 947ncvintr(arg) 948 void *arg; 949{ 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; 955 struct buf *bp; 956 u_int derror, flags; 957 int len; 958 u_int8_t regv, status, ireason; 959 960again: 961 if (slp->sl_flags & HW_INACTIVE) 962 return 0; 963 964 /******************************************** 965 * Status 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) 970 return 0; 971 972 ireason = bus_space_read_1(iot, ioh, cr0_istat); 973 if ((ireason & INTR_SBR) != 0) 974 { 975 u_int8_t val; 976 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); 980 981 /* status init */ 982 scsi_low_restart(slp, SCSI_LOW_RESTART_SOFT, 983 "bus reset (power off?)"); 984 return 1; 985 } 986 987 /******************************************** 988 * Debug section 989 ********************************************/ 990#ifdef NCV_DEBUG 991 if (ncv_debug) 992 { 993 scsi_low_print(slp, NULL); 994 device_printf(slp->sl_dev, "st %x ist %x\n\n", 995 status, ireason); 996#ifdef KDB 997 if (ncv_debug > 1) 998 kdb_enter(KDB_WHY_CAM, "ncv"); 999#endif /* KDB */ 1000 } 1001#endif /* NCV_DEBUG */ 1002 1003 /******************************************** 1004 * Reselect or Disconnect or Nexus check 1005 ********************************************/ 1006 /* (I) reselect */ 1007 if (ireason == INTR_RESELECT) 1008 { 1009 if (ncv_reselected(sc) == EJUSTRETURN) 1010 return 1; 1011 } 1012 1013 /* (II) nexus */ 1014 if ((ti = slp->sl_Tnexus) == NULL) 1015 return 0; 1016 1017 derror = 0; 1018 if ((status & (STAT_PE | STAT_GE)) != 0) 1019 { 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); 1023 else 1024 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ERROR, 1); 1025 derror = SCSI_LOW_DATA_PE; 1026 } 1027 1028 if ((ireason & (INTR_DIS | INTR_ILL)) != 0) 1029 { 1030 if ((ireason & INTR_ILL) == 0) 1031 return ncv_disconnected(sc, ti); 1032 1033 slp->sl_error |= FATALIO; 1034 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, "illegal cmd"); 1035 return 1; 1036 } 1037 1038 /******************************************** 1039 * Internal scsi phase 1040 ********************************************/ 1041 switch (ti->ti_phase) 1042 { 1043 case PH_SELSTART: 1044 scsi_low_arbit_win(slp); 1045 SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED); 1046 1047 if (sc->sc_selstop == 0) 1048 { 1049 /* XXX: 1050 * Here scsi phases expected are 1051 * DATA PHASE: 1052 * MSGIN : target wants to disconnect the host. 1053 * STATUSIN : immediate command completed. 1054 * CMD PHASE : command out failed 1055 * MSGOUT : identify command failed. 1056 */ 1057 if ((status & PHASE_MASK) != MESSAGE_OUT_PHASE) 1058 break; 1059 } 1060 else 1061 { 1062 if ((status & PHASE_MASK) != MESSAGE_OUT_PHASE) 1063 break; 1064 if ((ireason & INTR_FC) != 0) 1065 { 1066 SCSI_LOW_ASSERT_ATN(slp); 1067 } 1068 } 1069 SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT); 1070 break; 1071 1072 case PH_RESEL: 1073 ncv_target_nexus_establish(sc); 1074 if ((status & PHASE_MASK) != MESSAGE_IN_PHASE) 1075 { 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); 1080 return 1; 1081 } 1082 break; 1083 1084 default: 1085 if ((slp->sl_flags & HW_PDMASTART) != 0) 1086 { 1087 ncv_pdma_end(sc, ti); 1088 } 1089 break; 1090 } 1091 1092 /******************************************** 1093 * Scsi phase sequencer 1094 ********************************************/ 1095 switch (status & PHASE_MASK) 1096 { 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) 1100 { 1101 scsi_low_attention(slp); 1102 } 1103 1104 if (slp->sl_scp.scp_datalen <= 0) 1105 { 1106 if ((ireason & INTR_BS) == 0) 1107 break; 1108 1109 if ((slp->sl_error & PDMAERR) == 0) 1110 device_printf(slp->sl_dev, "data underrun\n"); 1111 slp->sl_error |= PDMAERR; 1112 1113 if ((slp->sl_flags & HW_WRITE_PADDING) != 0) 1114 { 1115 u_int8_t padding[NCV_PADDING_SIZE]; 1116 1117 bzero(padding, sizeof(padding)); 1118 ncv_pio_write(sc, padding, sizeof(padding)); 1119 } 1120 else 1121 { 1122 device_printf(slp->sl_dev, 1123 "write padding required\n"); 1124 } 1125 } 1126 else 1127 { 1128 len = slp->sl_scp.scp_datalen; 1129 if ((ncv_io_control & NCV_WRITE_INTERRUPTS_DRIVEN) != 0) 1130 { 1131 if (len > ncv_data_write_bytes) 1132 len = ncv_data_write_bytes; 1133 } 1134 ncv_pio_write(sc, slp->sl_scp.scp_data, len); 1135 } 1136 break; 1137 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) 1141 { 1142 scsi_low_attention(slp); 1143 } 1144 1145 if (slp->sl_scp.scp_datalen <= 0) 1146 { 1147 if ((ireason & INTR_BS) == 0) 1148 break; 1149 1150 if ((slp->sl_error & PDMAERR) == 0) 1151 device_printf(slp->sl_dev, "data overrun\n"); 1152 slp->sl_error |= PDMAERR; 1153 1154 if ((slp->sl_flags & HW_READ_PADDING) != 0) 1155 { 1156 u_int8_t padding[NCV_PADDING_SIZE]; 1157 1158 ncv_pio_read(sc, padding, sizeof(padding)); 1159 } 1160 else 1161 { 1162 device_printf(slp->sl_dev, 1163 "read padding required\n"); 1164 break; 1165 } 1166 } 1167 else 1168 { 1169 len = slp->sl_scp.scp_datalen; 1170 if ((ncv_io_control & NCV_READ_INTERRUPTS_DRIVEN) != 0) 1171 { 1172 if (len > ncv_data_read_bytes) 1173 len = ncv_data_read_bytes; 1174 } 1175 ncv_pio_read(sc, slp->sl_scp.scp_data, len); 1176 } 1177 break; 1178 1179 case COMMAND_PHASE: /* cmd out */ 1180 SCSI_LOW_SETUP_PHASE(ti, PH_CMD); 1181 if (scsi_low_cmd(slp, ti) != 0) 1182 { 1183 scsi_low_attention(slp); 1184 } 1185 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); 1190 break; 1191 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); 1196 sc->sc_compseq = 1; 1197 break; 1198 1199 default: 1200 break; 1201 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); 1205 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); 1210 1211 if (len > 1 && slp->sl_atten == 0) 1212 { 1213 scsi_low_attention(slp); 1214 } 1215 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); 1219 break; 1220 1221 case MESSAGE_IN_PHASE: /* msg in */ 1222 SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN); 1223 1224 len = bus_space_read_1(iot, ioh, cr0_sffl) & CR0_SFFLR_BMASK; 1225 if (sc->sc_compseq != 0) 1226 { 1227 sc->sc_compseq = 0; 1228 if ((ireason & INTR_FC) && len == 2) 1229 { 1230 regv = bus_space_read_1(iot, ioh, cr0_sfifo); 1231 scsi_low_statusin(slp, ti, regv | derror); 1232 len --; 1233 } 1234 else 1235 { 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); 1241 break; 1242 } 1243 } 1244 else if (ireason & INTR_BS) 1245 { 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) 1249 { 1250 if (ncv_catch_intr(sc) == 0) 1251 goto again; 1252 } 1253 break; 1254 } 1255 1256 if ((ireason & INTR_FC) && len == 1) 1257 { 1258 regv = bus_space_read_1(sc->sc_iot, sc->sc_ioh, 1259 cr0_sfifo); 1260 if (scsi_low_msgin(slp, ti, regv | derror) == 0) 1261 { 1262 if (scsi_low_is_msgout_continue(ti, 0) != 0) 1263 { 1264 scsi_low_attention(slp); 1265 } 1266 } 1267 bus_space_write_1(sc->sc_iot, sc->sc_ioh, cr0_cmd, 1268 CMD_MSGOK); 1269 if ((ncv_io_control & NCV_FAST_INTERRUPTS) != 0) 1270 { 1271 /* XXX: 1272 * clear a pending interrupt and sync with 1273 * a next interrupt! 1274 */ 1275 ncv_catch_intr(sc); 1276 } 1277 } 1278 else 1279 { 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, 1283 CMD_MSGOK); 1284 } 1285 break; 1286 } 1287 1288 return 1; 1289} 1290