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