6 7#define SCSI_LOW_STATICS 8#define SCSI_LOW_DEBUG 9#define SCSI_LOW_NEGOTIATE_BEFORE_SENSE 10#define SCSI_LOW_START_UP_CHECK 11 12/* #define SCSI_LOW_INFO_DETAIL */ 13 14/* #define SCSI_LOW_QCLEAR_AFTER_CA */ 15/* #define SCSI_LOW_FLAGS_QUIRKS_OK */ 16 17#ifdef __NetBSD__ 18#define SCSI_LOW_TARGET_OPEN 19#endif /* __NetBSD__ */ 20 21#ifdef __FreeBSD__ 22#define SCSI_LOW_FLAGS_QUIRKS_OK 23#endif /* __FreeBSD__ */ 24 25/*- 26 * [NetBSD for NEC PC-98 series] 27 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001 28 * NetBSD/pc98 porting staff. All rights reserved. 29 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001 30 * Naofumi HONDA. All rights reserved. 31 * 32 * [Ported for FreeBSD CAM] 33 * Copyright (c) 2000, 2001 34 * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro. 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. The name of the author may not be used to endorse or promote products 46 * derived from this software without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 49 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 51 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 52 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 54 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 56 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 57 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 58 * POSSIBILITY OF SUCH DAMAGE. 59 */ 60 61/* <On the nexus establishment> 62 * When our host is reselected, 63 * nexus establish processes are little complicated. 64 * Normal steps are followings: 65 * 1) Our host selected by target => target nexus (slp->sl_Tnexus) 66 * 2) Identify msgin => lun nexus (slp->sl_Lnexus) 67 * 3) Qtag msg => ccb nexus (slp->sl_Qnexus) 68 */ 69#include "opt_ddb.h" 70 71#include <sys/param.h> 72#include <sys/systm.h> 73#include <sys/kernel.h> 74 75#ifdef __FreeBSD__ 76#if __FreeBSD_version >= 500001 77#include <sys/bio.h> 78#else 79#include <machine/clock.h> 80#endif 81#endif /* __FreeBSD__ */ 82 83#include <sys/buf.h> 84#include <sys/queue.h> 85#include <sys/malloc.h> 86#include <sys/errno.h> 87 88#ifdef __NetBSD__ 89#include <sys/device.h> 90#include <vm/vm.h> 91 92#include <machine/bus.h> 93#include <machine/intr.h> 94#include <machine/dvcfg.h> 95 96#include <dev/cons.h> 97 98#include <dev/scsipi/scsipi_all.h> 99#include <dev/scsipi/scsipiconf.h> 100#include <dev/scsipi/scsipi_disk.h> 101#include <dev/scsipi/scsi_all.h> 102#include <dev/scsipi/scsiconf.h> 103#include <sys/scsiio.h> 104 105#include <i386/Cbus/dev/scsi_low.h> 106#endif /* __NetBSD__ */ 107 108#ifdef __FreeBSD__ 109#include <cam/cam.h> 110#include <cam/cam_ccb.h> 111#include <cam/cam_sim.h> 112#include <cam/cam_debug.h> 113#include <cam/cam_periph.h> 114#include <cam/cam_xpt_periph.h> 115 116#include <cam/scsi/scsi_all.h> 117#include <cam/scsi/scsi_message.h> 118 119#include <cam/scsi/scsi_low.h> 120 121#include <sys/cons.h> 122#endif /* __FreeBSD__ */ 123 124/************************************************************** 125 * Constants 126 **************************************************************/ 127#define SCSI_LOW_POLL_HZ 1000 128 129/* functions return values */ 130#define SCSI_LOW_START_NO_QTAG 0 131#define SCSI_LOW_START_QTAG 1 132 133#define SCSI_LOW_DONE_COMPLETE 0 134#define SCSI_LOW_DONE_RETRY 1 135 136/* internal disk flags */ 137#define SCSI_LOW_DISK_DISC 0x00000001 138#define SCSI_LOW_DISK_QTAG 0x00000002 139#define SCSI_LOW_DISK_LINK 0x00000004 140#define SCSI_LOW_DISK_PARITY 0x00000008 141#define SCSI_LOW_DISK_SYNC 0x00010000 142#define SCSI_LOW_DISK_WIDE_16 0x00020000 143#define SCSI_LOW_DISK_WIDE_32 0x00040000 144#define SCSI_LOW_DISK_WIDE (SCSI_LOW_DISK_WIDE_16 | SCSI_LOW_DISK_WIDE_32) 145#define SCSI_LOW_DISK_LFLAGS 0x0000ffff 146#define SCSI_LOW_DISK_TFLAGS 0xffff0000 147 148MALLOC_DEFINE(M_SCSILOW, "SCSI low", "SCSI low buffers"); 149 150/************************************************************** 151 * Declarations 152 **************************************************************/ 153/* static */ void scsi_low_info(struct scsi_low_softc *, struct targ_info *, u_char *); 154static void scsi_low_engage(void *); 155static struct slccb *scsi_low_establish_ccb(struct targ_info *, struct lun_info *, scsi_low_tag_t); 156static int scsi_low_done(struct scsi_low_softc *, struct slccb *); 157static int scsi_low_setup_done(struct scsi_low_softc *, struct slccb *); 158static void scsi_low_bus_release(struct scsi_low_softc *, struct targ_info *); 159static void scsi_low_twiddle_wait(void); 160static struct lun_info *scsi_low_alloc_li(struct targ_info *, int, int); 161static struct targ_info *scsi_low_alloc_ti(struct scsi_low_softc *, int); 162static void scsi_low_calcf_lun(struct lun_info *); 163static void scsi_low_calcf_target(struct targ_info *); 164static void scsi_low_calcf_show(struct lun_info *); 165static void scsi_low_reset_nexus(struct scsi_low_softc *, int); 166static void scsi_low_reset_nexus_target(struct scsi_low_softc *, struct targ_info *, int); 167static void scsi_low_reset_nexus_lun(struct scsi_low_softc *, struct lun_info *, int); 168static int scsi_low_init(struct scsi_low_softc *, u_int); 169static void scsi_low_start(struct scsi_low_softc *); 170static void scsi_low_free_ti(struct scsi_low_softc *); 171 172static int scsi_low_alloc_qtag(struct slccb *); 173static int scsi_low_dealloc_qtag(struct slccb *); 174static int scsi_low_enqueue(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int); 175static int scsi_low_message_enqueue(struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int); 176static void scsi_low_unit_ready_cmd(struct slccb *); 177static void scsi_low_timeout(void *); 178static int scsi_low_timeout_check(struct scsi_low_softc *); 179#ifdef SCSI_LOW_START_UP_CHECK 180static int scsi_low_start_up(struct scsi_low_softc *); 181#endif /* SCSI_LOW_START_UP_CHECK */ 182static int scsi_low_abort_ccb(struct scsi_low_softc *, struct slccb *); 183static struct slccb *scsi_low_revoke_ccb(struct scsi_low_softc *, struct slccb *, int); 184 185int scsi_low_version_major = 2; 186int scsi_low_version_minor = 17; 187 188static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab); 189 190/************************************************************** 191 * Debug, Run test and Statics 192 **************************************************************/ 193#ifdef SCSI_LOW_INFO_DETAIL 194#define SCSI_LOW_INFO(slp, ti, s) scsi_low_info((slp), (ti), (s)) 195#else /* !SCSI_LOW_INFO_DETAIL */ 196#define SCSI_LOW_INFO(slp, ti, s) printf("%s: %s\n", (slp)->sl_xname, (s)) 197#endif /* !SCSI_LOW_INFO_DETAIL */ 198 199#ifdef SCSI_LOW_STATICS 200static struct scsi_low_statics { 201 int nexus_win; 202 int nexus_fail; 203 int nexus_disconnected; 204 int nexus_reselected; 205 int nexus_conflict; 206} scsi_low_statics; 207#endif /* SCSI_LOW_STATICS */ 208 209#ifdef SCSI_LOW_DEBUG 210#define SCSI_LOW_DEBUG_DONE 0x00001 211#define SCSI_LOW_DEBUG_DISC 0x00002 212#define SCSI_LOW_DEBUG_SENSE 0x00004 213#define SCSI_LOW_DEBUG_CALCF 0x00008 214#define SCSI_LOW_DEBUG_ACTION 0x10000 215int scsi_low_debug = 0; 216 217#define SCSI_LOW_MAX_ATTEN_CHECK 32 218#define SCSI_LOW_ATTEN_CHECK 0x0001 219#define SCSI_LOW_CMDLNK_CHECK 0x0002 220#define SCSI_LOW_ABORT_CHECK 0x0004 221#define SCSI_LOW_NEXUS_CHECK 0x0008 222int scsi_low_test = 0; 223int scsi_low_test_id = 0; 224 225static void scsi_low_test_abort(struct scsi_low_softc *, struct targ_info *, struct lun_info *); 226static void scsi_low_test_cmdlnk(struct scsi_low_softc *, struct slccb *); 227static void scsi_low_test_atten(struct scsi_low_softc *, struct targ_info *, u_int); 228#define SCSI_LOW_DEBUG_TEST_GO(fl, id) \ 229 ((scsi_low_test & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0) 230#define SCSI_LOW_DEBUG_GO(fl, id) \ 231 ((scsi_low_debug & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0) 232#endif /* SCSI_LOW_DEBUG */ 233 234/************************************************************** 235 * CCB 236 **************************************************************/ 237GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb) 238GENERIC_CCB(scsi_low, slccb, ccb_chain) 239 240/************************************************************** 241 * Inline functions 242 **************************************************************/ 243#define SCSI_LOW_INLINE static __inline 244SCSI_LOW_INLINE void scsi_low_activate_qtag(struct slccb *); 245SCSI_LOW_INLINE void scsi_low_deactivate_qtag(struct slccb *); 246SCSI_LOW_INLINE void scsi_low_ccb_message_assert(struct slccb *, u_int); 247SCSI_LOW_INLINE void scsi_low_ccb_message_exec(struct scsi_low_softc *, struct slccb *); 248SCSI_LOW_INLINE void scsi_low_ccb_message_retry(struct slccb *); 249SCSI_LOW_INLINE void scsi_low_ccb_message_clear(struct slccb *); 250SCSI_LOW_INLINE void scsi_low_init_msgsys(struct scsi_low_softc *, struct targ_info *); 251 252SCSI_LOW_INLINE void 253scsi_low_activate_qtag(cb) 254 struct slccb *cb; 255{ 256 struct lun_info *li = cb->li; 257 258 if (cb->ccb_tag != SCSI_LOW_UNKTAG) 259 return; 260 261 li->li_nqio ++; 262 cb->ccb_tag = cb->ccb_otag; 263} 264 265SCSI_LOW_INLINE void 266scsi_low_deactivate_qtag(cb) 267 struct slccb *cb; 268{ 269 struct lun_info *li = cb->li; 270 271 if (cb->ccb_tag == SCSI_LOW_UNKTAG) 272 return; 273 274 li->li_nqio --; 275 cb->ccb_tag = SCSI_LOW_UNKTAG; 276} 277 278SCSI_LOW_INLINE void 279scsi_low_ccb_message_exec(slp, cb) 280 struct scsi_low_softc *slp; 281 struct slccb *cb; 282{ 283 284 scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0); 285 cb->ccb_msgoutflag = 0; 286} 287 288SCSI_LOW_INLINE void 289scsi_low_ccb_message_assert(cb, msg) 290 struct slccb *cb; 291 u_int msg; 292{ 293 294 cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg; 295} 296 297SCSI_LOW_INLINE void 298scsi_low_ccb_message_retry(cb) 299 struct slccb *cb; 300{ 301 cb->ccb_msgoutflag = cb->ccb_omsgoutflag; 302} 303 304SCSI_LOW_INLINE void 305scsi_low_ccb_message_clear(cb) 306 struct slccb *cb; 307{ 308 cb->ccb_msgoutflag = 0; 309} 310 311SCSI_LOW_INLINE void 312scsi_low_init_msgsys(slp, ti) 313 struct scsi_low_softc *slp; 314 struct targ_info *ti; 315{ 316 317 ti->ti_msginptr = 0; 318 ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0; 319 SCSI_LOW_DEASSERT_ATN(slp); 320 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL); 321} 322 323/*============================================================= 324 * START OF OS switch (All OS depend fucntions should be here) 325 =============================================================*/ 326/* common os depend utitlities */ 327#define SCSI_LOW_CMD_RESIDUAL_CHK 0x0001 328#define SCSI_LOW_CMD_ORDERED_QTAG 0x0002 329#define SCSI_LOW_CMD_ABORT_WARNING 0x0004 330 331static u_int8_t scsi_low_cmd_flags[256] = { 332/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 333/*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0, 334/*1*/ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 335/*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5, 336/*3*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 337}; 338 339struct scsi_low_error_code { 340 int error_bits; 341 int error_code; 342}; 343 344static struct slccb *scsi_low_find_ccb(struct scsi_low_softc *, u_int, u_int, void *); 345static int scsi_low_translate_error_code(struct slccb *, struct scsi_low_error_code *); 346 347static struct slccb * 348scsi_low_find_ccb(slp, target, lun, osdep) 349 struct scsi_low_softc *slp; 350 u_int target, lun; 351 void *osdep; 352{ 353 struct targ_info *ti; 354 struct lun_info *li; 355 struct slccb *cb; 356 357 ti = slp->sl_ti[target]; 358 li = scsi_low_alloc_li(ti, lun, 0); 359 if (li == NULL) 360 return NULL; 361 362 if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep) 363 return cb; 364 365 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL; 366 cb = TAILQ_NEXT(cb, ccb_chain)) 367 { 368 if (cb->osdep == osdep) 369 return cb; 370 } 371 372 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; 373 cb = TAILQ_NEXT(cb, ccb_chain)) 374 { 375 if (cb->osdep == osdep) 376 return cb; 377 } 378 return NULL; 379} 380 381static int 382scsi_low_translate_error_code(cb, tp) 383 struct slccb *cb; 384 struct scsi_low_error_code *tp; 385{ 386 387 if (cb->ccb_error == 0) 388 return tp->error_code; 389 390 for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++) 391 ; 392 return tp->error_code; 393} 394 395#ifdef SCSI_LOW_INTERFACE_XS 396/************************************************************** 397 * SCSI INTERFACE (XS) 398 **************************************************************/ 399#define SCSI_LOW_MINPHYS 0x10000 400#define SCSI_LOW_MALLOC(size) malloc((size), M_SCSILOW, M_NOWAIT) 401#define SCSI_LOW_FREE(pt) free((pt), M_SCSILOW) 402#define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb((flags)) 403#define SCSI_LOW_XS_POLL_HZ 1000 404 405static int scsi_low_poll_xs(struct scsi_low_softc *, struct slccb *); 406static void scsi_low_scsi_minphys_xs(struct buf *); 407#ifdef SCSI_LOW_TARGET_OPEN 408static int scsi_low_target_open(struct scsipi_link *, struct cfdata *); 409#endif /* SCSI_LOW_TARGET_OPEN */ 410static int scsi_low_scsi_cmd_xs(struct scsipi_xfer *); 411static int scsi_low_enable_xs(void *, int); 412static int scsi_low_ioctl_xs(struct scsipi_link *, u_long, caddr_t, int, struct proc *); 413 414static int scsi_low_attach_xs(struct scsi_low_softc *); 415static int scsi_low_world_start_xs(struct scsi_low_softc *); 416static int scsi_low_dettach_xs(struct scsi_low_softc *); 417static int scsi_low_ccb_setup_xs(struct scsi_low_softc *, struct slccb *); 418static int scsi_low_done_xs(struct scsi_low_softc *, struct slccb *); 419static void scsi_low_timeout_xs(struct scsi_low_softc *, int, int); 420static u_int scsi_low_translate_quirks_xs(u_int); 421static void scsi_low_setup_quirks_xs(struct targ_info *, struct lun_info *, u_int); 422 423struct scsi_low_osdep_funcs scsi_low_osdep_funcs_xs = { 424 scsi_low_attach_xs, 425 scsi_low_world_start_xs, 426 scsi_low_dettach_xs, 427 scsi_low_ccb_setup_xs, 428 scsi_low_done_xs, 429 scsi_low_timeout_xs 430}; 431 432struct scsipi_device scsi_low_dev = { 433 NULL, /* Use default error handler */ 434 NULL, /* have a queue, served by this */ 435 NULL, /* have no async handler */ 436 NULL, /* Use default 'done' routine */ 437}; 438 439struct scsi_low_error_code scsi_low_error_code_xs[] = { 440 {0, XS_NOERROR}, 441 {SENSEIO, XS_SENSE}, 442 {BUSYERR, XS_BUSY }, 443 {SELTIMEOUTIO, XS_SELTIMEOUT}, 444 {TIMEOUTIO, XS_TIMEOUT}, 445 {-1, XS_DRIVER_STUFFUP} 446}; 447 448static int 449scsi_low_ioctl_xs(link, cmd, addr, flag, p) 450 struct scsipi_link *link; 451 u_long cmd; 452 caddr_t addr; 453 int flag; 454 struct proc *p; 455{ 456 struct scsi_low_softc *slp; 457 int s, error = ENOTTY; 458 459 slp = (struct scsi_low_softc *) link->adapter_softc; 460 if ((slp->sl_flags & HW_INACTIVE) != 0) 461 return ENXIO; 462 463 if (cmd == SCBUSIORESET) 464 { 465 s = SCSI_LOW_SPLSCSI(); 466 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL); 467 splx(s); 468 error = 0; 469 } 470 else if (slp->sl_funcs->scsi_low_ioctl != 0) 471 { 472 error = (*slp->sl_funcs->scsi_low_ioctl) 473 (slp, cmd, addr, flag, p); 474 } 475 476 return error; 477} 478 479static int 480scsi_low_enable_xs(arg, enable) 481 void *arg; 482 int enable; 483{ 484 struct scsi_low_softc *slp = arg; 485 486 if (enable != 0) 487 { 488 if ((slp->sl_flags & HW_INACTIVE) != 0) 489 return ENXIO; 490 } 491 else 492 { 493 if ((slp->sl_flags & HW_INACTIVE) != 0 || 494 (slp->sl_flags & HW_POWERCTRL) == 0) 495 return 0; 496 497 slp->sl_flags |= HW_POWDOWN; 498 if (slp->sl_funcs->scsi_low_power != NULL) 499 { 500 (*slp->sl_funcs->scsi_low_power) 501 (slp, SCSI_LOW_POWDOWN); 502 } 503 } 504 return 0; 505} 506 507static void 508scsi_low_scsi_minphys_xs(bp) 509 struct buf *bp; 510{ 511 512 if (bp->b_bcount > SCSI_LOW_MINPHYS) 513 bp->b_bcount = SCSI_LOW_MINPHYS; 514 minphys(bp); 515} 516 517static int 518scsi_low_poll_xs(slp, cb) 519 struct scsi_low_softc *slp; 520 struct slccb *cb; 521{ 522 struct scsipi_xfer *xs = cb->osdep; 523 int tcount; 524 525 cb->ccb_flags |= CCB_NOSDONE; 526 tcount = 0; 527 528 while (slp->sl_nio > 0) 529 { 530 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_XS_POLL_HZ); 531 532 (*slp->sl_funcs->scsi_low_poll) (slp); 533 534 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0) 535 { 536 cb->ccb_flags |= CCB_NORETRY; 537 cb->ccb_error |= FATALIO; 538 (void) scsi_low_revoke_ccb(slp, cb, 1); 539 printf("%s: hardware inactive in poll mode\n", 540 slp->sl_xname); 541 } 542 543 if ((xs->flags & ITSDONE) != 0) 544 break; 545 546 if (tcount ++ < SCSI_LOW_XS_POLL_HZ / SCSI_LOW_TIMEOUT_HZ) 547 continue; 548 549 tcount = 0; 550 scsi_low_timeout_check(slp); 551 } 552 553 xs->flags |= ITSDONE; 554 scsipi_done(xs); 555 return COMPLETE; 556} 557 558static int 559scsi_low_scsi_cmd_xs(xs) 560 struct scsipi_xfer *xs; 561{ 562 struct scsipi_link *splp = xs->sc_link; 563 struct scsi_low_softc *slp = splp->adapter_softc; 564 struct targ_info *ti; 565 struct lun_info *li; 566 struct slccb *cb; 567 int s, targ, lun, flags, rv; 568 569 if ((cb = SCSI_LOW_ALLOC_CCB(xs->flags & SCSI_NOSLEEP)) == NULL) 570 return TRY_AGAIN_LATER; 571 572 targ = splp->scsipi_scsi.target, 573 lun = splp->scsipi_scsi.lun; 574 ti = slp->sl_ti[targ]; 575 576 cb->osdep = xs; 577 cb->bp = xs->bp; 578 579 if ((xs->flags & SCSI_POLL) == 0) 580 flags = CCB_AUTOSENSE; 581 else 582 flags = CCB_AUTOSENSE | CCB_POLLED; 583 584 585 s = SCSI_LOW_SPLSCSI(); 586 li = scsi_low_alloc_li(ti, lun, 1); 587 if ((u_int) splp->quirks != li->li_sloi.sloi_quirks) 588 { 589 scsi_low_setup_quirks_xs(ti, li, (u_int) splp->quirks); 590 } 591 592 if ((xs->flags & SCSI_RESET) != 0) 593 { 594 flags |= CCB_NORETRY | CCB_URGENT; 595 scsi_low_enqueue(slp, ti, li, cb, flags, SCSI_LOW_MSG_RESET); 596 } 597 else 598 { 599 if (ti->ti_setup_msg != 0) 600 { 601 scsi_low_message_enqueue(slp, ti, li, flags); 602 } 603 604 flags |= CCB_SCSIIO; 605 scsi_low_enqueue(slp, ti, li, cb, flags, 0); 606 } 607 608#ifdef SCSI_LOW_DEBUG 609 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, ti->ti_id) != 0) 610 { 611 scsi_low_test_abort(slp, ti, li); 612 } 613#endif /* SCSI_LOW_DEBUG */ 614 615 if ((cb->ccb_flags & CCB_POLLED) != 0) 616 { 617 rv = scsi_low_poll_xs(slp, cb); 618 } 619 else 620 { 621 rv = SUCCESSFULLY_QUEUED; 622 } 623 splx(s); 624 return rv; 625} 626 627static int 628scsi_low_attach_xs(slp) 629 struct scsi_low_softc *slp; 630{ 631 struct scsipi_adapter *sap; 632 struct scsipi_link *splp; 633 634 strncpy(slp->sl_xname, slp->sl_dev.dv_xname, 16); 635 636 sap = SCSI_LOW_MALLOC(sizeof(*sap)); 637 if (sap == NULL) 638 return ENOMEM; 639 splp = SCSI_LOW_MALLOC(sizeof(*splp)); 640 if (splp == NULL) 641 { 642 SCSI_LOW_FREE(sap); 643 return ENOMEM; 644 } 645 646 SCSI_LOW_BZERO(sap, sizeof(*sap)); 647 SCSI_LOW_BZERO(splp, sizeof(*splp)); 648 649 sap->scsipi_cmd = scsi_low_scsi_cmd_xs; 650 sap->scsipi_minphys = scsi_low_scsi_minphys_xs; 651 sap->scsipi_enable = scsi_low_enable_xs; 652 sap->scsipi_ioctl = scsi_low_ioctl_xs; 653#ifdef SCSI_LOW_TARGET_OPEN 654 sap->open_target_lu = scsi_low_target_open; 655#endif /* SCSI_LOW_TARGET_OPEN */ 656 657 splp->adapter_softc = slp; 658 splp->scsipi_scsi.adapter_target = slp->sl_hostid; 659 splp->scsipi_scsi.max_target = slp->sl_ntargs - 1; 660 splp->scsipi_scsi.max_lun = slp->sl_nluns - 1; 661 splp->scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE; 662 splp->openings = slp->sl_openings; 663 splp->type = BUS_SCSI; 664 splp->adapter_softc = slp; 665 splp->adapter = sap; 666 splp->device = &scsi_low_dev; 667 668 slp->sl_si.si_splp = splp; 669 slp->sl_show_result = SHOW_ALL_NEG; 670 return 0; 671} 672 673static int 674scsi_low_world_start_xs(slp) 675 struct scsi_low_softc *slp; 676{ 677 678 return 0; 679} 680 681static int 682scsi_low_dettach_xs(slp) 683 struct scsi_low_softc *slp; 684{ 685 686 /* 687 * scsipi does not have dettach bus fucntion. 688 * 689 scsipi_dettach_scsibus(slp->sl_si.si_splp); 690 */ 691 return 0; 692} 693 694static int 695scsi_low_ccb_setup_xs(slp, cb) 696 struct scsi_low_softc *slp; 697 struct slccb *cb; 698{ 699 struct scsipi_xfer *xs = (struct scsipi_xfer *) cb->osdep; 700 701 if ((cb->ccb_flags & CCB_SCSIIO) != 0) 702 { 703 cb->ccb_scp.scp_cmd = (u_int8_t *) xs->cmd; 704 cb->ccb_scp.scp_cmdlen = xs->cmdlen; 705 cb->ccb_scp.scp_data = xs->data; 706 cb->ccb_scp.scp_datalen = xs->datalen; 707 cb->ccb_scp.scp_direction = (xs->flags & SCSI_DATA_OUT) ? 708 SCSI_LOW_WRITE : SCSI_LOW_READ; 709 cb->ccb_tcmax = xs->timeout / 1000; 710 } 711 else 712 { 713 scsi_low_unit_ready_cmd(cb); 714 } 715 return SCSI_LOW_START_QTAG; 716} 717 718static int 719scsi_low_done_xs(slp, cb) 720 struct scsi_low_softc *slp; 721 struct slccb *cb; 722{ 723 struct scsipi_xfer *xs; 724 725 xs = (struct scsipi_xfer *) cb->osdep; 726 if (cb->ccb_error == 0) 727 { 728 xs->error = XS_NOERROR; 729 xs->resid = 0; 730 } 731 else 732 { 733 if (cb->ccb_rcnt >= slp->sl_max_retry) 734 cb->ccb_error |= ABORTIO; 735 736 if ((cb->ccb_flags & CCB_NORETRY) == 0 && 737 (cb->ccb_error & ABORTIO) == 0) 738 return EJUSTRETURN; 739 740 if ((cb->ccb_error & SENSEIO) != 0) 741 { 742 xs->sense.scsi_sense = cb->ccb_sense; 743 } 744 745 xs->error = scsi_low_translate_error_code(cb, 746 &scsi_low_error_code_xs[0]); 747 748#ifdef SCSI_LOW_DIAGNOSTIC 749 if ((cb->ccb_flags & CCB_SILENT) == 0 && 750 cb->ccb_scp.scp_cmdlen > 0 && 751 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & 752 SCSI_LOW_CMD_ABORT_WARNING) != 0) 753 { 754 printf("%s: WARNING: scsi_low IO abort\n", 755 slp->sl_xname); 756 scsi_low_print(slp, NULL); 757 } 758#endif /* SCSI_LOW_DIAGNOSTIC */ 759 } 760 761 if (cb->ccb_scp.scp_status == ST_UNKNOWN) 762 xs->status = 0; /* XXX */ 763 else 764 xs->status = cb->ccb_scp.scp_status; 765 766 xs->flags |= ITSDONE; 767 if ((cb->ccb_flags & CCB_NOSDONE) == 0) 768 scsipi_done(xs); 769 770 return 0; 771} 772 773static void 774scsi_low_timeout_xs(slp, ch, action) 775 struct scsi_low_softc *slp; 776 int ch; 777 int action; 778{ 779 780 switch (ch) 781 { 782 case SCSI_LOW_TIMEOUT_CH_IO: 783 switch (action) 784 { 785 case SCSI_LOW_TIMEOUT_START: 786 timeout(scsi_low_timeout, slp, 787 hz / SCSI_LOW_TIMEOUT_HZ); 788 break; 789 case SCSI_LOW_TIMEOUT_STOP: 790 untimeout(scsi_low_timeout, slp); 791 break; 792 } 793 break; 794 795 case SCSI_LOW_TIMEOUT_CH_ENGAGE: 796 switch (action) 797 { 798 case SCSI_LOW_TIMEOUT_START: 799 timeout(scsi_low_engage, slp, 1); 800 break; 801 case SCSI_LOW_TIMEOUT_STOP: 802 untimeout(scsi_low_engage, slp); 803 break; 804 } 805 break; 806 807 case SCSI_LOW_TIMEOUT_CH_RECOVER: 808 break; 809 } 810} 811 812u_int 813scsi_low_translate_quirks_xs(quirks) 814 u_int quirks; 815{ 816 u_int flags; 817 818 flags = SCSI_LOW_DISK_LFLAGS | SCSI_LOW_DISK_TFLAGS; 819 820#ifdef SDEV_NODISC 821 if (quirks & SDEV_NODISC) 822 flags &= ~SCSI_LOW_DISK_DISC; 823#endif /* SDEV_NODISC */ 824#ifdef SDEV_NOPARITY 825 if (quirks & SDEV_NOPARITY) 826 flags &= ~SCSI_LOW_DISK_PARITY; 827#endif /* SDEV_NOPARITY */ 828#ifdef SDEV_NOCMDLNK 829 if (quirks & SDEV_NOCMDLNK) 830 flags &= ~SCSI_LOW_DISK_LINK; 831#endif /* SDEV_NOCMDLNK */ 832#ifdef SDEV_NOTAG 833 if (quirks & SDEV_NOTAG) 834 flags &= ~SCSI_LOW_DISK_QTAG; 835#endif /* SDEV_NOTAG */ 836#ifdef SDEV_NOSYNC 837 if (quirks & SDEV_NOSYNC) 838 flags &= ~SCSI_LOW_DISK_SYNC; 839#endif /* SDEV_NOSYNC */ 840 841 return flags; 842} 843 844static void 845scsi_low_setup_quirks_xs(ti, li, flags) 846 struct targ_info *ti; 847 struct lun_info *li; 848 u_int flags; 849{ 850 u_int quirks; 851 852 li->li_sloi.sloi_quirks = flags; 853 quirks = scsi_low_translate_quirks_xs(flags); 854 ti->ti_quirks = quirks & SCSI_LOW_DISK_TFLAGS; 855 li->li_quirks = quirks & SCSI_LOW_DISK_LFLAGS; 856 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID; 857 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID; 858 scsi_low_calcf_target(ti); 859 scsi_low_calcf_lun(li); 860 scsi_low_calcf_show(li); 861} 862 863#ifdef SCSI_LOW_TARGET_OPEN 864static int 865scsi_low_target_open(link, cf) 866 struct scsipi_link *link; 867 struct cfdata *cf; 868{ 869 u_int target = link->scsipi_scsi.target; 870 u_int lun = link->scsipi_scsi.lun; 871 struct scsi_low_softc *slp; 872 struct targ_info *ti; 873 struct lun_info *li; 874 875 slp = (struct scsi_low_softc *) link->adapter_softc; 876 ti = slp->sl_ti[target]; 877 li = scsi_low_alloc_li(ti, lun, 0); 878 if (li == NULL) 879 return 0; 880 881 li->li_cfgflags = cf->cf_flags; 882 scsi_low_setup_quirks_xs(ti, li, (u_int) link->quirks); 883 return 0; 884} 885#endif /* SCSI_LOW_TARGET_OPEN */ 886 887#endif /* SCSI_LOW_INTERFACE_XS */ 888 889#ifdef SCSI_LOW_INTERFACE_CAM 890/************************************************************** 891 * SCSI INTERFACE (CAM) 892 **************************************************************/ 893#define SCSI_LOW_MALLOC(size) malloc((size), M_SCSILOW, M_NOWAIT) 894#define SCSI_LOW_FREE(pt) free((pt), M_SCSILOW) 895#define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb() 896 897static void scsi_low_poll_cam(struct cam_sim *);
| 6 7#define SCSI_LOW_STATICS 8#define SCSI_LOW_DEBUG 9#define SCSI_LOW_NEGOTIATE_BEFORE_SENSE 10#define SCSI_LOW_START_UP_CHECK 11 12/* #define SCSI_LOW_INFO_DETAIL */ 13 14/* #define SCSI_LOW_QCLEAR_AFTER_CA */ 15/* #define SCSI_LOW_FLAGS_QUIRKS_OK */ 16 17#ifdef __NetBSD__ 18#define SCSI_LOW_TARGET_OPEN 19#endif /* __NetBSD__ */ 20 21#ifdef __FreeBSD__ 22#define SCSI_LOW_FLAGS_QUIRKS_OK 23#endif /* __FreeBSD__ */ 24 25/*- 26 * [NetBSD for NEC PC-98 series] 27 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001 28 * NetBSD/pc98 porting staff. All rights reserved. 29 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001 30 * Naofumi HONDA. All rights reserved. 31 * 32 * [Ported for FreeBSD CAM] 33 * Copyright (c) 2000, 2001 34 * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro. 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. The name of the author may not be used to endorse or promote products 46 * derived from this software without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 49 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 51 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 52 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 54 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 56 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 57 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 58 * POSSIBILITY OF SUCH DAMAGE. 59 */ 60 61/* <On the nexus establishment> 62 * When our host is reselected, 63 * nexus establish processes are little complicated. 64 * Normal steps are followings: 65 * 1) Our host selected by target => target nexus (slp->sl_Tnexus) 66 * 2) Identify msgin => lun nexus (slp->sl_Lnexus) 67 * 3) Qtag msg => ccb nexus (slp->sl_Qnexus) 68 */ 69#include "opt_ddb.h" 70 71#include <sys/param.h> 72#include <sys/systm.h> 73#include <sys/kernel.h> 74 75#ifdef __FreeBSD__ 76#if __FreeBSD_version >= 500001 77#include <sys/bio.h> 78#else 79#include <machine/clock.h> 80#endif 81#endif /* __FreeBSD__ */ 82 83#include <sys/buf.h> 84#include <sys/queue.h> 85#include <sys/malloc.h> 86#include <sys/errno.h> 87 88#ifdef __NetBSD__ 89#include <sys/device.h> 90#include <vm/vm.h> 91 92#include <machine/bus.h> 93#include <machine/intr.h> 94#include <machine/dvcfg.h> 95 96#include <dev/cons.h> 97 98#include <dev/scsipi/scsipi_all.h> 99#include <dev/scsipi/scsipiconf.h> 100#include <dev/scsipi/scsipi_disk.h> 101#include <dev/scsipi/scsi_all.h> 102#include <dev/scsipi/scsiconf.h> 103#include <sys/scsiio.h> 104 105#include <i386/Cbus/dev/scsi_low.h> 106#endif /* __NetBSD__ */ 107 108#ifdef __FreeBSD__ 109#include <cam/cam.h> 110#include <cam/cam_ccb.h> 111#include <cam/cam_sim.h> 112#include <cam/cam_debug.h> 113#include <cam/cam_periph.h> 114#include <cam/cam_xpt_periph.h> 115 116#include <cam/scsi/scsi_all.h> 117#include <cam/scsi/scsi_message.h> 118 119#include <cam/scsi/scsi_low.h> 120 121#include <sys/cons.h> 122#endif /* __FreeBSD__ */ 123 124/************************************************************** 125 * Constants 126 **************************************************************/ 127#define SCSI_LOW_POLL_HZ 1000 128 129/* functions return values */ 130#define SCSI_LOW_START_NO_QTAG 0 131#define SCSI_LOW_START_QTAG 1 132 133#define SCSI_LOW_DONE_COMPLETE 0 134#define SCSI_LOW_DONE_RETRY 1 135 136/* internal disk flags */ 137#define SCSI_LOW_DISK_DISC 0x00000001 138#define SCSI_LOW_DISK_QTAG 0x00000002 139#define SCSI_LOW_DISK_LINK 0x00000004 140#define SCSI_LOW_DISK_PARITY 0x00000008 141#define SCSI_LOW_DISK_SYNC 0x00010000 142#define SCSI_LOW_DISK_WIDE_16 0x00020000 143#define SCSI_LOW_DISK_WIDE_32 0x00040000 144#define SCSI_LOW_DISK_WIDE (SCSI_LOW_DISK_WIDE_16 | SCSI_LOW_DISK_WIDE_32) 145#define SCSI_LOW_DISK_LFLAGS 0x0000ffff 146#define SCSI_LOW_DISK_TFLAGS 0xffff0000 147 148MALLOC_DEFINE(M_SCSILOW, "SCSI low", "SCSI low buffers"); 149 150/************************************************************** 151 * Declarations 152 **************************************************************/ 153/* static */ void scsi_low_info(struct scsi_low_softc *, struct targ_info *, u_char *); 154static void scsi_low_engage(void *); 155static struct slccb *scsi_low_establish_ccb(struct targ_info *, struct lun_info *, scsi_low_tag_t); 156static int scsi_low_done(struct scsi_low_softc *, struct slccb *); 157static int scsi_low_setup_done(struct scsi_low_softc *, struct slccb *); 158static void scsi_low_bus_release(struct scsi_low_softc *, struct targ_info *); 159static void scsi_low_twiddle_wait(void); 160static struct lun_info *scsi_low_alloc_li(struct targ_info *, int, int); 161static struct targ_info *scsi_low_alloc_ti(struct scsi_low_softc *, int); 162static void scsi_low_calcf_lun(struct lun_info *); 163static void scsi_low_calcf_target(struct targ_info *); 164static void scsi_low_calcf_show(struct lun_info *); 165static void scsi_low_reset_nexus(struct scsi_low_softc *, int); 166static void scsi_low_reset_nexus_target(struct scsi_low_softc *, struct targ_info *, int); 167static void scsi_low_reset_nexus_lun(struct scsi_low_softc *, struct lun_info *, int); 168static int scsi_low_init(struct scsi_low_softc *, u_int); 169static void scsi_low_start(struct scsi_low_softc *); 170static void scsi_low_free_ti(struct scsi_low_softc *); 171 172static int scsi_low_alloc_qtag(struct slccb *); 173static int scsi_low_dealloc_qtag(struct slccb *); 174static int scsi_low_enqueue(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int); 175static int scsi_low_message_enqueue(struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int); 176static void scsi_low_unit_ready_cmd(struct slccb *); 177static void scsi_low_timeout(void *); 178static int scsi_low_timeout_check(struct scsi_low_softc *); 179#ifdef SCSI_LOW_START_UP_CHECK 180static int scsi_low_start_up(struct scsi_low_softc *); 181#endif /* SCSI_LOW_START_UP_CHECK */ 182static int scsi_low_abort_ccb(struct scsi_low_softc *, struct slccb *); 183static struct slccb *scsi_low_revoke_ccb(struct scsi_low_softc *, struct slccb *, int); 184 185int scsi_low_version_major = 2; 186int scsi_low_version_minor = 17; 187 188static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab); 189 190/************************************************************** 191 * Debug, Run test and Statics 192 **************************************************************/ 193#ifdef SCSI_LOW_INFO_DETAIL 194#define SCSI_LOW_INFO(slp, ti, s) scsi_low_info((slp), (ti), (s)) 195#else /* !SCSI_LOW_INFO_DETAIL */ 196#define SCSI_LOW_INFO(slp, ti, s) printf("%s: %s\n", (slp)->sl_xname, (s)) 197#endif /* !SCSI_LOW_INFO_DETAIL */ 198 199#ifdef SCSI_LOW_STATICS 200static struct scsi_low_statics { 201 int nexus_win; 202 int nexus_fail; 203 int nexus_disconnected; 204 int nexus_reselected; 205 int nexus_conflict; 206} scsi_low_statics; 207#endif /* SCSI_LOW_STATICS */ 208 209#ifdef SCSI_LOW_DEBUG 210#define SCSI_LOW_DEBUG_DONE 0x00001 211#define SCSI_LOW_DEBUG_DISC 0x00002 212#define SCSI_LOW_DEBUG_SENSE 0x00004 213#define SCSI_LOW_DEBUG_CALCF 0x00008 214#define SCSI_LOW_DEBUG_ACTION 0x10000 215int scsi_low_debug = 0; 216 217#define SCSI_LOW_MAX_ATTEN_CHECK 32 218#define SCSI_LOW_ATTEN_CHECK 0x0001 219#define SCSI_LOW_CMDLNK_CHECK 0x0002 220#define SCSI_LOW_ABORT_CHECK 0x0004 221#define SCSI_LOW_NEXUS_CHECK 0x0008 222int scsi_low_test = 0; 223int scsi_low_test_id = 0; 224 225static void scsi_low_test_abort(struct scsi_low_softc *, struct targ_info *, struct lun_info *); 226static void scsi_low_test_cmdlnk(struct scsi_low_softc *, struct slccb *); 227static void scsi_low_test_atten(struct scsi_low_softc *, struct targ_info *, u_int); 228#define SCSI_LOW_DEBUG_TEST_GO(fl, id) \ 229 ((scsi_low_test & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0) 230#define SCSI_LOW_DEBUG_GO(fl, id) \ 231 ((scsi_low_debug & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0) 232#endif /* SCSI_LOW_DEBUG */ 233 234/************************************************************** 235 * CCB 236 **************************************************************/ 237GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb) 238GENERIC_CCB(scsi_low, slccb, ccb_chain) 239 240/************************************************************** 241 * Inline functions 242 **************************************************************/ 243#define SCSI_LOW_INLINE static __inline 244SCSI_LOW_INLINE void scsi_low_activate_qtag(struct slccb *); 245SCSI_LOW_INLINE void scsi_low_deactivate_qtag(struct slccb *); 246SCSI_LOW_INLINE void scsi_low_ccb_message_assert(struct slccb *, u_int); 247SCSI_LOW_INLINE void scsi_low_ccb_message_exec(struct scsi_low_softc *, struct slccb *); 248SCSI_LOW_INLINE void scsi_low_ccb_message_retry(struct slccb *); 249SCSI_LOW_INLINE void scsi_low_ccb_message_clear(struct slccb *); 250SCSI_LOW_INLINE void scsi_low_init_msgsys(struct scsi_low_softc *, struct targ_info *); 251 252SCSI_LOW_INLINE void 253scsi_low_activate_qtag(cb) 254 struct slccb *cb; 255{ 256 struct lun_info *li = cb->li; 257 258 if (cb->ccb_tag != SCSI_LOW_UNKTAG) 259 return; 260 261 li->li_nqio ++; 262 cb->ccb_tag = cb->ccb_otag; 263} 264 265SCSI_LOW_INLINE void 266scsi_low_deactivate_qtag(cb) 267 struct slccb *cb; 268{ 269 struct lun_info *li = cb->li; 270 271 if (cb->ccb_tag == SCSI_LOW_UNKTAG) 272 return; 273 274 li->li_nqio --; 275 cb->ccb_tag = SCSI_LOW_UNKTAG; 276} 277 278SCSI_LOW_INLINE void 279scsi_low_ccb_message_exec(slp, cb) 280 struct scsi_low_softc *slp; 281 struct slccb *cb; 282{ 283 284 scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0); 285 cb->ccb_msgoutflag = 0; 286} 287 288SCSI_LOW_INLINE void 289scsi_low_ccb_message_assert(cb, msg) 290 struct slccb *cb; 291 u_int msg; 292{ 293 294 cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg; 295} 296 297SCSI_LOW_INLINE void 298scsi_low_ccb_message_retry(cb) 299 struct slccb *cb; 300{ 301 cb->ccb_msgoutflag = cb->ccb_omsgoutflag; 302} 303 304SCSI_LOW_INLINE void 305scsi_low_ccb_message_clear(cb) 306 struct slccb *cb; 307{ 308 cb->ccb_msgoutflag = 0; 309} 310 311SCSI_LOW_INLINE void 312scsi_low_init_msgsys(slp, ti) 313 struct scsi_low_softc *slp; 314 struct targ_info *ti; 315{ 316 317 ti->ti_msginptr = 0; 318 ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0; 319 SCSI_LOW_DEASSERT_ATN(slp); 320 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL); 321} 322 323/*============================================================= 324 * START OF OS switch (All OS depend fucntions should be here) 325 =============================================================*/ 326/* common os depend utitlities */ 327#define SCSI_LOW_CMD_RESIDUAL_CHK 0x0001 328#define SCSI_LOW_CMD_ORDERED_QTAG 0x0002 329#define SCSI_LOW_CMD_ABORT_WARNING 0x0004 330 331static u_int8_t scsi_low_cmd_flags[256] = { 332/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 333/*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0, 334/*1*/ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 335/*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5, 336/*3*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 337}; 338 339struct scsi_low_error_code { 340 int error_bits; 341 int error_code; 342}; 343 344static struct slccb *scsi_low_find_ccb(struct scsi_low_softc *, u_int, u_int, void *); 345static int scsi_low_translate_error_code(struct slccb *, struct scsi_low_error_code *); 346 347static struct slccb * 348scsi_low_find_ccb(slp, target, lun, osdep) 349 struct scsi_low_softc *slp; 350 u_int target, lun; 351 void *osdep; 352{ 353 struct targ_info *ti; 354 struct lun_info *li; 355 struct slccb *cb; 356 357 ti = slp->sl_ti[target]; 358 li = scsi_low_alloc_li(ti, lun, 0); 359 if (li == NULL) 360 return NULL; 361 362 if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep) 363 return cb; 364 365 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL; 366 cb = TAILQ_NEXT(cb, ccb_chain)) 367 { 368 if (cb->osdep == osdep) 369 return cb; 370 } 371 372 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; 373 cb = TAILQ_NEXT(cb, ccb_chain)) 374 { 375 if (cb->osdep == osdep) 376 return cb; 377 } 378 return NULL; 379} 380 381static int 382scsi_low_translate_error_code(cb, tp) 383 struct slccb *cb; 384 struct scsi_low_error_code *tp; 385{ 386 387 if (cb->ccb_error == 0) 388 return tp->error_code; 389 390 for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++) 391 ; 392 return tp->error_code; 393} 394 395#ifdef SCSI_LOW_INTERFACE_XS 396/************************************************************** 397 * SCSI INTERFACE (XS) 398 **************************************************************/ 399#define SCSI_LOW_MINPHYS 0x10000 400#define SCSI_LOW_MALLOC(size) malloc((size), M_SCSILOW, M_NOWAIT) 401#define SCSI_LOW_FREE(pt) free((pt), M_SCSILOW) 402#define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb((flags)) 403#define SCSI_LOW_XS_POLL_HZ 1000 404 405static int scsi_low_poll_xs(struct scsi_low_softc *, struct slccb *); 406static void scsi_low_scsi_minphys_xs(struct buf *); 407#ifdef SCSI_LOW_TARGET_OPEN 408static int scsi_low_target_open(struct scsipi_link *, struct cfdata *); 409#endif /* SCSI_LOW_TARGET_OPEN */ 410static int scsi_low_scsi_cmd_xs(struct scsipi_xfer *); 411static int scsi_low_enable_xs(void *, int); 412static int scsi_low_ioctl_xs(struct scsipi_link *, u_long, caddr_t, int, struct proc *); 413 414static int scsi_low_attach_xs(struct scsi_low_softc *); 415static int scsi_low_world_start_xs(struct scsi_low_softc *); 416static int scsi_low_dettach_xs(struct scsi_low_softc *); 417static int scsi_low_ccb_setup_xs(struct scsi_low_softc *, struct slccb *); 418static int scsi_low_done_xs(struct scsi_low_softc *, struct slccb *); 419static void scsi_low_timeout_xs(struct scsi_low_softc *, int, int); 420static u_int scsi_low_translate_quirks_xs(u_int); 421static void scsi_low_setup_quirks_xs(struct targ_info *, struct lun_info *, u_int); 422 423struct scsi_low_osdep_funcs scsi_low_osdep_funcs_xs = { 424 scsi_low_attach_xs, 425 scsi_low_world_start_xs, 426 scsi_low_dettach_xs, 427 scsi_low_ccb_setup_xs, 428 scsi_low_done_xs, 429 scsi_low_timeout_xs 430}; 431 432struct scsipi_device scsi_low_dev = { 433 NULL, /* Use default error handler */ 434 NULL, /* have a queue, served by this */ 435 NULL, /* have no async handler */ 436 NULL, /* Use default 'done' routine */ 437}; 438 439struct scsi_low_error_code scsi_low_error_code_xs[] = { 440 {0, XS_NOERROR}, 441 {SENSEIO, XS_SENSE}, 442 {BUSYERR, XS_BUSY }, 443 {SELTIMEOUTIO, XS_SELTIMEOUT}, 444 {TIMEOUTIO, XS_TIMEOUT}, 445 {-1, XS_DRIVER_STUFFUP} 446}; 447 448static int 449scsi_low_ioctl_xs(link, cmd, addr, flag, p) 450 struct scsipi_link *link; 451 u_long cmd; 452 caddr_t addr; 453 int flag; 454 struct proc *p; 455{ 456 struct scsi_low_softc *slp; 457 int s, error = ENOTTY; 458 459 slp = (struct scsi_low_softc *) link->adapter_softc; 460 if ((slp->sl_flags & HW_INACTIVE) != 0) 461 return ENXIO; 462 463 if (cmd == SCBUSIORESET) 464 { 465 s = SCSI_LOW_SPLSCSI(); 466 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL); 467 splx(s); 468 error = 0; 469 } 470 else if (slp->sl_funcs->scsi_low_ioctl != 0) 471 { 472 error = (*slp->sl_funcs->scsi_low_ioctl) 473 (slp, cmd, addr, flag, p); 474 } 475 476 return error; 477} 478 479static int 480scsi_low_enable_xs(arg, enable) 481 void *arg; 482 int enable; 483{ 484 struct scsi_low_softc *slp = arg; 485 486 if (enable != 0) 487 { 488 if ((slp->sl_flags & HW_INACTIVE) != 0) 489 return ENXIO; 490 } 491 else 492 { 493 if ((slp->sl_flags & HW_INACTIVE) != 0 || 494 (slp->sl_flags & HW_POWERCTRL) == 0) 495 return 0; 496 497 slp->sl_flags |= HW_POWDOWN; 498 if (slp->sl_funcs->scsi_low_power != NULL) 499 { 500 (*slp->sl_funcs->scsi_low_power) 501 (slp, SCSI_LOW_POWDOWN); 502 } 503 } 504 return 0; 505} 506 507static void 508scsi_low_scsi_minphys_xs(bp) 509 struct buf *bp; 510{ 511 512 if (bp->b_bcount > SCSI_LOW_MINPHYS) 513 bp->b_bcount = SCSI_LOW_MINPHYS; 514 minphys(bp); 515} 516 517static int 518scsi_low_poll_xs(slp, cb) 519 struct scsi_low_softc *slp; 520 struct slccb *cb; 521{ 522 struct scsipi_xfer *xs = cb->osdep; 523 int tcount; 524 525 cb->ccb_flags |= CCB_NOSDONE; 526 tcount = 0; 527 528 while (slp->sl_nio > 0) 529 { 530 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_XS_POLL_HZ); 531 532 (*slp->sl_funcs->scsi_low_poll) (slp); 533 534 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0) 535 { 536 cb->ccb_flags |= CCB_NORETRY; 537 cb->ccb_error |= FATALIO; 538 (void) scsi_low_revoke_ccb(slp, cb, 1); 539 printf("%s: hardware inactive in poll mode\n", 540 slp->sl_xname); 541 } 542 543 if ((xs->flags & ITSDONE) != 0) 544 break; 545 546 if (tcount ++ < SCSI_LOW_XS_POLL_HZ / SCSI_LOW_TIMEOUT_HZ) 547 continue; 548 549 tcount = 0; 550 scsi_low_timeout_check(slp); 551 } 552 553 xs->flags |= ITSDONE; 554 scsipi_done(xs); 555 return COMPLETE; 556} 557 558static int 559scsi_low_scsi_cmd_xs(xs) 560 struct scsipi_xfer *xs; 561{ 562 struct scsipi_link *splp = xs->sc_link; 563 struct scsi_low_softc *slp = splp->adapter_softc; 564 struct targ_info *ti; 565 struct lun_info *li; 566 struct slccb *cb; 567 int s, targ, lun, flags, rv; 568 569 if ((cb = SCSI_LOW_ALLOC_CCB(xs->flags & SCSI_NOSLEEP)) == NULL) 570 return TRY_AGAIN_LATER; 571 572 targ = splp->scsipi_scsi.target, 573 lun = splp->scsipi_scsi.lun; 574 ti = slp->sl_ti[targ]; 575 576 cb->osdep = xs; 577 cb->bp = xs->bp; 578 579 if ((xs->flags & SCSI_POLL) == 0) 580 flags = CCB_AUTOSENSE; 581 else 582 flags = CCB_AUTOSENSE | CCB_POLLED; 583 584 585 s = SCSI_LOW_SPLSCSI(); 586 li = scsi_low_alloc_li(ti, lun, 1); 587 if ((u_int) splp->quirks != li->li_sloi.sloi_quirks) 588 { 589 scsi_low_setup_quirks_xs(ti, li, (u_int) splp->quirks); 590 } 591 592 if ((xs->flags & SCSI_RESET) != 0) 593 { 594 flags |= CCB_NORETRY | CCB_URGENT; 595 scsi_low_enqueue(slp, ti, li, cb, flags, SCSI_LOW_MSG_RESET); 596 } 597 else 598 { 599 if (ti->ti_setup_msg != 0) 600 { 601 scsi_low_message_enqueue(slp, ti, li, flags); 602 } 603 604 flags |= CCB_SCSIIO; 605 scsi_low_enqueue(slp, ti, li, cb, flags, 0); 606 } 607 608#ifdef SCSI_LOW_DEBUG 609 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, ti->ti_id) != 0) 610 { 611 scsi_low_test_abort(slp, ti, li); 612 } 613#endif /* SCSI_LOW_DEBUG */ 614 615 if ((cb->ccb_flags & CCB_POLLED) != 0) 616 { 617 rv = scsi_low_poll_xs(slp, cb); 618 } 619 else 620 { 621 rv = SUCCESSFULLY_QUEUED; 622 } 623 splx(s); 624 return rv; 625} 626 627static int 628scsi_low_attach_xs(slp) 629 struct scsi_low_softc *slp; 630{ 631 struct scsipi_adapter *sap; 632 struct scsipi_link *splp; 633 634 strncpy(slp->sl_xname, slp->sl_dev.dv_xname, 16); 635 636 sap = SCSI_LOW_MALLOC(sizeof(*sap)); 637 if (sap == NULL) 638 return ENOMEM; 639 splp = SCSI_LOW_MALLOC(sizeof(*splp)); 640 if (splp == NULL) 641 { 642 SCSI_LOW_FREE(sap); 643 return ENOMEM; 644 } 645 646 SCSI_LOW_BZERO(sap, sizeof(*sap)); 647 SCSI_LOW_BZERO(splp, sizeof(*splp)); 648 649 sap->scsipi_cmd = scsi_low_scsi_cmd_xs; 650 sap->scsipi_minphys = scsi_low_scsi_minphys_xs; 651 sap->scsipi_enable = scsi_low_enable_xs; 652 sap->scsipi_ioctl = scsi_low_ioctl_xs; 653#ifdef SCSI_LOW_TARGET_OPEN 654 sap->open_target_lu = scsi_low_target_open; 655#endif /* SCSI_LOW_TARGET_OPEN */ 656 657 splp->adapter_softc = slp; 658 splp->scsipi_scsi.adapter_target = slp->sl_hostid; 659 splp->scsipi_scsi.max_target = slp->sl_ntargs - 1; 660 splp->scsipi_scsi.max_lun = slp->sl_nluns - 1; 661 splp->scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE; 662 splp->openings = slp->sl_openings; 663 splp->type = BUS_SCSI; 664 splp->adapter_softc = slp; 665 splp->adapter = sap; 666 splp->device = &scsi_low_dev; 667 668 slp->sl_si.si_splp = splp; 669 slp->sl_show_result = SHOW_ALL_NEG; 670 return 0; 671} 672 673static int 674scsi_low_world_start_xs(slp) 675 struct scsi_low_softc *slp; 676{ 677 678 return 0; 679} 680 681static int 682scsi_low_dettach_xs(slp) 683 struct scsi_low_softc *slp; 684{ 685 686 /* 687 * scsipi does not have dettach bus fucntion. 688 * 689 scsipi_dettach_scsibus(slp->sl_si.si_splp); 690 */ 691 return 0; 692} 693 694static int 695scsi_low_ccb_setup_xs(slp, cb) 696 struct scsi_low_softc *slp; 697 struct slccb *cb; 698{ 699 struct scsipi_xfer *xs = (struct scsipi_xfer *) cb->osdep; 700 701 if ((cb->ccb_flags & CCB_SCSIIO) != 0) 702 { 703 cb->ccb_scp.scp_cmd = (u_int8_t *) xs->cmd; 704 cb->ccb_scp.scp_cmdlen = xs->cmdlen; 705 cb->ccb_scp.scp_data = xs->data; 706 cb->ccb_scp.scp_datalen = xs->datalen; 707 cb->ccb_scp.scp_direction = (xs->flags & SCSI_DATA_OUT) ? 708 SCSI_LOW_WRITE : SCSI_LOW_READ; 709 cb->ccb_tcmax = xs->timeout / 1000; 710 } 711 else 712 { 713 scsi_low_unit_ready_cmd(cb); 714 } 715 return SCSI_LOW_START_QTAG; 716} 717 718static int 719scsi_low_done_xs(slp, cb) 720 struct scsi_low_softc *slp; 721 struct slccb *cb; 722{ 723 struct scsipi_xfer *xs; 724 725 xs = (struct scsipi_xfer *) cb->osdep; 726 if (cb->ccb_error == 0) 727 { 728 xs->error = XS_NOERROR; 729 xs->resid = 0; 730 } 731 else 732 { 733 if (cb->ccb_rcnt >= slp->sl_max_retry) 734 cb->ccb_error |= ABORTIO; 735 736 if ((cb->ccb_flags & CCB_NORETRY) == 0 && 737 (cb->ccb_error & ABORTIO) == 0) 738 return EJUSTRETURN; 739 740 if ((cb->ccb_error & SENSEIO) != 0) 741 { 742 xs->sense.scsi_sense = cb->ccb_sense; 743 } 744 745 xs->error = scsi_low_translate_error_code(cb, 746 &scsi_low_error_code_xs[0]); 747 748#ifdef SCSI_LOW_DIAGNOSTIC 749 if ((cb->ccb_flags & CCB_SILENT) == 0 && 750 cb->ccb_scp.scp_cmdlen > 0 && 751 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & 752 SCSI_LOW_CMD_ABORT_WARNING) != 0) 753 { 754 printf("%s: WARNING: scsi_low IO abort\n", 755 slp->sl_xname); 756 scsi_low_print(slp, NULL); 757 } 758#endif /* SCSI_LOW_DIAGNOSTIC */ 759 } 760 761 if (cb->ccb_scp.scp_status == ST_UNKNOWN) 762 xs->status = 0; /* XXX */ 763 else 764 xs->status = cb->ccb_scp.scp_status; 765 766 xs->flags |= ITSDONE; 767 if ((cb->ccb_flags & CCB_NOSDONE) == 0) 768 scsipi_done(xs); 769 770 return 0; 771} 772 773static void 774scsi_low_timeout_xs(slp, ch, action) 775 struct scsi_low_softc *slp; 776 int ch; 777 int action; 778{ 779 780 switch (ch) 781 { 782 case SCSI_LOW_TIMEOUT_CH_IO: 783 switch (action) 784 { 785 case SCSI_LOW_TIMEOUT_START: 786 timeout(scsi_low_timeout, slp, 787 hz / SCSI_LOW_TIMEOUT_HZ); 788 break; 789 case SCSI_LOW_TIMEOUT_STOP: 790 untimeout(scsi_low_timeout, slp); 791 break; 792 } 793 break; 794 795 case SCSI_LOW_TIMEOUT_CH_ENGAGE: 796 switch (action) 797 { 798 case SCSI_LOW_TIMEOUT_START: 799 timeout(scsi_low_engage, slp, 1); 800 break; 801 case SCSI_LOW_TIMEOUT_STOP: 802 untimeout(scsi_low_engage, slp); 803 break; 804 } 805 break; 806 807 case SCSI_LOW_TIMEOUT_CH_RECOVER: 808 break; 809 } 810} 811 812u_int 813scsi_low_translate_quirks_xs(quirks) 814 u_int quirks; 815{ 816 u_int flags; 817 818 flags = SCSI_LOW_DISK_LFLAGS | SCSI_LOW_DISK_TFLAGS; 819 820#ifdef SDEV_NODISC 821 if (quirks & SDEV_NODISC) 822 flags &= ~SCSI_LOW_DISK_DISC; 823#endif /* SDEV_NODISC */ 824#ifdef SDEV_NOPARITY 825 if (quirks & SDEV_NOPARITY) 826 flags &= ~SCSI_LOW_DISK_PARITY; 827#endif /* SDEV_NOPARITY */ 828#ifdef SDEV_NOCMDLNK 829 if (quirks & SDEV_NOCMDLNK) 830 flags &= ~SCSI_LOW_DISK_LINK; 831#endif /* SDEV_NOCMDLNK */ 832#ifdef SDEV_NOTAG 833 if (quirks & SDEV_NOTAG) 834 flags &= ~SCSI_LOW_DISK_QTAG; 835#endif /* SDEV_NOTAG */ 836#ifdef SDEV_NOSYNC 837 if (quirks & SDEV_NOSYNC) 838 flags &= ~SCSI_LOW_DISK_SYNC; 839#endif /* SDEV_NOSYNC */ 840 841 return flags; 842} 843 844static void 845scsi_low_setup_quirks_xs(ti, li, flags) 846 struct targ_info *ti; 847 struct lun_info *li; 848 u_int flags; 849{ 850 u_int quirks; 851 852 li->li_sloi.sloi_quirks = flags; 853 quirks = scsi_low_translate_quirks_xs(flags); 854 ti->ti_quirks = quirks & SCSI_LOW_DISK_TFLAGS; 855 li->li_quirks = quirks & SCSI_LOW_DISK_LFLAGS; 856 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID; 857 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID; 858 scsi_low_calcf_target(ti); 859 scsi_low_calcf_lun(li); 860 scsi_low_calcf_show(li); 861} 862 863#ifdef SCSI_LOW_TARGET_OPEN 864static int 865scsi_low_target_open(link, cf) 866 struct scsipi_link *link; 867 struct cfdata *cf; 868{ 869 u_int target = link->scsipi_scsi.target; 870 u_int lun = link->scsipi_scsi.lun; 871 struct scsi_low_softc *slp; 872 struct targ_info *ti; 873 struct lun_info *li; 874 875 slp = (struct scsi_low_softc *) link->adapter_softc; 876 ti = slp->sl_ti[target]; 877 li = scsi_low_alloc_li(ti, lun, 0); 878 if (li == NULL) 879 return 0; 880 881 li->li_cfgflags = cf->cf_flags; 882 scsi_low_setup_quirks_xs(ti, li, (u_int) link->quirks); 883 return 0; 884} 885#endif /* SCSI_LOW_TARGET_OPEN */ 886 887#endif /* SCSI_LOW_INTERFACE_XS */ 888 889#ifdef SCSI_LOW_INTERFACE_CAM 890/************************************************************** 891 * SCSI INTERFACE (CAM) 892 **************************************************************/ 893#define SCSI_LOW_MALLOC(size) malloc((size), M_SCSILOW, M_NOWAIT) 894#define SCSI_LOW_FREE(pt) free((pt), M_SCSILOW) 895#define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb() 896 897static void scsi_low_poll_cam(struct cam_sim *);
|
1381 return 0; 1382} 1383 1384static int 1385scsi_low_dettach_cam(slp) 1386 struct scsi_low_softc *slp; 1387{ 1388 1389 xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL); 1390 xpt_free_path(slp->sl_si.path); 1391 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim)); 1392 cam_sim_free(slp->sl_si.sim, /* free_devq */ TRUE); 1393 return 0; 1394} 1395 1396static int 1397scsi_low_ccb_setup_cam(slp, cb) 1398 struct scsi_low_softc *slp; 1399 struct slccb *cb; 1400{ 1401 union ccb *ccb = (union ccb *) cb->osdep; 1402 1403 if ((cb->ccb_flags & CCB_SCSIIO) != 0) 1404 { 1405 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes; 1406 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len; 1407 cb->ccb_scp.scp_data = ccb->csio.data_ptr; 1408 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len; 1409 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) 1410 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE; 1411 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */ 1412 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 1413 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000; 1414 } 1415 else 1416 { 1417 scsi_low_unit_ready_cmd(cb); 1418 } 1419 return SCSI_LOW_START_QTAG; 1420} 1421 1422static int 1423scsi_low_done_cam(slp, cb) 1424 struct scsi_low_softc *slp; 1425 struct slccb *cb; 1426{ 1427 union ccb *ccb; 1428 1429 ccb = (union ccb *) cb->osdep; 1430 if (cb->ccb_error == 0) 1431 { 1432 ccb->ccb_h.status = CAM_REQ_CMP; 1433 ccb->csio.resid = 0; 1434 } 1435 else 1436 { 1437 if (cb->ccb_rcnt >= slp->sl_max_retry) 1438 cb->ccb_error |= ABORTIO; 1439 1440 if ((cb->ccb_flags & CCB_NORETRY) == 0 && 1441 (cb->ccb_error & ABORTIO) == 0) 1442 return EJUSTRETURN; 1443 1444 if ((cb->ccb_error & SENSEIO) != 0) 1445 { 1446 memcpy(&ccb->csio.sense_data, 1447 &cb->ccb_sense, 1448 sizeof(ccb->csio.sense_data)); 1449 } 1450 1451 ccb->ccb_h.status = scsi_low_translate_error_code(cb, 1452 &scsi_low_error_code_cam[0]); 1453 1454#ifdef SCSI_LOW_DIAGNOSTIC 1455 if ((cb->ccb_flags & CCB_SILENT) == 0 && 1456 cb->ccb_scp.scp_cmdlen > 0 && 1457 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & 1458 SCSI_LOW_CMD_ABORT_WARNING) != 0) 1459 { 1460 printf("%s: WARNING: scsi_low IO abort\n", 1461 slp->sl_xname); 1462 scsi_low_print(slp, NULL); 1463 } 1464#endif /* SCSI_LOW_DIAGNOSTIC */ 1465 } 1466 1467 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0) 1468 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; 1469 1470 if (cb->ccb_scp.scp_status == ST_UNKNOWN) 1471 ccb->csio.scsi_status = 0; /* XXX */ 1472 else 1473 ccb->csio.scsi_status = cb->ccb_scp.scp_status; 1474 1475 if ((cb->ccb_flags & CCB_NOSDONE) == 0) 1476 xpt_done(ccb); 1477 return 0; 1478} 1479 1480static void 1481scsi_low_timeout_cam(slp, ch, action) 1482 struct scsi_low_softc *slp; 1483 int ch; 1484 int action; 1485{ 1486 1487 switch (ch) 1488 { 1489 case SCSI_LOW_TIMEOUT_CH_IO: 1490 switch (action) 1491 { 1492 case SCSI_LOW_TIMEOUT_START: 1493 slp->sl_si.timeout_ch = timeout(scsi_low_timeout, slp, 1494 hz / SCSI_LOW_TIMEOUT_HZ); 1495 break; 1496 case SCSI_LOW_TIMEOUT_STOP: 1497 untimeout(scsi_low_timeout, slp, slp->sl_si.timeout_ch); 1498 break; 1499 } 1500 break; 1501 1502 case SCSI_LOW_TIMEOUT_CH_ENGAGE: 1503 switch (action) 1504 { 1505 case SCSI_LOW_TIMEOUT_START: 1506 slp->sl_si.engage_ch = timeout(scsi_low_engage, slp, 1); 1507 break; 1508 case SCSI_LOW_TIMEOUT_STOP: 1509 untimeout(scsi_low_engage, slp, slp->sl_si.engage_ch); 1510 break; 1511 } 1512 break; 1513 case SCSI_LOW_TIMEOUT_CH_RECOVER: 1514 break; 1515 } 1516} 1517 1518#endif /* SCSI_LOW_INTERFACE_CAM */ 1519 1520/*============================================================= 1521 * END OF OS switch (All OS depend fucntions should be above) 1522 =============================================================*/ 1523 1524/************************************************************** 1525 * scsi low deactivate and activate 1526 **************************************************************/ 1527int 1528scsi_low_is_busy(slp) 1529 struct scsi_low_softc *slp; 1530{ 1531 1532 if (slp->sl_nio > 0) 1533 return EBUSY; 1534 return 0; 1535} 1536 1537int 1538scsi_low_deactivate(slp) 1539 struct scsi_low_softc *slp; 1540{ 1541 int s; 1542 1543 s = SCSI_LOW_SPLSCSI(); 1544 slp->sl_flags |= HW_INACTIVE; 1545 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 1546 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP); 1547 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 1548 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP); 1549 splx(s); 1550 return 0; 1551} 1552 1553int 1554scsi_low_activate(slp) 1555 struct scsi_low_softc *slp; 1556{ 1557 int error, s; 1558 1559 s = SCSI_LOW_SPLSCSI(); 1560 slp->sl_flags &= ~HW_INACTIVE; 1561 if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0) 1562 { 1563 slp->sl_flags |= HW_INACTIVE; 1564 splx(s); 1565 return error; 1566 } 1567 1568 slp->sl_timeout_count = 0; 1569 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 1570 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); 1571 splx(s); 1572 return 0; 1573} 1574 1575/************************************************************** 1576 * scsi low log 1577 **************************************************************/ 1578#ifdef SCSI_LOW_DIAGNOSTIC 1579static void scsi_low_msg_log_init(struct scsi_low_msg_log *); 1580static void scsi_low_msg_log_write(struct scsi_low_msg_log *, u_int8_t *, int); 1581static void scsi_low_msg_log_show(struct scsi_low_msg_log *, char *, int); 1582 1583static void 1584scsi_low_msg_log_init(slmlp) 1585 struct scsi_low_msg_log *slmlp; 1586{ 1587 1588 slmlp->slml_ptr = 0; 1589} 1590 1591static void 1592scsi_low_msg_log_write(slmlp, datap, len) 1593 struct scsi_low_msg_log *slmlp; 1594 u_int8_t *datap; 1595 int len; 1596{ 1597 int ptr, ind; 1598 1599 if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN) 1600 return; 1601 1602 ptr = slmlp->slml_ptr ++; 1603 for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++) 1604 slmlp->slml_msg[ptr].msg[ind] = datap[ind]; 1605 for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++) 1606 slmlp->slml_msg[ptr].msg[ind] = 0; 1607} 1608 1609static void 1610scsi_low_msg_log_show(slmlp, s, len) 1611 struct scsi_low_msg_log *slmlp; 1612 char *s; 1613 int len; 1614{ 1615 int ptr, ind; 1616 1617 printf("%s: (%d) ", s, slmlp->slml_ptr); 1618 for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++) 1619 { 1620 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]); 1621 ind ++) 1622 { 1623 printf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]); 1624 } 1625 printf(">"); 1626 } 1627 printf("\n"); 1628} 1629#endif /* SCSI_LOW_DIAGNOSTIC */ 1630 1631/************************************************************** 1632 * power control 1633 **************************************************************/ 1634static void 1635scsi_low_engage(arg) 1636 void *arg; 1637{ 1638 struct scsi_low_softc *slp = arg; 1639 int s = SCSI_LOW_SPLSCSI(); 1640 1641 switch (slp->sl_rstep) 1642 { 1643 case 0: 1644 slp->sl_rstep ++; 1645 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE); 1646 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp, 1647 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START); 1648 break; 1649 1650 case 1: 1651 slp->sl_rstep ++; 1652 slp->sl_flags &= ~HW_RESUME; 1653 scsi_low_start(slp); 1654 break; 1655 1656 case 2: 1657 break; 1658 } 1659 splx(s); 1660} 1661 1662static int 1663scsi_low_init(slp, flags) 1664 struct scsi_low_softc *slp; 1665 u_int flags; 1666{ 1667 int rv = 0; 1668 1669 slp->sl_flags |= HW_INITIALIZING; 1670 1671 /* clear power control timeout */ 1672 if ((slp->sl_flags & HW_POWERCTRL) != 0) 1673 { 1674 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp, 1675 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP); 1676 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME); 1677 slp->sl_active = 1; 1678 slp->sl_powc = SCSI_LOW_POWDOWN_TC; 1679 } 1680 1681 /* reset current nexus */ 1682 scsi_low_reset_nexus(slp, flags); 1683 if ((slp->sl_flags & HW_INACTIVE) != 0) 1684 { 1685 rv = EBUSY; 1686 goto out; 1687 } 1688 1689 if (flags != SCSI_LOW_RESTART_SOFT) 1690 { 1691 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags)); 1692 } 1693 1694out: 1695 slp->sl_flags &= ~HW_INITIALIZING; 1696 return rv; 1697} 1698 1699/************************************************************** 1700 * allocate lun_info 1701 **************************************************************/ 1702static struct lun_info * 1703scsi_low_alloc_li(ti, lun, alloc) 1704 struct targ_info *ti; 1705 int lun; 1706 int alloc; 1707{ 1708 struct scsi_low_softc *slp = ti->ti_sc; 1709 struct lun_info *li; 1710 1711 li = LIST_FIRST(&ti->ti_litab); 1712 if (li != NULL) 1713 { 1714 if (li->li_lun == lun) 1715 return li; 1716 1717 while ((li = LIST_NEXT(li, lun_chain)) != NULL) 1718 { 1719 if (li->li_lun == lun) 1720 { 1721 LIST_REMOVE(li, lun_chain); 1722 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain); 1723 return li; 1724 } 1725 } 1726 } 1727 1728 if (alloc == 0) 1729 return li; 1730 1731 li = SCSI_LOW_MALLOC(ti->ti_lunsize); 1732 if (li == NULL) 1733 panic("no lun info mem"); 1734 1735 SCSI_LOW_BZERO(li, ti->ti_lunsize); 1736 li->li_lun = lun; 1737 li->li_ti = ti; 1738 1739 li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC | 1740 SCSI_LOW_QTAG; 1741 li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS; 1742 li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID; 1743#ifdef SCSI_LOW_FLAGS_QUIRKS_OK 1744 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID; 1745#endif /* SCSI_LOW_FLAGS_QUIRKS_OK */ 1746 1747 li->li_qtagbits = (u_int) -1; 1748 1749 TAILQ_INIT(&li->li_discq); 1750 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain); 1751 1752 /* host specific structure initialization per lun */ 1753 if (slp->sl_funcs->scsi_low_lun_init != NULL) 1754 (*slp->sl_funcs->scsi_low_lun_init) 1755 (slp, ti, li, SCSI_LOW_INFO_ALLOC); 1756 scsi_low_calcf_lun(li); 1757 return li; 1758} 1759 1760/************************************************************** 1761 * allocate targ_info 1762 **************************************************************/ 1763static struct targ_info * 1764scsi_low_alloc_ti(slp, targ) 1765 struct scsi_low_softc *slp; 1766 int targ; 1767{ 1768 struct targ_info *ti; 1769 1770 if (TAILQ_FIRST(&slp->sl_titab) == NULL) 1771 TAILQ_INIT(&slp->sl_titab); 1772 1773 ti = SCSI_LOW_MALLOC(slp->sl_targsize); 1774 if (ti == NULL) 1775 panic("%s short of memory", slp->sl_xname); 1776 1777 SCSI_LOW_BZERO(ti, slp->sl_targsize); 1778 ti->ti_id = targ; 1779 ti->ti_sc = slp; 1780 1781 slp->sl_ti[targ] = ti; 1782 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain); 1783 LIST_INIT(&ti->ti_litab); 1784 1785 ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS; 1786 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8; 1787 ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID; 1788#ifdef SCSI_LOW_FLAGS_QUIRKS_OK 1789 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID; 1790#endif /* SCSI_LOW_FLAGS_QUIRKS_OK */ 1791 1792 if (slp->sl_funcs->scsi_low_targ_init != NULL) 1793 { 1794 (*slp->sl_funcs->scsi_low_targ_init) 1795 (slp, ti, SCSI_LOW_INFO_ALLOC); 1796 } 1797 scsi_low_calcf_target(ti); 1798 return ti; 1799} 1800 1801static void 1802scsi_low_free_ti(slp) 1803 struct scsi_low_softc *slp; 1804{ 1805 struct targ_info *ti, *tib; 1806 struct lun_info *li, *nli; 1807 1808 for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib) 1809 { 1810 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli) 1811 { 1812 if (slp->sl_funcs->scsi_low_lun_init != NULL) 1813 { 1814 (*slp->sl_funcs->scsi_low_lun_init) 1815 (slp, ti, li, SCSI_LOW_INFO_DEALLOC); 1816 } 1817 nli = LIST_NEXT(li, lun_chain); 1818 SCSI_LOW_FREE(li); 1819 } 1820 1821 if (slp->sl_funcs->scsi_low_targ_init != NULL) 1822 { 1823 (*slp->sl_funcs->scsi_low_targ_init) 1824 (slp, ti, SCSI_LOW_INFO_DEALLOC); 1825 } 1826 tib = TAILQ_NEXT(ti, ti_chain); 1827 SCSI_LOW_FREE(ti); 1828 } 1829} 1830 1831/************************************************************** 1832 * timeout 1833 **************************************************************/ 1834void 1835scsi_low_bus_idle(slp) 1836 struct scsi_low_softc *slp; 1837{ 1838 1839 slp->sl_retry_sel = 0; 1840 if (slp->sl_Tnexus == NULL) 1841 scsi_low_start(slp); 1842} 1843 1844static void 1845scsi_low_timeout(arg) 1846 void *arg; 1847{ 1848 struct scsi_low_softc *slp = arg; 1849 int s; 1850 1851 s = SCSI_LOW_SPLSCSI(); 1852 (void) scsi_low_timeout_check(slp); 1853 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 1854 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); 1855 splx(s); 1856} 1857 1858static int 1859scsi_low_timeout_check(slp) 1860 struct scsi_low_softc *slp; 1861{ 1862 struct targ_info *ti; 1863 struct lun_info *li; 1864 struct slccb *cb = NULL; /* XXX */ 1865 1866 /* selection restart */ 1867 if (slp->sl_retry_sel != 0) 1868 { 1869 slp->sl_retry_sel = 0; 1870 if (slp->sl_Tnexus != NULL) 1871 goto step1; 1872 1873 cb = TAILQ_FIRST(&slp->sl_start); 1874 if (cb == NULL) 1875 goto step1; 1876 1877 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY) 1878 { 1879 cb->ccb_flags |= CCB_NORETRY; 1880 cb->ccb_error |= SELTIMEOUTIO; 1881 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL) 1882 panic("%s: ccb not finished", slp->sl_xname); 1883 } 1884 1885 if (slp->sl_Tnexus == NULL) 1886 scsi_low_start(slp); 1887 } 1888 1889 /* call hardware timeout */ 1890step1: 1891 if (slp->sl_funcs->scsi_low_timeout != NULL) 1892 { 1893 (*slp->sl_funcs->scsi_low_timeout) (slp); 1894 } 1895 1896 if (slp->sl_timeout_count ++ < 1897 SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ) 1898 return 0; 1899 1900 slp->sl_timeout_count = 0; 1901 if (slp->sl_nio > 0) 1902 { 1903 if ((cb = slp->sl_Qnexus) != NULL) 1904 { 1905 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL; 1906 if (cb->ccb_tc < 0) 1907 goto bus_reset; 1908 } 1909 else if (slp->sl_disc == 0) 1910 { 1911 if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL) 1912 return 0; 1913 1914 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL; 1915 if (cb->ccb_tc < 0) 1916 goto bus_reset; 1917 } 1918 else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL; 1919 ti = TAILQ_NEXT(ti, ti_chain)) 1920 { 1921 if (ti->ti_disc == 0) 1922 continue; 1923 1924 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; 1925 li = LIST_NEXT(li, lun_chain)) 1926 { 1927 for (cb = TAILQ_FIRST(&li->li_discq); 1928 cb != NULL; 1929 cb = TAILQ_NEXT(cb, ccb_chain)) 1930 { 1931 cb->ccb_tc -= 1932 SCSI_LOW_TIMEOUT_CHECK_INTERVAL; 1933 if (cb->ccb_tc < 0) 1934 goto bus_reset; 1935 } 1936 } 1937 } 1938 1939 } 1940 else if ((slp->sl_flags & HW_POWERCTRL) != 0) 1941 { 1942 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0) 1943 return 0; 1944 1945 if (slp->sl_active != 0) 1946 { 1947 slp->sl_powc = SCSI_LOW_POWDOWN_TC; 1948 slp->sl_active = 0; 1949 return 0; 1950 } 1951 1952 slp->sl_powc --; 1953 if (slp->sl_powc < 0) 1954 { 1955 slp->sl_powc = SCSI_LOW_POWDOWN_TC; 1956 slp->sl_flags |= HW_POWDOWN; 1957 (*slp->sl_funcs->scsi_low_power) 1958 (slp, SCSI_LOW_POWDOWN); 1959 } 1960 } 1961 return 0; 1962 1963bus_reset: 1964 cb->ccb_error |= TIMEOUTIO; 1965 printf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb); 1966 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover."); 1967 scsi_low_init(slp, SCSI_LOW_RESTART_HARD); 1968 scsi_low_start(slp); 1969 return ERESTART; 1970} 1971 1972 1973static int 1974scsi_low_abort_ccb(slp, cb) 1975 struct scsi_low_softc *slp; 1976 struct slccb *cb; 1977{ 1978 struct targ_info *ti; 1979 struct lun_info *li; 1980 u_int msg; 1981 1982 if (cb == NULL) 1983 return EINVAL; 1984 if ((cb->ccb_omsgoutflag & 1985 (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0) 1986 return EBUSY; 1987 1988 ti = cb->ti; 1989 li = cb->li; 1990 if (cb->ccb_tag == SCSI_LOW_UNKTAG) 1991 msg = SCSI_LOW_MSG_ABORT; 1992 else 1993 msg = SCSI_LOW_MSG_ABORT_QTAG; 1994 1995 cb->ccb_error |= ABORTIO; 1996 cb->ccb_flags |= CCB_NORETRY; 1997 scsi_low_ccb_message_assert(cb, msg); 1998 1999 if (cb == slp->sl_Qnexus) 2000 { 2001 scsi_low_assert_msg(slp, ti, msg, 1); 2002 } 2003 else if ((cb->ccb_flags & CCB_DISCQ) != 0) 2004 { 2005 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL) 2006 panic("%s: revoked ccb done", slp->sl_xname); 2007 2008 cb->ccb_flags |= CCB_STARTQ; 2009 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 2010 2011 if (slp->sl_Tnexus == NULL) 2012 scsi_low_start(slp); 2013 } 2014 else 2015 { 2016 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL) 2017 panic("%s: revoked ccb retried", slp->sl_xname); 2018 } 2019 return 0; 2020} 2021 2022/************************************************************** 2023 * Generic SCSI INTERFACE 2024 **************************************************************/ 2025int 2026scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize) 2027 struct scsi_low_softc *slp; 2028 int openings, ntargs, nluns, targsize, lunsize; 2029{ 2030 struct targ_info *ti; 2031 struct lun_info *li; 2032 int s, i, nccb, rv; 2033 2034#ifdef SCSI_LOW_INTERFACE_XS 2035 slp->sl_osdep_fp = &scsi_low_osdep_funcs_xs; 2036#endif /* SCSI_LOW_INTERFACE_XS */ 2037#ifdef SCSI_LOW_INTERFACE_CAM 2038 slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam; 2039#endif /* SCSI_LOW_INTERFACE_CAM */ 2040 2041 if (slp->sl_osdep_fp == NULL) 2042 panic("scsi_low: interface not spcified"); 2043 2044 if (ntargs > SCSI_LOW_NTARGETS) 2045 { 2046 printf("scsi_low: %d targets are too large\n", ntargs); 2047 printf("change kernel options SCSI_LOW_NTARGETS"); 2048 return EINVAL; 2049 } 2050 2051 if (openings <= 0) 2052 slp->sl_openings = (SCSI_LOW_NCCB / ntargs); 2053 else 2054 slp->sl_openings = openings; 2055 slp->sl_ntargs = ntargs; 2056 slp->sl_nluns = nluns; 2057 slp->sl_max_retry = SCSI_LOW_MAX_RETRY; 2058 2059 if (lunsize < sizeof(struct lun_info)) 2060 lunsize = sizeof(struct lun_info); 2061 2062 if (targsize < sizeof(struct targ_info)) 2063 targsize = sizeof(struct targ_info); 2064 2065 slp->sl_targsize = targsize; 2066 for (i = 0; i < ntargs; i ++) 2067 { 2068 ti = scsi_low_alloc_ti(slp, i); 2069 ti->ti_lunsize = lunsize; 2070 li = scsi_low_alloc_li(ti, 0, 1); 2071 } 2072 2073 /* initialize queue */ 2074 nccb = openings * ntargs; 2075 if (nccb >= SCSI_LOW_NCCB || nccb <= 0) 2076 nccb = SCSI_LOW_NCCB; 2077 scsi_low_init_ccbque(nccb); 2078 TAILQ_INIT(&slp->sl_start); 2079 2080 /* call os depend attach */ 2081 s = SCSI_LOW_SPLSCSI(); 2082 rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp); 2083 if (rv != 0) 2084 { 2085 splx(s); 2086 printf("%s: scsi_low_attach: osdep attach failed\n", 2087 slp->sl_xname); 2088 return EINVAL; 2089 } 2090 2091 /* check hardware */ 2092 SCSI_LOW_DELAY(1000); /* wait for 1ms */ 2093 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0) 2094 { 2095 splx(s); 2096 printf("%s: scsi_low_attach: initialization failed\n", 2097 slp->sl_xname); 2098 return EINVAL; 2099 } 2100 2101 /* start watch dog */ 2102 slp->sl_timeout_count = 0; 2103 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 2104 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); 2105 LIST_INSERT_HEAD(&sl_tab, slp, sl_chain); 2106 2107 /* fake call */ 2108 scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL)); 2109 2110#ifdef SCSI_LOW_START_UP_CHECK 2111 /* probing devices */ 2112 scsi_low_start_up(slp); 2113#endif /* SCSI_LOW_START_UP_CHECK */ 2114 2115 /* call os depend attach done*/ 2116 (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp); 2117 splx(s); 2118 return 0; 2119} 2120 2121int 2122scsi_low_dettach(slp) 2123 struct scsi_low_softc *slp; 2124{ 2125 int s, rv; 2126 2127 s = SCSI_LOW_SPLSCSI(); 2128 if (scsi_low_is_busy(slp) != 0) 2129 { 2130 splx(s); 2131 return EBUSY; 2132 } 2133 2134 scsi_low_deactivate(slp); 2135 2136 rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp); 2137 if (rv != 0) 2138 { 2139 splx(s); 2140 return EBUSY; 2141 } 2142 2143 scsi_low_free_ti(slp); 2144 LIST_REMOVE(slp, sl_chain); 2145 splx(s); 2146 return 0; 2147} 2148 2149/************************************************************** 2150 * Generic enqueue 2151 **************************************************************/ 2152static int 2153scsi_low_enqueue(slp, ti, li, cb, flags, msg) 2154 struct scsi_low_softc *slp; 2155 struct targ_info *ti; 2156 struct lun_info *li; 2157 struct slccb *cb; 2158 u_int flags, msg; 2159{ 2160 2161 cb->ti = ti; 2162 cb->li = li; 2163 2164 scsi_low_ccb_message_assert(cb, msg); 2165 2166 cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG; 2167 scsi_low_alloc_qtag(cb); 2168 2169 cb->ccb_flags = flags | CCB_STARTQ; 2170 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 2171 cb->ccb_error |= PENDINGIO; 2172 2173 if ((flags & CCB_URGENT) != 0) 2174 { 2175 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 2176 } 2177 else 2178 { 2179 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain); 2180 } 2181 2182 slp->sl_nio ++; 2183 2184 if (slp->sl_Tnexus == NULL) 2185 scsi_low_start(slp); 2186 return 0; 2187} 2188 2189static int 2190scsi_low_message_enqueue(slp, ti, li, flags) 2191 struct scsi_low_softc *slp; 2192 struct targ_info *ti; 2193 struct lun_info *li; 2194 u_int flags; 2195{ 2196 struct slccb *cb; 2197 u_int tmsgflags; 2198 2199 tmsgflags = ti->ti_setup_msg; 2200 ti->ti_setup_msg = 0; 2201 2202 flags |= CCB_NORETRY; 2203 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL) 2204 return ENOMEM; 2205 2206 cb->osdep = NULL; 2207 cb->bp = NULL; 2208 scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags); 2209 return 0; 2210} 2211 2212/************************************************************** 2213 * Generic Start & Done 2214 **************************************************************/ 2215#define SLSC_MODE_SENSE_SHORT 0x1a 2216static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0}; 2217static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0, 2218 sizeof(struct scsi_low_mode_sense_data), 0}; 2219static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0, 2220 sizeof(struct scsi_low_inq_data), 0}; 2221static u_int8_t unit_ready_cmd[6]; 2222static int scsi_low_setup_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *); 2223static int scsi_low_sense_abort_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *); 2224static int scsi_low_resume(struct scsi_low_softc *); 2225 2226static void 2227scsi_low_unit_ready_cmd(cb) 2228 struct slccb *cb; 2229{ 2230 2231 cb->ccb_scp.scp_cmd = unit_ready_cmd; 2232 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd); 2233 cb->ccb_scp.scp_datalen = 0; 2234 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2235 cb->ccb_tcmax = 15; 2236} 2237 2238static int 2239scsi_low_sense_abort_start(slp, ti, li, cb) 2240 struct scsi_low_softc *slp; 2241 struct targ_info *ti; 2242 struct lun_info *li; 2243 struct slccb *cb; 2244{ 2245 2246 cb->ccb_scp.scp_cmdlen = 6; 2247 SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen); 2248 cb->ccb_scsi_cmd[0] = REQUEST_SENSE; 2249 cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense); 2250 cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd; 2251 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense; 2252 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense); 2253 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2254 cb->ccb_tcmax = 15; 2255 scsi_low_ccb_message_clear(cb); 2256 if ((cb->ccb_flags & CCB_CLEARQ) != 0) 2257 { 2258 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 2259 } 2260 else 2261 { 2262 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense)); 2263#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE 2264 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0); 2265#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */ 2266 } 2267 2268 return SCSI_LOW_START_NO_QTAG; 2269} 2270 2271static int 2272scsi_low_setup_start(slp, ti, li, cb) 2273 struct scsi_low_softc *slp; 2274 struct targ_info *ti; 2275 struct lun_info *li; 2276 struct slccb *cb; 2277{ 2278 2279 switch(li->li_state) 2280 { 2281 case SCSI_LOW_LUN_SLEEP: 2282 scsi_low_unit_ready_cmd(cb); 2283 break; 2284 2285 case SCSI_LOW_LUN_START: 2286 cb->ccb_scp.scp_cmd = ss_cmd; 2287 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd); 2288 cb->ccb_scp.scp_datalen = 0; 2289 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2290 cb->ccb_tcmax = 30; 2291 break; 2292 2293 case SCSI_LOW_LUN_INQ: 2294 cb->ccb_scp.scp_cmd = inq_cmd; 2295 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd); 2296 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq; 2297 cb->ccb_scp.scp_datalen = sizeof(li->li_inq); 2298 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2299 cb->ccb_tcmax = 15; 2300 break; 2301 2302 case SCSI_LOW_LUN_MODEQ: 2303 cb->ccb_scp.scp_cmd = sms_cmd; 2304 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd); 2305 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms; 2306 cb->ccb_scp.scp_datalen = sizeof(li->li_sms); 2307 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2308 cb->ccb_tcmax = 15; 2309 return SCSI_LOW_START_QTAG; 2310 2311 default: 2312 panic("%s: no setup phase", slp->sl_xname); 2313 } 2314 2315 return SCSI_LOW_START_NO_QTAG; 2316} 2317 2318static int 2319scsi_low_resume(slp) 2320 struct scsi_low_softc *slp; 2321{ 2322 2323 if (slp->sl_flags & HW_RESUME) 2324 return EJUSTRETURN; 2325 slp->sl_flags &= ~HW_POWDOWN; 2326 if (slp->sl_funcs->scsi_low_power != NULL) 2327 { 2328 slp->sl_flags |= HW_RESUME; 2329 slp->sl_rstep = 0; 2330 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE); 2331 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 2332 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, 2333 SCSI_LOW_TIMEOUT_START); 2334 return EJUSTRETURN; 2335 } 2336 return 0; 2337} 2338 2339static void 2340scsi_low_start(slp) 2341 struct scsi_low_softc *slp; 2342{ 2343 struct targ_info *ti; 2344 struct lun_info *li; 2345 struct slccb *cb; 2346 int rv; 2347 2348 /* check hardware exists or under initializations ? */ 2349 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0) 2350 return; 2351 2352 /* check hardware power up ? */ 2353 if ((slp->sl_flags & HW_POWERCTRL) != 0) 2354 { 2355 slp->sl_active ++; 2356 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME)) 2357 { 2358 if (scsi_low_resume(slp) == EJUSTRETURN) 2359 return; 2360 } 2361 } 2362 2363 /* setup nexus */ 2364#ifdef SCSI_LOW_DIAGNOSTIC 2365 if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus) 2366 { 2367 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT"); 2368 panic("%s: inconsistent", slp->sl_xname); 2369 } 2370#endif /* SCSI_LOW_DIAGNOSTIC */ 2371 2372 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL; 2373 cb = TAILQ_NEXT(cb, ccb_chain)) 2374 { 2375 li = cb->li; 2376 2377 if (li->li_disc == 0) 2378 { 2379 goto scsi_low_cmd_start; 2380 } 2381 else if (li->li_nqio > 0) 2382 { 2383 if (li->li_nqio < li->li_maxnqio || 2384 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0) 2385 goto scsi_low_cmd_start; 2386 } 2387 } 2388 return; 2389 2390scsi_low_cmd_start: 2391 cb->ccb_flags &= ~CCB_STARTQ; 2392 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain); 2393 ti = cb->ti; 2394 2395 /* clear all error flag bits (for restart) */ 2396 cb->ccb_error = 0; 2397 cb->ccb_datalen = -1; 2398 cb->ccb_scp.scp_status = ST_UNKNOWN; 2399 2400 /* setup nexus pointer */ 2401 slp->sl_Qnexus = cb; 2402 slp->sl_Lnexus = li; 2403 slp->sl_Tnexus = ti; 2404 2405 /* initialize msgsys */ 2406 scsi_low_init_msgsys(slp, ti); 2407 2408 /* exec cmd */ 2409 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0) 2410 { 2411 /* CA state or forced abort */ 2412 rv = scsi_low_sense_abort_start(slp, ti, li, cb); 2413 } 2414 else if (li->li_state >= SCSI_LOW_LUN_OK) 2415 { 2416 cb->ccb_flags &= ~CCB_INTERNAL; 2417 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb); 2418 if (cb->ccb_msgoutflag != 0) 2419 { 2420 scsi_low_ccb_message_exec(slp, cb); 2421 } 2422 } 2423 else 2424 { 2425 cb->ccb_flags |= CCB_INTERNAL; 2426 rv = scsi_low_setup_start(slp, ti, li, cb); 2427 } 2428 2429 /* allocate qtag */ 2430#define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC) 2431 2432 if (rv == SCSI_LOW_START_QTAG && 2433 (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK && 2434 li->li_maxnqio > 0) 2435 { 2436 u_int qmsg; 2437 2438 scsi_low_activate_qtag(cb); 2439 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & 2440 SCSI_LOW_CMD_ORDERED_QTAG) != 0) 2441 qmsg = SCSI_LOW_MSG_ORDERED_QTAG; 2442 else if ((cb->ccb_flags & CCB_URGENT) != 0) 2443 qmsg = SCSI_LOW_MSG_HEAD_QTAG; 2444 else 2445 qmsg = SCSI_LOW_MSG_SIMPLE_QTAG; 2446 scsi_low_assert_msg(slp, ti, qmsg, 0); 2447 } 2448 2449 /* timeout */ 2450 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT) 2451 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 2452 cb->ccb_tc = cb->ccb_tcmax; 2453 2454 /* setup saved scsi data pointer */ 2455 cb->ccb_sscp = cb->ccb_scp; 2456 2457 /* setup current scsi pointer */ 2458 slp->sl_scp = cb->ccb_sscp; 2459 slp->sl_error = cb->ccb_error; 2460 2461 /* assert always an identify msg */ 2462 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0); 2463 2464 /* debug section */ 2465#ifdef SCSI_LOW_DIAGNOSTIC 2466 scsi_low_msg_log_init(&ti->ti_log_msgin); 2467 scsi_low_msg_log_init(&ti->ti_log_msgout); 2468#endif /* SCSI_LOW_DIAGNOSTIC */ 2469 2470 /* selection start */ 2471 slp->sl_selid = cb; 2472 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb)); 2473 if (rv == SCSI_LOW_START_OK) 2474 { 2475#ifdef SCSI_LOW_STATICS 2476 scsi_low_statics.nexus_win ++; 2477#endif /* SCSI_LOW_STATICS */ 2478 return; 2479 } 2480 2481 scsi_low_arbit_fail(slp, cb); 2482#ifdef SCSI_LOW_STATICS 2483 scsi_low_statics.nexus_fail ++; 2484#endif /* SCSI_LOW_STATICS */ 2485} 2486 2487void 2488scsi_low_arbit_fail(slp, cb) 2489 struct scsi_low_softc *slp; 2490 struct slccb *cb; 2491{ 2492 struct targ_info *ti = cb->ti; 2493 2494 scsi_low_deactivate_qtag(cb); 2495 scsi_low_ccb_message_retry(cb); 2496 cb->ccb_flags |= CCB_STARTQ; 2497 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 2498 2499 scsi_low_bus_release(slp, ti); 2500 2501 cb->ccb_selrcnt ++; 2502 if (slp->sl_disc == 0) 2503 { 2504#ifdef SCSI_LOW_DIAGNOSTIC 2505 printf("%s: try selection again\n", slp->sl_xname); 2506#endif /* SCSI_LOW_DIAGNOSTIC */ 2507 slp->sl_retry_sel = 1; 2508 } 2509} 2510 2511static void 2512scsi_low_bus_release(slp, ti) 2513 struct scsi_low_softc *slp; 2514 struct targ_info *ti; 2515{ 2516 2517 if (ti->ti_disc > 0) 2518 { 2519 SCSI_LOW_SETUP_PHASE(ti, PH_DISC); 2520 } 2521 else 2522 { 2523 SCSI_LOW_SETUP_PHASE(ti, PH_NULL); 2524 } 2525 2526 /* clear all nexus pointer */ 2527 slp->sl_Qnexus = NULL; 2528 slp->sl_Lnexus = NULL; 2529 slp->sl_Tnexus = NULL; 2530 2531 /* clear selection assert */ 2532 slp->sl_selid = NULL; 2533 2534 /* clear nexus data */ 2535 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK; 2536 2537 /* clear phase change counter */ 2538 slp->sl_ph_count = 0; 2539} 2540 2541static int 2542scsi_low_setup_done(slp, cb) 2543 struct scsi_low_softc *slp; 2544 struct slccb *cb; 2545{ 2546 struct targ_info *ti; 2547 struct lun_info *li; 2548 2549 ti = cb->ti; 2550 li = cb->li; 2551 2552 if (cb->ccb_rcnt >= slp->sl_max_retry) 2553 { 2554 cb->ccb_error |= ABORTIO; 2555 return SCSI_LOW_DONE_COMPLETE; 2556 } 2557 2558 /* XXX: special huck for selection timeout */ 2559 if (li->li_state == SCSI_LOW_LUN_SLEEP && 2560 (cb->ccb_error & SELTIMEOUTIO) != 0) 2561 { 2562 cb->ccb_error |= ABORTIO; 2563 return SCSI_LOW_DONE_COMPLETE; 2564 } 2565 2566 switch(li->li_state) 2567 { 2568 case SCSI_LOW_LUN_INQ: 2569 if (cb->ccb_error != 0) 2570 { 2571 li->li_diskflags &= 2572 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG); 2573 if (li->li_lun > 0) 2574 goto resume; 2575 ti->ti_diskflags &= 2576 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE); 2577 } 2578 else if ((li->li_inq.sd_version & 7) >= 2 || 2579 (li->li_inq.sd_len >= 4)) 2580 { 2581 if ((li->li_inq.sd_support & 0x2) == 0) 2582 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG; 2583 if ((li->li_inq.sd_support & 0x8) == 0) 2584 li->li_diskflags &= ~SCSI_LOW_DISK_LINK; 2585 if (li->li_lun > 0) 2586 goto resume; 2587 if ((li->li_inq.sd_support & 0x10) == 0) 2588 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC; 2589 if ((li->li_inq.sd_support & 0x20) == 0) 2590 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16; 2591 if ((li->li_inq.sd_support & 0x40) == 0) 2592 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32; 2593 } 2594 else 2595 { 2596 li->li_diskflags &= 2597 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK); 2598 if (li->li_lun > 0) 2599 goto resume; 2600 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE; 2601 } 2602 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID; 2603resume: 2604 scsi_low_calcf_target(ti); 2605 scsi_low_calcf_lun(li); 2606 break; 2607 2608 case SCSI_LOW_LUN_MODEQ: 2609 if (cb->ccb_error != 0) 2610 { 2611 if (cb->ccb_error & SENSEIO) 2612 { 2613#ifdef SCSI_LOW_DEBUG 2614 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE) 2615 { 2616 printf("SENSE: [%x][%x][%x][%x][%x]\n", 2617 (u_int) cb->ccb_sense.error_code, 2618 (u_int) cb->ccb_sense.segment, 2619 (u_int) cb->ccb_sense.flags, 2620 (u_int) cb->ccb_sense.add_sense_code, 2621 (u_int) cb->ccb_sense.add_sense_code_qual); 2622 } 2623#endif /* SCSI_LOW_DEBUG */ 2624 } 2625 else 2626 { 2627 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG; 2628 } 2629 } 2630 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a) 2631 { 2632 if (li->li_sms.sms_cmp.cmp_qc & 0x02) 2633 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR; 2634 else 2635 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR; 2636 if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0) 2637 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG; 2638 } 2639 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID; 2640 scsi_low_calcf_lun(li); 2641 break; 2642 2643 default: 2644 break; 2645 } 2646 2647 li->li_state ++; 2648 if (li->li_state == SCSI_LOW_LUN_OK) 2649 { 2650 scsi_low_calcf_target(ti); 2651 scsi_low_calcf_lun(li); 2652 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID && 2653 (slp->sl_show_result & SHOW_CALCF_RES) != 0) 2654 { 2655 scsi_low_calcf_show(li); 2656 } 2657 } 2658 2659 cb->ccb_rcnt --; 2660 return SCSI_LOW_DONE_RETRY; 2661} 2662 2663static int 2664scsi_low_done(slp, cb) 2665 struct scsi_low_softc *slp; 2666 struct slccb *cb; 2667{ 2668 int rv; 2669 2670 if (cb->ccb_error == 0) 2671 { 2672 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0) 2673 { 2674#ifdef SCSI_LOW_QCLEAR_AFTER_CA 2675 /* XXX: 2676 * SCSI-2 draft suggests 2677 * page 0x0a QErr bit determins if 2678 * the target aborts or continues 2679 * the queueing io's after CA state resolved. 2680 * However many targets seem not to support 2681 * the page 0x0a. Thus we should manually clear the 2682 * queuing io's after CA state. 2683 */ 2684 if ((cb->ccb_flags & CCB_CLEARQ) == 0) 2685 { 2686 cb->ccb_rcnt --; 2687 cb->ccb_flags |= CCB_CLEARQ; 2688 goto retry; 2689 } 2690#endif /* SCSI_LOW_QCLEAR_AFTER_CA */ 2691 2692 if ((cb->ccb_flags & CCB_SENSE) != 0) 2693 cb->ccb_error |= (SENSEIO | ABORTIO); 2694 cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ); 2695 } 2696 else switch (cb->ccb_sscp.scp_status) 2697 { 2698 case ST_GOOD: 2699 case ST_MET: 2700 case ST_INTERGOOD: 2701 case ST_INTERMET: 2702 if (cb->ccb_datalen == 0 || 2703 cb->ccb_scp.scp_datalen == 0) 2704 break; 2705 2706 if (cb->ccb_scp.scp_cmdlen > 0 && 2707 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & 2708 SCSI_LOW_CMD_RESIDUAL_CHK) == 0) 2709 break; 2710 2711 cb->ccb_error |= PDMAERR; 2712 break; 2713 2714 case ST_BUSY: 2715 case ST_QUEFULL: 2716 cb->ccb_error |= (BUSYERR | STATERR); 2717 break; 2718 2719 case ST_CONFLICT: 2720 cb->ccb_error |= (STATERR | ABORTIO); 2721 break; 2722 2723 case ST_CHKCOND: 2724 case ST_CMDTERM: 2725 if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL)) 2726 { 2727 cb->ccb_rcnt --; 2728 cb->ccb_flags |= CCB_SENSE; 2729 goto retry; 2730 } 2731 cb->ccb_error |= (UACAERR | STATERR | ABORTIO); 2732 break; 2733 2734 case ST_UNKNOWN: 2735 default: 2736 cb->ccb_error |= FATALIO; 2737 break; 2738 } 2739 } 2740 else 2741 { 2742 if (cb->ccb_flags & CCB_SENSE) 2743 { 2744 cb->ccb_error |= (SENSEERR | ABORTIO); 2745 } 2746 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE); 2747 } 2748 2749 /* internal ccb */ 2750 if ((cb->ccb_flags & CCB_INTERNAL) != 0) 2751 { 2752 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY) 2753 goto retry; 2754 } 2755 2756 /* check a ccb msgout flag */ 2757 if (cb->ccb_omsgoutflag != 0) 2758 { 2759#define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \ 2760 SCSI_LOW_MSG_ABORT_QTAG | \ 2761 SCSI_LOW_MSG_CLEAR_QTAG | \ 2762 SCSI_LOW_MSG_TERMIO) 2763 2764 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0) 2765 { 2766 cb->ccb_error |= ABORTIO; 2767 } 2768 } 2769 2770 /* call OS depend done */ 2771 if (cb->osdep != NULL) 2772 { 2773 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb); 2774 if (rv == EJUSTRETURN) 2775 goto retry; 2776 } 2777 else if (cb->ccb_error != 0) 2778 { 2779 if (cb->ccb_rcnt >= slp->sl_max_retry) 2780 cb->ccb_error |= ABORTIO; 2781 2782 if ((cb->ccb_flags & CCB_NORETRY) == 0 && 2783 (cb->ccb_error & ABORTIO) == 0) 2784 goto retry; 2785 } 2786 2787 /* free our target */ 2788#ifdef SCSI_LOW_DEBUG 2789 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0) 2790 { 2791 printf(">> SCSI_LOW_DONE_COMPLETE ===============\n"); 2792 scsi_low_print(slp, NULL); 2793 } 2794#endif /* SCSI_LOW_DEBUG */ 2795 2796 scsi_low_deactivate_qtag(cb); 2797 scsi_low_dealloc_qtag(cb); 2798 scsi_low_free_ccb(cb); 2799 slp->sl_nio --; 2800 return SCSI_LOW_DONE_COMPLETE; 2801 2802retry: 2803#ifdef SCSI_LOW_DEBUG 2804 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0) 2805 { 2806 printf("** SCSI_LOW_DONE_RETRY ===============\n"); 2807 scsi_low_print(slp, NULL); 2808 } 2809#endif /* SCSI_LOW_DEBUG */ 2810 2811 cb->ccb_rcnt ++; 2812 scsi_low_deactivate_qtag(cb); 2813 scsi_low_ccb_message_retry(cb); 2814 return SCSI_LOW_DONE_RETRY; 2815} 2816 2817/************************************************************** 2818 * Reset 2819 **************************************************************/ 2820static void 2821scsi_low_reset_nexus_target(slp, ti, fdone) 2822 struct scsi_low_softc *slp; 2823 struct targ_info *ti; 2824 int fdone; 2825{ 2826 struct lun_info *li; 2827 2828 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; 2829 li = LIST_NEXT(li, lun_chain)) 2830 { 2831 scsi_low_reset_nexus_lun(slp, li, fdone); 2832 li->li_state = SCSI_LOW_LUN_SLEEP; 2833 li->li_maxnqio = 0; 2834 } 2835 2836 ti->ti_disc = 0; 2837 ti->ti_setup_msg = 0; 2838 ti->ti_setup_msg_done = 0; 2839 2840 ti->ti_osynch.offset = ti->ti_osynch.period = 0; 2841 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8; 2842 2843 ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS; 2844 ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID; 2845 2846 if (slp->sl_funcs->scsi_low_targ_init != NULL) 2847 { 2848 ((*slp->sl_funcs->scsi_low_targ_init) 2849 (slp, ti, SCSI_LOW_INFO_REVOKE)); 2850 } 2851 scsi_low_calcf_target(ti); 2852 2853 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; 2854 li = LIST_NEXT(li, lun_chain)) 2855 { 2856 li->li_flags = 0; 2857 2858 li->li_diskflags = SCSI_LOW_DISK_LFLAGS; 2859 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID; 2860 2861 if (slp->sl_funcs->scsi_low_lun_init != NULL) 2862 { 2863 ((*slp->sl_funcs->scsi_low_lun_init) 2864 (slp, ti, li, SCSI_LOW_INFO_REVOKE)); 2865 } 2866 scsi_low_calcf_lun(li); 2867 } 2868} 2869 2870static void 2871scsi_low_reset_nexus(slp, fdone) 2872 struct scsi_low_softc *slp; 2873 int fdone; 2874{ 2875 struct targ_info *ti; 2876 struct slccb *cb, *topcb; 2877 2878 if ((cb = slp->sl_Qnexus) != NULL) 2879 { 2880 topcb = scsi_low_revoke_ccb(slp, cb, fdone); 2881 } 2882 else 2883 { 2884 topcb = NULL; 2885 } 2886 2887 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL; 2888 ti = TAILQ_NEXT(ti, ti_chain)) 2889 { 2890 scsi_low_reset_nexus_target(slp, ti, fdone); 2891 scsi_low_bus_release(slp, ti); 2892 scsi_low_init_msgsys(slp, ti); 2893 } 2894 2895 if (topcb != NULL) 2896 { 2897 topcb->ccb_flags |= CCB_STARTQ; 2898 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain); 2899 } 2900 2901 slp->sl_disc = 0; 2902 slp->sl_retry_sel = 0; 2903 slp->sl_flags &= ~HW_PDMASTART; 2904} 2905 2906/* misc */ 2907static int tw_pos; 2908static char tw_chars[] = "|/-\\"; 2909#define TWIDDLEWAIT 10000 2910 2911static void 2912scsi_low_twiddle_wait(void) 2913{ 2914 2915 cnputc('\b'); 2916 cnputc(tw_chars[tw_pos++]); 2917 tw_pos %= (sizeof(tw_chars) - 1); 2918 SCSI_LOW_DELAY(TWIDDLEWAIT); 2919} 2920 2921void 2922scsi_low_bus_reset(slp) 2923 struct scsi_low_softc *slp; 2924{ 2925 int i; 2926 2927 (*slp->sl_funcs->scsi_low_bus_reset) (slp); 2928 2929 printf("%s: try to reset scsi bus ", slp->sl_xname); 2930 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++) 2931 scsi_low_twiddle_wait(); 2932 cnputc('\b'); 2933 printf("\n"); 2934} 2935 2936int 2937scsi_low_restart(slp, flags, s) 2938 struct scsi_low_softc *slp; 2939 int flags; 2940 u_char *s; 2941{ 2942 int error; 2943 2944 if (s != NULL) 2945 printf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s); 2946 2947 if ((error = scsi_low_init(slp, flags)) != 0) 2948 return error; 2949 2950 scsi_low_start(slp); 2951 return 0; 2952} 2953 2954/************************************************************** 2955 * disconnect and reselect 2956 **************************************************************/ 2957#define MSGCMD_LUN(msg) (msg & 0x07) 2958 2959static struct slccb * 2960scsi_low_establish_ccb(ti, li, tag) 2961 struct targ_info *ti; 2962 struct lun_info *li; 2963 scsi_low_tag_t tag; 2964{ 2965 struct scsi_low_softc *slp = ti->ti_sc; 2966 struct slccb *cb; 2967 2968 if (li == NULL) 2969 return NULL; 2970 2971 cb = TAILQ_FIRST(&li->li_discq); 2972 for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain)) 2973 if (cb->ccb_tag == tag) 2974 goto found; 2975 return cb; 2976 2977 /* 2978 * establish our ccb nexus 2979 */ 2980found: 2981#ifdef SCSI_LOW_DEBUG 2982 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0) 2983 { 2984 printf("%s: nexus(0x%lx) abort check start\n", 2985 slp->sl_xname, (u_long) cb); 2986 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT); 2987 scsi_low_revoke_ccb(slp, cb, 1); 2988 return NULL; 2989 } 2990 2991 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0) 2992 { 2993 if (cb->ccb_omsgoutflag == 0) 2994 scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP); 2995 } 2996#endif /* SCSI_LOW_DEBUG */ 2997 2998 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain); 2999 cb->ccb_flags &= ~CCB_DISCQ; 3000 slp->sl_Qnexus = cb; 3001 3002 slp->sl_scp = cb->ccb_sscp; 3003 slp->sl_error |= cb->ccb_error; 3004 3005 slp->sl_disc --; 3006 ti->ti_disc --; 3007 li->li_disc --; 3008 3009 /* inform "ccb nexus established" to the host driver */ 3010 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp); 3011 3012 /* check msg */ 3013 if (cb->ccb_msgoutflag != 0) 3014 { 3015 scsi_low_ccb_message_exec(slp, cb); 3016 } 3017 3018 return cb; 3019} 3020 3021struct targ_info * 3022scsi_low_reselected(slp, targ) 3023 struct scsi_low_softc *slp; 3024 u_int targ; 3025{ 3026 struct targ_info *ti; 3027 struct slccb *cb; 3028 u_char *s; 3029 3030 /* 3031 * Check select vs reselected collision. 3032 */ 3033 3034 if ((cb = slp->sl_selid) != NULL) 3035 { 3036 scsi_low_arbit_fail(slp, cb); 3037#ifdef SCSI_LOW_STATICS 3038 scsi_low_statics.nexus_conflict ++; 3039#endif /* SCSI_LOW_STATICS */ 3040 } 3041 3042 /* 3043 * Check if no current active nexus. 3044 */ 3045 if (slp->sl_Tnexus != NULL) 3046 { 3047 s = "host busy"; 3048 goto world_restart; 3049 } 3050 3051 /* 3052 * Check a valid target id asserted ? 3053 */ 3054 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid) 3055 { 3056 s = "scsi id illegal"; 3057 goto world_restart; 3058 } 3059 3060 /* 3061 * Check the target scsi status. 3062 */ 3063 ti = slp->sl_ti[targ]; 3064 if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL) 3065 { 3066 s = "phase mismatch"; 3067 goto world_restart; 3068 } 3069 3070 /* 3071 * Setup init msgsys 3072 */ 3073 slp->sl_error = 0; 3074 scsi_low_init_msgsys(slp, ti); 3075 3076 /* 3077 * Establish our target nexus 3078 */ 3079 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL); 3080 slp->sl_Tnexus = ti; 3081#ifdef SCSI_LOW_STATICS 3082 scsi_low_statics.nexus_reselected ++; 3083#endif /* SCSI_LOW_STATICS */ 3084 return ti; 3085 3086world_restart: 3087 printf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s); 3088 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, 3089 "reselect: scsi world confused"); 3090 return NULL; 3091} 3092 3093/************************************************************** 3094 * cmd out pointer setup 3095 **************************************************************/ 3096int 3097scsi_low_cmd(slp, ti) 3098 struct scsi_low_softc *slp; 3099 struct targ_info *ti; 3100{ 3101 struct slccb *cb = slp->sl_Qnexus; 3102 3103 slp->sl_ph_count ++; 3104 if (cb == NULL) 3105 { 3106 /* 3107 * no ccb, abort! 3108 */ 3109 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd; 3110 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd); 3111 slp->sl_scp.scp_datalen = 0; 3112 slp->sl_scp.scp_direction = SCSI_LOW_READ; 3113 slp->sl_error |= FATALIO; 3114 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3115 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found"); 3116 return EINVAL; 3117 } 3118 else 3119 { 3120#ifdef SCSI_LOW_DEBUG 3121 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id)) 3122 { 3123 scsi_low_test_cmdlnk(slp, cb); 3124 } 3125#endif /* SCSI_LOW_DEBUG */ 3126 } 3127 return 0; 3128} 3129 3130/************************************************************** 3131 * data out pointer setup 3132 **************************************************************/ 3133int 3134scsi_low_data(slp, ti, bp, direction) 3135 struct scsi_low_softc *slp; 3136 struct targ_info *ti; 3137 struct buf **bp; 3138 int direction; 3139{ 3140 struct slccb *cb = slp->sl_Qnexus; 3141 3142 if (cb != NULL && direction == cb->ccb_sscp.scp_direction) 3143 { 3144 *bp = cb->bp; 3145 return 0; 3146 } 3147 3148 slp->sl_error |= (FATALIO | PDMAERR); 3149 slp->sl_scp.scp_datalen = 0; 3150 slp->sl_scp.scp_direction = direction; 3151 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3152 if (ti->ti_ophase != ti->ti_phase) 3153 { 3154 char *s; 3155 3156 if (cb == NULL) 3157 s = "DATA PHASE: ccb nexus not found"; 3158 else 3159 s = "DATA PHASE: xfer direction mismatch"; 3160 SCSI_LOW_INFO(slp, ti, s); 3161 } 3162 3163 *bp = NULL; 3164 return EINVAL; 3165} 3166 3167/************************************************************** 3168 * MSG_SYS 3169 **************************************************************/ 3170#define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;} 3171#define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3]) 3172#define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4]) 3173#define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3]) 3174#define MSGIN_DATA_LAST 0x30 3175 3176static int scsi_low_errfunc_synch(struct scsi_low_softc *, u_int); 3177static int scsi_low_errfunc_wide(struct scsi_low_softc *, u_int); 3178static int scsi_low_errfunc_identify(struct scsi_low_softc *, u_int); 3179static int scsi_low_errfunc_qtag(struct scsi_low_softc *, u_int); 3180 3181static int scsi_low_msgfunc_synch(struct scsi_low_softc *); 3182static int scsi_low_msgfunc_wide(struct scsi_low_softc *); 3183static int scsi_low_msgfunc_identify(struct scsi_low_softc *); 3184static int scsi_low_msgfunc_abort(struct scsi_low_softc *); 3185static int scsi_low_msgfunc_qabort(struct scsi_low_softc *); 3186static int scsi_low_msgfunc_qtag(struct scsi_low_softc *); 3187static int scsi_low_msgfunc_reset(struct scsi_low_softc *); 3188 3189struct scsi_low_msgout_data { 3190 u_int md_flags; 3191 u_int8_t md_msg; 3192 int (*md_msgfunc)(struct scsi_low_softc *); 3193 int (*md_errfunc)(struct scsi_low_softc *, u_int); 3194#define MSG_RELEASE_ATN 0x0001 3195 u_int md_condition; 3196}; 3197 3198struct scsi_low_msgout_data scsi_low_msgout_data[] = { 3199/* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN}, 3200/* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN}, 3201/* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN}, 3202/* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN}, 3203/* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0}, 3204/* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN}, 3205/* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN}, 3206/* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0}, 3207/* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0}, 3208/* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0}, 3209/* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN}, 3210/* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN}, 3211/* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN}, 3212/* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN}, 3213/* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN}, 3214/* 15 */{SCSI_LOW_MSG_ALL, 0}, 3215}; 3216 3217static int scsi_low_msginfunc_ext(struct scsi_low_softc *); 3218static int scsi_low_synch(struct scsi_low_softc *); 3219static int scsi_low_wide(struct scsi_low_softc *); 3220static int scsi_low_msginfunc_msg_reject(struct scsi_low_softc *); 3221static int scsi_low_msginfunc_rejop(struct scsi_low_softc *); 3222static int scsi_low_msginfunc_rp(struct scsi_low_softc *); 3223static int scsi_low_msginfunc_sdp(struct scsi_low_softc *); 3224static int scsi_low_msginfunc_disc(struct scsi_low_softc *); 3225static int scsi_low_msginfunc_cc(struct scsi_low_softc *); 3226static int scsi_low_msginfunc_lcc(struct scsi_low_softc *); 3227static int scsi_low_msginfunc_parity(struct scsi_low_softc *); 3228static int scsi_low_msginfunc_noop(struct scsi_low_softc *); 3229static int scsi_low_msginfunc_simple_qtag(struct scsi_low_softc *); 3230static int scsi_low_msginfunc_i_wide_residue(struct scsi_low_softc *); 3231 3232struct scsi_low_msgin_data { 3233 u_int md_len; 3234 int (*md_msgfunc)(struct scsi_low_softc *); 3235}; 3236 3237struct scsi_low_msgin_data scsi_low_msgin_data[] = { 3238/* 0 */ {1, scsi_low_msginfunc_cc}, 3239/* 1 */ {2, scsi_low_msginfunc_ext}, 3240/* 2 */ {1, scsi_low_msginfunc_sdp}, 3241/* 3 */ {1, scsi_low_msginfunc_rp}, 3242/* 4 */ {1, scsi_low_msginfunc_disc}, 3243/* 5 */ {1, scsi_low_msginfunc_rejop}, 3244/* 6 */ {1, scsi_low_msginfunc_rejop}, 3245/* 7 */ {1, scsi_low_msginfunc_msg_reject}, 3246/* 8 */ {1, scsi_low_msginfunc_noop}, 3247/* 9 */ {1, scsi_low_msginfunc_parity}, 3248/* a */ {1, scsi_low_msginfunc_lcc}, 3249/* b */ {1, scsi_low_msginfunc_lcc}, 3250/* c */ {1, scsi_low_msginfunc_rejop}, 3251/* d */ {2, scsi_low_msginfunc_rejop}, 3252/* e */ {1, scsi_low_msginfunc_rejop}, 3253/* f */ {1, scsi_low_msginfunc_rejop}, 3254/* 0x10 */ {1, scsi_low_msginfunc_rejop}, 3255/* 0x11 */ {1, scsi_low_msginfunc_rejop}, 3256/* 0x12 */ {1, scsi_low_msginfunc_rejop}, 3257/* 0x13 */ {1, scsi_low_msginfunc_rejop}, 3258/* 0x14 */ {1, scsi_low_msginfunc_rejop}, 3259/* 0x15 */ {1, scsi_low_msginfunc_rejop}, 3260/* 0x16 */ {1, scsi_low_msginfunc_rejop}, 3261/* 0x17 */ {1, scsi_low_msginfunc_rejop}, 3262/* 0x18 */ {1, scsi_low_msginfunc_rejop}, 3263/* 0x19 */ {1, scsi_low_msginfunc_rejop}, 3264/* 0x1a */ {1, scsi_low_msginfunc_rejop}, 3265/* 0x1b */ {1, scsi_low_msginfunc_rejop}, 3266/* 0x1c */ {1, scsi_low_msginfunc_rejop}, 3267/* 0x1d */ {1, scsi_low_msginfunc_rejop}, 3268/* 0x1e */ {1, scsi_low_msginfunc_rejop}, 3269/* 0x1f */ {1, scsi_low_msginfunc_rejop}, 3270/* 0x20 */ {2, scsi_low_msginfunc_simple_qtag}, 3271/* 0x21 */ {2, scsi_low_msginfunc_rejop}, 3272/* 0x22 */ {2, scsi_low_msginfunc_rejop}, 3273/* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue}, 3274/* 0x24 */ {2, scsi_low_msginfunc_rejop}, 3275/* 0x25 */ {2, scsi_low_msginfunc_rejop}, 3276/* 0x26 */ {2, scsi_low_msginfunc_rejop}, 3277/* 0x27 */ {2, scsi_low_msginfunc_rejop}, 3278/* 0x28 */ {2, scsi_low_msginfunc_rejop}, 3279/* 0x29 */ {2, scsi_low_msginfunc_rejop}, 3280/* 0x2a */ {2, scsi_low_msginfunc_rejop}, 3281/* 0x2b */ {2, scsi_low_msginfunc_rejop}, 3282/* 0x2c */ {2, scsi_low_msginfunc_rejop}, 3283/* 0x2d */ {2, scsi_low_msginfunc_rejop}, 3284/* 0x2e */ {2, scsi_low_msginfunc_rejop}, 3285/* 0x2f */ {2, scsi_low_msginfunc_rejop}, 3286/* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */ 3287}; 3288 3289/************************************************************** 3290 * msgout 3291 **************************************************************/ 3292static int 3293scsi_low_msgfunc_synch(slp) 3294 struct scsi_low_softc *slp; 3295{ 3296 struct targ_info *ti = slp->sl_Tnexus; 3297 int ptr = ti->ti_msgoutlen; 3298 3299 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN; 3300 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE; 3301 ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period; 3302 ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset; 3303 return MSG_EXTEND_SYNCHLEN + 2; 3304} 3305 3306static int 3307scsi_low_msgfunc_wide(slp) 3308 struct scsi_low_softc *slp; 3309{ 3310 struct targ_info *ti = slp->sl_Tnexus; 3311 int ptr = ti->ti_msgoutlen; 3312 3313 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN; 3314 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE; 3315 ti->ti_msgoutstr[ptr + 3] = ti->ti_width; 3316 return MSG_EXTEND_WIDELEN + 2; 3317} 3318 3319static int 3320scsi_low_msgfunc_identify(slp) 3321 struct scsi_low_softc *slp; 3322{ 3323 struct targ_info *ti = slp->sl_Tnexus; 3324 struct lun_info *li = slp->sl_Lnexus; 3325 struct slccb *cb = slp->sl_Qnexus; 3326 int ptr = ti->ti_msgoutlen; 3327 u_int8_t msg; 3328 3329 msg = MSG_IDENTIFY; 3330 if (cb == NULL) 3331 { 3332 slp->sl_error |= FATALIO; 3333 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3334 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown"); 3335 } 3336 else 3337 { 3338 if (scsi_low_is_disconnect_ok(cb) != 0) 3339 msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun); 3340 else 3341 msg |= li->li_lun; 3342 3343 if (ti->ti_phase == PH_MSGOUT) 3344 { 3345 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp); 3346 if (cb->ccb_tag == SCSI_LOW_UNKTAG) 3347 { 3348 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp); 3349 } 3350 } 3351 } 3352 ti->ti_msgoutstr[ptr + 0] = msg; 3353 return 1; 3354} 3355 3356static int 3357scsi_low_msgfunc_abort(slp) 3358 struct scsi_low_softc *slp; 3359{ 3360 3361 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT); 3362 return 1; 3363} 3364 3365static int 3366scsi_low_msgfunc_qabort(slp) 3367 struct scsi_low_softc *slp; 3368{ 3369 3370 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM); 3371 return 1; 3372} 3373 3374static int 3375scsi_low_msgfunc_reset(slp) 3376 struct scsi_low_softc *slp; 3377{ 3378 3379 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET); 3380 return 1; 3381} 3382 3383static int 3384scsi_low_msgfunc_qtag(slp) 3385 struct scsi_low_softc *slp; 3386{ 3387 struct targ_info *ti = slp->sl_Tnexus; 3388 struct slccb *cb = slp->sl_Qnexus; 3389 int ptr = ti->ti_msgoutlen; 3390 3391 if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG) 3392 { 3393 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP; 3394 return 1; 3395 } 3396 else 3397 { 3398 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag; 3399 if (ti->ti_phase == PH_MSGOUT) 3400 { 3401 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp); 3402 } 3403 } 3404 return 2; 3405} 3406 3407/* 3408 * The following functions are called when targets give unexpected 3409 * responces in msgin (after msgout). 3410 */ 3411static int 3412scsi_low_errfunc_identify(slp, msgflags) 3413 struct scsi_low_softc *slp; 3414 u_int msgflags; 3415{ 3416 3417 if (slp->sl_Lnexus != NULL) 3418 { 3419 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC; 3420 scsi_low_calcf_lun(slp->sl_Lnexus); 3421 } 3422 return 0; 3423} 3424 3425static int 3426scsi_low_errfunc_synch(slp, msgflags) 3427 struct scsi_low_softc *slp; 3428 u_int msgflags; 3429{ 3430 struct targ_info *ti = slp->sl_Tnexus; 3431 3432 MSGIN_PERIOD(ti) = 0; 3433 MSGIN_OFFSET(ti) = 0; 3434 scsi_low_synch(slp); 3435 return 0; 3436} 3437 3438static int 3439scsi_low_errfunc_wide(slp, msgflags) 3440 struct scsi_low_softc *slp; 3441 u_int msgflags; 3442{ 3443 struct targ_info *ti = slp->sl_Tnexus; 3444 3445 MSGIN_WIDTHP(ti) = 0; 3446 scsi_low_wide(slp); 3447 return 0; 3448} 3449 3450static int 3451scsi_low_errfunc_qtag(slp, msgflags) 3452 struct scsi_low_softc *slp; 3453 u_int msgflags; 3454{ 3455 3456 if ((msgflags & SCSI_LOW_MSG_REJECT) != 0) 3457 { 3458 if (slp->sl_Qnexus != NULL) 3459 { 3460 scsi_low_deactivate_qtag(slp->sl_Qnexus); 3461 } 3462 if (slp->sl_Lnexus != NULL) 3463 { 3464 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG; 3465 scsi_low_calcf_lun(slp->sl_Lnexus); 3466 } 3467 printf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname); 3468 } 3469 return 0; 3470} 3471 3472 3473int 3474scsi_low_msgout(slp, ti, fl) 3475 struct scsi_low_softc *slp; 3476 struct targ_info *ti; 3477 u_int fl; 3478{ 3479 struct scsi_low_msgout_data *mdp; 3480 int len = 0; 3481 3482#ifdef SCSI_LOW_DIAGNOSTIC 3483 if (ti != slp->sl_Tnexus) 3484 { 3485 scsi_low_print(slp, NULL); 3486 panic("scsi_low_msgout: Target nexus inconsistent"); 3487 } 3488#endif /* SCSI_LOW_DIAGNOSTIC */ 3489 3490 slp->sl_ph_count ++; 3491 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES) 3492 { 3493 printf("%s: too many phase changes\n", slp->sl_xname); 3494 slp->sl_error |= FATALIO; 3495 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3496 } 3497 3498 /* STEP I. 3499 * Scsi phase changes. 3500 * Previously msgs asserted are accepted by our target or 3501 * processed by scsi_low_msgin. 3502 * Thus clear all saved informations. 3503 */ 3504 if ((fl & SCSI_LOW_MSGOUT_INIT) != 0) 3505 { 3506 ti->ti_omsgflags = 0; 3507 ti->ti_emsgflags = 0; 3508 } 3509 else if (slp->sl_atten == 0) 3510 { 3511 /* STEP II. 3512 * We did not assert attention, however still our target required 3513 * msgs. Resend previous msgs. 3514 */ 3515 ti->ti_msgflags |= ti->ti_omsgflags; 3516 ti->ti_omsgflags = 0; 3517#ifdef SCSI_LOW_DIAGNOSTIC 3518 printf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname); 3519#endif /* SCSI_LOW_DIAGNOSTIC */ 3520 } 3521 3522 /* STEP III. 3523 * We have no msgs. send MSG_NOOP (OK?) 3524 */ 3525 if (scsi_low_is_msgout_continue(ti, 0) == 0) 3526 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0); 3527 3528 /* STEP IV. 3529 * Process all msgs 3530 */ 3531 ti->ti_msgoutlen = 0; 3532 slp->sl_clear_atten = 0; 3533 mdp = &scsi_low_msgout_data[0]; 3534 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++) 3535 { 3536 if ((ti->ti_msgflags & mdp->md_flags) != 0) 3537 { 3538 ti->ti_omsgflags |= mdp->md_flags; 3539 ti->ti_msgflags &= ~mdp->md_flags; 3540 ti->ti_emsgflags = mdp->md_flags; 3541 3542 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg; 3543 if (mdp->md_msgfunc != NULL) 3544 len = (*mdp->md_msgfunc) (slp); 3545 else 3546 len = 1; 3547 3548#ifdef SCSI_LOW_DIAGNOSTIC 3549 scsi_low_msg_log_write(&ti->ti_log_msgout, 3550 &ti->ti_msgoutstr[ti->ti_msgoutlen], len); 3551#endif /* SCSI_LOW_DIAGNOSTIC */ 3552 3553 ti->ti_msgoutlen += len; 3554 if ((mdp->md_condition & MSG_RELEASE_ATN) != 0) 3555 { 3556 slp->sl_clear_atten = 1; 3557 break; 3558 } 3559 3560 if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 || 3561 ti->ti_msgflags == 0) 3562 break; 3563 3564 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5) 3565 break; 3566 } 3567 } 3568 3569 if (scsi_low_is_msgout_continue(ti, 0) == 0) 3570 slp->sl_clear_atten = 1; 3571 3572 return ti->ti_msgoutlen; 3573} 3574 3575/************************************************************** 3576 * msgin 3577 **************************************************************/ 3578static int 3579scsi_low_msginfunc_noop(slp) 3580 struct scsi_low_softc *slp; 3581{ 3582 3583 return 0; 3584} 3585 3586static int 3587scsi_low_msginfunc_rejop(slp) 3588 struct scsi_low_softc *slp; 3589{ 3590 struct targ_info *ti = slp->sl_Tnexus; 3591 u_int8_t msg = ti->ti_msgin[0]; 3592 3593 printf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg); 3594 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 3595 return 0; 3596} 3597 3598static int 3599scsi_low_msginfunc_cc(slp) 3600 struct scsi_low_softc *slp; 3601{ 3602 struct lun_info *li; 3603 3604 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC); 3605 3606 /* validate status */ 3607 if (slp->sl_Qnexus == NULL) 3608 return ENOENT; 3609 3610 slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status; 3611 li = slp->sl_Lnexus; 3612 switch (slp->sl_scp.scp_status) 3613 { 3614 case ST_GOOD: 3615 li->li_maxnqio = li->li_maxnexus; 3616 break; 3617 3618 case ST_CHKCOND: 3619 li->li_maxnqio = 0; 3620 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR) 3621 scsi_low_reset_nexus_lun(slp, li, 0); 3622 break; 3623 3624 case ST_BUSY: 3625 li->li_maxnqio = 0; 3626 break; 3627 3628 case ST_QUEFULL: 3629 if (li->li_maxnexus >= li->li_nqio) 3630 li->li_maxnexus = li->li_nqio - 1; 3631 li->li_maxnqio = li->li_maxnexus; 3632 break; 3633 3634 case ST_INTERGOOD: 3635 case ST_INTERMET: 3636 slp->sl_error |= MSGERR; 3637 break; 3638 3639 default: 3640 break; 3641 } 3642 return 0; 3643} 3644 3645static int 3646scsi_low_msginfunc_lcc(slp) 3647 struct scsi_low_softc *slp; 3648{ 3649 struct targ_info *ti; 3650 struct lun_info *li; 3651 struct slccb *ncb, *cb; 3652 3653 ti = slp->sl_Tnexus; 3654 li = slp->sl_Lnexus; 3655 if ((cb = slp->sl_Qnexus) == NULL) 3656 goto bad; 3657 3658 cb->ccb_sscp.scp_status = slp->sl_scp.scp_status; 3659 switch (slp->sl_scp.scp_status) 3660 { 3661 case ST_INTERGOOD: 3662 case ST_INTERMET: 3663 li->li_maxnqio = li->li_maxnexus; 3664 break; 3665 3666 default: 3667 slp->sl_error |= MSGERR; 3668 break; 3669 } 3670 3671 if ((li->li_flags & SCSI_LOW_LINK) == 0) 3672 goto bad; 3673 3674 cb->ccb_error |= slp->sl_error; 3675 if (cb->ccb_error != 0) 3676 goto bad; 3677 3678 for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL; 3679 ncb = TAILQ_NEXT(ncb, ccb_chain)) 3680 { 3681 if (ncb->li == li) 3682 goto cmd_link_start; 3683 } 3684 3685 3686bad: 3687 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM); 3688 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 3689 return EIO; 3690 3691cmd_link_start: 3692 ncb->ccb_flags &= ~CCB_STARTQ; 3693 TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain); 3694 3695 scsi_low_dealloc_qtag(ncb); 3696 ncb->ccb_tag = cb->ccb_tag; 3697 ncb->ccb_otag = cb->ccb_otag; 3698 cb->ccb_tag = SCSI_LOW_UNKTAG; 3699 cb->ccb_otag = SCSI_LOW_UNKTAG; 3700 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY) 3701 panic("%s: linked ccb retried", slp->sl_xname); 3702 3703 slp->sl_Qnexus = ncb; 3704 slp->sl_ph_count = 0; 3705 3706 ncb->ccb_error = 0; 3707 ncb->ccb_datalen = -1; 3708 ncb->ccb_scp.scp_status = ST_UNKNOWN; 3709 ncb->ccb_flags &= ~CCB_INTERNAL; 3710 3711 scsi_low_init_msgsys(slp, ti); 3712 3713 (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb); 3714 3715 if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT) 3716 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 3717 ncb->ccb_tc = ncb->ccb_tcmax; 3718 3719 /* setup saved scsi data pointer */ 3720 ncb->ccb_sscp = ncb->ccb_scp; 3721 slp->sl_scp = ncb->ccb_sscp; 3722 slp->sl_error = ncb->ccb_error; 3723 3724#ifdef SCSI_LOW_DIAGNOSTIC 3725 scsi_low_msg_log_init(&ti->ti_log_msgin); 3726 scsi_low_msg_log_init(&ti->ti_log_msgout); 3727#endif /* SCSI_LOW_DIAGNOSTIC */ 3728 return EJUSTRETURN; 3729} 3730 3731static int 3732scsi_low_msginfunc_disc(slp) 3733 struct scsi_low_softc *slp; 3734{ 3735 3736 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC); 3737 return 0; 3738} 3739 3740static int 3741scsi_low_msginfunc_sdp(slp) 3742 struct scsi_low_softc *slp; 3743{ 3744 struct slccb *cb = slp->sl_Qnexus; 3745 3746 if (cb != NULL) 3747 { 3748 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen; 3749 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data; 3750 } 3751 else 3752 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0); 3753 return 0; 3754} 3755 3756static int 3757scsi_low_msginfunc_rp(slp) 3758 struct scsi_low_softc *slp; 3759{ 3760 3761 if (slp->sl_Qnexus != NULL) 3762 slp->sl_scp = slp->sl_Qnexus->ccb_sscp; 3763 else 3764 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0); 3765 return 0; 3766} 3767 3768static int 3769scsi_low_synch(slp) 3770 struct scsi_low_softc *slp; 3771{ 3772 struct targ_info *ti = slp->sl_Tnexus; 3773 u_int period = 0, offset = 0, speed; 3774 u_char *s; 3775 int error; 3776 3777 if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period && 3778 MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) || 3779 MSGIN_OFFSET(ti) == 0) 3780 { 3781 if ((offset = MSGIN_OFFSET(ti)) != 0) 3782 period = MSGIN_PERIOD(ti); 3783 s = offset ? "synchronous" : "async"; 3784 } 3785 else 3786 { 3787 /* XXX: 3788 * Target seems to be brain damaged. 3789 * Force async transfer. 3790 */ 3791 ti->ti_maxsynch.period = 0; 3792 ti->ti_maxsynch.offset = 0; 3793 printf("%s: target brain damaged. async transfer\n", 3794 slp->sl_xname); 3795 return EINVAL; 3796 } 3797 3798 ti->ti_maxsynch.period = period; 3799 ti->ti_maxsynch.offset = offset; 3800 3801 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH); 3802 if (error != 0) 3803 { 3804 /* XXX: 3805 * Current period and offset are not acceptable 3806 * for our adapter. 3807 * The adapter changes max synch and max offset. 3808 */ 3809 printf("%s: synch neg failed. retry synch msg neg ...\n", 3810 slp->sl_xname); 3811 return error; 3812 } 3813 3814 ti->ti_osynch = ti->ti_maxsynch; 3815 if (offset > 0) 3816 { 3817 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH; 3818 } 3819 3820 /* inform data */ 3821 if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0) 3822 { 3823#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE 3824 struct slccb *cb = slp->sl_Qnexus; 3825 3826 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0) 3827 return 0; 3828#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */ 3829 3830 printf("%s(%d:*): <%s> offset %d period %dns ", 3831 slp->sl_xname, ti->ti_id, s, offset, period * 4); 3832 3833 if (period != 0) 3834 { 3835 speed = 1000 * 10 / (period * 4); 3836 printf("%d.%d M/s", speed / 10, speed % 10); 3837 } 3838 printf("\n"); 3839 } 3840 return 0; 3841} 3842 3843static int 3844scsi_low_wide(slp) 3845 struct scsi_low_softc *slp; 3846{ 3847 struct targ_info *ti = slp->sl_Tnexus; 3848 int error; 3849 3850 ti->ti_width = MSGIN_WIDTHP(ti); 3851 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE); 3852 if (error != 0) 3853 { 3854 /* XXX: 3855 * Current width is not acceptable for our adapter. 3856 * The adapter changes max width. 3857 */ 3858 printf("%s: wide neg failed. retry wide msg neg ...\n", 3859 slp->sl_xname); 3860 return error; 3861 } 3862 3863 ti->ti_owidth = ti->ti_width; 3864 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8) 3865 { 3866 ti->ti_setup_msg_done |= 3867 (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE); 3868 } 3869 3870 /* inform data */ 3871 if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0) 3872 { 3873#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE 3874 struct slccb *cb = slp->sl_Qnexus; 3875 3876 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0) 3877 return 0; 3878#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */ 3879 3880 printf("%s(%d:*): transfer width %d bits\n", 3881 slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width)); 3882 } 3883 return 0; 3884} 3885 3886static int 3887scsi_low_msginfunc_simple_qtag(slp) 3888 struct scsi_low_softc *slp; 3889{ 3890 struct targ_info *ti = slp->sl_Tnexus; 3891 scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1]; 3892 3893 if (slp->sl_Qnexus != NULL) 3894 { 3895 if (slp->sl_Qnexus->ccb_tag != etag) 3896 { 3897 slp->sl_error |= FATALIO; 3898 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3899 SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch"); 3900 } 3901 } 3902 else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL) 3903 { 3904#ifdef SCSI_LOW_DEBUG 3905 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id)) 3906 return 0; 3907#endif /* SCSI_LOW_DEBUG */ 3908 3909 slp->sl_error |= FATALIO; 3910 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0); 3911 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found"); 3912 } 3913 return 0; 3914} 3915 3916static int 3917scsi_low_msginfunc_i_wide_residue(slp) 3918 struct scsi_low_softc *slp; 3919{ 3920 struct targ_info *ti = slp->sl_Tnexus; 3921 struct slccb *cb = slp->sl_Qnexus; 3922 int res = (int) ti->ti_msgin[1]; 3923 3924 if (cb == NULL || res <= 0 || 3925 (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) || 3926 (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3)) 3927 return EINVAL; 3928 3929 if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen) 3930 return EINVAL; 3931 3932 slp->sl_scp.scp_datalen += res; 3933 slp->sl_scp.scp_data -= res; 3934 scsi_low_data_finish(slp); 3935 return 0; 3936} 3937 3938static int 3939scsi_low_msginfunc_ext(slp) 3940 struct scsi_low_softc *slp; 3941{ 3942 struct slccb *cb = slp->sl_Qnexus; 3943 struct lun_info *li = slp->sl_Lnexus; 3944 struct targ_info *ti = slp->sl_Tnexus; 3945 int count, retry; 3946 u_int32_t *ptr; 3947 3948 if (ti->ti_msginptr == 2) 3949 { 3950 ti->ti_msginlen = ti->ti_msgin[1] + 2; 3951 return 0; 3952 } 3953 3954 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2])) 3955 { 3956 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE): 3957 if (cb == NULL) 3958 break; 3959 3960 ptr = (u_int32_t *)(&ti->ti_msgin[3]); 3961 count = (int) htonl((long) (*ptr)); 3962 if(slp->sl_scp.scp_datalen - count < 0 || 3963 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen) 3964 break; 3965 3966 slp->sl_scp.scp_datalen -= count; 3967 slp->sl_scp.scp_data += count; 3968 return 0; 3969 3970 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE): 3971 if (li == NULL) 3972 break; 3973 3974 retry = scsi_low_synch(slp); 3975 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0) 3976 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0); 3977 3978#ifdef SCSI_LOW_DEBUG 3979 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id)) 3980 { 3981 scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH); 3982 } 3983#endif /* SCSI_LOW_DEBUG */ 3984 return 0; 3985 3986 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE): 3987 if (li == NULL) 3988 break; 3989 3990 retry = scsi_low_wide(slp); 3991 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0) 3992 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0); 3993 3994 return 0; 3995 3996 default: 3997 break; 3998 } 3999 4000 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 4001 return EINVAL; 4002} 4003 4004static int 4005scsi_low_msginfunc_parity(slp) 4006 struct scsi_low_softc *slp; 4007{ 4008 struct targ_info *ti = slp->sl_Tnexus; 4009 4010 /* only I -> T, invalid! */ 4011 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 4012 return 0; 4013} 4014 4015static int 4016scsi_low_msginfunc_msg_reject(slp) 4017 struct scsi_low_softc *slp; 4018{ 4019 struct targ_info *ti = slp->sl_Tnexus; 4020 struct scsi_low_msgout_data *mdp; 4021 u_int msgflags; 4022 4023 if (ti->ti_emsgflags != 0) 4024 { 4025 printf("%s: msg flags [0x%x] rejected\n", 4026 slp->sl_xname, ti->ti_emsgflags); 4027 msgflags = SCSI_LOW_MSG_REJECT; 4028 mdp = &scsi_low_msgout_data[0]; 4029 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++) 4030 { 4031 if ((ti->ti_emsgflags & mdp->md_flags) != 0) 4032 { 4033 ti->ti_emsgflags &= ~mdp->md_flags; 4034 if (mdp->md_errfunc != NULL) 4035 (*mdp->md_errfunc) (slp, msgflags); 4036 break; 4037 } 4038 } 4039 return 0; 4040 } 4041 else 4042 { 4043 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found"); 4044 slp->sl_error |= MSGERR; 4045 } 4046 return EINVAL; 4047} 4048 4049int 4050scsi_low_msgin(slp, ti, c) 4051 struct scsi_low_softc *slp; 4052 struct targ_info *ti; 4053 u_int c; 4054{ 4055 struct scsi_low_msgin_data *sdp; 4056 struct lun_info *li; 4057 u_int8_t msg; 4058 4059#ifdef SCSI_LOW_DIAGNOSTIC 4060 if (ti != slp->sl_Tnexus) 4061 { 4062 scsi_low_print(slp, NULL); 4063 panic("scsi_low_msgin: Target nexus inconsistent"); 4064 } 4065#endif /* SCSI_LOW_DIAGNOSTIC */ 4066 4067 /* 4068 * Phase changes, clear the pointer. 4069 */ 4070 if (ti->ti_ophase != ti->ti_phase) 4071 { 4072 MSGINPTR_CLR(ti); 4073 ti->ti_msgin_parity_error = 0; 4074 4075 slp->sl_ph_count ++; 4076 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES) 4077 { 4078 printf("%s: too many phase changes\n", slp->sl_xname); 4079 slp->sl_error |= FATALIO; 4080 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 4081 } 4082 } 4083 4084 /* 4085 * Store a current messages byte into buffer and 4086 * wait for the completion of the current msg. 4087 */ 4088 ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c; 4089 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN) 4090 { 4091 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1; 4092 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 4093 } 4094 4095 /* 4096 * Check parity errors. 4097 */ 4098 if ((c & SCSI_LOW_DATA_PE) != 0) 4099 { 4100 ti->ti_msgin_parity_error ++; 4101 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0); 4102 goto out; 4103 } 4104 4105 if (ti->ti_msgin_parity_error != 0) 4106 goto out; 4107 4108 /* 4109 * Calculate messages length. 4110 */ 4111 msg = ti->ti_msgin[0]; 4112 if (msg < MSGIN_DATA_LAST) 4113 sdp = &scsi_low_msgin_data[msg]; 4114 else 4115 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST]; 4116 4117 if (ti->ti_msginlen == 0) 4118 { 4119 ti->ti_msginlen = sdp->md_len; 4120 } 4121 4122 /* 4123 * Check comletion. 4124 */ 4125 if (ti->ti_msginptr < ti->ti_msginlen) 4126 return EJUSTRETURN; 4127 4128 /* 4129 * Do process. 4130 */ 4131 if ((msg & MSG_IDENTIFY) == 0) 4132 { 4133 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN) 4134 return EJUSTRETURN; 4135 } 4136 else 4137 { 4138 li = slp->sl_Lnexus; 4139 if (li == NULL) 4140 { 4141 li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0); 4142 if (li == NULL) 4143 goto badlun; 4144 slp->sl_Lnexus = li; 4145 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp); 4146 } 4147 else 4148 { 4149 if (MSGCMD_LUN(msg) != li->li_lun) 4150 goto badlun; 4151 } 4152 4153 if (slp->sl_Qnexus == NULL && li->li_nqio == 0) 4154 { 4155 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG)) 4156 { 4157#ifdef SCSI_LOW_DEBUG 4158 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0) 4159 { 4160 goto out; 4161 } 4162#endif /* SCSI_LOW_DEBUG */ 4163 goto badlun; 4164 } 4165 } 4166 } 4167 goto out; 4168 4169 /* 4170 * Msg process completed, reset msgin pointer and assert ATN if desired. 4171 */ 4172badlun: 4173 slp->sl_error |= FATALIO; 4174 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 4175 SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong"); 4176 4177out: 4178 if (ti->ti_msginptr < ti->ti_msginlen) 4179 return EJUSTRETURN; 4180 4181#ifdef SCSI_LOW_DIAGNOSTIC 4182 scsi_low_msg_log_write(&ti->ti_log_msgin, 4183 &ti->ti_msgin[0], ti->ti_msginlen); 4184#endif /* SCSI_LOW_DIAGNOSTIC */ 4185 4186 MSGINPTR_CLR(ti); 4187 return 0; 4188} 4189 4190/********************************************************** 4191 * disconnect 4192 **********************************************************/ 4193int 4194scsi_low_disconnected(slp, ti) 4195 struct scsi_low_softc *slp; 4196 struct targ_info *ti; 4197{ 4198 struct slccb *cb = slp->sl_Qnexus; 4199 4200 /* check phase completion */ 4201 switch (slp->sl_msgphase) 4202 { 4203 case MSGPH_RESET: 4204 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD); 4205 scsi_low_msginfunc_cc(slp); 4206 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0); 4207 goto io_resume; 4208 4209 case MSGPH_ABORT: 4210 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD); 4211 scsi_low_msginfunc_cc(slp); 4212 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0); 4213 goto io_resume; 4214 4215 case MSGPH_TERM: 4216 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD); 4217 scsi_low_msginfunc_cc(slp); 4218 goto io_resume; 4219 4220 case MSGPH_DISC: 4221 if (cb != NULL) 4222 { 4223 struct lun_info *li; 4224 4225 li = cb->li; 4226 TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain); 4227 cb->ccb_flags |= CCB_DISCQ; 4228 cb->ccb_error |= slp->sl_error; 4229 li->li_disc ++; 4230 ti->ti_disc ++; 4231 slp->sl_disc ++; 4232 } 4233 4234#ifdef SCSI_LOW_STATICS 4235 scsi_low_statics.nexus_disconnected ++; 4236#endif /* SCSI_LOW_STATICS */ 4237 4238#ifdef SCSI_LOW_DEBUG 4239 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0) 4240 { 4241 printf("## SCSI_LOW_DISCONNECTED ===============\n"); 4242 scsi_low_print(slp, NULL); 4243 } 4244#endif /* SCSI_LOW_DEBUG */ 4245 break; 4246 4247 case MSGPH_NULL: 4248 slp->sl_error |= FATALIO; 4249 if (ti->ti_phase == PH_SELSTART) 4250 slp->sl_error |= SELTIMEOUTIO; 4251 else 4252 slp->sl_error |= UBFERR; 4253 /* fall through */ 4254 4255 case MSGPH_LCTERM: 4256 case MSGPH_CMDC: 4257io_resume: 4258 if (cb == NULL) 4259 break; 4260 4261#ifdef SCSI_LOW_DEBUG 4262 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id)) 4263 { 4264 if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP && 4265 (cb->ccb_msgoutflag != 0 || 4266 (ti->ti_msgflags & SCSI_LOW_MSG_NOOP))) 4267 { 4268 scsi_low_info(slp, ti, "ATTEN CHECK FAILED"); 4269 } 4270 } 4271#endif /* SCSI_LOW_DEBUG */ 4272 4273 cb->ccb_error |= slp->sl_error; 4274 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY) 4275 { 4276 cb->ccb_flags |= CCB_STARTQ; 4277 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 4278 } 4279 break; 4280 } 4281 4282 scsi_low_bus_release(slp, ti); 4283 scsi_low_start(slp); 4284 return 1; 4285} 4286 4287/********************************************************** 4288 * TAG operations 4289 **********************************************************/ 4290static int 4291scsi_low_alloc_qtag(cb) 4292 struct slccb *cb; 4293{ 4294 struct lun_info *li = cb->li; 4295 scsi_low_tag_t etag; 4296 4297 if (cb->ccb_otag != SCSI_LOW_UNKTAG) 4298 return 0; 4299 4300#ifndef SCSI_LOW_ALT_QTAG_ALLOCATE 4301 etag = ffs(li->li_qtagbits); 4302 if (etag == 0) 4303 return ENOSPC; 4304 4305 li->li_qtagbits &= ~(1 << (etag - 1)); 4306 cb->ccb_otag = etag; 4307 return 0; 4308 4309#else /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 4310 for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++) 4311 if (li->li_qtagarray[li->li_qd] == 0) 4312 goto found; 4313 4314 for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++) 4315 if (li->li_qtagarray[li->li_qd] == 0) 4316 goto found; 4317 4318 return ENOSPC; 4319 4320found: 4321 li->li_qtagarray[li->li_qd] ++; 4322 cb->ccb_otag = (li->li_qd ++); 4323 return 0; 4324#endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 4325} 4326 4327static int 4328scsi_low_dealloc_qtag(cb) 4329 struct slccb *cb; 4330{ 4331 struct lun_info *li = cb->li; 4332 scsi_low_tag_t etag; 4333 4334 if (cb->ccb_otag == SCSI_LOW_UNKTAG) 4335 return 0; 4336 4337#ifndef SCSI_LOW_ALT_QTAG_ALLOCATE 4338 etag = cb->ccb_otag - 1; 4339#ifdef SCSI_LOW_DIAGNOSTIC 4340 if (etag >= sizeof(li->li_qtagbits) * NBBY) 4341 panic("scsi_low_dealloc_tag: illegal tag"); 4342#endif /* SCSI_LOW_DIAGNOSTIC */ 4343 li->li_qtagbits |= (1 << etag); 4344 4345#else /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 4346 etag = cb->ccb_otag; 4347#ifdef SCSI_LOW_DIAGNOSTIC 4348 if (etag >= SCSI_LOW_MAXNEXUS) 4349 panic("scsi_low_dealloc_tag: illegal tag"); 4350#endif /* SCSI_LOW_DIAGNOSTIC */ 4351 li->li_qtagarray[etag] --; 4352#endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 4353 4354 cb->ccb_otag = SCSI_LOW_UNKTAG; 4355 return 0; 4356} 4357 4358static struct slccb * 4359scsi_low_revoke_ccb(slp, cb, fdone) 4360 struct scsi_low_softc *slp; 4361 struct slccb *cb; 4362 int fdone; 4363{ 4364 struct targ_info *ti = cb->ti; 4365 struct lun_info *li = cb->li; 4366 4367#ifdef SCSI_LOW_DIAGNOSTIC 4368 if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) == 4369 (CCB_STARTQ | CCB_DISCQ)) 4370 { 4371 panic("%s: ccb in both queue", slp->sl_xname); 4372 } 4373#endif /* SCSI_LOW_DIAGNOSTIC */ 4374 4375 if ((cb->ccb_flags & CCB_STARTQ) != 0) 4376 { 4377 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain); 4378 } 4379 4380 if ((cb->ccb_flags & CCB_DISCQ) != 0) 4381 { 4382 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain); 4383 li->li_disc --; 4384 ti->ti_disc --; 4385 slp->sl_disc --; 4386 } 4387 4388 cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ | 4389 CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL); 4390 4391 if (fdone != 0 && 4392 (cb->ccb_rcnt ++ >= slp->sl_max_retry || 4393 (cb->ccb_flags & CCB_NORETRY) != 0)) 4394 { 4395 cb->ccb_error |= FATALIO; 4396 cb->ccb_flags &= ~CCB_AUTOSENSE; 4397 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE) 4398 panic("%s: done ccb retried", slp->sl_xname); 4399 return NULL; 4400 } 4401 else 4402 { 4403 cb->ccb_error |= PENDINGIO; 4404 scsi_low_deactivate_qtag(cb); 4405 scsi_low_ccb_message_retry(cb); 4406 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 4407 return cb; 4408 } 4409} 4410 4411static void 4412scsi_low_reset_nexus_lun(slp, li, fdone) 4413 struct scsi_low_softc *slp; 4414 struct lun_info *li; 4415 int fdone; 4416{ 4417 struct slccb *cb, *ncb, *ecb; 4418 4419 if (li == NULL) 4420 return; 4421 4422 ecb = NULL; 4423 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb) 4424 { 4425 ncb = TAILQ_NEXT(cb, ccb_chain); 4426 cb = scsi_low_revoke_ccb(slp, cb, fdone); 4427 if (cb != NULL) 4428 { 4429 /* 4430 * presumely keep ordering of io 4431 */ 4432 cb->ccb_flags |= CCB_STARTQ; 4433 if (ecb == NULL) 4434 { 4435 TAILQ_INSERT_HEAD(&slp->sl_start,\ 4436 cb, ccb_chain); 4437 } 4438 else 4439 { 4440 TAILQ_INSERT_AFTER(&slp->sl_start,\ 4441 ecb, cb, ccb_chain); 4442 } 4443 ecb = cb; 4444 } 4445 } 4446} 4447 4448/************************************************************** 4449 * Qurik setup 4450 **************************************************************/ 4451static void 4452scsi_low_calcf_lun(li) 4453 struct lun_info *li; 4454{ 4455 struct targ_info *ti = li->li_ti; 4456 struct scsi_low_softc *slp = ti->ti_sc; 4457 u_int cfgflags, diskflags; 4458 4459 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID) 4460 cfgflags = li->li_cfgflags; 4461 else 4462 cfgflags = 0; 4463 4464 diskflags = li->li_diskflags & li->li_quirks; 4465 4466 /* disconnect */ 4467 li->li_flags &= ~SCSI_LOW_DISC; 4468 if ((slp->sl_cfgflags & CFG_NODISC) == 0 && 4469 (diskflags & SCSI_LOW_DISK_DISC) != 0 && 4470 (cfgflags & SCSI_LOW_DISC) != 0) 4471 li->li_flags |= SCSI_LOW_DISC; 4472 4473 /* parity */ 4474 li->li_flags |= SCSI_LOW_NOPARITY; 4475 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 && 4476 (diskflags & SCSI_LOW_DISK_PARITY) != 0 && 4477 (cfgflags & SCSI_LOW_NOPARITY) == 0) 4478 li->li_flags &= ~SCSI_LOW_NOPARITY; 4479 4480 /* qtag */ 4481 if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 && 4482 (cfgflags & SCSI_LOW_QTAG) != 0 && 4483 (diskflags & SCSI_LOW_DISK_QTAG) != 0) 4484 { 4485 li->li_flags |= SCSI_LOW_QTAG; 4486 li->li_maxnexus = SCSI_LOW_MAXNEXUS; 4487 li->li_maxnqio = li->li_maxnexus; 4488 } 4489 else 4490 { 4491 li->li_flags &= ~SCSI_LOW_QTAG; 4492 li->li_maxnexus = 0; 4493 li->li_maxnqio = li->li_maxnexus; 4494 } 4495 4496 /* cmd link */ 4497 li->li_flags &= ~SCSI_LOW_LINK; 4498 if ((cfgflags & SCSI_LOW_LINK) != 0 && 4499 (diskflags & SCSI_LOW_DISK_LINK) != 0) 4500 li->li_flags |= SCSI_LOW_LINK; 4501 4502 /* compatible flags */ 4503 li->li_flags &= ~SCSI_LOW_SYNC; 4504 if (ti->ti_maxsynch.offset > 0) 4505 li->li_flags |= SCSI_LOW_SYNC; 4506 4507#ifdef SCSI_LOW_DEBUG 4508 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0) 4509 { 4510 scsi_low_calcf_show(li); 4511 } 4512#endif /* SCSI_LOW_DEBUG */ 4513} 4514 4515static void 4516scsi_low_calcf_target(ti) 4517 struct targ_info *ti; 4518{ 4519 struct scsi_low_softc *slp = ti->ti_sc; 4520 u_int offset, period, diskflags; 4521 4522 diskflags = ti->ti_diskflags & ti->ti_quirks; 4523 4524 /* synch */ 4525 if ((slp->sl_cfgflags & CFG_ASYNC) == 0 && 4526 (diskflags & SCSI_LOW_DISK_SYNC) != 0) 4527 { 4528 offset = ti->ti_maxsynch.offset; 4529 period = ti->ti_maxsynch.period; 4530 if (offset == 0 || period == 0) 4531 offset = period = 0; 4532 } 4533 else 4534 { 4535 offset = period = 0; 4536 } 4537 4538 ti->ti_maxsynch.offset = offset; 4539 ti->ti_maxsynch.period = period; 4540 4541 /* wide */ 4542 if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 && 4543 ti->ti_width > SCSI_LOW_BUS_WIDTH_16) 4544 ti->ti_width = SCSI_LOW_BUS_WIDTH_16; 4545 4546 if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 && 4547 ti->ti_width > SCSI_LOW_BUS_WIDTH_8) 4548 ti->ti_width = SCSI_LOW_BUS_WIDTH_8; 4549 4550 if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID) 4551 { 4552 if (ti->ti_maxsynch.offset != ti->ti_osynch.offset || 4553 ti->ti_maxsynch.period != ti->ti_osynch.period) 4554 ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH; 4555 if (ti->ti_width != ti->ti_owidth) 4556 ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH); 4557 4558 ti->ti_osynch = ti->ti_maxsynch; 4559 ti->ti_owidth = ti->ti_width; 4560 } 4561 4562#ifdef SCSI_LOW_DEBUG 4563 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0) 4564 { 4565 printf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n", 4566 slp->sl_xname, ti->ti_id, 4567 ti->ti_maxsynch.period * 4, 4568 ti->ti_maxsynch.offset, 4569 ti->ti_width); 4570 } 4571#endif /* SCSI_LOW_DEBUG */ 4572} 4573 4574static void 4575scsi_low_calcf_show(li) 4576 struct lun_info *li; 4577{ 4578 struct targ_info *ti = li->li_ti; 4579 struct scsi_low_softc *slp = ti->ti_sc; 4580 4581 printf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n", 4582 slp->sl_xname, ti->ti_id, li->li_lun, 4583 ti->ti_maxsynch.period * 4, 4584 ti->ti_maxsynch.offset, 4585 ti->ti_width, 4586 li->li_flags, SCSI_LOW_BITS); 4587} 4588 4589#ifdef SCSI_LOW_START_UP_CHECK 4590/************************************************************** 4591 * scsi world start up 4592 **************************************************************/ 4593static int scsi_low_poll(struct scsi_low_softc *, struct slccb *); 4594 4595static int 4596scsi_low_start_up(slp) 4597 struct scsi_low_softc *slp; 4598{ 4599 struct targ_info *ti; 4600 struct lun_info *li; 4601 struct slccb *cb; 4602 int target, lun; 4603 4604 printf("%s: scsi_low: probing all devices ....\n", slp->sl_xname); 4605 4606 for (target = 0; target < slp->sl_ntargs; target ++) 4607 { 4608 if (target == slp->sl_hostid) 4609 { 4610 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) 4611 { 4612 printf("%s: scsi_low: target %d (host card)\n", 4613 slp->sl_xname, target); 4614 } 4615 continue; 4616 } 4617 4618 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) 4619 { 4620 printf("%s: scsi_low: target %d lun ", 4621 slp->sl_xname, target); 4622 } 4623 4624 ti = slp->sl_ti[target]; 4625 for (lun = 0; lun < slp->sl_nluns; lun ++) 4626 { 4627 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL) 4628 break; 4629 4630 cb->osdep = NULL; 4631 cb->bp = NULL; 4632 4633 li = scsi_low_alloc_li(ti, lun, 1); 4634 4635 scsi_low_enqueue(slp, ti, li, cb, 4636 CCB_AUTOSENSE | CCB_POLLED, 0); 4637 4638 scsi_low_poll(slp, cb); 4639 4640 if (li->li_state != SCSI_LOW_LUN_OK) 4641 break; 4642 4643 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) 4644 { 4645 printf("%d ", lun); 4646 } 4647 } 4648 4649 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) 4650 { 4651 printf("\n"); 4652 } 4653 } 4654 return 0; 4655} 4656 4657static int 4658scsi_low_poll(slp, cb) 4659 struct scsi_low_softc *slp; 4660 struct slccb *cb; 4661{ 4662 int tcount; 4663 4664 tcount = 0; 4665 while (slp->sl_nio > 0) 4666 { 4667 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ); 4668 4669 (*slp->sl_funcs->scsi_low_poll) (slp); 4670 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ) 4671 continue; 4672 4673 tcount = 0; 4674 scsi_low_timeout_check(slp); 4675 } 4676 4677 return 0; 4678} 4679#endif /* SCSI_LOW_START_UP_CHECK */ 4680 4681/********************************************************** 4682 * DEBUG SECTION 4683 **********************************************************/ 4684#ifdef SCSI_LOW_DEBUG 4685static void 4686scsi_low_test_abort(slp, ti, li) 4687 struct scsi_low_softc *slp; 4688 struct targ_info *ti; 4689 struct lun_info *li; 4690{ 4691 struct slccb *acb; 4692 4693 if (li->li_disc > 1) 4694 { 4695 acb = TAILQ_FIRST(&li->li_discq); 4696 if (scsi_low_abort_ccb(slp, acb) == 0) 4697 { 4698 printf("%s: aborting ccb(0x%lx) start\n", 4699 slp->sl_xname, (u_long) acb); 4700 } 4701 } 4702} 4703 4704static void 4705scsi_low_test_atten(slp, ti, msg) 4706 struct scsi_low_softc *slp; 4707 struct targ_info *ti; 4708 u_int msg; 4709{ 4710 4711 if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK) 4712 scsi_low_assert_msg(slp, ti, msg, 0); 4713 else 4714 printf("%s: atten check OK\n", slp->sl_xname); 4715} 4716 4717static void 4718scsi_low_test_cmdlnk(slp, cb) 4719 struct scsi_low_softc *slp; 4720 struct slccb *cb; 4721{ 4722#define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ) 4723 4724 if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0) 4725 return; 4726 4727 memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd, 4728 slp->sl_scp.scp_cmdlen); 4729 cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1; 4730 slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd; 4731} 4732#endif /* SCSI_LOW_DEBUG */ 4733 4734/* static */ void 4735scsi_low_info(slp, ti, s) 4736 struct scsi_low_softc *slp; 4737 struct targ_info *ti; 4738 u_char *s; 4739{ 4740 4741 if (slp == NULL) 4742 slp = LIST_FIRST(&sl_tab); 4743 if (s == NULL) 4744 s = "no message"; 4745 4746 printf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s); 4747 if (ti == NULL) 4748 { 4749 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL; 4750 ti = TAILQ_NEXT(ti, ti_chain)) 4751 { 4752 scsi_low_print(slp, ti); 4753 } 4754 } 4755 else 4756 { 4757 scsi_low_print(slp, ti); 4758 } 4759} 4760 4761static u_char *phase[] = 4762{ 4763 "FREE", "ARBSTART", "SELSTART", "SELECTED", 4764 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL" 4765}; 4766 4767void 4768scsi_low_print(slp, ti) 4769 struct scsi_low_softc *slp; 4770 struct targ_info *ti; 4771{ 4772 struct lun_info *li; 4773 struct slccb *cb; 4774 struct sc_p *sp; 4775 4776 if (ti == NULL || ti == slp->sl_Tnexus) 4777 { 4778 ti = slp->sl_Tnexus; 4779 li = slp->sl_Lnexus; 4780 cb = slp->sl_Qnexus; 4781 } 4782 else 4783 { 4784 li = LIST_FIRST(&ti->ti_litab); 4785 cb = TAILQ_FIRST(&li->li_discq); 4786 } 4787 sp = &slp->sl_scp; 4788 4789 printf("%s: === NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n", 4790 slp->sl_xname, (u_long) ti, (u_long) li, (u_long) cb, 4791 slp->sl_nio); 4792 4793 /* target stat */ 4794 if (ti != NULL) 4795 { 4796 u_int flags = 0, maxnqio = 0, nqio = 0; 4797 int lun = -1; 4798 4799 if (li != NULL) 4800 { 4801 lun = li->li_lun; 4802 flags = li->li_flags; 4803 maxnqio = li->li_maxnqio; 4804 nqio = li->li_nqio; 4805 } 4806 4807 printf("%s(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n", 4808 slp->sl_xname, 4809 ti->ti_id, lun, phase[(int) ti->ti_ophase], 4810 phase[(int) ti->ti_phase], ti->ti_disc, 4811 nqio, maxnqio); 4812 4813 if (cb != NULL) 4814 { 4815printf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n", 4816 (u_int) cb->ccb_scp.scp_cmd[0], 4817 cb->ccb_scp.scp_cmdlen, 4818 cb->ccb_datalen, 4819 cb->ccb_scp.scp_datalen, 4820 (u_int) cb->ccb_sscp.scp_status, 4821 cb->ccb_error, SCSI_LOW_ERRORBITS); 4822 } 4823 4824printf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n", 4825 (u_int) (ti->ti_msginptr), 4826 (u_int) (ti->ti_msgin[0]), 4827 (u_int) (ti->ti_msgin[1]), 4828 (u_int) (ti->ti_msgin[2]), 4829 (u_int) (ti->ti_msgin[3]), 4830 (u_int) (ti->ti_msgin[4]), 4831 slp->sl_atten); 4832 4833printf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n", 4834 (u_int) ti->ti_msgflags, 4835 (u_int) (ti->ti_msgoutstr[0]), 4836 (u_int) (ti->ti_msgoutstr[1]), 4837 (u_int) (ti->ti_msgoutstr[2]), 4838 (u_int) (ti->ti_msgoutstr[3]), 4839 (u_int) (ti->ti_msgoutstr[4]), 4840 ti->ti_msgoutlen, 4841 flags, SCSI_LOW_BITS); 4842 4843#ifdef SCSI_LOW_DIAGNOSTIC 4844 scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2); 4845 scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2); 4846#endif /* SCSI_LOW_DIAGNOSTIC */ 4847 4848 } 4849 4850 printf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n", 4851 (u_long) sp->scp_data, 4852 sp->scp_datalen, 4853 (u_int) sp->scp_status, 4854 slp->sl_error, SCSI_LOW_ERRORBITS); 4855}
| 1345 return 0; 1346} 1347 1348static int 1349scsi_low_dettach_cam(slp) 1350 struct scsi_low_softc *slp; 1351{ 1352 1353 xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL); 1354 xpt_free_path(slp->sl_si.path); 1355 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim)); 1356 cam_sim_free(slp->sl_si.sim, /* free_devq */ TRUE); 1357 return 0; 1358} 1359 1360static int 1361scsi_low_ccb_setup_cam(slp, cb) 1362 struct scsi_low_softc *slp; 1363 struct slccb *cb; 1364{ 1365 union ccb *ccb = (union ccb *) cb->osdep; 1366 1367 if ((cb->ccb_flags & CCB_SCSIIO) != 0) 1368 { 1369 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes; 1370 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len; 1371 cb->ccb_scp.scp_data = ccb->csio.data_ptr; 1372 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len; 1373 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) 1374 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE; 1375 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */ 1376 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 1377 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000; 1378 } 1379 else 1380 { 1381 scsi_low_unit_ready_cmd(cb); 1382 } 1383 return SCSI_LOW_START_QTAG; 1384} 1385 1386static int 1387scsi_low_done_cam(slp, cb) 1388 struct scsi_low_softc *slp; 1389 struct slccb *cb; 1390{ 1391 union ccb *ccb; 1392 1393 ccb = (union ccb *) cb->osdep; 1394 if (cb->ccb_error == 0) 1395 { 1396 ccb->ccb_h.status = CAM_REQ_CMP; 1397 ccb->csio.resid = 0; 1398 } 1399 else 1400 { 1401 if (cb->ccb_rcnt >= slp->sl_max_retry) 1402 cb->ccb_error |= ABORTIO; 1403 1404 if ((cb->ccb_flags & CCB_NORETRY) == 0 && 1405 (cb->ccb_error & ABORTIO) == 0) 1406 return EJUSTRETURN; 1407 1408 if ((cb->ccb_error & SENSEIO) != 0) 1409 { 1410 memcpy(&ccb->csio.sense_data, 1411 &cb->ccb_sense, 1412 sizeof(ccb->csio.sense_data)); 1413 } 1414 1415 ccb->ccb_h.status = scsi_low_translate_error_code(cb, 1416 &scsi_low_error_code_cam[0]); 1417 1418#ifdef SCSI_LOW_DIAGNOSTIC 1419 if ((cb->ccb_flags & CCB_SILENT) == 0 && 1420 cb->ccb_scp.scp_cmdlen > 0 && 1421 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & 1422 SCSI_LOW_CMD_ABORT_WARNING) != 0) 1423 { 1424 printf("%s: WARNING: scsi_low IO abort\n", 1425 slp->sl_xname); 1426 scsi_low_print(slp, NULL); 1427 } 1428#endif /* SCSI_LOW_DIAGNOSTIC */ 1429 } 1430 1431 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0) 1432 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; 1433 1434 if (cb->ccb_scp.scp_status == ST_UNKNOWN) 1435 ccb->csio.scsi_status = 0; /* XXX */ 1436 else 1437 ccb->csio.scsi_status = cb->ccb_scp.scp_status; 1438 1439 if ((cb->ccb_flags & CCB_NOSDONE) == 0) 1440 xpt_done(ccb); 1441 return 0; 1442} 1443 1444static void 1445scsi_low_timeout_cam(slp, ch, action) 1446 struct scsi_low_softc *slp; 1447 int ch; 1448 int action; 1449{ 1450 1451 switch (ch) 1452 { 1453 case SCSI_LOW_TIMEOUT_CH_IO: 1454 switch (action) 1455 { 1456 case SCSI_LOW_TIMEOUT_START: 1457 slp->sl_si.timeout_ch = timeout(scsi_low_timeout, slp, 1458 hz / SCSI_LOW_TIMEOUT_HZ); 1459 break; 1460 case SCSI_LOW_TIMEOUT_STOP: 1461 untimeout(scsi_low_timeout, slp, slp->sl_si.timeout_ch); 1462 break; 1463 } 1464 break; 1465 1466 case SCSI_LOW_TIMEOUT_CH_ENGAGE: 1467 switch (action) 1468 { 1469 case SCSI_LOW_TIMEOUT_START: 1470 slp->sl_si.engage_ch = timeout(scsi_low_engage, slp, 1); 1471 break; 1472 case SCSI_LOW_TIMEOUT_STOP: 1473 untimeout(scsi_low_engage, slp, slp->sl_si.engage_ch); 1474 break; 1475 } 1476 break; 1477 case SCSI_LOW_TIMEOUT_CH_RECOVER: 1478 break; 1479 } 1480} 1481 1482#endif /* SCSI_LOW_INTERFACE_CAM */ 1483 1484/*============================================================= 1485 * END OF OS switch (All OS depend fucntions should be above) 1486 =============================================================*/ 1487 1488/************************************************************** 1489 * scsi low deactivate and activate 1490 **************************************************************/ 1491int 1492scsi_low_is_busy(slp) 1493 struct scsi_low_softc *slp; 1494{ 1495 1496 if (slp->sl_nio > 0) 1497 return EBUSY; 1498 return 0; 1499} 1500 1501int 1502scsi_low_deactivate(slp) 1503 struct scsi_low_softc *slp; 1504{ 1505 int s; 1506 1507 s = SCSI_LOW_SPLSCSI(); 1508 slp->sl_flags |= HW_INACTIVE; 1509 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 1510 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP); 1511 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 1512 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP); 1513 splx(s); 1514 return 0; 1515} 1516 1517int 1518scsi_low_activate(slp) 1519 struct scsi_low_softc *slp; 1520{ 1521 int error, s; 1522 1523 s = SCSI_LOW_SPLSCSI(); 1524 slp->sl_flags &= ~HW_INACTIVE; 1525 if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0) 1526 { 1527 slp->sl_flags |= HW_INACTIVE; 1528 splx(s); 1529 return error; 1530 } 1531 1532 slp->sl_timeout_count = 0; 1533 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 1534 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); 1535 splx(s); 1536 return 0; 1537} 1538 1539/************************************************************** 1540 * scsi low log 1541 **************************************************************/ 1542#ifdef SCSI_LOW_DIAGNOSTIC 1543static void scsi_low_msg_log_init(struct scsi_low_msg_log *); 1544static void scsi_low_msg_log_write(struct scsi_low_msg_log *, u_int8_t *, int); 1545static void scsi_low_msg_log_show(struct scsi_low_msg_log *, char *, int); 1546 1547static void 1548scsi_low_msg_log_init(slmlp) 1549 struct scsi_low_msg_log *slmlp; 1550{ 1551 1552 slmlp->slml_ptr = 0; 1553} 1554 1555static void 1556scsi_low_msg_log_write(slmlp, datap, len) 1557 struct scsi_low_msg_log *slmlp; 1558 u_int8_t *datap; 1559 int len; 1560{ 1561 int ptr, ind; 1562 1563 if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN) 1564 return; 1565 1566 ptr = slmlp->slml_ptr ++; 1567 for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++) 1568 slmlp->slml_msg[ptr].msg[ind] = datap[ind]; 1569 for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++) 1570 slmlp->slml_msg[ptr].msg[ind] = 0; 1571} 1572 1573static void 1574scsi_low_msg_log_show(slmlp, s, len) 1575 struct scsi_low_msg_log *slmlp; 1576 char *s; 1577 int len; 1578{ 1579 int ptr, ind; 1580 1581 printf("%s: (%d) ", s, slmlp->slml_ptr); 1582 for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++) 1583 { 1584 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]); 1585 ind ++) 1586 { 1587 printf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]); 1588 } 1589 printf(">"); 1590 } 1591 printf("\n"); 1592} 1593#endif /* SCSI_LOW_DIAGNOSTIC */ 1594 1595/************************************************************** 1596 * power control 1597 **************************************************************/ 1598static void 1599scsi_low_engage(arg) 1600 void *arg; 1601{ 1602 struct scsi_low_softc *slp = arg; 1603 int s = SCSI_LOW_SPLSCSI(); 1604 1605 switch (slp->sl_rstep) 1606 { 1607 case 0: 1608 slp->sl_rstep ++; 1609 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE); 1610 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp, 1611 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START); 1612 break; 1613 1614 case 1: 1615 slp->sl_rstep ++; 1616 slp->sl_flags &= ~HW_RESUME; 1617 scsi_low_start(slp); 1618 break; 1619 1620 case 2: 1621 break; 1622 } 1623 splx(s); 1624} 1625 1626static int 1627scsi_low_init(slp, flags) 1628 struct scsi_low_softc *slp; 1629 u_int flags; 1630{ 1631 int rv = 0; 1632 1633 slp->sl_flags |= HW_INITIALIZING; 1634 1635 /* clear power control timeout */ 1636 if ((slp->sl_flags & HW_POWERCTRL) != 0) 1637 { 1638 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp, 1639 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP); 1640 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME); 1641 slp->sl_active = 1; 1642 slp->sl_powc = SCSI_LOW_POWDOWN_TC; 1643 } 1644 1645 /* reset current nexus */ 1646 scsi_low_reset_nexus(slp, flags); 1647 if ((slp->sl_flags & HW_INACTIVE) != 0) 1648 { 1649 rv = EBUSY; 1650 goto out; 1651 } 1652 1653 if (flags != SCSI_LOW_RESTART_SOFT) 1654 { 1655 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags)); 1656 } 1657 1658out: 1659 slp->sl_flags &= ~HW_INITIALIZING; 1660 return rv; 1661} 1662 1663/************************************************************** 1664 * allocate lun_info 1665 **************************************************************/ 1666static struct lun_info * 1667scsi_low_alloc_li(ti, lun, alloc) 1668 struct targ_info *ti; 1669 int lun; 1670 int alloc; 1671{ 1672 struct scsi_low_softc *slp = ti->ti_sc; 1673 struct lun_info *li; 1674 1675 li = LIST_FIRST(&ti->ti_litab); 1676 if (li != NULL) 1677 { 1678 if (li->li_lun == lun) 1679 return li; 1680 1681 while ((li = LIST_NEXT(li, lun_chain)) != NULL) 1682 { 1683 if (li->li_lun == lun) 1684 { 1685 LIST_REMOVE(li, lun_chain); 1686 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain); 1687 return li; 1688 } 1689 } 1690 } 1691 1692 if (alloc == 0) 1693 return li; 1694 1695 li = SCSI_LOW_MALLOC(ti->ti_lunsize); 1696 if (li == NULL) 1697 panic("no lun info mem"); 1698 1699 SCSI_LOW_BZERO(li, ti->ti_lunsize); 1700 li->li_lun = lun; 1701 li->li_ti = ti; 1702 1703 li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC | 1704 SCSI_LOW_QTAG; 1705 li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS; 1706 li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID; 1707#ifdef SCSI_LOW_FLAGS_QUIRKS_OK 1708 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID; 1709#endif /* SCSI_LOW_FLAGS_QUIRKS_OK */ 1710 1711 li->li_qtagbits = (u_int) -1; 1712 1713 TAILQ_INIT(&li->li_discq); 1714 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain); 1715 1716 /* host specific structure initialization per lun */ 1717 if (slp->sl_funcs->scsi_low_lun_init != NULL) 1718 (*slp->sl_funcs->scsi_low_lun_init) 1719 (slp, ti, li, SCSI_LOW_INFO_ALLOC); 1720 scsi_low_calcf_lun(li); 1721 return li; 1722} 1723 1724/************************************************************** 1725 * allocate targ_info 1726 **************************************************************/ 1727static struct targ_info * 1728scsi_low_alloc_ti(slp, targ) 1729 struct scsi_low_softc *slp; 1730 int targ; 1731{ 1732 struct targ_info *ti; 1733 1734 if (TAILQ_FIRST(&slp->sl_titab) == NULL) 1735 TAILQ_INIT(&slp->sl_titab); 1736 1737 ti = SCSI_LOW_MALLOC(slp->sl_targsize); 1738 if (ti == NULL) 1739 panic("%s short of memory", slp->sl_xname); 1740 1741 SCSI_LOW_BZERO(ti, slp->sl_targsize); 1742 ti->ti_id = targ; 1743 ti->ti_sc = slp; 1744 1745 slp->sl_ti[targ] = ti; 1746 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain); 1747 LIST_INIT(&ti->ti_litab); 1748 1749 ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS; 1750 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8; 1751 ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID; 1752#ifdef SCSI_LOW_FLAGS_QUIRKS_OK 1753 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID; 1754#endif /* SCSI_LOW_FLAGS_QUIRKS_OK */ 1755 1756 if (slp->sl_funcs->scsi_low_targ_init != NULL) 1757 { 1758 (*slp->sl_funcs->scsi_low_targ_init) 1759 (slp, ti, SCSI_LOW_INFO_ALLOC); 1760 } 1761 scsi_low_calcf_target(ti); 1762 return ti; 1763} 1764 1765static void 1766scsi_low_free_ti(slp) 1767 struct scsi_low_softc *slp; 1768{ 1769 struct targ_info *ti, *tib; 1770 struct lun_info *li, *nli; 1771 1772 for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib) 1773 { 1774 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli) 1775 { 1776 if (slp->sl_funcs->scsi_low_lun_init != NULL) 1777 { 1778 (*slp->sl_funcs->scsi_low_lun_init) 1779 (slp, ti, li, SCSI_LOW_INFO_DEALLOC); 1780 } 1781 nli = LIST_NEXT(li, lun_chain); 1782 SCSI_LOW_FREE(li); 1783 } 1784 1785 if (slp->sl_funcs->scsi_low_targ_init != NULL) 1786 { 1787 (*slp->sl_funcs->scsi_low_targ_init) 1788 (slp, ti, SCSI_LOW_INFO_DEALLOC); 1789 } 1790 tib = TAILQ_NEXT(ti, ti_chain); 1791 SCSI_LOW_FREE(ti); 1792 } 1793} 1794 1795/************************************************************** 1796 * timeout 1797 **************************************************************/ 1798void 1799scsi_low_bus_idle(slp) 1800 struct scsi_low_softc *slp; 1801{ 1802 1803 slp->sl_retry_sel = 0; 1804 if (slp->sl_Tnexus == NULL) 1805 scsi_low_start(slp); 1806} 1807 1808static void 1809scsi_low_timeout(arg) 1810 void *arg; 1811{ 1812 struct scsi_low_softc *slp = arg; 1813 int s; 1814 1815 s = SCSI_LOW_SPLSCSI(); 1816 (void) scsi_low_timeout_check(slp); 1817 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 1818 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); 1819 splx(s); 1820} 1821 1822static int 1823scsi_low_timeout_check(slp) 1824 struct scsi_low_softc *slp; 1825{ 1826 struct targ_info *ti; 1827 struct lun_info *li; 1828 struct slccb *cb = NULL; /* XXX */ 1829 1830 /* selection restart */ 1831 if (slp->sl_retry_sel != 0) 1832 { 1833 slp->sl_retry_sel = 0; 1834 if (slp->sl_Tnexus != NULL) 1835 goto step1; 1836 1837 cb = TAILQ_FIRST(&slp->sl_start); 1838 if (cb == NULL) 1839 goto step1; 1840 1841 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY) 1842 { 1843 cb->ccb_flags |= CCB_NORETRY; 1844 cb->ccb_error |= SELTIMEOUTIO; 1845 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL) 1846 panic("%s: ccb not finished", slp->sl_xname); 1847 } 1848 1849 if (slp->sl_Tnexus == NULL) 1850 scsi_low_start(slp); 1851 } 1852 1853 /* call hardware timeout */ 1854step1: 1855 if (slp->sl_funcs->scsi_low_timeout != NULL) 1856 { 1857 (*slp->sl_funcs->scsi_low_timeout) (slp); 1858 } 1859 1860 if (slp->sl_timeout_count ++ < 1861 SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ) 1862 return 0; 1863 1864 slp->sl_timeout_count = 0; 1865 if (slp->sl_nio > 0) 1866 { 1867 if ((cb = slp->sl_Qnexus) != NULL) 1868 { 1869 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL; 1870 if (cb->ccb_tc < 0) 1871 goto bus_reset; 1872 } 1873 else if (slp->sl_disc == 0) 1874 { 1875 if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL) 1876 return 0; 1877 1878 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL; 1879 if (cb->ccb_tc < 0) 1880 goto bus_reset; 1881 } 1882 else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL; 1883 ti = TAILQ_NEXT(ti, ti_chain)) 1884 { 1885 if (ti->ti_disc == 0) 1886 continue; 1887 1888 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; 1889 li = LIST_NEXT(li, lun_chain)) 1890 { 1891 for (cb = TAILQ_FIRST(&li->li_discq); 1892 cb != NULL; 1893 cb = TAILQ_NEXT(cb, ccb_chain)) 1894 { 1895 cb->ccb_tc -= 1896 SCSI_LOW_TIMEOUT_CHECK_INTERVAL; 1897 if (cb->ccb_tc < 0) 1898 goto bus_reset; 1899 } 1900 } 1901 } 1902 1903 } 1904 else if ((slp->sl_flags & HW_POWERCTRL) != 0) 1905 { 1906 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0) 1907 return 0; 1908 1909 if (slp->sl_active != 0) 1910 { 1911 slp->sl_powc = SCSI_LOW_POWDOWN_TC; 1912 slp->sl_active = 0; 1913 return 0; 1914 } 1915 1916 slp->sl_powc --; 1917 if (slp->sl_powc < 0) 1918 { 1919 slp->sl_powc = SCSI_LOW_POWDOWN_TC; 1920 slp->sl_flags |= HW_POWDOWN; 1921 (*slp->sl_funcs->scsi_low_power) 1922 (slp, SCSI_LOW_POWDOWN); 1923 } 1924 } 1925 return 0; 1926 1927bus_reset: 1928 cb->ccb_error |= TIMEOUTIO; 1929 printf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb); 1930 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover."); 1931 scsi_low_init(slp, SCSI_LOW_RESTART_HARD); 1932 scsi_low_start(slp); 1933 return ERESTART; 1934} 1935 1936 1937static int 1938scsi_low_abort_ccb(slp, cb) 1939 struct scsi_low_softc *slp; 1940 struct slccb *cb; 1941{ 1942 struct targ_info *ti; 1943 struct lun_info *li; 1944 u_int msg; 1945 1946 if (cb == NULL) 1947 return EINVAL; 1948 if ((cb->ccb_omsgoutflag & 1949 (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0) 1950 return EBUSY; 1951 1952 ti = cb->ti; 1953 li = cb->li; 1954 if (cb->ccb_tag == SCSI_LOW_UNKTAG) 1955 msg = SCSI_LOW_MSG_ABORT; 1956 else 1957 msg = SCSI_LOW_MSG_ABORT_QTAG; 1958 1959 cb->ccb_error |= ABORTIO; 1960 cb->ccb_flags |= CCB_NORETRY; 1961 scsi_low_ccb_message_assert(cb, msg); 1962 1963 if (cb == slp->sl_Qnexus) 1964 { 1965 scsi_low_assert_msg(slp, ti, msg, 1); 1966 } 1967 else if ((cb->ccb_flags & CCB_DISCQ) != 0) 1968 { 1969 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL) 1970 panic("%s: revoked ccb done", slp->sl_xname); 1971 1972 cb->ccb_flags |= CCB_STARTQ; 1973 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 1974 1975 if (slp->sl_Tnexus == NULL) 1976 scsi_low_start(slp); 1977 } 1978 else 1979 { 1980 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL) 1981 panic("%s: revoked ccb retried", slp->sl_xname); 1982 } 1983 return 0; 1984} 1985 1986/************************************************************** 1987 * Generic SCSI INTERFACE 1988 **************************************************************/ 1989int 1990scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize) 1991 struct scsi_low_softc *slp; 1992 int openings, ntargs, nluns, targsize, lunsize; 1993{ 1994 struct targ_info *ti; 1995 struct lun_info *li; 1996 int s, i, nccb, rv; 1997 1998#ifdef SCSI_LOW_INTERFACE_XS 1999 slp->sl_osdep_fp = &scsi_low_osdep_funcs_xs; 2000#endif /* SCSI_LOW_INTERFACE_XS */ 2001#ifdef SCSI_LOW_INTERFACE_CAM 2002 slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam; 2003#endif /* SCSI_LOW_INTERFACE_CAM */ 2004 2005 if (slp->sl_osdep_fp == NULL) 2006 panic("scsi_low: interface not spcified"); 2007 2008 if (ntargs > SCSI_LOW_NTARGETS) 2009 { 2010 printf("scsi_low: %d targets are too large\n", ntargs); 2011 printf("change kernel options SCSI_LOW_NTARGETS"); 2012 return EINVAL; 2013 } 2014 2015 if (openings <= 0) 2016 slp->sl_openings = (SCSI_LOW_NCCB / ntargs); 2017 else 2018 slp->sl_openings = openings; 2019 slp->sl_ntargs = ntargs; 2020 slp->sl_nluns = nluns; 2021 slp->sl_max_retry = SCSI_LOW_MAX_RETRY; 2022 2023 if (lunsize < sizeof(struct lun_info)) 2024 lunsize = sizeof(struct lun_info); 2025 2026 if (targsize < sizeof(struct targ_info)) 2027 targsize = sizeof(struct targ_info); 2028 2029 slp->sl_targsize = targsize; 2030 for (i = 0; i < ntargs; i ++) 2031 { 2032 ti = scsi_low_alloc_ti(slp, i); 2033 ti->ti_lunsize = lunsize; 2034 li = scsi_low_alloc_li(ti, 0, 1); 2035 } 2036 2037 /* initialize queue */ 2038 nccb = openings * ntargs; 2039 if (nccb >= SCSI_LOW_NCCB || nccb <= 0) 2040 nccb = SCSI_LOW_NCCB; 2041 scsi_low_init_ccbque(nccb); 2042 TAILQ_INIT(&slp->sl_start); 2043 2044 /* call os depend attach */ 2045 s = SCSI_LOW_SPLSCSI(); 2046 rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp); 2047 if (rv != 0) 2048 { 2049 splx(s); 2050 printf("%s: scsi_low_attach: osdep attach failed\n", 2051 slp->sl_xname); 2052 return EINVAL; 2053 } 2054 2055 /* check hardware */ 2056 SCSI_LOW_DELAY(1000); /* wait for 1ms */ 2057 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0) 2058 { 2059 splx(s); 2060 printf("%s: scsi_low_attach: initialization failed\n", 2061 slp->sl_xname); 2062 return EINVAL; 2063 } 2064 2065 /* start watch dog */ 2066 slp->sl_timeout_count = 0; 2067 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 2068 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); 2069 LIST_INSERT_HEAD(&sl_tab, slp, sl_chain); 2070 2071 /* fake call */ 2072 scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL)); 2073 2074#ifdef SCSI_LOW_START_UP_CHECK 2075 /* probing devices */ 2076 scsi_low_start_up(slp); 2077#endif /* SCSI_LOW_START_UP_CHECK */ 2078 2079 /* call os depend attach done*/ 2080 (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp); 2081 splx(s); 2082 return 0; 2083} 2084 2085int 2086scsi_low_dettach(slp) 2087 struct scsi_low_softc *slp; 2088{ 2089 int s, rv; 2090 2091 s = SCSI_LOW_SPLSCSI(); 2092 if (scsi_low_is_busy(slp) != 0) 2093 { 2094 splx(s); 2095 return EBUSY; 2096 } 2097 2098 scsi_low_deactivate(slp); 2099 2100 rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp); 2101 if (rv != 0) 2102 { 2103 splx(s); 2104 return EBUSY; 2105 } 2106 2107 scsi_low_free_ti(slp); 2108 LIST_REMOVE(slp, sl_chain); 2109 splx(s); 2110 return 0; 2111} 2112 2113/************************************************************** 2114 * Generic enqueue 2115 **************************************************************/ 2116static int 2117scsi_low_enqueue(slp, ti, li, cb, flags, msg) 2118 struct scsi_low_softc *slp; 2119 struct targ_info *ti; 2120 struct lun_info *li; 2121 struct slccb *cb; 2122 u_int flags, msg; 2123{ 2124 2125 cb->ti = ti; 2126 cb->li = li; 2127 2128 scsi_low_ccb_message_assert(cb, msg); 2129 2130 cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG; 2131 scsi_low_alloc_qtag(cb); 2132 2133 cb->ccb_flags = flags | CCB_STARTQ; 2134 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 2135 cb->ccb_error |= PENDINGIO; 2136 2137 if ((flags & CCB_URGENT) != 0) 2138 { 2139 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 2140 } 2141 else 2142 { 2143 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain); 2144 } 2145 2146 slp->sl_nio ++; 2147 2148 if (slp->sl_Tnexus == NULL) 2149 scsi_low_start(slp); 2150 return 0; 2151} 2152 2153static int 2154scsi_low_message_enqueue(slp, ti, li, flags) 2155 struct scsi_low_softc *slp; 2156 struct targ_info *ti; 2157 struct lun_info *li; 2158 u_int flags; 2159{ 2160 struct slccb *cb; 2161 u_int tmsgflags; 2162 2163 tmsgflags = ti->ti_setup_msg; 2164 ti->ti_setup_msg = 0; 2165 2166 flags |= CCB_NORETRY; 2167 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL) 2168 return ENOMEM; 2169 2170 cb->osdep = NULL; 2171 cb->bp = NULL; 2172 scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags); 2173 return 0; 2174} 2175 2176/************************************************************** 2177 * Generic Start & Done 2178 **************************************************************/ 2179#define SLSC_MODE_SENSE_SHORT 0x1a 2180static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0}; 2181static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0, 2182 sizeof(struct scsi_low_mode_sense_data), 0}; 2183static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0, 2184 sizeof(struct scsi_low_inq_data), 0}; 2185static u_int8_t unit_ready_cmd[6]; 2186static int scsi_low_setup_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *); 2187static int scsi_low_sense_abort_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *); 2188static int scsi_low_resume(struct scsi_low_softc *); 2189 2190static void 2191scsi_low_unit_ready_cmd(cb) 2192 struct slccb *cb; 2193{ 2194 2195 cb->ccb_scp.scp_cmd = unit_ready_cmd; 2196 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd); 2197 cb->ccb_scp.scp_datalen = 0; 2198 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2199 cb->ccb_tcmax = 15; 2200} 2201 2202static int 2203scsi_low_sense_abort_start(slp, ti, li, cb) 2204 struct scsi_low_softc *slp; 2205 struct targ_info *ti; 2206 struct lun_info *li; 2207 struct slccb *cb; 2208{ 2209 2210 cb->ccb_scp.scp_cmdlen = 6; 2211 SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen); 2212 cb->ccb_scsi_cmd[0] = REQUEST_SENSE; 2213 cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense); 2214 cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd; 2215 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense; 2216 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense); 2217 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2218 cb->ccb_tcmax = 15; 2219 scsi_low_ccb_message_clear(cb); 2220 if ((cb->ccb_flags & CCB_CLEARQ) != 0) 2221 { 2222 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 2223 } 2224 else 2225 { 2226 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense)); 2227#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE 2228 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0); 2229#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */ 2230 } 2231 2232 return SCSI_LOW_START_NO_QTAG; 2233} 2234 2235static int 2236scsi_low_setup_start(slp, ti, li, cb) 2237 struct scsi_low_softc *slp; 2238 struct targ_info *ti; 2239 struct lun_info *li; 2240 struct slccb *cb; 2241{ 2242 2243 switch(li->li_state) 2244 { 2245 case SCSI_LOW_LUN_SLEEP: 2246 scsi_low_unit_ready_cmd(cb); 2247 break; 2248 2249 case SCSI_LOW_LUN_START: 2250 cb->ccb_scp.scp_cmd = ss_cmd; 2251 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd); 2252 cb->ccb_scp.scp_datalen = 0; 2253 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2254 cb->ccb_tcmax = 30; 2255 break; 2256 2257 case SCSI_LOW_LUN_INQ: 2258 cb->ccb_scp.scp_cmd = inq_cmd; 2259 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd); 2260 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq; 2261 cb->ccb_scp.scp_datalen = sizeof(li->li_inq); 2262 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2263 cb->ccb_tcmax = 15; 2264 break; 2265 2266 case SCSI_LOW_LUN_MODEQ: 2267 cb->ccb_scp.scp_cmd = sms_cmd; 2268 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd); 2269 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms; 2270 cb->ccb_scp.scp_datalen = sizeof(li->li_sms); 2271 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2272 cb->ccb_tcmax = 15; 2273 return SCSI_LOW_START_QTAG; 2274 2275 default: 2276 panic("%s: no setup phase", slp->sl_xname); 2277 } 2278 2279 return SCSI_LOW_START_NO_QTAG; 2280} 2281 2282static int 2283scsi_low_resume(slp) 2284 struct scsi_low_softc *slp; 2285{ 2286 2287 if (slp->sl_flags & HW_RESUME) 2288 return EJUSTRETURN; 2289 slp->sl_flags &= ~HW_POWDOWN; 2290 if (slp->sl_funcs->scsi_low_power != NULL) 2291 { 2292 slp->sl_flags |= HW_RESUME; 2293 slp->sl_rstep = 0; 2294 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE); 2295 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 2296 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, 2297 SCSI_LOW_TIMEOUT_START); 2298 return EJUSTRETURN; 2299 } 2300 return 0; 2301} 2302 2303static void 2304scsi_low_start(slp) 2305 struct scsi_low_softc *slp; 2306{ 2307 struct targ_info *ti; 2308 struct lun_info *li; 2309 struct slccb *cb; 2310 int rv; 2311 2312 /* check hardware exists or under initializations ? */ 2313 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0) 2314 return; 2315 2316 /* check hardware power up ? */ 2317 if ((slp->sl_flags & HW_POWERCTRL) != 0) 2318 { 2319 slp->sl_active ++; 2320 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME)) 2321 { 2322 if (scsi_low_resume(slp) == EJUSTRETURN) 2323 return; 2324 } 2325 } 2326 2327 /* setup nexus */ 2328#ifdef SCSI_LOW_DIAGNOSTIC 2329 if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus) 2330 { 2331 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT"); 2332 panic("%s: inconsistent", slp->sl_xname); 2333 } 2334#endif /* SCSI_LOW_DIAGNOSTIC */ 2335 2336 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL; 2337 cb = TAILQ_NEXT(cb, ccb_chain)) 2338 { 2339 li = cb->li; 2340 2341 if (li->li_disc == 0) 2342 { 2343 goto scsi_low_cmd_start; 2344 } 2345 else if (li->li_nqio > 0) 2346 { 2347 if (li->li_nqio < li->li_maxnqio || 2348 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0) 2349 goto scsi_low_cmd_start; 2350 } 2351 } 2352 return; 2353 2354scsi_low_cmd_start: 2355 cb->ccb_flags &= ~CCB_STARTQ; 2356 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain); 2357 ti = cb->ti; 2358 2359 /* clear all error flag bits (for restart) */ 2360 cb->ccb_error = 0; 2361 cb->ccb_datalen = -1; 2362 cb->ccb_scp.scp_status = ST_UNKNOWN; 2363 2364 /* setup nexus pointer */ 2365 slp->sl_Qnexus = cb; 2366 slp->sl_Lnexus = li; 2367 slp->sl_Tnexus = ti; 2368 2369 /* initialize msgsys */ 2370 scsi_low_init_msgsys(slp, ti); 2371 2372 /* exec cmd */ 2373 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0) 2374 { 2375 /* CA state or forced abort */ 2376 rv = scsi_low_sense_abort_start(slp, ti, li, cb); 2377 } 2378 else if (li->li_state >= SCSI_LOW_LUN_OK) 2379 { 2380 cb->ccb_flags &= ~CCB_INTERNAL; 2381 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb); 2382 if (cb->ccb_msgoutflag != 0) 2383 { 2384 scsi_low_ccb_message_exec(slp, cb); 2385 } 2386 } 2387 else 2388 { 2389 cb->ccb_flags |= CCB_INTERNAL; 2390 rv = scsi_low_setup_start(slp, ti, li, cb); 2391 } 2392 2393 /* allocate qtag */ 2394#define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC) 2395 2396 if (rv == SCSI_LOW_START_QTAG && 2397 (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK && 2398 li->li_maxnqio > 0) 2399 { 2400 u_int qmsg; 2401 2402 scsi_low_activate_qtag(cb); 2403 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & 2404 SCSI_LOW_CMD_ORDERED_QTAG) != 0) 2405 qmsg = SCSI_LOW_MSG_ORDERED_QTAG; 2406 else if ((cb->ccb_flags & CCB_URGENT) != 0) 2407 qmsg = SCSI_LOW_MSG_HEAD_QTAG; 2408 else 2409 qmsg = SCSI_LOW_MSG_SIMPLE_QTAG; 2410 scsi_low_assert_msg(slp, ti, qmsg, 0); 2411 } 2412 2413 /* timeout */ 2414 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT) 2415 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 2416 cb->ccb_tc = cb->ccb_tcmax; 2417 2418 /* setup saved scsi data pointer */ 2419 cb->ccb_sscp = cb->ccb_scp; 2420 2421 /* setup current scsi pointer */ 2422 slp->sl_scp = cb->ccb_sscp; 2423 slp->sl_error = cb->ccb_error; 2424 2425 /* assert always an identify msg */ 2426 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0); 2427 2428 /* debug section */ 2429#ifdef SCSI_LOW_DIAGNOSTIC 2430 scsi_low_msg_log_init(&ti->ti_log_msgin); 2431 scsi_low_msg_log_init(&ti->ti_log_msgout); 2432#endif /* SCSI_LOW_DIAGNOSTIC */ 2433 2434 /* selection start */ 2435 slp->sl_selid = cb; 2436 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb)); 2437 if (rv == SCSI_LOW_START_OK) 2438 { 2439#ifdef SCSI_LOW_STATICS 2440 scsi_low_statics.nexus_win ++; 2441#endif /* SCSI_LOW_STATICS */ 2442 return; 2443 } 2444 2445 scsi_low_arbit_fail(slp, cb); 2446#ifdef SCSI_LOW_STATICS 2447 scsi_low_statics.nexus_fail ++; 2448#endif /* SCSI_LOW_STATICS */ 2449} 2450 2451void 2452scsi_low_arbit_fail(slp, cb) 2453 struct scsi_low_softc *slp; 2454 struct slccb *cb; 2455{ 2456 struct targ_info *ti = cb->ti; 2457 2458 scsi_low_deactivate_qtag(cb); 2459 scsi_low_ccb_message_retry(cb); 2460 cb->ccb_flags |= CCB_STARTQ; 2461 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 2462 2463 scsi_low_bus_release(slp, ti); 2464 2465 cb->ccb_selrcnt ++; 2466 if (slp->sl_disc == 0) 2467 { 2468#ifdef SCSI_LOW_DIAGNOSTIC 2469 printf("%s: try selection again\n", slp->sl_xname); 2470#endif /* SCSI_LOW_DIAGNOSTIC */ 2471 slp->sl_retry_sel = 1; 2472 } 2473} 2474 2475static void 2476scsi_low_bus_release(slp, ti) 2477 struct scsi_low_softc *slp; 2478 struct targ_info *ti; 2479{ 2480 2481 if (ti->ti_disc > 0) 2482 { 2483 SCSI_LOW_SETUP_PHASE(ti, PH_DISC); 2484 } 2485 else 2486 { 2487 SCSI_LOW_SETUP_PHASE(ti, PH_NULL); 2488 } 2489 2490 /* clear all nexus pointer */ 2491 slp->sl_Qnexus = NULL; 2492 slp->sl_Lnexus = NULL; 2493 slp->sl_Tnexus = NULL; 2494 2495 /* clear selection assert */ 2496 slp->sl_selid = NULL; 2497 2498 /* clear nexus data */ 2499 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK; 2500 2501 /* clear phase change counter */ 2502 slp->sl_ph_count = 0; 2503} 2504 2505static int 2506scsi_low_setup_done(slp, cb) 2507 struct scsi_low_softc *slp; 2508 struct slccb *cb; 2509{ 2510 struct targ_info *ti; 2511 struct lun_info *li; 2512 2513 ti = cb->ti; 2514 li = cb->li; 2515 2516 if (cb->ccb_rcnt >= slp->sl_max_retry) 2517 { 2518 cb->ccb_error |= ABORTIO; 2519 return SCSI_LOW_DONE_COMPLETE; 2520 } 2521 2522 /* XXX: special huck for selection timeout */ 2523 if (li->li_state == SCSI_LOW_LUN_SLEEP && 2524 (cb->ccb_error & SELTIMEOUTIO) != 0) 2525 { 2526 cb->ccb_error |= ABORTIO; 2527 return SCSI_LOW_DONE_COMPLETE; 2528 } 2529 2530 switch(li->li_state) 2531 { 2532 case SCSI_LOW_LUN_INQ: 2533 if (cb->ccb_error != 0) 2534 { 2535 li->li_diskflags &= 2536 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG); 2537 if (li->li_lun > 0) 2538 goto resume; 2539 ti->ti_diskflags &= 2540 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE); 2541 } 2542 else if ((li->li_inq.sd_version & 7) >= 2 || 2543 (li->li_inq.sd_len >= 4)) 2544 { 2545 if ((li->li_inq.sd_support & 0x2) == 0) 2546 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG; 2547 if ((li->li_inq.sd_support & 0x8) == 0) 2548 li->li_diskflags &= ~SCSI_LOW_DISK_LINK; 2549 if (li->li_lun > 0) 2550 goto resume; 2551 if ((li->li_inq.sd_support & 0x10) == 0) 2552 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC; 2553 if ((li->li_inq.sd_support & 0x20) == 0) 2554 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16; 2555 if ((li->li_inq.sd_support & 0x40) == 0) 2556 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32; 2557 } 2558 else 2559 { 2560 li->li_diskflags &= 2561 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK); 2562 if (li->li_lun > 0) 2563 goto resume; 2564 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE; 2565 } 2566 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID; 2567resume: 2568 scsi_low_calcf_target(ti); 2569 scsi_low_calcf_lun(li); 2570 break; 2571 2572 case SCSI_LOW_LUN_MODEQ: 2573 if (cb->ccb_error != 0) 2574 { 2575 if (cb->ccb_error & SENSEIO) 2576 { 2577#ifdef SCSI_LOW_DEBUG 2578 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE) 2579 { 2580 printf("SENSE: [%x][%x][%x][%x][%x]\n", 2581 (u_int) cb->ccb_sense.error_code, 2582 (u_int) cb->ccb_sense.segment, 2583 (u_int) cb->ccb_sense.flags, 2584 (u_int) cb->ccb_sense.add_sense_code, 2585 (u_int) cb->ccb_sense.add_sense_code_qual); 2586 } 2587#endif /* SCSI_LOW_DEBUG */ 2588 } 2589 else 2590 { 2591 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG; 2592 } 2593 } 2594 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a) 2595 { 2596 if (li->li_sms.sms_cmp.cmp_qc & 0x02) 2597 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR; 2598 else 2599 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR; 2600 if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0) 2601 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG; 2602 } 2603 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID; 2604 scsi_low_calcf_lun(li); 2605 break; 2606 2607 default: 2608 break; 2609 } 2610 2611 li->li_state ++; 2612 if (li->li_state == SCSI_LOW_LUN_OK) 2613 { 2614 scsi_low_calcf_target(ti); 2615 scsi_low_calcf_lun(li); 2616 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID && 2617 (slp->sl_show_result & SHOW_CALCF_RES) != 0) 2618 { 2619 scsi_low_calcf_show(li); 2620 } 2621 } 2622 2623 cb->ccb_rcnt --; 2624 return SCSI_LOW_DONE_RETRY; 2625} 2626 2627static int 2628scsi_low_done(slp, cb) 2629 struct scsi_low_softc *slp; 2630 struct slccb *cb; 2631{ 2632 int rv; 2633 2634 if (cb->ccb_error == 0) 2635 { 2636 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0) 2637 { 2638#ifdef SCSI_LOW_QCLEAR_AFTER_CA 2639 /* XXX: 2640 * SCSI-2 draft suggests 2641 * page 0x0a QErr bit determins if 2642 * the target aborts or continues 2643 * the queueing io's after CA state resolved. 2644 * However many targets seem not to support 2645 * the page 0x0a. Thus we should manually clear the 2646 * queuing io's after CA state. 2647 */ 2648 if ((cb->ccb_flags & CCB_CLEARQ) == 0) 2649 { 2650 cb->ccb_rcnt --; 2651 cb->ccb_flags |= CCB_CLEARQ; 2652 goto retry; 2653 } 2654#endif /* SCSI_LOW_QCLEAR_AFTER_CA */ 2655 2656 if ((cb->ccb_flags & CCB_SENSE) != 0) 2657 cb->ccb_error |= (SENSEIO | ABORTIO); 2658 cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ); 2659 } 2660 else switch (cb->ccb_sscp.scp_status) 2661 { 2662 case ST_GOOD: 2663 case ST_MET: 2664 case ST_INTERGOOD: 2665 case ST_INTERMET: 2666 if (cb->ccb_datalen == 0 || 2667 cb->ccb_scp.scp_datalen == 0) 2668 break; 2669 2670 if (cb->ccb_scp.scp_cmdlen > 0 && 2671 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & 2672 SCSI_LOW_CMD_RESIDUAL_CHK) == 0) 2673 break; 2674 2675 cb->ccb_error |= PDMAERR; 2676 break; 2677 2678 case ST_BUSY: 2679 case ST_QUEFULL: 2680 cb->ccb_error |= (BUSYERR | STATERR); 2681 break; 2682 2683 case ST_CONFLICT: 2684 cb->ccb_error |= (STATERR | ABORTIO); 2685 break; 2686 2687 case ST_CHKCOND: 2688 case ST_CMDTERM: 2689 if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL)) 2690 { 2691 cb->ccb_rcnt --; 2692 cb->ccb_flags |= CCB_SENSE; 2693 goto retry; 2694 } 2695 cb->ccb_error |= (UACAERR | STATERR | ABORTIO); 2696 break; 2697 2698 case ST_UNKNOWN: 2699 default: 2700 cb->ccb_error |= FATALIO; 2701 break; 2702 } 2703 } 2704 else 2705 { 2706 if (cb->ccb_flags & CCB_SENSE) 2707 { 2708 cb->ccb_error |= (SENSEERR | ABORTIO); 2709 } 2710 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE); 2711 } 2712 2713 /* internal ccb */ 2714 if ((cb->ccb_flags & CCB_INTERNAL) != 0) 2715 { 2716 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY) 2717 goto retry; 2718 } 2719 2720 /* check a ccb msgout flag */ 2721 if (cb->ccb_omsgoutflag != 0) 2722 { 2723#define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \ 2724 SCSI_LOW_MSG_ABORT_QTAG | \ 2725 SCSI_LOW_MSG_CLEAR_QTAG | \ 2726 SCSI_LOW_MSG_TERMIO) 2727 2728 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0) 2729 { 2730 cb->ccb_error |= ABORTIO; 2731 } 2732 } 2733 2734 /* call OS depend done */ 2735 if (cb->osdep != NULL) 2736 { 2737 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb); 2738 if (rv == EJUSTRETURN) 2739 goto retry; 2740 } 2741 else if (cb->ccb_error != 0) 2742 { 2743 if (cb->ccb_rcnt >= slp->sl_max_retry) 2744 cb->ccb_error |= ABORTIO; 2745 2746 if ((cb->ccb_flags & CCB_NORETRY) == 0 && 2747 (cb->ccb_error & ABORTIO) == 0) 2748 goto retry; 2749 } 2750 2751 /* free our target */ 2752#ifdef SCSI_LOW_DEBUG 2753 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0) 2754 { 2755 printf(">> SCSI_LOW_DONE_COMPLETE ===============\n"); 2756 scsi_low_print(slp, NULL); 2757 } 2758#endif /* SCSI_LOW_DEBUG */ 2759 2760 scsi_low_deactivate_qtag(cb); 2761 scsi_low_dealloc_qtag(cb); 2762 scsi_low_free_ccb(cb); 2763 slp->sl_nio --; 2764 return SCSI_LOW_DONE_COMPLETE; 2765 2766retry: 2767#ifdef SCSI_LOW_DEBUG 2768 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0) 2769 { 2770 printf("** SCSI_LOW_DONE_RETRY ===============\n"); 2771 scsi_low_print(slp, NULL); 2772 } 2773#endif /* SCSI_LOW_DEBUG */ 2774 2775 cb->ccb_rcnt ++; 2776 scsi_low_deactivate_qtag(cb); 2777 scsi_low_ccb_message_retry(cb); 2778 return SCSI_LOW_DONE_RETRY; 2779} 2780 2781/************************************************************** 2782 * Reset 2783 **************************************************************/ 2784static void 2785scsi_low_reset_nexus_target(slp, ti, fdone) 2786 struct scsi_low_softc *slp; 2787 struct targ_info *ti; 2788 int fdone; 2789{ 2790 struct lun_info *li; 2791 2792 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; 2793 li = LIST_NEXT(li, lun_chain)) 2794 { 2795 scsi_low_reset_nexus_lun(slp, li, fdone); 2796 li->li_state = SCSI_LOW_LUN_SLEEP; 2797 li->li_maxnqio = 0; 2798 } 2799 2800 ti->ti_disc = 0; 2801 ti->ti_setup_msg = 0; 2802 ti->ti_setup_msg_done = 0; 2803 2804 ti->ti_osynch.offset = ti->ti_osynch.period = 0; 2805 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8; 2806 2807 ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS; 2808 ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID; 2809 2810 if (slp->sl_funcs->scsi_low_targ_init != NULL) 2811 { 2812 ((*slp->sl_funcs->scsi_low_targ_init) 2813 (slp, ti, SCSI_LOW_INFO_REVOKE)); 2814 } 2815 scsi_low_calcf_target(ti); 2816 2817 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; 2818 li = LIST_NEXT(li, lun_chain)) 2819 { 2820 li->li_flags = 0; 2821 2822 li->li_diskflags = SCSI_LOW_DISK_LFLAGS; 2823 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID; 2824 2825 if (slp->sl_funcs->scsi_low_lun_init != NULL) 2826 { 2827 ((*slp->sl_funcs->scsi_low_lun_init) 2828 (slp, ti, li, SCSI_LOW_INFO_REVOKE)); 2829 } 2830 scsi_low_calcf_lun(li); 2831 } 2832} 2833 2834static void 2835scsi_low_reset_nexus(slp, fdone) 2836 struct scsi_low_softc *slp; 2837 int fdone; 2838{ 2839 struct targ_info *ti; 2840 struct slccb *cb, *topcb; 2841 2842 if ((cb = slp->sl_Qnexus) != NULL) 2843 { 2844 topcb = scsi_low_revoke_ccb(slp, cb, fdone); 2845 } 2846 else 2847 { 2848 topcb = NULL; 2849 } 2850 2851 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL; 2852 ti = TAILQ_NEXT(ti, ti_chain)) 2853 { 2854 scsi_low_reset_nexus_target(slp, ti, fdone); 2855 scsi_low_bus_release(slp, ti); 2856 scsi_low_init_msgsys(slp, ti); 2857 } 2858 2859 if (topcb != NULL) 2860 { 2861 topcb->ccb_flags |= CCB_STARTQ; 2862 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain); 2863 } 2864 2865 slp->sl_disc = 0; 2866 slp->sl_retry_sel = 0; 2867 slp->sl_flags &= ~HW_PDMASTART; 2868} 2869 2870/* misc */ 2871static int tw_pos; 2872static char tw_chars[] = "|/-\\"; 2873#define TWIDDLEWAIT 10000 2874 2875static void 2876scsi_low_twiddle_wait(void) 2877{ 2878 2879 cnputc('\b'); 2880 cnputc(tw_chars[tw_pos++]); 2881 tw_pos %= (sizeof(tw_chars) - 1); 2882 SCSI_LOW_DELAY(TWIDDLEWAIT); 2883} 2884 2885void 2886scsi_low_bus_reset(slp) 2887 struct scsi_low_softc *slp; 2888{ 2889 int i; 2890 2891 (*slp->sl_funcs->scsi_low_bus_reset) (slp); 2892 2893 printf("%s: try to reset scsi bus ", slp->sl_xname); 2894 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++) 2895 scsi_low_twiddle_wait(); 2896 cnputc('\b'); 2897 printf("\n"); 2898} 2899 2900int 2901scsi_low_restart(slp, flags, s) 2902 struct scsi_low_softc *slp; 2903 int flags; 2904 u_char *s; 2905{ 2906 int error; 2907 2908 if (s != NULL) 2909 printf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s); 2910 2911 if ((error = scsi_low_init(slp, flags)) != 0) 2912 return error; 2913 2914 scsi_low_start(slp); 2915 return 0; 2916} 2917 2918/************************************************************** 2919 * disconnect and reselect 2920 **************************************************************/ 2921#define MSGCMD_LUN(msg) (msg & 0x07) 2922 2923static struct slccb * 2924scsi_low_establish_ccb(ti, li, tag) 2925 struct targ_info *ti; 2926 struct lun_info *li; 2927 scsi_low_tag_t tag; 2928{ 2929 struct scsi_low_softc *slp = ti->ti_sc; 2930 struct slccb *cb; 2931 2932 if (li == NULL) 2933 return NULL; 2934 2935 cb = TAILQ_FIRST(&li->li_discq); 2936 for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain)) 2937 if (cb->ccb_tag == tag) 2938 goto found; 2939 return cb; 2940 2941 /* 2942 * establish our ccb nexus 2943 */ 2944found: 2945#ifdef SCSI_LOW_DEBUG 2946 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0) 2947 { 2948 printf("%s: nexus(0x%lx) abort check start\n", 2949 slp->sl_xname, (u_long) cb); 2950 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT); 2951 scsi_low_revoke_ccb(slp, cb, 1); 2952 return NULL; 2953 } 2954 2955 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0) 2956 { 2957 if (cb->ccb_omsgoutflag == 0) 2958 scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP); 2959 } 2960#endif /* SCSI_LOW_DEBUG */ 2961 2962 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain); 2963 cb->ccb_flags &= ~CCB_DISCQ; 2964 slp->sl_Qnexus = cb; 2965 2966 slp->sl_scp = cb->ccb_sscp; 2967 slp->sl_error |= cb->ccb_error; 2968 2969 slp->sl_disc --; 2970 ti->ti_disc --; 2971 li->li_disc --; 2972 2973 /* inform "ccb nexus established" to the host driver */ 2974 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp); 2975 2976 /* check msg */ 2977 if (cb->ccb_msgoutflag != 0) 2978 { 2979 scsi_low_ccb_message_exec(slp, cb); 2980 } 2981 2982 return cb; 2983} 2984 2985struct targ_info * 2986scsi_low_reselected(slp, targ) 2987 struct scsi_low_softc *slp; 2988 u_int targ; 2989{ 2990 struct targ_info *ti; 2991 struct slccb *cb; 2992 u_char *s; 2993 2994 /* 2995 * Check select vs reselected collision. 2996 */ 2997 2998 if ((cb = slp->sl_selid) != NULL) 2999 { 3000 scsi_low_arbit_fail(slp, cb); 3001#ifdef SCSI_LOW_STATICS 3002 scsi_low_statics.nexus_conflict ++; 3003#endif /* SCSI_LOW_STATICS */ 3004 } 3005 3006 /* 3007 * Check if no current active nexus. 3008 */ 3009 if (slp->sl_Tnexus != NULL) 3010 { 3011 s = "host busy"; 3012 goto world_restart; 3013 } 3014 3015 /* 3016 * Check a valid target id asserted ? 3017 */ 3018 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid) 3019 { 3020 s = "scsi id illegal"; 3021 goto world_restart; 3022 } 3023 3024 /* 3025 * Check the target scsi status. 3026 */ 3027 ti = slp->sl_ti[targ]; 3028 if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL) 3029 { 3030 s = "phase mismatch"; 3031 goto world_restart; 3032 } 3033 3034 /* 3035 * Setup init msgsys 3036 */ 3037 slp->sl_error = 0; 3038 scsi_low_init_msgsys(slp, ti); 3039 3040 /* 3041 * Establish our target nexus 3042 */ 3043 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL); 3044 slp->sl_Tnexus = ti; 3045#ifdef SCSI_LOW_STATICS 3046 scsi_low_statics.nexus_reselected ++; 3047#endif /* SCSI_LOW_STATICS */ 3048 return ti; 3049 3050world_restart: 3051 printf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s); 3052 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, 3053 "reselect: scsi world confused"); 3054 return NULL; 3055} 3056 3057/************************************************************** 3058 * cmd out pointer setup 3059 **************************************************************/ 3060int 3061scsi_low_cmd(slp, ti) 3062 struct scsi_low_softc *slp; 3063 struct targ_info *ti; 3064{ 3065 struct slccb *cb = slp->sl_Qnexus; 3066 3067 slp->sl_ph_count ++; 3068 if (cb == NULL) 3069 { 3070 /* 3071 * no ccb, abort! 3072 */ 3073 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd; 3074 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd); 3075 slp->sl_scp.scp_datalen = 0; 3076 slp->sl_scp.scp_direction = SCSI_LOW_READ; 3077 slp->sl_error |= FATALIO; 3078 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3079 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found"); 3080 return EINVAL; 3081 } 3082 else 3083 { 3084#ifdef SCSI_LOW_DEBUG 3085 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id)) 3086 { 3087 scsi_low_test_cmdlnk(slp, cb); 3088 } 3089#endif /* SCSI_LOW_DEBUG */ 3090 } 3091 return 0; 3092} 3093 3094/************************************************************** 3095 * data out pointer setup 3096 **************************************************************/ 3097int 3098scsi_low_data(slp, ti, bp, direction) 3099 struct scsi_low_softc *slp; 3100 struct targ_info *ti; 3101 struct buf **bp; 3102 int direction; 3103{ 3104 struct slccb *cb = slp->sl_Qnexus; 3105 3106 if (cb != NULL && direction == cb->ccb_sscp.scp_direction) 3107 { 3108 *bp = cb->bp; 3109 return 0; 3110 } 3111 3112 slp->sl_error |= (FATALIO | PDMAERR); 3113 slp->sl_scp.scp_datalen = 0; 3114 slp->sl_scp.scp_direction = direction; 3115 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3116 if (ti->ti_ophase != ti->ti_phase) 3117 { 3118 char *s; 3119 3120 if (cb == NULL) 3121 s = "DATA PHASE: ccb nexus not found"; 3122 else 3123 s = "DATA PHASE: xfer direction mismatch"; 3124 SCSI_LOW_INFO(slp, ti, s); 3125 } 3126 3127 *bp = NULL; 3128 return EINVAL; 3129} 3130 3131/************************************************************** 3132 * MSG_SYS 3133 **************************************************************/ 3134#define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;} 3135#define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3]) 3136#define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4]) 3137#define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3]) 3138#define MSGIN_DATA_LAST 0x30 3139 3140static int scsi_low_errfunc_synch(struct scsi_low_softc *, u_int); 3141static int scsi_low_errfunc_wide(struct scsi_low_softc *, u_int); 3142static int scsi_low_errfunc_identify(struct scsi_low_softc *, u_int); 3143static int scsi_low_errfunc_qtag(struct scsi_low_softc *, u_int); 3144 3145static int scsi_low_msgfunc_synch(struct scsi_low_softc *); 3146static int scsi_low_msgfunc_wide(struct scsi_low_softc *); 3147static int scsi_low_msgfunc_identify(struct scsi_low_softc *); 3148static int scsi_low_msgfunc_abort(struct scsi_low_softc *); 3149static int scsi_low_msgfunc_qabort(struct scsi_low_softc *); 3150static int scsi_low_msgfunc_qtag(struct scsi_low_softc *); 3151static int scsi_low_msgfunc_reset(struct scsi_low_softc *); 3152 3153struct scsi_low_msgout_data { 3154 u_int md_flags; 3155 u_int8_t md_msg; 3156 int (*md_msgfunc)(struct scsi_low_softc *); 3157 int (*md_errfunc)(struct scsi_low_softc *, u_int); 3158#define MSG_RELEASE_ATN 0x0001 3159 u_int md_condition; 3160}; 3161 3162struct scsi_low_msgout_data scsi_low_msgout_data[] = { 3163/* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN}, 3164/* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN}, 3165/* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN}, 3166/* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN}, 3167/* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0}, 3168/* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN}, 3169/* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN}, 3170/* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0}, 3171/* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0}, 3172/* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0}, 3173/* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN}, 3174/* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN}, 3175/* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN}, 3176/* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN}, 3177/* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN}, 3178/* 15 */{SCSI_LOW_MSG_ALL, 0}, 3179}; 3180 3181static int scsi_low_msginfunc_ext(struct scsi_low_softc *); 3182static int scsi_low_synch(struct scsi_low_softc *); 3183static int scsi_low_wide(struct scsi_low_softc *); 3184static int scsi_low_msginfunc_msg_reject(struct scsi_low_softc *); 3185static int scsi_low_msginfunc_rejop(struct scsi_low_softc *); 3186static int scsi_low_msginfunc_rp(struct scsi_low_softc *); 3187static int scsi_low_msginfunc_sdp(struct scsi_low_softc *); 3188static int scsi_low_msginfunc_disc(struct scsi_low_softc *); 3189static int scsi_low_msginfunc_cc(struct scsi_low_softc *); 3190static int scsi_low_msginfunc_lcc(struct scsi_low_softc *); 3191static int scsi_low_msginfunc_parity(struct scsi_low_softc *); 3192static int scsi_low_msginfunc_noop(struct scsi_low_softc *); 3193static int scsi_low_msginfunc_simple_qtag(struct scsi_low_softc *); 3194static int scsi_low_msginfunc_i_wide_residue(struct scsi_low_softc *); 3195 3196struct scsi_low_msgin_data { 3197 u_int md_len; 3198 int (*md_msgfunc)(struct scsi_low_softc *); 3199}; 3200 3201struct scsi_low_msgin_data scsi_low_msgin_data[] = { 3202/* 0 */ {1, scsi_low_msginfunc_cc}, 3203/* 1 */ {2, scsi_low_msginfunc_ext}, 3204/* 2 */ {1, scsi_low_msginfunc_sdp}, 3205/* 3 */ {1, scsi_low_msginfunc_rp}, 3206/* 4 */ {1, scsi_low_msginfunc_disc}, 3207/* 5 */ {1, scsi_low_msginfunc_rejop}, 3208/* 6 */ {1, scsi_low_msginfunc_rejop}, 3209/* 7 */ {1, scsi_low_msginfunc_msg_reject}, 3210/* 8 */ {1, scsi_low_msginfunc_noop}, 3211/* 9 */ {1, scsi_low_msginfunc_parity}, 3212/* a */ {1, scsi_low_msginfunc_lcc}, 3213/* b */ {1, scsi_low_msginfunc_lcc}, 3214/* c */ {1, scsi_low_msginfunc_rejop}, 3215/* d */ {2, scsi_low_msginfunc_rejop}, 3216/* e */ {1, scsi_low_msginfunc_rejop}, 3217/* f */ {1, scsi_low_msginfunc_rejop}, 3218/* 0x10 */ {1, scsi_low_msginfunc_rejop}, 3219/* 0x11 */ {1, scsi_low_msginfunc_rejop}, 3220/* 0x12 */ {1, scsi_low_msginfunc_rejop}, 3221/* 0x13 */ {1, scsi_low_msginfunc_rejop}, 3222/* 0x14 */ {1, scsi_low_msginfunc_rejop}, 3223/* 0x15 */ {1, scsi_low_msginfunc_rejop}, 3224/* 0x16 */ {1, scsi_low_msginfunc_rejop}, 3225/* 0x17 */ {1, scsi_low_msginfunc_rejop}, 3226/* 0x18 */ {1, scsi_low_msginfunc_rejop}, 3227/* 0x19 */ {1, scsi_low_msginfunc_rejop}, 3228/* 0x1a */ {1, scsi_low_msginfunc_rejop}, 3229/* 0x1b */ {1, scsi_low_msginfunc_rejop}, 3230/* 0x1c */ {1, scsi_low_msginfunc_rejop}, 3231/* 0x1d */ {1, scsi_low_msginfunc_rejop}, 3232/* 0x1e */ {1, scsi_low_msginfunc_rejop}, 3233/* 0x1f */ {1, scsi_low_msginfunc_rejop}, 3234/* 0x20 */ {2, scsi_low_msginfunc_simple_qtag}, 3235/* 0x21 */ {2, scsi_low_msginfunc_rejop}, 3236/* 0x22 */ {2, scsi_low_msginfunc_rejop}, 3237/* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue}, 3238/* 0x24 */ {2, scsi_low_msginfunc_rejop}, 3239/* 0x25 */ {2, scsi_low_msginfunc_rejop}, 3240/* 0x26 */ {2, scsi_low_msginfunc_rejop}, 3241/* 0x27 */ {2, scsi_low_msginfunc_rejop}, 3242/* 0x28 */ {2, scsi_low_msginfunc_rejop}, 3243/* 0x29 */ {2, scsi_low_msginfunc_rejop}, 3244/* 0x2a */ {2, scsi_low_msginfunc_rejop}, 3245/* 0x2b */ {2, scsi_low_msginfunc_rejop}, 3246/* 0x2c */ {2, scsi_low_msginfunc_rejop}, 3247/* 0x2d */ {2, scsi_low_msginfunc_rejop}, 3248/* 0x2e */ {2, scsi_low_msginfunc_rejop}, 3249/* 0x2f */ {2, scsi_low_msginfunc_rejop}, 3250/* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */ 3251}; 3252 3253/************************************************************** 3254 * msgout 3255 **************************************************************/ 3256static int 3257scsi_low_msgfunc_synch(slp) 3258 struct scsi_low_softc *slp; 3259{ 3260 struct targ_info *ti = slp->sl_Tnexus; 3261 int ptr = ti->ti_msgoutlen; 3262 3263 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN; 3264 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE; 3265 ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period; 3266 ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset; 3267 return MSG_EXTEND_SYNCHLEN + 2; 3268} 3269 3270static int 3271scsi_low_msgfunc_wide(slp) 3272 struct scsi_low_softc *slp; 3273{ 3274 struct targ_info *ti = slp->sl_Tnexus; 3275 int ptr = ti->ti_msgoutlen; 3276 3277 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN; 3278 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE; 3279 ti->ti_msgoutstr[ptr + 3] = ti->ti_width; 3280 return MSG_EXTEND_WIDELEN + 2; 3281} 3282 3283static int 3284scsi_low_msgfunc_identify(slp) 3285 struct scsi_low_softc *slp; 3286{ 3287 struct targ_info *ti = slp->sl_Tnexus; 3288 struct lun_info *li = slp->sl_Lnexus; 3289 struct slccb *cb = slp->sl_Qnexus; 3290 int ptr = ti->ti_msgoutlen; 3291 u_int8_t msg; 3292 3293 msg = MSG_IDENTIFY; 3294 if (cb == NULL) 3295 { 3296 slp->sl_error |= FATALIO; 3297 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3298 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown"); 3299 } 3300 else 3301 { 3302 if (scsi_low_is_disconnect_ok(cb) != 0) 3303 msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun); 3304 else 3305 msg |= li->li_lun; 3306 3307 if (ti->ti_phase == PH_MSGOUT) 3308 { 3309 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp); 3310 if (cb->ccb_tag == SCSI_LOW_UNKTAG) 3311 { 3312 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp); 3313 } 3314 } 3315 } 3316 ti->ti_msgoutstr[ptr + 0] = msg; 3317 return 1; 3318} 3319 3320static int 3321scsi_low_msgfunc_abort(slp) 3322 struct scsi_low_softc *slp; 3323{ 3324 3325 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT); 3326 return 1; 3327} 3328 3329static int 3330scsi_low_msgfunc_qabort(slp) 3331 struct scsi_low_softc *slp; 3332{ 3333 3334 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM); 3335 return 1; 3336} 3337 3338static int 3339scsi_low_msgfunc_reset(slp) 3340 struct scsi_low_softc *slp; 3341{ 3342 3343 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET); 3344 return 1; 3345} 3346 3347static int 3348scsi_low_msgfunc_qtag(slp) 3349 struct scsi_low_softc *slp; 3350{ 3351 struct targ_info *ti = slp->sl_Tnexus; 3352 struct slccb *cb = slp->sl_Qnexus; 3353 int ptr = ti->ti_msgoutlen; 3354 3355 if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG) 3356 { 3357 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP; 3358 return 1; 3359 } 3360 else 3361 { 3362 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag; 3363 if (ti->ti_phase == PH_MSGOUT) 3364 { 3365 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp); 3366 } 3367 } 3368 return 2; 3369} 3370 3371/* 3372 * The following functions are called when targets give unexpected 3373 * responces in msgin (after msgout). 3374 */ 3375static int 3376scsi_low_errfunc_identify(slp, msgflags) 3377 struct scsi_low_softc *slp; 3378 u_int msgflags; 3379{ 3380 3381 if (slp->sl_Lnexus != NULL) 3382 { 3383 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC; 3384 scsi_low_calcf_lun(slp->sl_Lnexus); 3385 } 3386 return 0; 3387} 3388 3389static int 3390scsi_low_errfunc_synch(slp, msgflags) 3391 struct scsi_low_softc *slp; 3392 u_int msgflags; 3393{ 3394 struct targ_info *ti = slp->sl_Tnexus; 3395 3396 MSGIN_PERIOD(ti) = 0; 3397 MSGIN_OFFSET(ti) = 0; 3398 scsi_low_synch(slp); 3399 return 0; 3400} 3401 3402static int 3403scsi_low_errfunc_wide(slp, msgflags) 3404 struct scsi_low_softc *slp; 3405 u_int msgflags; 3406{ 3407 struct targ_info *ti = slp->sl_Tnexus; 3408 3409 MSGIN_WIDTHP(ti) = 0; 3410 scsi_low_wide(slp); 3411 return 0; 3412} 3413 3414static int 3415scsi_low_errfunc_qtag(slp, msgflags) 3416 struct scsi_low_softc *slp; 3417 u_int msgflags; 3418{ 3419 3420 if ((msgflags & SCSI_LOW_MSG_REJECT) != 0) 3421 { 3422 if (slp->sl_Qnexus != NULL) 3423 { 3424 scsi_low_deactivate_qtag(slp->sl_Qnexus); 3425 } 3426 if (slp->sl_Lnexus != NULL) 3427 { 3428 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG; 3429 scsi_low_calcf_lun(slp->sl_Lnexus); 3430 } 3431 printf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname); 3432 } 3433 return 0; 3434} 3435 3436 3437int 3438scsi_low_msgout(slp, ti, fl) 3439 struct scsi_low_softc *slp; 3440 struct targ_info *ti; 3441 u_int fl; 3442{ 3443 struct scsi_low_msgout_data *mdp; 3444 int len = 0; 3445 3446#ifdef SCSI_LOW_DIAGNOSTIC 3447 if (ti != slp->sl_Tnexus) 3448 { 3449 scsi_low_print(slp, NULL); 3450 panic("scsi_low_msgout: Target nexus inconsistent"); 3451 } 3452#endif /* SCSI_LOW_DIAGNOSTIC */ 3453 3454 slp->sl_ph_count ++; 3455 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES) 3456 { 3457 printf("%s: too many phase changes\n", slp->sl_xname); 3458 slp->sl_error |= FATALIO; 3459 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3460 } 3461 3462 /* STEP I. 3463 * Scsi phase changes. 3464 * Previously msgs asserted are accepted by our target or 3465 * processed by scsi_low_msgin. 3466 * Thus clear all saved informations. 3467 */ 3468 if ((fl & SCSI_LOW_MSGOUT_INIT) != 0) 3469 { 3470 ti->ti_omsgflags = 0; 3471 ti->ti_emsgflags = 0; 3472 } 3473 else if (slp->sl_atten == 0) 3474 { 3475 /* STEP II. 3476 * We did not assert attention, however still our target required 3477 * msgs. Resend previous msgs. 3478 */ 3479 ti->ti_msgflags |= ti->ti_omsgflags; 3480 ti->ti_omsgflags = 0; 3481#ifdef SCSI_LOW_DIAGNOSTIC 3482 printf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname); 3483#endif /* SCSI_LOW_DIAGNOSTIC */ 3484 } 3485 3486 /* STEP III. 3487 * We have no msgs. send MSG_NOOP (OK?) 3488 */ 3489 if (scsi_low_is_msgout_continue(ti, 0) == 0) 3490 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0); 3491 3492 /* STEP IV. 3493 * Process all msgs 3494 */ 3495 ti->ti_msgoutlen = 0; 3496 slp->sl_clear_atten = 0; 3497 mdp = &scsi_low_msgout_data[0]; 3498 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++) 3499 { 3500 if ((ti->ti_msgflags & mdp->md_flags) != 0) 3501 { 3502 ti->ti_omsgflags |= mdp->md_flags; 3503 ti->ti_msgflags &= ~mdp->md_flags; 3504 ti->ti_emsgflags = mdp->md_flags; 3505 3506 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg; 3507 if (mdp->md_msgfunc != NULL) 3508 len = (*mdp->md_msgfunc) (slp); 3509 else 3510 len = 1; 3511 3512#ifdef SCSI_LOW_DIAGNOSTIC 3513 scsi_low_msg_log_write(&ti->ti_log_msgout, 3514 &ti->ti_msgoutstr[ti->ti_msgoutlen], len); 3515#endif /* SCSI_LOW_DIAGNOSTIC */ 3516 3517 ti->ti_msgoutlen += len; 3518 if ((mdp->md_condition & MSG_RELEASE_ATN) != 0) 3519 { 3520 slp->sl_clear_atten = 1; 3521 break; 3522 } 3523 3524 if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 || 3525 ti->ti_msgflags == 0) 3526 break; 3527 3528 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5) 3529 break; 3530 } 3531 } 3532 3533 if (scsi_low_is_msgout_continue(ti, 0) == 0) 3534 slp->sl_clear_atten = 1; 3535 3536 return ti->ti_msgoutlen; 3537} 3538 3539/************************************************************** 3540 * msgin 3541 **************************************************************/ 3542static int 3543scsi_low_msginfunc_noop(slp) 3544 struct scsi_low_softc *slp; 3545{ 3546 3547 return 0; 3548} 3549 3550static int 3551scsi_low_msginfunc_rejop(slp) 3552 struct scsi_low_softc *slp; 3553{ 3554 struct targ_info *ti = slp->sl_Tnexus; 3555 u_int8_t msg = ti->ti_msgin[0]; 3556 3557 printf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg); 3558 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 3559 return 0; 3560} 3561 3562static int 3563scsi_low_msginfunc_cc(slp) 3564 struct scsi_low_softc *slp; 3565{ 3566 struct lun_info *li; 3567 3568 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC); 3569 3570 /* validate status */ 3571 if (slp->sl_Qnexus == NULL) 3572 return ENOENT; 3573 3574 slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status; 3575 li = slp->sl_Lnexus; 3576 switch (slp->sl_scp.scp_status) 3577 { 3578 case ST_GOOD: 3579 li->li_maxnqio = li->li_maxnexus; 3580 break; 3581 3582 case ST_CHKCOND: 3583 li->li_maxnqio = 0; 3584 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR) 3585 scsi_low_reset_nexus_lun(slp, li, 0); 3586 break; 3587 3588 case ST_BUSY: 3589 li->li_maxnqio = 0; 3590 break; 3591 3592 case ST_QUEFULL: 3593 if (li->li_maxnexus >= li->li_nqio) 3594 li->li_maxnexus = li->li_nqio - 1; 3595 li->li_maxnqio = li->li_maxnexus; 3596 break; 3597 3598 case ST_INTERGOOD: 3599 case ST_INTERMET: 3600 slp->sl_error |= MSGERR; 3601 break; 3602 3603 default: 3604 break; 3605 } 3606 return 0; 3607} 3608 3609static int 3610scsi_low_msginfunc_lcc(slp) 3611 struct scsi_low_softc *slp; 3612{ 3613 struct targ_info *ti; 3614 struct lun_info *li; 3615 struct slccb *ncb, *cb; 3616 3617 ti = slp->sl_Tnexus; 3618 li = slp->sl_Lnexus; 3619 if ((cb = slp->sl_Qnexus) == NULL) 3620 goto bad; 3621 3622 cb->ccb_sscp.scp_status = slp->sl_scp.scp_status; 3623 switch (slp->sl_scp.scp_status) 3624 { 3625 case ST_INTERGOOD: 3626 case ST_INTERMET: 3627 li->li_maxnqio = li->li_maxnexus; 3628 break; 3629 3630 default: 3631 slp->sl_error |= MSGERR; 3632 break; 3633 } 3634 3635 if ((li->li_flags & SCSI_LOW_LINK) == 0) 3636 goto bad; 3637 3638 cb->ccb_error |= slp->sl_error; 3639 if (cb->ccb_error != 0) 3640 goto bad; 3641 3642 for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL; 3643 ncb = TAILQ_NEXT(ncb, ccb_chain)) 3644 { 3645 if (ncb->li == li) 3646 goto cmd_link_start; 3647 } 3648 3649 3650bad: 3651 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM); 3652 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 3653 return EIO; 3654 3655cmd_link_start: 3656 ncb->ccb_flags &= ~CCB_STARTQ; 3657 TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain); 3658 3659 scsi_low_dealloc_qtag(ncb); 3660 ncb->ccb_tag = cb->ccb_tag; 3661 ncb->ccb_otag = cb->ccb_otag; 3662 cb->ccb_tag = SCSI_LOW_UNKTAG; 3663 cb->ccb_otag = SCSI_LOW_UNKTAG; 3664 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY) 3665 panic("%s: linked ccb retried", slp->sl_xname); 3666 3667 slp->sl_Qnexus = ncb; 3668 slp->sl_ph_count = 0; 3669 3670 ncb->ccb_error = 0; 3671 ncb->ccb_datalen = -1; 3672 ncb->ccb_scp.scp_status = ST_UNKNOWN; 3673 ncb->ccb_flags &= ~CCB_INTERNAL; 3674 3675 scsi_low_init_msgsys(slp, ti); 3676 3677 (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb); 3678 3679 if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT) 3680 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 3681 ncb->ccb_tc = ncb->ccb_tcmax; 3682 3683 /* setup saved scsi data pointer */ 3684 ncb->ccb_sscp = ncb->ccb_scp; 3685 slp->sl_scp = ncb->ccb_sscp; 3686 slp->sl_error = ncb->ccb_error; 3687 3688#ifdef SCSI_LOW_DIAGNOSTIC 3689 scsi_low_msg_log_init(&ti->ti_log_msgin); 3690 scsi_low_msg_log_init(&ti->ti_log_msgout); 3691#endif /* SCSI_LOW_DIAGNOSTIC */ 3692 return EJUSTRETURN; 3693} 3694 3695static int 3696scsi_low_msginfunc_disc(slp) 3697 struct scsi_low_softc *slp; 3698{ 3699 3700 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC); 3701 return 0; 3702} 3703 3704static int 3705scsi_low_msginfunc_sdp(slp) 3706 struct scsi_low_softc *slp; 3707{ 3708 struct slccb *cb = slp->sl_Qnexus; 3709 3710 if (cb != NULL) 3711 { 3712 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen; 3713 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data; 3714 } 3715 else 3716 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0); 3717 return 0; 3718} 3719 3720static int 3721scsi_low_msginfunc_rp(slp) 3722 struct scsi_low_softc *slp; 3723{ 3724 3725 if (slp->sl_Qnexus != NULL) 3726 slp->sl_scp = slp->sl_Qnexus->ccb_sscp; 3727 else 3728 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0); 3729 return 0; 3730} 3731 3732static int 3733scsi_low_synch(slp) 3734 struct scsi_low_softc *slp; 3735{ 3736 struct targ_info *ti = slp->sl_Tnexus; 3737 u_int period = 0, offset = 0, speed; 3738 u_char *s; 3739 int error; 3740 3741 if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period && 3742 MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) || 3743 MSGIN_OFFSET(ti) == 0) 3744 { 3745 if ((offset = MSGIN_OFFSET(ti)) != 0) 3746 period = MSGIN_PERIOD(ti); 3747 s = offset ? "synchronous" : "async"; 3748 } 3749 else 3750 { 3751 /* XXX: 3752 * Target seems to be brain damaged. 3753 * Force async transfer. 3754 */ 3755 ti->ti_maxsynch.period = 0; 3756 ti->ti_maxsynch.offset = 0; 3757 printf("%s: target brain damaged. async transfer\n", 3758 slp->sl_xname); 3759 return EINVAL; 3760 } 3761 3762 ti->ti_maxsynch.period = period; 3763 ti->ti_maxsynch.offset = offset; 3764 3765 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH); 3766 if (error != 0) 3767 { 3768 /* XXX: 3769 * Current period and offset are not acceptable 3770 * for our adapter. 3771 * The adapter changes max synch and max offset. 3772 */ 3773 printf("%s: synch neg failed. retry synch msg neg ...\n", 3774 slp->sl_xname); 3775 return error; 3776 } 3777 3778 ti->ti_osynch = ti->ti_maxsynch; 3779 if (offset > 0) 3780 { 3781 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH; 3782 } 3783 3784 /* inform data */ 3785 if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0) 3786 { 3787#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE 3788 struct slccb *cb = slp->sl_Qnexus; 3789 3790 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0) 3791 return 0; 3792#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */ 3793 3794 printf("%s(%d:*): <%s> offset %d period %dns ", 3795 slp->sl_xname, ti->ti_id, s, offset, period * 4); 3796 3797 if (period != 0) 3798 { 3799 speed = 1000 * 10 / (period * 4); 3800 printf("%d.%d M/s", speed / 10, speed % 10); 3801 } 3802 printf("\n"); 3803 } 3804 return 0; 3805} 3806 3807static int 3808scsi_low_wide(slp) 3809 struct scsi_low_softc *slp; 3810{ 3811 struct targ_info *ti = slp->sl_Tnexus; 3812 int error; 3813 3814 ti->ti_width = MSGIN_WIDTHP(ti); 3815 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE); 3816 if (error != 0) 3817 { 3818 /* XXX: 3819 * Current width is not acceptable for our adapter. 3820 * The adapter changes max width. 3821 */ 3822 printf("%s: wide neg failed. retry wide msg neg ...\n", 3823 slp->sl_xname); 3824 return error; 3825 } 3826 3827 ti->ti_owidth = ti->ti_width; 3828 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8) 3829 { 3830 ti->ti_setup_msg_done |= 3831 (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE); 3832 } 3833 3834 /* inform data */ 3835 if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0) 3836 { 3837#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE 3838 struct slccb *cb = slp->sl_Qnexus; 3839 3840 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0) 3841 return 0; 3842#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */ 3843 3844 printf("%s(%d:*): transfer width %d bits\n", 3845 slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width)); 3846 } 3847 return 0; 3848} 3849 3850static int 3851scsi_low_msginfunc_simple_qtag(slp) 3852 struct scsi_low_softc *slp; 3853{ 3854 struct targ_info *ti = slp->sl_Tnexus; 3855 scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1]; 3856 3857 if (slp->sl_Qnexus != NULL) 3858 { 3859 if (slp->sl_Qnexus->ccb_tag != etag) 3860 { 3861 slp->sl_error |= FATALIO; 3862 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3863 SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch"); 3864 } 3865 } 3866 else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL) 3867 { 3868#ifdef SCSI_LOW_DEBUG 3869 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id)) 3870 return 0; 3871#endif /* SCSI_LOW_DEBUG */ 3872 3873 slp->sl_error |= FATALIO; 3874 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0); 3875 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found"); 3876 } 3877 return 0; 3878} 3879 3880static int 3881scsi_low_msginfunc_i_wide_residue(slp) 3882 struct scsi_low_softc *slp; 3883{ 3884 struct targ_info *ti = slp->sl_Tnexus; 3885 struct slccb *cb = slp->sl_Qnexus; 3886 int res = (int) ti->ti_msgin[1]; 3887 3888 if (cb == NULL || res <= 0 || 3889 (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) || 3890 (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3)) 3891 return EINVAL; 3892 3893 if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen) 3894 return EINVAL; 3895 3896 slp->sl_scp.scp_datalen += res; 3897 slp->sl_scp.scp_data -= res; 3898 scsi_low_data_finish(slp); 3899 return 0; 3900} 3901 3902static int 3903scsi_low_msginfunc_ext(slp) 3904 struct scsi_low_softc *slp; 3905{ 3906 struct slccb *cb = slp->sl_Qnexus; 3907 struct lun_info *li = slp->sl_Lnexus; 3908 struct targ_info *ti = slp->sl_Tnexus; 3909 int count, retry; 3910 u_int32_t *ptr; 3911 3912 if (ti->ti_msginptr == 2) 3913 { 3914 ti->ti_msginlen = ti->ti_msgin[1] + 2; 3915 return 0; 3916 } 3917 3918 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2])) 3919 { 3920 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE): 3921 if (cb == NULL) 3922 break; 3923 3924 ptr = (u_int32_t *)(&ti->ti_msgin[3]); 3925 count = (int) htonl((long) (*ptr)); 3926 if(slp->sl_scp.scp_datalen - count < 0 || 3927 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen) 3928 break; 3929 3930 slp->sl_scp.scp_datalen -= count; 3931 slp->sl_scp.scp_data += count; 3932 return 0; 3933 3934 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE): 3935 if (li == NULL) 3936 break; 3937 3938 retry = scsi_low_synch(slp); 3939 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0) 3940 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0); 3941 3942#ifdef SCSI_LOW_DEBUG 3943 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id)) 3944 { 3945 scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH); 3946 } 3947#endif /* SCSI_LOW_DEBUG */ 3948 return 0; 3949 3950 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE): 3951 if (li == NULL) 3952 break; 3953 3954 retry = scsi_low_wide(slp); 3955 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0) 3956 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0); 3957 3958 return 0; 3959 3960 default: 3961 break; 3962 } 3963 3964 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 3965 return EINVAL; 3966} 3967 3968static int 3969scsi_low_msginfunc_parity(slp) 3970 struct scsi_low_softc *slp; 3971{ 3972 struct targ_info *ti = slp->sl_Tnexus; 3973 3974 /* only I -> T, invalid! */ 3975 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 3976 return 0; 3977} 3978 3979static int 3980scsi_low_msginfunc_msg_reject(slp) 3981 struct scsi_low_softc *slp; 3982{ 3983 struct targ_info *ti = slp->sl_Tnexus; 3984 struct scsi_low_msgout_data *mdp; 3985 u_int msgflags; 3986 3987 if (ti->ti_emsgflags != 0) 3988 { 3989 printf("%s: msg flags [0x%x] rejected\n", 3990 slp->sl_xname, ti->ti_emsgflags); 3991 msgflags = SCSI_LOW_MSG_REJECT; 3992 mdp = &scsi_low_msgout_data[0]; 3993 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++) 3994 { 3995 if ((ti->ti_emsgflags & mdp->md_flags) != 0) 3996 { 3997 ti->ti_emsgflags &= ~mdp->md_flags; 3998 if (mdp->md_errfunc != NULL) 3999 (*mdp->md_errfunc) (slp, msgflags); 4000 break; 4001 } 4002 } 4003 return 0; 4004 } 4005 else 4006 { 4007 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found"); 4008 slp->sl_error |= MSGERR; 4009 } 4010 return EINVAL; 4011} 4012 4013int 4014scsi_low_msgin(slp, ti, c) 4015 struct scsi_low_softc *slp; 4016 struct targ_info *ti; 4017 u_int c; 4018{ 4019 struct scsi_low_msgin_data *sdp; 4020 struct lun_info *li; 4021 u_int8_t msg; 4022 4023#ifdef SCSI_LOW_DIAGNOSTIC 4024 if (ti != slp->sl_Tnexus) 4025 { 4026 scsi_low_print(slp, NULL); 4027 panic("scsi_low_msgin: Target nexus inconsistent"); 4028 } 4029#endif /* SCSI_LOW_DIAGNOSTIC */ 4030 4031 /* 4032 * Phase changes, clear the pointer. 4033 */ 4034 if (ti->ti_ophase != ti->ti_phase) 4035 { 4036 MSGINPTR_CLR(ti); 4037 ti->ti_msgin_parity_error = 0; 4038 4039 slp->sl_ph_count ++; 4040 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES) 4041 { 4042 printf("%s: too many phase changes\n", slp->sl_xname); 4043 slp->sl_error |= FATALIO; 4044 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 4045 } 4046 } 4047 4048 /* 4049 * Store a current messages byte into buffer and 4050 * wait for the completion of the current msg. 4051 */ 4052 ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c; 4053 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN) 4054 { 4055 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1; 4056 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 4057 } 4058 4059 /* 4060 * Check parity errors. 4061 */ 4062 if ((c & SCSI_LOW_DATA_PE) != 0) 4063 { 4064 ti->ti_msgin_parity_error ++; 4065 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0); 4066 goto out; 4067 } 4068 4069 if (ti->ti_msgin_parity_error != 0) 4070 goto out; 4071 4072 /* 4073 * Calculate messages length. 4074 */ 4075 msg = ti->ti_msgin[0]; 4076 if (msg < MSGIN_DATA_LAST) 4077 sdp = &scsi_low_msgin_data[msg]; 4078 else 4079 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST]; 4080 4081 if (ti->ti_msginlen == 0) 4082 { 4083 ti->ti_msginlen = sdp->md_len; 4084 } 4085 4086 /* 4087 * Check comletion. 4088 */ 4089 if (ti->ti_msginptr < ti->ti_msginlen) 4090 return EJUSTRETURN; 4091 4092 /* 4093 * Do process. 4094 */ 4095 if ((msg & MSG_IDENTIFY) == 0) 4096 { 4097 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN) 4098 return EJUSTRETURN; 4099 } 4100 else 4101 { 4102 li = slp->sl_Lnexus; 4103 if (li == NULL) 4104 { 4105 li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0); 4106 if (li == NULL) 4107 goto badlun; 4108 slp->sl_Lnexus = li; 4109 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp); 4110 } 4111 else 4112 { 4113 if (MSGCMD_LUN(msg) != li->li_lun) 4114 goto badlun; 4115 } 4116 4117 if (slp->sl_Qnexus == NULL && li->li_nqio == 0) 4118 { 4119 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG)) 4120 { 4121#ifdef SCSI_LOW_DEBUG 4122 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0) 4123 { 4124 goto out; 4125 } 4126#endif /* SCSI_LOW_DEBUG */ 4127 goto badlun; 4128 } 4129 } 4130 } 4131 goto out; 4132 4133 /* 4134 * Msg process completed, reset msgin pointer and assert ATN if desired. 4135 */ 4136badlun: 4137 slp->sl_error |= FATALIO; 4138 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 4139 SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong"); 4140 4141out: 4142 if (ti->ti_msginptr < ti->ti_msginlen) 4143 return EJUSTRETURN; 4144 4145#ifdef SCSI_LOW_DIAGNOSTIC 4146 scsi_low_msg_log_write(&ti->ti_log_msgin, 4147 &ti->ti_msgin[0], ti->ti_msginlen); 4148#endif /* SCSI_LOW_DIAGNOSTIC */ 4149 4150 MSGINPTR_CLR(ti); 4151 return 0; 4152} 4153 4154/********************************************************** 4155 * disconnect 4156 **********************************************************/ 4157int 4158scsi_low_disconnected(slp, ti) 4159 struct scsi_low_softc *slp; 4160 struct targ_info *ti; 4161{ 4162 struct slccb *cb = slp->sl_Qnexus; 4163 4164 /* check phase completion */ 4165 switch (slp->sl_msgphase) 4166 { 4167 case MSGPH_RESET: 4168 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD); 4169 scsi_low_msginfunc_cc(slp); 4170 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0); 4171 goto io_resume; 4172 4173 case MSGPH_ABORT: 4174 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD); 4175 scsi_low_msginfunc_cc(slp); 4176 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0); 4177 goto io_resume; 4178 4179 case MSGPH_TERM: 4180 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD); 4181 scsi_low_msginfunc_cc(slp); 4182 goto io_resume; 4183 4184 case MSGPH_DISC: 4185 if (cb != NULL) 4186 { 4187 struct lun_info *li; 4188 4189 li = cb->li; 4190 TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain); 4191 cb->ccb_flags |= CCB_DISCQ; 4192 cb->ccb_error |= slp->sl_error; 4193 li->li_disc ++; 4194 ti->ti_disc ++; 4195 slp->sl_disc ++; 4196 } 4197 4198#ifdef SCSI_LOW_STATICS 4199 scsi_low_statics.nexus_disconnected ++; 4200#endif /* SCSI_LOW_STATICS */ 4201 4202#ifdef SCSI_LOW_DEBUG 4203 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0) 4204 { 4205 printf("## SCSI_LOW_DISCONNECTED ===============\n"); 4206 scsi_low_print(slp, NULL); 4207 } 4208#endif /* SCSI_LOW_DEBUG */ 4209 break; 4210 4211 case MSGPH_NULL: 4212 slp->sl_error |= FATALIO; 4213 if (ti->ti_phase == PH_SELSTART) 4214 slp->sl_error |= SELTIMEOUTIO; 4215 else 4216 slp->sl_error |= UBFERR; 4217 /* fall through */ 4218 4219 case MSGPH_LCTERM: 4220 case MSGPH_CMDC: 4221io_resume: 4222 if (cb == NULL) 4223 break; 4224 4225#ifdef SCSI_LOW_DEBUG 4226 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id)) 4227 { 4228 if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP && 4229 (cb->ccb_msgoutflag != 0 || 4230 (ti->ti_msgflags & SCSI_LOW_MSG_NOOP))) 4231 { 4232 scsi_low_info(slp, ti, "ATTEN CHECK FAILED"); 4233 } 4234 } 4235#endif /* SCSI_LOW_DEBUG */ 4236 4237 cb->ccb_error |= slp->sl_error; 4238 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY) 4239 { 4240 cb->ccb_flags |= CCB_STARTQ; 4241 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 4242 } 4243 break; 4244 } 4245 4246 scsi_low_bus_release(slp, ti); 4247 scsi_low_start(slp); 4248 return 1; 4249} 4250 4251/********************************************************** 4252 * TAG operations 4253 **********************************************************/ 4254static int 4255scsi_low_alloc_qtag(cb) 4256 struct slccb *cb; 4257{ 4258 struct lun_info *li = cb->li; 4259 scsi_low_tag_t etag; 4260 4261 if (cb->ccb_otag != SCSI_LOW_UNKTAG) 4262 return 0; 4263 4264#ifndef SCSI_LOW_ALT_QTAG_ALLOCATE 4265 etag = ffs(li->li_qtagbits); 4266 if (etag == 0) 4267 return ENOSPC; 4268 4269 li->li_qtagbits &= ~(1 << (etag - 1)); 4270 cb->ccb_otag = etag; 4271 return 0; 4272 4273#else /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 4274 for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++) 4275 if (li->li_qtagarray[li->li_qd] == 0) 4276 goto found; 4277 4278 for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++) 4279 if (li->li_qtagarray[li->li_qd] == 0) 4280 goto found; 4281 4282 return ENOSPC; 4283 4284found: 4285 li->li_qtagarray[li->li_qd] ++; 4286 cb->ccb_otag = (li->li_qd ++); 4287 return 0; 4288#endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 4289} 4290 4291static int 4292scsi_low_dealloc_qtag(cb) 4293 struct slccb *cb; 4294{ 4295 struct lun_info *li = cb->li; 4296 scsi_low_tag_t etag; 4297 4298 if (cb->ccb_otag == SCSI_LOW_UNKTAG) 4299 return 0; 4300 4301#ifndef SCSI_LOW_ALT_QTAG_ALLOCATE 4302 etag = cb->ccb_otag - 1; 4303#ifdef SCSI_LOW_DIAGNOSTIC 4304 if (etag >= sizeof(li->li_qtagbits) * NBBY) 4305 panic("scsi_low_dealloc_tag: illegal tag"); 4306#endif /* SCSI_LOW_DIAGNOSTIC */ 4307 li->li_qtagbits |= (1 << etag); 4308 4309#else /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 4310 etag = cb->ccb_otag; 4311#ifdef SCSI_LOW_DIAGNOSTIC 4312 if (etag >= SCSI_LOW_MAXNEXUS) 4313 panic("scsi_low_dealloc_tag: illegal tag"); 4314#endif /* SCSI_LOW_DIAGNOSTIC */ 4315 li->li_qtagarray[etag] --; 4316#endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 4317 4318 cb->ccb_otag = SCSI_LOW_UNKTAG; 4319 return 0; 4320} 4321 4322static struct slccb * 4323scsi_low_revoke_ccb(slp, cb, fdone) 4324 struct scsi_low_softc *slp; 4325 struct slccb *cb; 4326 int fdone; 4327{ 4328 struct targ_info *ti = cb->ti; 4329 struct lun_info *li = cb->li; 4330 4331#ifdef SCSI_LOW_DIAGNOSTIC 4332 if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) == 4333 (CCB_STARTQ | CCB_DISCQ)) 4334 { 4335 panic("%s: ccb in both queue", slp->sl_xname); 4336 } 4337#endif /* SCSI_LOW_DIAGNOSTIC */ 4338 4339 if ((cb->ccb_flags & CCB_STARTQ) != 0) 4340 { 4341 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain); 4342 } 4343 4344 if ((cb->ccb_flags & CCB_DISCQ) != 0) 4345 { 4346 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain); 4347 li->li_disc --; 4348 ti->ti_disc --; 4349 slp->sl_disc --; 4350 } 4351 4352 cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ | 4353 CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL); 4354 4355 if (fdone != 0 && 4356 (cb->ccb_rcnt ++ >= slp->sl_max_retry || 4357 (cb->ccb_flags & CCB_NORETRY) != 0)) 4358 { 4359 cb->ccb_error |= FATALIO; 4360 cb->ccb_flags &= ~CCB_AUTOSENSE; 4361 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE) 4362 panic("%s: done ccb retried", slp->sl_xname); 4363 return NULL; 4364 } 4365 else 4366 { 4367 cb->ccb_error |= PENDINGIO; 4368 scsi_low_deactivate_qtag(cb); 4369 scsi_low_ccb_message_retry(cb); 4370 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 4371 return cb; 4372 } 4373} 4374 4375static void 4376scsi_low_reset_nexus_lun(slp, li, fdone) 4377 struct scsi_low_softc *slp; 4378 struct lun_info *li; 4379 int fdone; 4380{ 4381 struct slccb *cb, *ncb, *ecb; 4382 4383 if (li == NULL) 4384 return; 4385 4386 ecb = NULL; 4387 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb) 4388 { 4389 ncb = TAILQ_NEXT(cb, ccb_chain); 4390 cb = scsi_low_revoke_ccb(slp, cb, fdone); 4391 if (cb != NULL) 4392 { 4393 /* 4394 * presumely keep ordering of io 4395 */ 4396 cb->ccb_flags |= CCB_STARTQ; 4397 if (ecb == NULL) 4398 { 4399 TAILQ_INSERT_HEAD(&slp->sl_start,\ 4400 cb, ccb_chain); 4401 } 4402 else 4403 { 4404 TAILQ_INSERT_AFTER(&slp->sl_start,\ 4405 ecb, cb, ccb_chain); 4406 } 4407 ecb = cb; 4408 } 4409 } 4410} 4411 4412/************************************************************** 4413 * Qurik setup 4414 **************************************************************/ 4415static void 4416scsi_low_calcf_lun(li) 4417 struct lun_info *li; 4418{ 4419 struct targ_info *ti = li->li_ti; 4420 struct scsi_low_softc *slp = ti->ti_sc; 4421 u_int cfgflags, diskflags; 4422 4423 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID) 4424 cfgflags = li->li_cfgflags; 4425 else 4426 cfgflags = 0; 4427 4428 diskflags = li->li_diskflags & li->li_quirks; 4429 4430 /* disconnect */ 4431 li->li_flags &= ~SCSI_LOW_DISC; 4432 if ((slp->sl_cfgflags & CFG_NODISC) == 0 && 4433 (diskflags & SCSI_LOW_DISK_DISC) != 0 && 4434 (cfgflags & SCSI_LOW_DISC) != 0) 4435 li->li_flags |= SCSI_LOW_DISC; 4436 4437 /* parity */ 4438 li->li_flags |= SCSI_LOW_NOPARITY; 4439 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 && 4440 (diskflags & SCSI_LOW_DISK_PARITY) != 0 && 4441 (cfgflags & SCSI_LOW_NOPARITY) == 0) 4442 li->li_flags &= ~SCSI_LOW_NOPARITY; 4443 4444 /* qtag */ 4445 if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 && 4446 (cfgflags & SCSI_LOW_QTAG) != 0 && 4447 (diskflags & SCSI_LOW_DISK_QTAG) != 0) 4448 { 4449 li->li_flags |= SCSI_LOW_QTAG; 4450 li->li_maxnexus = SCSI_LOW_MAXNEXUS; 4451 li->li_maxnqio = li->li_maxnexus; 4452 } 4453 else 4454 { 4455 li->li_flags &= ~SCSI_LOW_QTAG; 4456 li->li_maxnexus = 0; 4457 li->li_maxnqio = li->li_maxnexus; 4458 } 4459 4460 /* cmd link */ 4461 li->li_flags &= ~SCSI_LOW_LINK; 4462 if ((cfgflags & SCSI_LOW_LINK) != 0 && 4463 (diskflags & SCSI_LOW_DISK_LINK) != 0) 4464 li->li_flags |= SCSI_LOW_LINK; 4465 4466 /* compatible flags */ 4467 li->li_flags &= ~SCSI_LOW_SYNC; 4468 if (ti->ti_maxsynch.offset > 0) 4469 li->li_flags |= SCSI_LOW_SYNC; 4470 4471#ifdef SCSI_LOW_DEBUG 4472 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0) 4473 { 4474 scsi_low_calcf_show(li); 4475 } 4476#endif /* SCSI_LOW_DEBUG */ 4477} 4478 4479static void 4480scsi_low_calcf_target(ti) 4481 struct targ_info *ti; 4482{ 4483 struct scsi_low_softc *slp = ti->ti_sc; 4484 u_int offset, period, diskflags; 4485 4486 diskflags = ti->ti_diskflags & ti->ti_quirks; 4487 4488 /* synch */ 4489 if ((slp->sl_cfgflags & CFG_ASYNC) == 0 && 4490 (diskflags & SCSI_LOW_DISK_SYNC) != 0) 4491 { 4492 offset = ti->ti_maxsynch.offset; 4493 period = ti->ti_maxsynch.period; 4494 if (offset == 0 || period == 0) 4495 offset = period = 0; 4496 } 4497 else 4498 { 4499 offset = period = 0; 4500 } 4501 4502 ti->ti_maxsynch.offset = offset; 4503 ti->ti_maxsynch.period = period; 4504 4505 /* wide */ 4506 if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 && 4507 ti->ti_width > SCSI_LOW_BUS_WIDTH_16) 4508 ti->ti_width = SCSI_LOW_BUS_WIDTH_16; 4509 4510 if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 && 4511 ti->ti_width > SCSI_LOW_BUS_WIDTH_8) 4512 ti->ti_width = SCSI_LOW_BUS_WIDTH_8; 4513 4514 if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID) 4515 { 4516 if (ti->ti_maxsynch.offset != ti->ti_osynch.offset || 4517 ti->ti_maxsynch.period != ti->ti_osynch.period) 4518 ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH; 4519 if (ti->ti_width != ti->ti_owidth) 4520 ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH); 4521 4522 ti->ti_osynch = ti->ti_maxsynch; 4523 ti->ti_owidth = ti->ti_width; 4524 } 4525 4526#ifdef SCSI_LOW_DEBUG 4527 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0) 4528 { 4529 printf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n", 4530 slp->sl_xname, ti->ti_id, 4531 ti->ti_maxsynch.period * 4, 4532 ti->ti_maxsynch.offset, 4533 ti->ti_width); 4534 } 4535#endif /* SCSI_LOW_DEBUG */ 4536} 4537 4538static void 4539scsi_low_calcf_show(li) 4540 struct lun_info *li; 4541{ 4542 struct targ_info *ti = li->li_ti; 4543 struct scsi_low_softc *slp = ti->ti_sc; 4544 4545 printf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n", 4546 slp->sl_xname, ti->ti_id, li->li_lun, 4547 ti->ti_maxsynch.period * 4, 4548 ti->ti_maxsynch.offset, 4549 ti->ti_width, 4550 li->li_flags, SCSI_LOW_BITS); 4551} 4552 4553#ifdef SCSI_LOW_START_UP_CHECK 4554/************************************************************** 4555 * scsi world start up 4556 **************************************************************/ 4557static int scsi_low_poll(struct scsi_low_softc *, struct slccb *); 4558 4559static int 4560scsi_low_start_up(slp) 4561 struct scsi_low_softc *slp; 4562{ 4563 struct targ_info *ti; 4564 struct lun_info *li; 4565 struct slccb *cb; 4566 int target, lun; 4567 4568 printf("%s: scsi_low: probing all devices ....\n", slp->sl_xname); 4569 4570 for (target = 0; target < slp->sl_ntargs; target ++) 4571 { 4572 if (target == slp->sl_hostid) 4573 { 4574 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) 4575 { 4576 printf("%s: scsi_low: target %d (host card)\n", 4577 slp->sl_xname, target); 4578 } 4579 continue; 4580 } 4581 4582 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) 4583 { 4584 printf("%s: scsi_low: target %d lun ", 4585 slp->sl_xname, target); 4586 } 4587 4588 ti = slp->sl_ti[target]; 4589 for (lun = 0; lun < slp->sl_nluns; lun ++) 4590 { 4591 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL) 4592 break; 4593 4594 cb->osdep = NULL; 4595 cb->bp = NULL; 4596 4597 li = scsi_low_alloc_li(ti, lun, 1); 4598 4599 scsi_low_enqueue(slp, ti, li, cb, 4600 CCB_AUTOSENSE | CCB_POLLED, 0); 4601 4602 scsi_low_poll(slp, cb); 4603 4604 if (li->li_state != SCSI_LOW_LUN_OK) 4605 break; 4606 4607 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) 4608 { 4609 printf("%d ", lun); 4610 } 4611 } 4612 4613 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) 4614 { 4615 printf("\n"); 4616 } 4617 } 4618 return 0; 4619} 4620 4621static int 4622scsi_low_poll(slp, cb) 4623 struct scsi_low_softc *slp; 4624 struct slccb *cb; 4625{ 4626 int tcount; 4627 4628 tcount = 0; 4629 while (slp->sl_nio > 0) 4630 { 4631 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ); 4632 4633 (*slp->sl_funcs->scsi_low_poll) (slp); 4634 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ) 4635 continue; 4636 4637 tcount = 0; 4638 scsi_low_timeout_check(slp); 4639 } 4640 4641 return 0; 4642} 4643#endif /* SCSI_LOW_START_UP_CHECK */ 4644 4645/********************************************************** 4646 * DEBUG SECTION 4647 **********************************************************/ 4648#ifdef SCSI_LOW_DEBUG 4649static void 4650scsi_low_test_abort(slp, ti, li) 4651 struct scsi_low_softc *slp; 4652 struct targ_info *ti; 4653 struct lun_info *li; 4654{ 4655 struct slccb *acb; 4656 4657 if (li->li_disc > 1) 4658 { 4659 acb = TAILQ_FIRST(&li->li_discq); 4660 if (scsi_low_abort_ccb(slp, acb) == 0) 4661 { 4662 printf("%s: aborting ccb(0x%lx) start\n", 4663 slp->sl_xname, (u_long) acb); 4664 } 4665 } 4666} 4667 4668static void 4669scsi_low_test_atten(slp, ti, msg) 4670 struct scsi_low_softc *slp; 4671 struct targ_info *ti; 4672 u_int msg; 4673{ 4674 4675 if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK) 4676 scsi_low_assert_msg(slp, ti, msg, 0); 4677 else 4678 printf("%s: atten check OK\n", slp->sl_xname); 4679} 4680 4681static void 4682scsi_low_test_cmdlnk(slp, cb) 4683 struct scsi_low_softc *slp; 4684 struct slccb *cb; 4685{ 4686#define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ) 4687 4688 if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0) 4689 return; 4690 4691 memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd, 4692 slp->sl_scp.scp_cmdlen); 4693 cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1; 4694 slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd; 4695} 4696#endif /* SCSI_LOW_DEBUG */ 4697 4698/* static */ void 4699scsi_low_info(slp, ti, s) 4700 struct scsi_low_softc *slp; 4701 struct targ_info *ti; 4702 u_char *s; 4703{ 4704 4705 if (slp == NULL) 4706 slp = LIST_FIRST(&sl_tab); 4707 if (s == NULL) 4708 s = "no message"; 4709 4710 printf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s); 4711 if (ti == NULL) 4712 { 4713 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL; 4714 ti = TAILQ_NEXT(ti, ti_chain)) 4715 { 4716 scsi_low_print(slp, ti); 4717 } 4718 } 4719 else 4720 { 4721 scsi_low_print(slp, ti); 4722 } 4723} 4724 4725static u_char *phase[] = 4726{ 4727 "FREE", "ARBSTART", "SELSTART", "SELECTED", 4728 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL" 4729}; 4730 4731void 4732scsi_low_print(slp, ti) 4733 struct scsi_low_softc *slp; 4734 struct targ_info *ti; 4735{ 4736 struct lun_info *li; 4737 struct slccb *cb; 4738 struct sc_p *sp; 4739 4740 if (ti == NULL || ti == slp->sl_Tnexus) 4741 { 4742 ti = slp->sl_Tnexus; 4743 li = slp->sl_Lnexus; 4744 cb = slp->sl_Qnexus; 4745 } 4746 else 4747 { 4748 li = LIST_FIRST(&ti->ti_litab); 4749 cb = TAILQ_FIRST(&li->li_discq); 4750 } 4751 sp = &slp->sl_scp; 4752 4753 printf("%s: === NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n", 4754 slp->sl_xname, (u_long) ti, (u_long) li, (u_long) cb, 4755 slp->sl_nio); 4756 4757 /* target stat */ 4758 if (ti != NULL) 4759 { 4760 u_int flags = 0, maxnqio = 0, nqio = 0; 4761 int lun = -1; 4762 4763 if (li != NULL) 4764 { 4765 lun = li->li_lun; 4766 flags = li->li_flags; 4767 maxnqio = li->li_maxnqio; 4768 nqio = li->li_nqio; 4769 } 4770 4771 printf("%s(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n", 4772 slp->sl_xname, 4773 ti->ti_id, lun, phase[(int) ti->ti_ophase], 4774 phase[(int) ti->ti_phase], ti->ti_disc, 4775 nqio, maxnqio); 4776 4777 if (cb != NULL) 4778 { 4779printf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n", 4780 (u_int) cb->ccb_scp.scp_cmd[0], 4781 cb->ccb_scp.scp_cmdlen, 4782 cb->ccb_datalen, 4783 cb->ccb_scp.scp_datalen, 4784 (u_int) cb->ccb_sscp.scp_status, 4785 cb->ccb_error, SCSI_LOW_ERRORBITS); 4786 } 4787 4788printf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n", 4789 (u_int) (ti->ti_msginptr), 4790 (u_int) (ti->ti_msgin[0]), 4791 (u_int) (ti->ti_msgin[1]), 4792 (u_int) (ti->ti_msgin[2]), 4793 (u_int) (ti->ti_msgin[3]), 4794 (u_int) (ti->ti_msgin[4]), 4795 slp->sl_atten); 4796 4797printf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n", 4798 (u_int) ti->ti_msgflags, 4799 (u_int) (ti->ti_msgoutstr[0]), 4800 (u_int) (ti->ti_msgoutstr[1]), 4801 (u_int) (ti->ti_msgoutstr[2]), 4802 (u_int) (ti->ti_msgoutstr[3]), 4803 (u_int) (ti->ti_msgoutstr[4]), 4804 ti->ti_msgoutlen, 4805 flags, SCSI_LOW_BITS); 4806 4807#ifdef SCSI_LOW_DIAGNOSTIC 4808 scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2); 4809 scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2); 4810#endif /* SCSI_LOW_DIAGNOSTIC */ 4811 4812 } 4813 4814 printf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n", 4815 (u_long) sp->scp_data, 4816 sp->scp_datalen, 4817 (u_int) sp->scp_status, 4818 slp->sl_error, SCSI_LOW_ERRORBITS); 4819}
|