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