scsi_low.c revision 168831
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 168831 2007-04-18 04:58:53Z scottl $"); 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_scsi *scsi; 1088 struct ccb_trans_settings_spi *spi; 1089 struct ccb_trans_settings *cts; 1090 u_int val; 1091 1092#ifdef SCSI_LOW_DIAGNOSTIC 1093 if (target == CAM_TARGET_WILDCARD) 1094 { 1095 printf("%s: invalid target\n", slp->sl_xname); 1096 ccb->ccb_h.status = CAM_REQ_INVALID; 1097 xpt_done(ccb); 1098 return; 1099 } 1100#endif /* SCSI_LOW_DIAGNOSTIC */ 1101 cts = &ccb->cts; 1102 ti = slp->sl_ti[target]; 1103 if (lun == CAM_LUN_WILDCARD) 1104 lun = 0; 1105 1106 s = SCSI_LOW_SPLSCSI(); 1107 scsi = &cts->proto_specific.scsi; 1108 spi = &cts->xport_specific.spi; 1109 if ((spi->valid & (CTS_SPI_VALID_BUS_WIDTH | 1110 CTS_SPI_VALID_SYNC_RATE | 1111 CTS_SPI_VALID_SYNC_OFFSET)) != 0) 1112 { 1113 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) { 1114 val = spi->bus_width; 1115 if (val < ti->ti_width) 1116 ti->ti_width = val; 1117 } 1118 if (spi->valid & CTS_SPI_VALID_SYNC_RATE) { 1119 val = spi->sync_period; 1120 if (val == 0 || val > ti->ti_maxsynch.period) 1121 ti->ti_maxsynch.period = val; 1122 } 1123 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) { 1124 val = spi->sync_offset; 1125 if (val < ti->ti_maxsynch.offset) 1126 ti->ti_maxsynch.offset = val; 1127 } 1128 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID; 1129 scsi_low_calcf_target(ti); 1130 } 1131 1132 if ((spi->valid & CTS_SPI_FLAGS_DISC_ENB) != 0 || 1133 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) { 1134 1135 li = scsi_low_alloc_li(ti, lun, 1); 1136 if (spi->valid & CTS_SPI_FLAGS_DISC_ENB) { 1137 li->li_quirks |= SCSI_LOW_DISK_DISC; 1138 } else { 1139 li->li_quirks &= ~SCSI_LOW_DISK_DISC; 1140 } 1141 1142 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) { 1143 li->li_quirks |= SCSI_LOW_DISK_QTAG; 1144 } else { 1145 li->li_quirks &= ~SCSI_LOW_DISK_QTAG; 1146 } 1147 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID; 1148 scsi_low_calcf_target(ti); 1149 scsi_low_calcf_lun(li); 1150 if ((slp->sl_show_result & SHOW_CALCF_RES) != 0) 1151 scsi_low_calcf_show(li); 1152 } 1153 splx(s); 1154 1155 ccb->ccb_h.status = CAM_REQ_CMP; 1156 xpt_done(ccb); 1157 break; 1158 } 1159 1160 case XPT_GET_TRAN_SETTINGS: { 1161 struct ccb_trans_settings *cts; 1162 u_int diskflags; 1163 1164 cts = &ccb->cts; 1165#ifdef SCSI_LOW_DIAGNOSTIC 1166 if (target == CAM_TARGET_WILDCARD) 1167 { 1168 printf("%s: invalid target\n", slp->sl_xname); 1169 ccb->ccb_h.status = CAM_REQ_INVALID; 1170 xpt_done(ccb); 1171 return; 1172 } 1173#endif /* SCSI_LOW_DIAGNOSTIC */ 1174 ti = slp->sl_ti[target]; 1175 if (lun == CAM_LUN_WILDCARD) 1176 lun = 0; 1177 1178 s = SCSI_LOW_SPLSCSI(); 1179 li = scsi_low_alloc_li(ti, lun, 1); 1180 if (li != NULL && cts->type == CTS_TYPE_CURRENT_SETTINGS) { 1181 struct ccb_trans_settings_scsi *scsi = 1182 &cts->proto_specific.scsi; 1183 struct ccb_trans_settings_spi *spi = 1184 &cts->xport_specific.spi; 1185#ifdef SCSI_LOW_DIAGNOSTIC 1186 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID) 1187 { 1188 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 1189 printf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n", 1190 slp->sl_xname); 1191 goto settings_out; 1192 } 1193#endif /* SCSI_LOW_DIAGNOSTIC */ 1194 cts->protocol = PROTO_SCSI; 1195 cts->protocol_version = SCSI_REV_2; 1196 cts->transport = XPORT_SPI; 1197 cts->transport_version = 2; 1198 1199 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 1200 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; 1201 1202 diskflags = li->li_diskflags & li->li_cfgflags; 1203 if (diskflags & SCSI_LOW_DISK_DISC) 1204 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 1205 if (diskflags & SCSI_LOW_DISK_QTAG) 1206 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 1207 1208 spi->sync_period = ti->ti_maxsynch.period; 1209 spi->valid |= CTS_SPI_VALID_SYNC_RATE; 1210 spi->sync_offset = ti->ti_maxsynch.offset; 1211 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET; 1212 1213 spi->valid |= CTS_SPI_VALID_BUS_WIDTH; 1214 spi->bus_width = ti->ti_width; 1215 1216 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) { 1217 scsi->valid = CTS_SCSI_VALID_TQ; 1218 spi->valid |= CTS_SPI_VALID_DISC; 1219 } else 1220 scsi->valid = 0; 1221 } else 1222 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 1223settings_out: 1224 splx(s); 1225 xpt_done(ccb); 1226 break; 1227 } 1228 1229 case XPT_CALC_GEOMETRY: { /* not yet HN2 */ 1230 cam_calc_geometry(&ccb->ccg, /*extended*/1); 1231 xpt_done(ccb); 1232 break; 1233 } 1234 1235 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 1236 s = SCSI_LOW_SPLSCSI(); 1237 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL); 1238 splx(s); 1239 ccb->ccb_h.status = CAM_REQ_CMP; 1240 xpt_done(ccb); 1241 break; 1242 1243 case XPT_TERM_IO: /* Terminate the I/O process */ 1244 ccb->ccb_h.status = CAM_REQ_INVALID; 1245 xpt_done(ccb); 1246 break; 1247 1248 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 1249#ifdef SCSI_LOW_DIAGNOSTIC 1250 if (target == CAM_TARGET_WILDCARD) 1251 { 1252 printf("%s: invalid target\n", slp->sl_xname); 1253 ccb->ccb_h.status = CAM_REQ_INVALID; 1254 xpt_done(ccb); 1255 return; 1256 } 1257#endif /* SCSI_LOW_DIAGNOSTIC */ 1258 1259 msg = SCSI_LOW_MSG_RESET; 1260 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)) 1261 { 1262 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 1263 xpt_done(ccb); 1264 return; 1265 } 1266 1267 ti = slp->sl_ti[target]; 1268 if (lun == CAM_LUN_WILDCARD) 1269 lun = 0; 1270 cb->osdep = ccb; 1271 cb->bp = NULL; 1272 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0) 1273 flags = CCB_AUTOSENSE | CCB_NORETRY | CCB_URGENT; 1274 else 1275 flags = CCB_NORETRY | CCB_URGENT; 1276 1277 s = SCSI_LOW_SPLSCSI(); 1278 li = scsi_low_alloc_li(ti, lun, 1); 1279 scsi_low_enqueue(slp, ti, li, cb, flags, msg); 1280 splx(s); 1281 break; 1282 1283 case XPT_PATH_INQ: { /* Path routing inquiry */ 1284 struct ccb_pathinq *cpi = &ccb->cpi; 1285 1286 cpi->version_num = scsi_low_version_major; 1287 cpi->hba_inquiry = PI_TAG_ABLE | PI_LINKED_CDB; 1288 ti = slp->sl_ti[slp->sl_hostid]; /* host id */ 1289 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8) 1290 cpi->hba_inquiry |= PI_WIDE_16; 1291 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_16) 1292 cpi->hba_inquiry |= PI_WIDE_32; 1293 if (ti->ti_maxsynch.offset > 0) 1294 cpi->hba_inquiry |= PI_SDTR_ABLE; 1295 cpi->target_sprt = 0; 1296 cpi->hba_misc = 0; 1297 cpi->hba_eng_cnt = 0; 1298 cpi->max_target = slp->sl_ntargs - 1; 1299 cpi->max_lun = slp->sl_nluns - 1; 1300 cpi->initiator_id = slp->sl_hostid; 1301 cpi->bus_id = cam_sim_bus(sim); 1302 cpi->base_transfer_speed = 3300; 1303 cpi->transport = XPORT_SPI; 1304 cpi->transport_version = 2; 1305 cpi->protocol = PROTO_SCSI; 1306 cpi->protocol_version = SCSI_REV_2; 1307 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1308 strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN); 1309 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1310 cpi->unit_number = cam_sim_unit(sim); 1311 cpi->ccb_h.status = CAM_REQ_CMP; 1312 xpt_done(ccb); 1313 break; 1314 } 1315 1316 default: 1317 printf("scsi_low: non support func_code = %d ", 1318 ccb->ccb_h.func_code); 1319 ccb->ccb_h.status = CAM_REQ_INVALID; 1320 xpt_done(ccb); 1321 break; 1322 } 1323} 1324 1325static int 1326scsi_low_attach_cam(slp) 1327 struct scsi_low_softc *slp; 1328{ 1329 struct cam_devq *devq; 1330 int tagged_openings; 1331 1332 sprintf(slp->sl_xname, "%s%d", 1333 DEVPORT_DEVNAME(slp->sl_dev), DEVPORT_DEVUNIT(slp->sl_dev)); 1334 1335 devq = cam_simq_alloc(SCSI_LOW_NCCB); 1336 if (devq == NULL) 1337 return (ENOMEM); 1338 1339 /* 1340 * ask the adapter what subunits are present 1341 */ 1342 tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS); 1343 slp->sl_si.sim = cam_sim_alloc(scsi_low_scsi_action_cam, 1344 scsi_low_poll_cam, 1345 DEVPORT_DEVNAME(slp->sl_dev), slp, 1346 DEVPORT_DEVUNIT(slp->sl_dev), &Giant, 1347 slp->sl_openings, tagged_openings, devq); 1348 1349 if (slp->sl_si.sim == NULL) { 1350 cam_simq_free(devq); 1351 return ENODEV; 1352 } 1353 1354 if (xpt_bus_register(slp->sl_si.sim, 0) != CAM_SUCCESS) { 1355 free(slp->sl_si.sim, M_SCSILOW); 1356 return ENODEV; 1357 } 1358 1359 if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL, 1360 cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD, 1361 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 1362 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim)); 1363 cam_sim_free(slp->sl_si.sim, /*free_simq*/TRUE); 1364 return ENODEV; 1365 } 1366 1367 slp->sl_show_result = SHOW_CALCF_RES; /* OK ? */ 1368 return 0; 1369} 1370 1371static int 1372scsi_low_world_start_cam(slp) 1373 struct scsi_low_softc *slp; 1374{ 1375 1376 if (!cold) 1377 scsi_low_rescan_bus_cam(slp); 1378 return 0; 1379} 1380 1381static int 1382scsi_low_dettach_cam(slp) 1383 struct scsi_low_softc *slp; 1384{ 1385 1386 xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL); 1387 xpt_free_path(slp->sl_si.path); 1388 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim)); 1389 cam_sim_free(slp->sl_si.sim, /* free_devq */ TRUE); 1390 return 0; 1391} 1392 1393static int 1394scsi_low_ccb_setup_cam(slp, cb) 1395 struct scsi_low_softc *slp; 1396 struct slccb *cb; 1397{ 1398 union ccb *ccb = (union ccb *) cb->osdep; 1399 1400 if ((cb->ccb_flags & CCB_SCSIIO) != 0) 1401 { 1402 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes; 1403 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len; 1404 cb->ccb_scp.scp_data = ccb->csio.data_ptr; 1405 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len; 1406 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) 1407 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE; 1408 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */ 1409 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 1410 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000; 1411 } 1412 else 1413 { 1414 scsi_low_unit_ready_cmd(cb); 1415 } 1416 return SCSI_LOW_START_QTAG; 1417} 1418 1419static int 1420scsi_low_done_cam(slp, cb) 1421 struct scsi_low_softc *slp; 1422 struct slccb *cb; 1423{ 1424 union ccb *ccb; 1425 1426 ccb = (union ccb *) cb->osdep; 1427 if (cb->ccb_error == 0) 1428 { 1429 ccb->ccb_h.status = CAM_REQ_CMP; 1430 ccb->csio.resid = 0; 1431 } 1432 else 1433 { 1434 if (cb->ccb_rcnt >= slp->sl_max_retry) 1435 cb->ccb_error |= ABORTIO; 1436 1437 if ((cb->ccb_flags & CCB_NORETRY) == 0 && 1438 (cb->ccb_error & ABORTIO) == 0) 1439 return EJUSTRETURN; 1440 1441 if ((cb->ccb_error & SENSEIO) != 0) 1442 { 1443 memcpy(&ccb->csio.sense_data, 1444 &cb->ccb_sense, 1445 sizeof(ccb->csio.sense_data)); 1446 } 1447 1448 ccb->ccb_h.status = scsi_low_translate_error_code(cb, 1449 &scsi_low_error_code_cam[0]); 1450 1451#ifdef SCSI_LOW_DIAGNOSTIC 1452 if ((cb->ccb_flags & CCB_SILENT) == 0 && 1453 cb->ccb_scp.scp_cmdlen > 0 && 1454 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & 1455 SCSI_LOW_CMD_ABORT_WARNING) != 0) 1456 { 1457 printf("%s: WARNING: scsi_low IO abort\n", 1458 slp->sl_xname); 1459 scsi_low_print(slp, NULL); 1460 } 1461#endif /* SCSI_LOW_DIAGNOSTIC */ 1462 } 1463 1464 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0) 1465 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; 1466 1467 if (cb->ccb_scp.scp_status == ST_UNKNOWN) 1468 ccb->csio.scsi_status = 0; /* XXX */ 1469 else 1470 ccb->csio.scsi_status = cb->ccb_scp.scp_status; 1471 1472 if ((cb->ccb_flags & CCB_NOSDONE) == 0) 1473 xpt_done(ccb); 1474 return 0; 1475} 1476 1477static void 1478scsi_low_timeout_cam(slp, ch, action) 1479 struct scsi_low_softc *slp; 1480 int ch; 1481 int action; 1482{ 1483 1484 switch (ch) 1485 { 1486 case SCSI_LOW_TIMEOUT_CH_IO: 1487 switch (action) 1488 { 1489 case SCSI_LOW_TIMEOUT_START: 1490 slp->sl_si.timeout_ch = timeout(scsi_low_timeout, slp, 1491 hz / SCSI_LOW_TIMEOUT_HZ); 1492 break; 1493 case SCSI_LOW_TIMEOUT_STOP: 1494 untimeout(scsi_low_timeout, slp, slp->sl_si.timeout_ch); 1495 break; 1496 } 1497 break; 1498 1499 case SCSI_LOW_TIMEOUT_CH_ENGAGE: 1500 switch (action) 1501 { 1502 case SCSI_LOW_TIMEOUT_START: 1503 slp->sl_si.engage_ch = timeout(scsi_low_engage, slp, 1); 1504 break; 1505 case SCSI_LOW_TIMEOUT_STOP: 1506 untimeout(scsi_low_engage, slp, slp->sl_si.engage_ch); 1507 break; 1508 } 1509 break; 1510 case SCSI_LOW_TIMEOUT_CH_RECOVER: 1511 break; 1512 } 1513} 1514 1515#endif /* SCSI_LOW_INTERFACE_CAM */ 1516 1517/*============================================================= 1518 * END OF OS switch (All OS depend fucntions should be above) 1519 =============================================================*/ 1520 1521/************************************************************** 1522 * scsi low deactivate and activate 1523 **************************************************************/ 1524int 1525scsi_low_is_busy(slp) 1526 struct scsi_low_softc *slp; 1527{ 1528 1529 if (slp->sl_nio > 0) 1530 return EBUSY; 1531 return 0; 1532} 1533 1534int 1535scsi_low_deactivate(slp) 1536 struct scsi_low_softc *slp; 1537{ 1538 int s; 1539 1540 s = SCSI_LOW_SPLSCSI(); 1541 slp->sl_flags |= HW_INACTIVE; 1542 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 1543 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP); 1544 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 1545 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP); 1546 splx(s); 1547 return 0; 1548} 1549 1550int 1551scsi_low_activate(slp) 1552 struct scsi_low_softc *slp; 1553{ 1554 int error, s; 1555 1556 s = SCSI_LOW_SPLSCSI(); 1557 slp->sl_flags &= ~HW_INACTIVE; 1558 if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0) 1559 { 1560 slp->sl_flags |= HW_INACTIVE; 1561 splx(s); 1562 return error; 1563 } 1564 1565 slp->sl_timeout_count = 0; 1566 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 1567 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); 1568 splx(s); 1569 return 0; 1570} 1571 1572/************************************************************** 1573 * scsi low log 1574 **************************************************************/ 1575#ifdef SCSI_LOW_DIAGNOSTIC 1576static void scsi_low_msg_log_init(struct scsi_low_msg_log *); 1577static void scsi_low_msg_log_write(struct scsi_low_msg_log *, u_int8_t *, int); 1578static void scsi_low_msg_log_show(struct scsi_low_msg_log *, char *, int); 1579 1580static void 1581scsi_low_msg_log_init(slmlp) 1582 struct scsi_low_msg_log *slmlp; 1583{ 1584 1585 slmlp->slml_ptr = 0; 1586} 1587 1588static void 1589scsi_low_msg_log_write(slmlp, datap, len) 1590 struct scsi_low_msg_log *slmlp; 1591 u_int8_t *datap; 1592 int len; 1593{ 1594 int ptr, ind; 1595 1596 if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN) 1597 return; 1598 1599 ptr = slmlp->slml_ptr ++; 1600 for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++) 1601 slmlp->slml_msg[ptr].msg[ind] = datap[ind]; 1602 for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++) 1603 slmlp->slml_msg[ptr].msg[ind] = 0; 1604} 1605 1606static void 1607scsi_low_msg_log_show(slmlp, s, len) 1608 struct scsi_low_msg_log *slmlp; 1609 char *s; 1610 int len; 1611{ 1612 int ptr, ind; 1613 1614 printf("%s: (%d) ", s, slmlp->slml_ptr); 1615 for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++) 1616 { 1617 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]); 1618 ind ++) 1619 { 1620 printf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]); 1621 } 1622 printf(">"); 1623 } 1624 printf("\n"); 1625} 1626#endif /* SCSI_LOW_DIAGNOSTIC */ 1627 1628/************************************************************** 1629 * power control 1630 **************************************************************/ 1631static void 1632scsi_low_engage(arg) 1633 void *arg; 1634{ 1635 struct scsi_low_softc *slp = arg; 1636 int s = SCSI_LOW_SPLSCSI(); 1637 1638 switch (slp->sl_rstep) 1639 { 1640 case 0: 1641 slp->sl_rstep ++; 1642 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE); 1643 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp, 1644 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START); 1645 break; 1646 1647 case 1: 1648 slp->sl_rstep ++; 1649 slp->sl_flags &= ~HW_RESUME; 1650 scsi_low_start(slp); 1651 break; 1652 1653 case 2: 1654 break; 1655 } 1656 splx(s); 1657} 1658 1659static int 1660scsi_low_init(slp, flags) 1661 struct scsi_low_softc *slp; 1662 u_int flags; 1663{ 1664 int rv = 0; 1665 1666 slp->sl_flags |= HW_INITIALIZING; 1667 1668 /* clear power control timeout */ 1669 if ((slp->sl_flags & HW_POWERCTRL) != 0) 1670 { 1671 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp, 1672 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP); 1673 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME); 1674 slp->sl_active = 1; 1675 slp->sl_powc = SCSI_LOW_POWDOWN_TC; 1676 } 1677 1678 /* reset current nexus */ 1679 scsi_low_reset_nexus(slp, flags); 1680 if ((slp->sl_flags & HW_INACTIVE) != 0) 1681 { 1682 rv = EBUSY; 1683 goto out; 1684 } 1685 1686 if (flags != SCSI_LOW_RESTART_SOFT) 1687 { 1688 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags)); 1689 } 1690 1691out: 1692 slp->sl_flags &= ~HW_INITIALIZING; 1693 return rv; 1694} 1695 1696/************************************************************** 1697 * allocate lun_info 1698 **************************************************************/ 1699static struct lun_info * 1700scsi_low_alloc_li(ti, lun, alloc) 1701 struct targ_info *ti; 1702 int lun; 1703 int alloc; 1704{ 1705 struct scsi_low_softc *slp = ti->ti_sc; 1706 struct lun_info *li; 1707 1708 li = LIST_FIRST(&ti->ti_litab); 1709 if (li != NULL) 1710 { 1711 if (li->li_lun == lun) 1712 return li; 1713 1714 while ((li = LIST_NEXT(li, lun_chain)) != NULL) 1715 { 1716 if (li->li_lun == lun) 1717 { 1718 LIST_REMOVE(li, lun_chain); 1719 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain); 1720 return li; 1721 } 1722 } 1723 } 1724 1725 if (alloc == 0) 1726 return li; 1727 1728 li = SCSI_LOW_MALLOC(ti->ti_lunsize); 1729 if (li == NULL) 1730 panic("no lun info mem"); 1731 1732 SCSI_LOW_BZERO(li, ti->ti_lunsize); 1733 li->li_lun = lun; 1734 li->li_ti = ti; 1735 1736 li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC | 1737 SCSI_LOW_QTAG; 1738 li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS; 1739 li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID; 1740#ifdef SCSI_LOW_FLAGS_QUIRKS_OK 1741 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID; 1742#endif /* SCSI_LOW_FLAGS_QUIRKS_OK */ 1743 1744 li->li_qtagbits = (u_int) -1; 1745 1746 TAILQ_INIT(&li->li_discq); 1747 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain); 1748 1749 /* host specific structure initialization per lun */ 1750 if (slp->sl_funcs->scsi_low_lun_init != NULL) 1751 (*slp->sl_funcs->scsi_low_lun_init) 1752 (slp, ti, li, SCSI_LOW_INFO_ALLOC); 1753 scsi_low_calcf_lun(li); 1754 return li; 1755} 1756 1757/************************************************************** 1758 * allocate targ_info 1759 **************************************************************/ 1760static struct targ_info * 1761scsi_low_alloc_ti(slp, targ) 1762 struct scsi_low_softc *slp; 1763 int targ; 1764{ 1765 struct targ_info *ti; 1766 1767 if (TAILQ_FIRST(&slp->sl_titab) == NULL) 1768 TAILQ_INIT(&slp->sl_titab); 1769 1770 ti = SCSI_LOW_MALLOC(slp->sl_targsize); 1771 if (ti == NULL) 1772 panic("%s short of memory", slp->sl_xname); 1773 1774 SCSI_LOW_BZERO(ti, slp->sl_targsize); 1775 ti->ti_id = targ; 1776 ti->ti_sc = slp; 1777 1778 slp->sl_ti[targ] = ti; 1779 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain); 1780 LIST_INIT(&ti->ti_litab); 1781 1782 ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS; 1783 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8; 1784 ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID; 1785#ifdef SCSI_LOW_FLAGS_QUIRKS_OK 1786 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID; 1787#endif /* SCSI_LOW_FLAGS_QUIRKS_OK */ 1788 1789 if (slp->sl_funcs->scsi_low_targ_init != NULL) 1790 { 1791 (*slp->sl_funcs->scsi_low_targ_init) 1792 (slp, ti, SCSI_LOW_INFO_ALLOC); 1793 } 1794 scsi_low_calcf_target(ti); 1795 return ti; 1796} 1797 1798static void 1799scsi_low_free_ti(slp) 1800 struct scsi_low_softc *slp; 1801{ 1802 struct targ_info *ti, *tib; 1803 struct lun_info *li, *nli; 1804 1805 for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib) 1806 { 1807 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli) 1808 { 1809 if (slp->sl_funcs->scsi_low_lun_init != NULL) 1810 { 1811 (*slp->sl_funcs->scsi_low_lun_init) 1812 (slp, ti, li, SCSI_LOW_INFO_DEALLOC); 1813 } 1814 nli = LIST_NEXT(li, lun_chain); 1815 SCSI_LOW_FREE(li); 1816 } 1817 1818 if (slp->sl_funcs->scsi_low_targ_init != NULL) 1819 { 1820 (*slp->sl_funcs->scsi_low_targ_init) 1821 (slp, ti, SCSI_LOW_INFO_DEALLOC); 1822 } 1823 tib = TAILQ_NEXT(ti, ti_chain); 1824 SCSI_LOW_FREE(ti); 1825 } 1826} 1827 1828/************************************************************** 1829 * timeout 1830 **************************************************************/ 1831void 1832scsi_low_bus_idle(slp) 1833 struct scsi_low_softc *slp; 1834{ 1835 1836 slp->sl_retry_sel = 0; 1837 if (slp->sl_Tnexus == NULL) 1838 scsi_low_start(slp); 1839} 1840 1841static void 1842scsi_low_timeout(arg) 1843 void *arg; 1844{ 1845 struct scsi_low_softc *slp = arg; 1846 int s; 1847 1848 s = SCSI_LOW_SPLSCSI(); 1849 (void) scsi_low_timeout_check(slp); 1850 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 1851 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); 1852 splx(s); 1853} 1854 1855static int 1856scsi_low_timeout_check(slp) 1857 struct scsi_low_softc *slp; 1858{ 1859 struct targ_info *ti; 1860 struct lun_info *li; 1861 struct slccb *cb = NULL; /* XXX */ 1862 1863 /* selection restart */ 1864 if (slp->sl_retry_sel != 0) 1865 { 1866 slp->sl_retry_sel = 0; 1867 if (slp->sl_Tnexus != NULL) 1868 goto step1; 1869 1870 cb = TAILQ_FIRST(&slp->sl_start); 1871 if (cb == NULL) 1872 goto step1; 1873 1874 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY) 1875 { 1876 cb->ccb_flags |= CCB_NORETRY; 1877 cb->ccb_error |= SELTIMEOUTIO; 1878 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL) 1879 panic("%s: ccb not finished", slp->sl_xname); 1880 } 1881 1882 if (slp->sl_Tnexus == NULL) 1883 scsi_low_start(slp); 1884 } 1885 1886 /* call hardware timeout */ 1887step1: 1888 if (slp->sl_funcs->scsi_low_timeout != NULL) 1889 { 1890 (*slp->sl_funcs->scsi_low_timeout) (slp); 1891 } 1892 1893 if (slp->sl_timeout_count ++ < 1894 SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ) 1895 return 0; 1896 1897 slp->sl_timeout_count = 0; 1898 if (slp->sl_nio > 0) 1899 { 1900 if ((cb = slp->sl_Qnexus) != NULL) 1901 { 1902 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL; 1903 if (cb->ccb_tc < 0) 1904 goto bus_reset; 1905 } 1906 else if (slp->sl_disc == 0) 1907 { 1908 if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL) 1909 return 0; 1910 1911 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL; 1912 if (cb->ccb_tc < 0) 1913 goto bus_reset; 1914 } 1915 else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL; 1916 ti = TAILQ_NEXT(ti, ti_chain)) 1917 { 1918 if (ti->ti_disc == 0) 1919 continue; 1920 1921 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; 1922 li = LIST_NEXT(li, lun_chain)) 1923 { 1924 for (cb = TAILQ_FIRST(&li->li_discq); 1925 cb != NULL; 1926 cb = TAILQ_NEXT(cb, ccb_chain)) 1927 { 1928 cb->ccb_tc -= 1929 SCSI_LOW_TIMEOUT_CHECK_INTERVAL; 1930 if (cb->ccb_tc < 0) 1931 goto bus_reset; 1932 } 1933 } 1934 } 1935 1936 } 1937 else if ((slp->sl_flags & HW_POWERCTRL) != 0) 1938 { 1939 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0) 1940 return 0; 1941 1942 if (slp->sl_active != 0) 1943 { 1944 slp->sl_powc = SCSI_LOW_POWDOWN_TC; 1945 slp->sl_active = 0; 1946 return 0; 1947 } 1948 1949 slp->sl_powc --; 1950 if (slp->sl_powc < 0) 1951 { 1952 slp->sl_powc = SCSI_LOW_POWDOWN_TC; 1953 slp->sl_flags |= HW_POWDOWN; 1954 (*slp->sl_funcs->scsi_low_power) 1955 (slp, SCSI_LOW_POWDOWN); 1956 } 1957 } 1958 return 0; 1959 1960bus_reset: 1961 cb->ccb_error |= TIMEOUTIO; 1962 printf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb); 1963 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover."); 1964 scsi_low_init(slp, SCSI_LOW_RESTART_HARD); 1965 scsi_low_start(slp); 1966 return ERESTART; 1967} 1968 1969 1970static int 1971scsi_low_abort_ccb(slp, cb) 1972 struct scsi_low_softc *slp; 1973 struct slccb *cb; 1974{ 1975 struct targ_info *ti; 1976 struct lun_info *li; 1977 u_int msg; 1978 1979 if (cb == NULL) 1980 return EINVAL; 1981 if ((cb->ccb_omsgoutflag & 1982 (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0) 1983 return EBUSY; 1984 1985 ti = cb->ti; 1986 li = cb->li; 1987 if (cb->ccb_tag == SCSI_LOW_UNKTAG) 1988 msg = SCSI_LOW_MSG_ABORT; 1989 else 1990 msg = SCSI_LOW_MSG_ABORT_QTAG; 1991 1992 cb->ccb_error |= ABORTIO; 1993 cb->ccb_flags |= CCB_NORETRY; 1994 scsi_low_ccb_message_assert(cb, msg); 1995 1996 if (cb == slp->sl_Qnexus) 1997 { 1998 scsi_low_assert_msg(slp, ti, msg, 1); 1999 } 2000 else if ((cb->ccb_flags & CCB_DISCQ) != 0) 2001 { 2002 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL) 2003 panic("%s: revoked ccb done", slp->sl_xname); 2004 2005 cb->ccb_flags |= CCB_STARTQ; 2006 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 2007 2008 if (slp->sl_Tnexus == NULL) 2009 scsi_low_start(slp); 2010 } 2011 else 2012 { 2013 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL) 2014 panic("%s: revoked ccb retried", slp->sl_xname); 2015 } 2016 return 0; 2017} 2018 2019/************************************************************** 2020 * Generic SCSI INTERFACE 2021 **************************************************************/ 2022int 2023scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize) 2024 struct scsi_low_softc *slp; 2025 int openings, ntargs, nluns, targsize, lunsize; 2026{ 2027 struct targ_info *ti; 2028 struct lun_info *li; 2029 int s, i, nccb, rv; 2030 2031#ifdef SCSI_LOW_INTERFACE_XS 2032 slp->sl_osdep_fp = &scsi_low_osdep_funcs_xs; 2033#endif /* SCSI_LOW_INTERFACE_XS */ 2034#ifdef SCSI_LOW_INTERFACE_CAM 2035 slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam; 2036#endif /* SCSI_LOW_INTERFACE_CAM */ 2037 2038 if (slp->sl_osdep_fp == NULL) 2039 panic("scsi_low: interface not spcified"); 2040 2041 if (ntargs > SCSI_LOW_NTARGETS) 2042 { 2043 printf("scsi_low: %d targets are too large\n", ntargs); 2044 printf("change kernel options SCSI_LOW_NTARGETS"); 2045 return EINVAL; 2046 } 2047 2048 if (openings <= 0) 2049 slp->sl_openings = (SCSI_LOW_NCCB / ntargs); 2050 else 2051 slp->sl_openings = openings; 2052 slp->sl_ntargs = ntargs; 2053 slp->sl_nluns = nluns; 2054 slp->sl_max_retry = SCSI_LOW_MAX_RETRY; 2055 2056 if (lunsize < sizeof(struct lun_info)) 2057 lunsize = sizeof(struct lun_info); 2058 2059 if (targsize < sizeof(struct targ_info)) 2060 targsize = sizeof(struct targ_info); 2061 2062 slp->sl_targsize = targsize; 2063 for (i = 0; i < ntargs; i ++) 2064 { 2065 ti = scsi_low_alloc_ti(slp, i); 2066 ti->ti_lunsize = lunsize; 2067 li = scsi_low_alloc_li(ti, 0, 1); 2068 } 2069 2070 /* initialize queue */ 2071 nccb = openings * ntargs; 2072 if (nccb >= SCSI_LOW_NCCB || nccb <= 0) 2073 nccb = SCSI_LOW_NCCB; 2074 scsi_low_init_ccbque(nccb); 2075 TAILQ_INIT(&slp->sl_start); 2076 2077 /* call os depend attach */ 2078 s = SCSI_LOW_SPLSCSI(); 2079 rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp); 2080 if (rv != 0) 2081 { 2082 splx(s); 2083 printf("%s: scsi_low_attach: osdep attach failed\n", 2084 slp->sl_xname); 2085 return EINVAL; 2086 } 2087 2088 /* check hardware */ 2089 SCSI_LOW_DELAY(1000); /* wait for 1ms */ 2090 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0) 2091 { 2092 splx(s); 2093 printf("%s: scsi_low_attach: initialization failed\n", 2094 slp->sl_xname); 2095 return EINVAL; 2096 } 2097 2098 /* start watch dog */ 2099 slp->sl_timeout_count = 0; 2100 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 2101 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); 2102 LIST_INSERT_HEAD(&sl_tab, slp, sl_chain); 2103 2104 /* fake call */ 2105 scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL)); 2106 2107#ifdef SCSI_LOW_START_UP_CHECK 2108 /* probing devices */ 2109 scsi_low_start_up(slp); 2110#endif /* SCSI_LOW_START_UP_CHECK */ 2111 2112 /* call os depend attach done*/ 2113 (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp); 2114 splx(s); 2115 return 0; 2116} 2117 2118int 2119scsi_low_dettach(slp) 2120 struct scsi_low_softc *slp; 2121{ 2122 int s, rv; 2123 2124 s = SCSI_LOW_SPLSCSI(); 2125 if (scsi_low_is_busy(slp) != 0) 2126 { 2127 splx(s); 2128 return EBUSY; 2129 } 2130 2131 scsi_low_deactivate(slp); 2132 2133 rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp); 2134 if (rv != 0) 2135 { 2136 splx(s); 2137 return EBUSY; 2138 } 2139 2140 scsi_low_free_ti(slp); 2141 LIST_REMOVE(slp, sl_chain); 2142 splx(s); 2143 return 0; 2144} 2145 2146/************************************************************** 2147 * Generic enqueue 2148 **************************************************************/ 2149static int 2150scsi_low_enqueue(slp, ti, li, cb, flags, msg) 2151 struct scsi_low_softc *slp; 2152 struct targ_info *ti; 2153 struct lun_info *li; 2154 struct slccb *cb; 2155 u_int flags, msg; 2156{ 2157 2158 cb->ti = ti; 2159 cb->li = li; 2160 2161 scsi_low_ccb_message_assert(cb, msg); 2162 2163 cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG; 2164 scsi_low_alloc_qtag(cb); 2165 2166 cb->ccb_flags = flags | CCB_STARTQ; 2167 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 2168 cb->ccb_error |= PENDINGIO; 2169 2170 if ((flags & CCB_URGENT) != 0) 2171 { 2172 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 2173 } 2174 else 2175 { 2176 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain); 2177 } 2178 2179 slp->sl_nio ++; 2180 2181 if (slp->sl_Tnexus == NULL) 2182 scsi_low_start(slp); 2183 return 0; 2184} 2185 2186static int 2187scsi_low_message_enqueue(slp, ti, li, flags) 2188 struct scsi_low_softc *slp; 2189 struct targ_info *ti; 2190 struct lun_info *li; 2191 u_int flags; 2192{ 2193 struct slccb *cb; 2194 u_int tmsgflags; 2195 2196 tmsgflags = ti->ti_setup_msg; 2197 ti->ti_setup_msg = 0; 2198 2199 flags |= CCB_NORETRY; 2200 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL) 2201 return ENOMEM; 2202 2203 cb->osdep = NULL; 2204 cb->bp = NULL; 2205 scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags); 2206 return 0; 2207} 2208 2209/************************************************************** 2210 * Generic Start & Done 2211 **************************************************************/ 2212#define SLSC_MODE_SENSE_SHORT 0x1a 2213static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0}; 2214static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0, 2215 sizeof(struct scsi_low_mode_sense_data), 0}; 2216static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0, 2217 sizeof(struct scsi_low_inq_data), 0}; 2218static u_int8_t unit_ready_cmd[6]; 2219static int scsi_low_setup_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *); 2220static int scsi_low_sense_abort_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *); 2221static int scsi_low_resume(struct scsi_low_softc *); 2222 2223static void 2224scsi_low_unit_ready_cmd(cb) 2225 struct slccb *cb; 2226{ 2227 2228 cb->ccb_scp.scp_cmd = unit_ready_cmd; 2229 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd); 2230 cb->ccb_scp.scp_datalen = 0; 2231 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2232 cb->ccb_tcmax = 15; 2233} 2234 2235static int 2236scsi_low_sense_abort_start(slp, ti, li, cb) 2237 struct scsi_low_softc *slp; 2238 struct targ_info *ti; 2239 struct lun_info *li; 2240 struct slccb *cb; 2241{ 2242 2243 cb->ccb_scp.scp_cmdlen = 6; 2244 SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen); 2245 cb->ccb_scsi_cmd[0] = REQUEST_SENSE; 2246 cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense); 2247 cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd; 2248 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense; 2249 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense); 2250 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2251 cb->ccb_tcmax = 15; 2252 scsi_low_ccb_message_clear(cb); 2253 if ((cb->ccb_flags & CCB_CLEARQ) != 0) 2254 { 2255 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 2256 } 2257 else 2258 { 2259 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense)); 2260#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE 2261 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0); 2262#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */ 2263 } 2264 2265 return SCSI_LOW_START_NO_QTAG; 2266} 2267 2268static int 2269scsi_low_setup_start(slp, ti, li, cb) 2270 struct scsi_low_softc *slp; 2271 struct targ_info *ti; 2272 struct lun_info *li; 2273 struct slccb *cb; 2274{ 2275 2276 switch(li->li_state) 2277 { 2278 case SCSI_LOW_LUN_SLEEP: 2279 scsi_low_unit_ready_cmd(cb); 2280 break; 2281 2282 case SCSI_LOW_LUN_START: 2283 cb->ccb_scp.scp_cmd = ss_cmd; 2284 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd); 2285 cb->ccb_scp.scp_datalen = 0; 2286 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2287 cb->ccb_tcmax = 30; 2288 break; 2289 2290 case SCSI_LOW_LUN_INQ: 2291 cb->ccb_scp.scp_cmd = inq_cmd; 2292 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd); 2293 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq; 2294 cb->ccb_scp.scp_datalen = sizeof(li->li_inq); 2295 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2296 cb->ccb_tcmax = 15; 2297 break; 2298 2299 case SCSI_LOW_LUN_MODEQ: 2300 cb->ccb_scp.scp_cmd = sms_cmd; 2301 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd); 2302 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms; 2303 cb->ccb_scp.scp_datalen = sizeof(li->li_sms); 2304 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2305 cb->ccb_tcmax = 15; 2306 return SCSI_LOW_START_QTAG; 2307 2308 default: 2309 panic("%s: no setup phase", slp->sl_xname); 2310 } 2311 2312 return SCSI_LOW_START_NO_QTAG; 2313} 2314 2315static int 2316scsi_low_resume(slp) 2317 struct scsi_low_softc *slp; 2318{ 2319 2320 if (slp->sl_flags & HW_RESUME) 2321 return EJUSTRETURN; 2322 slp->sl_flags &= ~HW_POWDOWN; 2323 if (slp->sl_funcs->scsi_low_power != NULL) 2324 { 2325 slp->sl_flags |= HW_RESUME; 2326 slp->sl_rstep = 0; 2327 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE); 2328 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 2329 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, 2330 SCSI_LOW_TIMEOUT_START); 2331 return EJUSTRETURN; 2332 } 2333 return 0; 2334} 2335 2336static void 2337scsi_low_start(slp) 2338 struct scsi_low_softc *slp; 2339{ 2340 struct targ_info *ti; 2341 struct lun_info *li; 2342 struct slccb *cb; 2343 int rv; 2344 2345 /* check hardware exists or under initializations ? */ 2346 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0) 2347 return; 2348 2349 /* check hardware power up ? */ 2350 if ((slp->sl_flags & HW_POWERCTRL) != 0) 2351 { 2352 slp->sl_active ++; 2353 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME)) 2354 { 2355 if (scsi_low_resume(slp) == EJUSTRETURN) 2356 return; 2357 } 2358 } 2359 2360 /* setup nexus */ 2361#ifdef SCSI_LOW_DIAGNOSTIC 2362 if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus) 2363 { 2364 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT"); 2365 panic("%s: inconsistent", slp->sl_xname); 2366 } 2367#endif /* SCSI_LOW_DIAGNOSTIC */ 2368 2369 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL; 2370 cb = TAILQ_NEXT(cb, ccb_chain)) 2371 { 2372 li = cb->li; 2373 2374 if (li->li_disc == 0) 2375 { 2376 goto scsi_low_cmd_start; 2377 } 2378 else if (li->li_nqio > 0) 2379 { 2380 if (li->li_nqio < li->li_maxnqio || 2381 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0) 2382 goto scsi_low_cmd_start; 2383 } 2384 } 2385 return; 2386 2387scsi_low_cmd_start: 2388 cb->ccb_flags &= ~CCB_STARTQ; 2389 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain); 2390 ti = cb->ti; 2391 2392 /* clear all error flag bits (for restart) */ 2393 cb->ccb_error = 0; 2394 cb->ccb_datalen = -1; 2395 cb->ccb_scp.scp_status = ST_UNKNOWN; 2396 2397 /* setup nexus pointer */ 2398 slp->sl_Qnexus = cb; 2399 slp->sl_Lnexus = li; 2400 slp->sl_Tnexus = ti; 2401 2402 /* initialize msgsys */ 2403 scsi_low_init_msgsys(slp, ti); 2404 2405 /* exec cmd */ 2406 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0) 2407 { 2408 /* CA state or forced abort */ 2409 rv = scsi_low_sense_abort_start(slp, ti, li, cb); 2410 } 2411 else if (li->li_state >= SCSI_LOW_LUN_OK) 2412 { 2413 cb->ccb_flags &= ~CCB_INTERNAL; 2414 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb); 2415 if (cb->ccb_msgoutflag != 0) 2416 { 2417 scsi_low_ccb_message_exec(slp, cb); 2418 } 2419 } 2420 else 2421 { 2422 cb->ccb_flags |= CCB_INTERNAL; 2423 rv = scsi_low_setup_start(slp, ti, li, cb); 2424 } 2425 2426 /* allocate qtag */ 2427#define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC) 2428 2429 if (rv == SCSI_LOW_START_QTAG && 2430 (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK && 2431 li->li_maxnqio > 0) 2432 { 2433 u_int qmsg; 2434 2435 scsi_low_activate_qtag(cb); 2436 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & 2437 SCSI_LOW_CMD_ORDERED_QTAG) != 0) 2438 qmsg = SCSI_LOW_MSG_ORDERED_QTAG; 2439 else if ((cb->ccb_flags & CCB_URGENT) != 0) 2440 qmsg = SCSI_LOW_MSG_HEAD_QTAG; 2441 else 2442 qmsg = SCSI_LOW_MSG_SIMPLE_QTAG; 2443 scsi_low_assert_msg(slp, ti, qmsg, 0); 2444 } 2445 2446 /* timeout */ 2447 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT) 2448 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 2449 cb->ccb_tc = cb->ccb_tcmax; 2450 2451 /* setup saved scsi data pointer */ 2452 cb->ccb_sscp = cb->ccb_scp; 2453 2454 /* setup current scsi pointer */ 2455 slp->sl_scp = cb->ccb_sscp; 2456 slp->sl_error = cb->ccb_error; 2457 2458 /* assert always an identify msg */ 2459 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0); 2460 2461 /* debug section */ 2462#ifdef SCSI_LOW_DIAGNOSTIC 2463 scsi_low_msg_log_init(&ti->ti_log_msgin); 2464 scsi_low_msg_log_init(&ti->ti_log_msgout); 2465#endif /* SCSI_LOW_DIAGNOSTIC */ 2466 2467 /* selection start */ 2468 slp->sl_selid = cb; 2469 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb)); 2470 if (rv == SCSI_LOW_START_OK) 2471 { 2472#ifdef SCSI_LOW_STATICS 2473 scsi_low_statics.nexus_win ++; 2474#endif /* SCSI_LOW_STATICS */ 2475 return; 2476 } 2477 2478 scsi_low_arbit_fail(slp, cb); 2479#ifdef SCSI_LOW_STATICS 2480 scsi_low_statics.nexus_fail ++; 2481#endif /* SCSI_LOW_STATICS */ 2482} 2483 2484void 2485scsi_low_arbit_fail(slp, cb) 2486 struct scsi_low_softc *slp; 2487 struct slccb *cb; 2488{ 2489 struct targ_info *ti = cb->ti; 2490 2491 scsi_low_deactivate_qtag(cb); 2492 scsi_low_ccb_message_retry(cb); 2493 cb->ccb_flags |= CCB_STARTQ; 2494 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 2495 2496 scsi_low_bus_release(slp, ti); 2497 2498 cb->ccb_selrcnt ++; 2499 if (slp->sl_disc == 0) 2500 { 2501#ifdef SCSI_LOW_DIAGNOSTIC 2502 printf("%s: try selection again\n", slp->sl_xname); 2503#endif /* SCSI_LOW_DIAGNOSTIC */ 2504 slp->sl_retry_sel = 1; 2505 } 2506} 2507 2508static void 2509scsi_low_bus_release(slp, ti) 2510 struct scsi_low_softc *slp; 2511 struct targ_info *ti; 2512{ 2513 2514 if (ti->ti_disc > 0) 2515 { 2516 SCSI_LOW_SETUP_PHASE(ti, PH_DISC); 2517 } 2518 else 2519 { 2520 SCSI_LOW_SETUP_PHASE(ti, PH_NULL); 2521 } 2522 2523 /* clear all nexus pointer */ 2524 slp->sl_Qnexus = NULL; 2525 slp->sl_Lnexus = NULL; 2526 slp->sl_Tnexus = NULL; 2527 2528 /* clear selection assert */ 2529 slp->sl_selid = NULL; 2530 2531 /* clear nexus data */ 2532 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK; 2533 2534 /* clear phase change counter */ 2535 slp->sl_ph_count = 0; 2536} 2537 2538static int 2539scsi_low_setup_done(slp, cb) 2540 struct scsi_low_softc *slp; 2541 struct slccb *cb; 2542{ 2543 struct targ_info *ti; 2544 struct lun_info *li; 2545 2546 ti = cb->ti; 2547 li = cb->li; 2548 2549 if (cb->ccb_rcnt >= slp->sl_max_retry) 2550 { 2551 cb->ccb_error |= ABORTIO; 2552 return SCSI_LOW_DONE_COMPLETE; 2553 } 2554 2555 /* XXX: special huck for selection timeout */ 2556 if (li->li_state == SCSI_LOW_LUN_SLEEP && 2557 (cb->ccb_error & SELTIMEOUTIO) != 0) 2558 { 2559 cb->ccb_error |= ABORTIO; 2560 return SCSI_LOW_DONE_COMPLETE; 2561 } 2562 2563 switch(li->li_state) 2564 { 2565 case SCSI_LOW_LUN_INQ: 2566 if (cb->ccb_error != 0) 2567 { 2568 li->li_diskflags &= 2569 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG); 2570 if (li->li_lun > 0) 2571 goto resume; 2572 ti->ti_diskflags &= 2573 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE); 2574 } 2575 else if ((li->li_inq.sd_version & 7) >= 2 || 2576 (li->li_inq.sd_len >= 4)) 2577 { 2578 if ((li->li_inq.sd_support & 0x2) == 0) 2579 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG; 2580 if ((li->li_inq.sd_support & 0x8) == 0) 2581 li->li_diskflags &= ~SCSI_LOW_DISK_LINK; 2582 if (li->li_lun > 0) 2583 goto resume; 2584 if ((li->li_inq.sd_support & 0x10) == 0) 2585 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC; 2586 if ((li->li_inq.sd_support & 0x20) == 0) 2587 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16; 2588 if ((li->li_inq.sd_support & 0x40) == 0) 2589 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32; 2590 } 2591 else 2592 { 2593 li->li_diskflags &= 2594 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK); 2595 if (li->li_lun > 0) 2596 goto resume; 2597 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE; 2598 } 2599 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID; 2600resume: 2601 scsi_low_calcf_target(ti); 2602 scsi_low_calcf_lun(li); 2603 break; 2604 2605 case SCSI_LOW_LUN_MODEQ: 2606 if (cb->ccb_error != 0) 2607 { 2608 if (cb->ccb_error & SENSEIO) 2609 { 2610#ifdef SCSI_LOW_DEBUG 2611 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE) 2612 { 2613 printf("SENSE: [%x][%x][%x][%x][%x]\n", 2614 (u_int) cb->ccb_sense.error_code, 2615 (u_int) cb->ccb_sense.segment, 2616 (u_int) cb->ccb_sense.flags, 2617 (u_int) cb->ccb_sense.add_sense_code, 2618 (u_int) cb->ccb_sense.add_sense_code_qual); 2619 } 2620#endif /* SCSI_LOW_DEBUG */ 2621 } 2622 else 2623 { 2624 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG; 2625 } 2626 } 2627 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a) 2628 { 2629 if (li->li_sms.sms_cmp.cmp_qc & 0x02) 2630 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR; 2631 else 2632 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR; 2633 if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0) 2634 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG; 2635 } 2636 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID; 2637 scsi_low_calcf_lun(li); 2638 break; 2639 2640 default: 2641 break; 2642 } 2643 2644 li->li_state ++; 2645 if (li->li_state == SCSI_LOW_LUN_OK) 2646 { 2647 scsi_low_calcf_target(ti); 2648 scsi_low_calcf_lun(li); 2649 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID && 2650 (slp->sl_show_result & SHOW_CALCF_RES) != 0) 2651 { 2652 scsi_low_calcf_show(li); 2653 } 2654 } 2655 2656 cb->ccb_rcnt --; 2657 return SCSI_LOW_DONE_RETRY; 2658} 2659 2660static int 2661scsi_low_done(slp, cb) 2662 struct scsi_low_softc *slp; 2663 struct slccb *cb; 2664{ 2665 int rv; 2666 2667 if (cb->ccb_error == 0) 2668 { 2669 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0) 2670 { 2671#ifdef SCSI_LOW_QCLEAR_AFTER_CA 2672 /* XXX: 2673 * SCSI-2 draft suggests 2674 * page 0x0a QErr bit determins if 2675 * the target aborts or continues 2676 * the queueing io's after CA state resolved. 2677 * However many targets seem not to support 2678 * the page 0x0a. Thus we should manually clear the 2679 * queuing io's after CA state. 2680 */ 2681 if ((cb->ccb_flags & CCB_CLEARQ) == 0) 2682 { 2683 cb->ccb_rcnt --; 2684 cb->ccb_flags |= CCB_CLEARQ; 2685 goto retry; 2686 } 2687#endif /* SCSI_LOW_QCLEAR_AFTER_CA */ 2688 2689 if ((cb->ccb_flags & CCB_SENSE) != 0) 2690 cb->ccb_error |= (SENSEIO | ABORTIO); 2691 cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ); 2692 } 2693 else switch (cb->ccb_sscp.scp_status) 2694 { 2695 case ST_GOOD: 2696 case ST_MET: 2697 case ST_INTERGOOD: 2698 case ST_INTERMET: 2699 if (cb->ccb_datalen == 0 || 2700 cb->ccb_scp.scp_datalen == 0) 2701 break; 2702 2703 if (cb->ccb_scp.scp_cmdlen > 0 && 2704 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & 2705 SCSI_LOW_CMD_RESIDUAL_CHK) == 0) 2706 break; 2707 2708 cb->ccb_error |= PDMAERR; 2709 break; 2710 2711 case ST_BUSY: 2712 case ST_QUEFULL: 2713 cb->ccb_error |= (BUSYERR | STATERR); 2714 break; 2715 2716 case ST_CONFLICT: 2717 cb->ccb_error |= (STATERR | ABORTIO); 2718 break; 2719 2720 case ST_CHKCOND: 2721 case ST_CMDTERM: 2722 if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL)) 2723 { 2724 cb->ccb_rcnt --; 2725 cb->ccb_flags |= CCB_SENSE; 2726 goto retry; 2727 } 2728 cb->ccb_error |= (UACAERR | STATERR | ABORTIO); 2729 break; 2730 2731 case ST_UNKNOWN: 2732 default: 2733 cb->ccb_error |= FATALIO; 2734 break; 2735 } 2736 } 2737 else 2738 { 2739 if (cb->ccb_flags & CCB_SENSE) 2740 { 2741 cb->ccb_error |= (SENSEERR | ABORTIO); 2742 } 2743 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE); 2744 } 2745 2746 /* internal ccb */ 2747 if ((cb->ccb_flags & CCB_INTERNAL) != 0) 2748 { 2749 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY) 2750 goto retry; 2751 } 2752 2753 /* check a ccb msgout flag */ 2754 if (cb->ccb_omsgoutflag != 0) 2755 { 2756#define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \ 2757 SCSI_LOW_MSG_ABORT_QTAG | \ 2758 SCSI_LOW_MSG_CLEAR_QTAG | \ 2759 SCSI_LOW_MSG_TERMIO) 2760 2761 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0) 2762 { 2763 cb->ccb_error |= ABORTIO; 2764 } 2765 } 2766 2767 /* call OS depend done */ 2768 if (cb->osdep != NULL) 2769 { 2770 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb); 2771 if (rv == EJUSTRETURN) 2772 goto retry; 2773 } 2774 else if (cb->ccb_error != 0) 2775 { 2776 if (cb->ccb_rcnt >= slp->sl_max_retry) 2777 cb->ccb_error |= ABORTIO; 2778 2779 if ((cb->ccb_flags & CCB_NORETRY) == 0 && 2780 (cb->ccb_error & ABORTIO) == 0) 2781 goto retry; 2782 } 2783 2784 /* free our target */ 2785#ifdef SCSI_LOW_DEBUG 2786 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0) 2787 { 2788 printf(">> SCSI_LOW_DONE_COMPLETE ===============\n"); 2789 scsi_low_print(slp, NULL); 2790 } 2791#endif /* SCSI_LOW_DEBUG */ 2792 2793 scsi_low_deactivate_qtag(cb); 2794 scsi_low_dealloc_qtag(cb); 2795 scsi_low_free_ccb(cb); 2796 slp->sl_nio --; 2797 return SCSI_LOW_DONE_COMPLETE; 2798 2799retry: 2800#ifdef SCSI_LOW_DEBUG 2801 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0) 2802 { 2803 printf("** SCSI_LOW_DONE_RETRY ===============\n"); 2804 scsi_low_print(slp, NULL); 2805 } 2806#endif /* SCSI_LOW_DEBUG */ 2807 2808 cb->ccb_rcnt ++; 2809 scsi_low_deactivate_qtag(cb); 2810 scsi_low_ccb_message_retry(cb); 2811 return SCSI_LOW_DONE_RETRY; 2812} 2813 2814/************************************************************** 2815 * Reset 2816 **************************************************************/ 2817static void 2818scsi_low_reset_nexus_target(slp, ti, fdone) 2819 struct scsi_low_softc *slp; 2820 struct targ_info *ti; 2821 int fdone; 2822{ 2823 struct lun_info *li; 2824 2825 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; 2826 li = LIST_NEXT(li, lun_chain)) 2827 { 2828 scsi_low_reset_nexus_lun(slp, li, fdone); 2829 li->li_state = SCSI_LOW_LUN_SLEEP; 2830 li->li_maxnqio = 0; 2831 } 2832 2833 ti->ti_disc = 0; 2834 ti->ti_setup_msg = 0; 2835 ti->ti_setup_msg_done = 0; 2836 2837 ti->ti_osynch.offset = ti->ti_osynch.period = 0; 2838 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8; 2839 2840 ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS; 2841 ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID; 2842 2843 if (slp->sl_funcs->scsi_low_targ_init != NULL) 2844 { 2845 ((*slp->sl_funcs->scsi_low_targ_init) 2846 (slp, ti, SCSI_LOW_INFO_REVOKE)); 2847 } 2848 scsi_low_calcf_target(ti); 2849 2850 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; 2851 li = LIST_NEXT(li, lun_chain)) 2852 { 2853 li->li_flags = 0; 2854 2855 li->li_diskflags = SCSI_LOW_DISK_LFLAGS; 2856 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID; 2857 2858 if (slp->sl_funcs->scsi_low_lun_init != NULL) 2859 { 2860 ((*slp->sl_funcs->scsi_low_lun_init) 2861 (slp, ti, li, SCSI_LOW_INFO_REVOKE)); 2862 } 2863 scsi_low_calcf_lun(li); 2864 } 2865} 2866 2867static void 2868scsi_low_reset_nexus(slp, fdone) 2869 struct scsi_low_softc *slp; 2870 int fdone; 2871{ 2872 struct targ_info *ti; 2873 struct slccb *cb, *topcb; 2874 2875 if ((cb = slp->sl_Qnexus) != NULL) 2876 { 2877 topcb = scsi_low_revoke_ccb(slp, cb, fdone); 2878 } 2879 else 2880 { 2881 topcb = NULL; 2882 } 2883 2884 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL; 2885 ti = TAILQ_NEXT(ti, ti_chain)) 2886 { 2887 scsi_low_reset_nexus_target(slp, ti, fdone); 2888 scsi_low_bus_release(slp, ti); 2889 scsi_low_init_msgsys(slp, ti); 2890 } 2891 2892 if (topcb != NULL) 2893 { 2894 topcb->ccb_flags |= CCB_STARTQ; 2895 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain); 2896 } 2897 2898 slp->sl_disc = 0; 2899 slp->sl_retry_sel = 0; 2900 slp->sl_flags &= ~HW_PDMASTART; 2901} 2902 2903/* misc */ 2904static int tw_pos; 2905static char tw_chars[] = "|/-\\"; 2906#define TWIDDLEWAIT 10000 2907 2908static void 2909scsi_low_twiddle_wait(void) 2910{ 2911 2912 cnputc('\b'); 2913 cnputc(tw_chars[tw_pos++]); 2914 tw_pos %= (sizeof(tw_chars) - 1); 2915 SCSI_LOW_DELAY(TWIDDLEWAIT); 2916} 2917 2918void 2919scsi_low_bus_reset(slp) 2920 struct scsi_low_softc *slp; 2921{ 2922 int i; 2923 2924 (*slp->sl_funcs->scsi_low_bus_reset) (slp); 2925 2926 printf("%s: try to reset scsi bus ", slp->sl_xname); 2927 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++) 2928 scsi_low_twiddle_wait(); 2929 cnputc('\b'); 2930 printf("\n"); 2931} 2932 2933int 2934scsi_low_restart(slp, flags, s) 2935 struct scsi_low_softc *slp; 2936 int flags; 2937 u_char *s; 2938{ 2939 int error; 2940 2941 if (s != NULL) 2942 printf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s); 2943 2944 if ((error = scsi_low_init(slp, flags)) != 0) 2945 return error; 2946 2947 scsi_low_start(slp); 2948 return 0; 2949} 2950 2951/************************************************************** 2952 * disconnect and reselect 2953 **************************************************************/ 2954#define MSGCMD_LUN(msg) (msg & 0x07) 2955 2956static struct slccb * 2957scsi_low_establish_ccb(ti, li, tag) 2958 struct targ_info *ti; 2959 struct lun_info *li; 2960 scsi_low_tag_t tag; 2961{ 2962 struct scsi_low_softc *slp = ti->ti_sc; 2963 struct slccb *cb; 2964 2965 if (li == NULL) 2966 return NULL; 2967 2968 cb = TAILQ_FIRST(&li->li_discq); 2969 for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain)) 2970 if (cb->ccb_tag == tag) 2971 goto found; 2972 return cb; 2973 2974 /* 2975 * establish our ccb nexus 2976 */ 2977found: 2978#ifdef SCSI_LOW_DEBUG 2979 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0) 2980 { 2981 printf("%s: nexus(0x%lx) abort check start\n", 2982 slp->sl_xname, (u_long) cb); 2983 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT); 2984 scsi_low_revoke_ccb(slp, cb, 1); 2985 return NULL; 2986 } 2987 2988 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0) 2989 { 2990 if (cb->ccb_omsgoutflag == 0) 2991 scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP); 2992 } 2993#endif /* SCSI_LOW_DEBUG */ 2994 2995 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain); 2996 cb->ccb_flags &= ~CCB_DISCQ; 2997 slp->sl_Qnexus = cb; 2998 2999 slp->sl_scp = cb->ccb_sscp; 3000 slp->sl_error |= cb->ccb_error; 3001 3002 slp->sl_disc --; 3003 ti->ti_disc --; 3004 li->li_disc --; 3005 3006 /* inform "ccb nexus established" to the host driver */ 3007 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp); 3008 3009 /* check msg */ 3010 if (cb->ccb_msgoutflag != 0) 3011 { 3012 scsi_low_ccb_message_exec(slp, cb); 3013 } 3014 3015 return cb; 3016} 3017 3018struct targ_info * 3019scsi_low_reselected(slp, targ) 3020 struct scsi_low_softc *slp; 3021 u_int targ; 3022{ 3023 struct targ_info *ti; 3024 struct slccb *cb; 3025 u_char *s; 3026 3027 /* 3028 * Check select vs reselected collision. 3029 */ 3030 3031 if ((cb = slp->sl_selid) != NULL) 3032 { 3033 scsi_low_arbit_fail(slp, cb); 3034#ifdef SCSI_LOW_STATICS 3035 scsi_low_statics.nexus_conflict ++; 3036#endif /* SCSI_LOW_STATICS */ 3037 } 3038 3039 /* 3040 * Check if no current active nexus. 3041 */ 3042 if (slp->sl_Tnexus != NULL) 3043 { 3044 s = "host busy"; 3045 goto world_restart; 3046 } 3047 3048 /* 3049 * Check a valid target id asserted ? 3050 */ 3051 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid) 3052 { 3053 s = "scsi id illegal"; 3054 goto world_restart; 3055 } 3056 3057 /* 3058 * Check the target scsi status. 3059 */ 3060 ti = slp->sl_ti[targ]; 3061 if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL) 3062 { 3063 s = "phase mismatch"; 3064 goto world_restart; 3065 } 3066 3067 /* 3068 * Setup init msgsys 3069 */ 3070 slp->sl_error = 0; 3071 scsi_low_init_msgsys(slp, ti); 3072 3073 /* 3074 * Establish our target nexus 3075 */ 3076 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL); 3077 slp->sl_Tnexus = ti; 3078#ifdef SCSI_LOW_STATICS 3079 scsi_low_statics.nexus_reselected ++; 3080#endif /* SCSI_LOW_STATICS */ 3081 return ti; 3082 3083world_restart: 3084 printf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s); 3085 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, 3086 "reselect: scsi world confused"); 3087 return NULL; 3088} 3089 3090/************************************************************** 3091 * cmd out pointer setup 3092 **************************************************************/ 3093int 3094scsi_low_cmd(slp, ti) 3095 struct scsi_low_softc *slp; 3096 struct targ_info *ti; 3097{ 3098 struct slccb *cb = slp->sl_Qnexus; 3099 3100 slp->sl_ph_count ++; 3101 if (cb == NULL) 3102 { 3103 /* 3104 * no ccb, abort! 3105 */ 3106 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd; 3107 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd); 3108 slp->sl_scp.scp_datalen = 0; 3109 slp->sl_scp.scp_direction = SCSI_LOW_READ; 3110 slp->sl_error |= FATALIO; 3111 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3112 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found"); 3113 return EINVAL; 3114 } 3115 else 3116 { 3117#ifdef SCSI_LOW_DEBUG 3118 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id)) 3119 { 3120 scsi_low_test_cmdlnk(slp, cb); 3121 } 3122#endif /* SCSI_LOW_DEBUG */ 3123 } 3124 return 0; 3125} 3126 3127/************************************************************** 3128 * data out pointer setup 3129 **************************************************************/ 3130int 3131scsi_low_data(slp, ti, bp, direction) 3132 struct scsi_low_softc *slp; 3133 struct targ_info *ti; 3134 struct buf **bp; 3135 int direction; 3136{ 3137 struct slccb *cb = slp->sl_Qnexus; 3138 3139 if (cb != NULL && direction == cb->ccb_sscp.scp_direction) 3140 { 3141 *bp = cb->bp; 3142 return 0; 3143 } 3144 3145 slp->sl_error |= (FATALIO | PDMAERR); 3146 slp->sl_scp.scp_datalen = 0; 3147 slp->sl_scp.scp_direction = direction; 3148 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3149 if (ti->ti_ophase != ti->ti_phase) 3150 { 3151 char *s; 3152 3153 if (cb == NULL) 3154 s = "DATA PHASE: ccb nexus not found"; 3155 else 3156 s = "DATA PHASE: xfer direction mismatch"; 3157 SCSI_LOW_INFO(slp, ti, s); 3158 } 3159 3160 *bp = NULL; 3161 return EINVAL; 3162} 3163 3164/************************************************************** 3165 * MSG_SYS 3166 **************************************************************/ 3167#define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;} 3168#define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3]) 3169#define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4]) 3170#define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3]) 3171#define MSGIN_DATA_LAST 0x30 3172 3173static int scsi_low_errfunc_synch(struct scsi_low_softc *, u_int); 3174static int scsi_low_errfunc_wide(struct scsi_low_softc *, u_int); 3175static int scsi_low_errfunc_identify(struct scsi_low_softc *, u_int); 3176static int scsi_low_errfunc_qtag(struct scsi_low_softc *, u_int); 3177 3178static int scsi_low_msgfunc_synch(struct scsi_low_softc *); 3179static int scsi_low_msgfunc_wide(struct scsi_low_softc *); 3180static int scsi_low_msgfunc_identify(struct scsi_low_softc *); 3181static int scsi_low_msgfunc_abort(struct scsi_low_softc *); 3182static int scsi_low_msgfunc_qabort(struct scsi_low_softc *); 3183static int scsi_low_msgfunc_qtag(struct scsi_low_softc *); 3184static int scsi_low_msgfunc_reset(struct scsi_low_softc *); 3185 3186struct scsi_low_msgout_data { 3187 u_int md_flags; 3188 u_int8_t md_msg; 3189 int (*md_msgfunc)(struct scsi_low_softc *); 3190 int (*md_errfunc)(struct scsi_low_softc *, u_int); 3191#define MSG_RELEASE_ATN 0x0001 3192 u_int md_condition; 3193}; 3194 3195struct scsi_low_msgout_data scsi_low_msgout_data[] = { 3196/* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN}, 3197/* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN}, 3198/* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN}, 3199/* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN}, 3200/* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0}, 3201/* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN}, 3202/* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN}, 3203/* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0}, 3204/* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0}, 3205/* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0}, 3206/* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN}, 3207/* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN}, 3208/* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN}, 3209/* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN}, 3210/* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN}, 3211/* 15 */{SCSI_LOW_MSG_ALL, 0}, 3212}; 3213 3214static int scsi_low_msginfunc_ext(struct scsi_low_softc *); 3215static int scsi_low_synch(struct scsi_low_softc *); 3216static int scsi_low_wide(struct scsi_low_softc *); 3217static int scsi_low_msginfunc_msg_reject(struct scsi_low_softc *); 3218static int scsi_low_msginfunc_rejop(struct scsi_low_softc *); 3219static int scsi_low_msginfunc_rp(struct scsi_low_softc *); 3220static int scsi_low_msginfunc_sdp(struct scsi_low_softc *); 3221static int scsi_low_msginfunc_disc(struct scsi_low_softc *); 3222static int scsi_low_msginfunc_cc(struct scsi_low_softc *); 3223static int scsi_low_msginfunc_lcc(struct scsi_low_softc *); 3224static int scsi_low_msginfunc_parity(struct scsi_low_softc *); 3225static int scsi_low_msginfunc_noop(struct scsi_low_softc *); 3226static int scsi_low_msginfunc_simple_qtag(struct scsi_low_softc *); 3227static int scsi_low_msginfunc_i_wide_residue(struct scsi_low_softc *); 3228 3229struct scsi_low_msgin_data { 3230 u_int md_len; 3231 int (*md_msgfunc)(struct scsi_low_softc *); 3232}; 3233 3234struct scsi_low_msgin_data scsi_low_msgin_data[] = { 3235/* 0 */ {1, scsi_low_msginfunc_cc}, 3236/* 1 */ {2, scsi_low_msginfunc_ext}, 3237/* 2 */ {1, scsi_low_msginfunc_sdp}, 3238/* 3 */ {1, scsi_low_msginfunc_rp}, 3239/* 4 */ {1, scsi_low_msginfunc_disc}, 3240/* 5 */ {1, scsi_low_msginfunc_rejop}, 3241/* 6 */ {1, scsi_low_msginfunc_rejop}, 3242/* 7 */ {1, scsi_low_msginfunc_msg_reject}, 3243/* 8 */ {1, scsi_low_msginfunc_noop}, 3244/* 9 */ {1, scsi_low_msginfunc_parity}, 3245/* a */ {1, scsi_low_msginfunc_lcc}, 3246/* b */ {1, scsi_low_msginfunc_lcc}, 3247/* c */ {1, scsi_low_msginfunc_rejop}, 3248/* d */ {2, scsi_low_msginfunc_rejop}, 3249/* e */ {1, scsi_low_msginfunc_rejop}, 3250/* f */ {1, scsi_low_msginfunc_rejop}, 3251/* 0x10 */ {1, scsi_low_msginfunc_rejop}, 3252/* 0x11 */ {1, scsi_low_msginfunc_rejop}, 3253/* 0x12 */ {1, scsi_low_msginfunc_rejop}, 3254/* 0x13 */ {1, scsi_low_msginfunc_rejop}, 3255/* 0x14 */ {1, scsi_low_msginfunc_rejop}, 3256/* 0x15 */ {1, scsi_low_msginfunc_rejop}, 3257/* 0x16 */ {1, scsi_low_msginfunc_rejop}, 3258/* 0x17 */ {1, scsi_low_msginfunc_rejop}, 3259/* 0x18 */ {1, scsi_low_msginfunc_rejop}, 3260/* 0x19 */ {1, scsi_low_msginfunc_rejop}, 3261/* 0x1a */ {1, scsi_low_msginfunc_rejop}, 3262/* 0x1b */ {1, scsi_low_msginfunc_rejop}, 3263/* 0x1c */ {1, scsi_low_msginfunc_rejop}, 3264/* 0x1d */ {1, scsi_low_msginfunc_rejop}, 3265/* 0x1e */ {1, scsi_low_msginfunc_rejop}, 3266/* 0x1f */ {1, scsi_low_msginfunc_rejop}, 3267/* 0x20 */ {2, scsi_low_msginfunc_simple_qtag}, 3268/* 0x21 */ {2, scsi_low_msginfunc_rejop}, 3269/* 0x22 */ {2, scsi_low_msginfunc_rejop}, 3270/* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue}, 3271/* 0x24 */ {2, scsi_low_msginfunc_rejop}, 3272/* 0x25 */ {2, scsi_low_msginfunc_rejop}, 3273/* 0x26 */ {2, scsi_low_msginfunc_rejop}, 3274/* 0x27 */ {2, scsi_low_msginfunc_rejop}, 3275/* 0x28 */ {2, scsi_low_msginfunc_rejop}, 3276/* 0x29 */ {2, scsi_low_msginfunc_rejop}, 3277/* 0x2a */ {2, scsi_low_msginfunc_rejop}, 3278/* 0x2b */ {2, scsi_low_msginfunc_rejop}, 3279/* 0x2c */ {2, scsi_low_msginfunc_rejop}, 3280/* 0x2d */ {2, scsi_low_msginfunc_rejop}, 3281/* 0x2e */ {2, scsi_low_msginfunc_rejop}, 3282/* 0x2f */ {2, scsi_low_msginfunc_rejop}, 3283/* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */ 3284}; 3285 3286/************************************************************** 3287 * msgout 3288 **************************************************************/ 3289static int 3290scsi_low_msgfunc_synch(slp) 3291 struct scsi_low_softc *slp; 3292{ 3293 struct targ_info *ti = slp->sl_Tnexus; 3294 int ptr = ti->ti_msgoutlen; 3295 3296 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN; 3297 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE; 3298 ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period; 3299 ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset; 3300 return MSG_EXTEND_SYNCHLEN + 2; 3301} 3302 3303static int 3304scsi_low_msgfunc_wide(slp) 3305 struct scsi_low_softc *slp; 3306{ 3307 struct targ_info *ti = slp->sl_Tnexus; 3308 int ptr = ti->ti_msgoutlen; 3309 3310 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN; 3311 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE; 3312 ti->ti_msgoutstr[ptr + 3] = ti->ti_width; 3313 return MSG_EXTEND_WIDELEN + 2; 3314} 3315 3316static int 3317scsi_low_msgfunc_identify(slp) 3318 struct scsi_low_softc *slp; 3319{ 3320 struct targ_info *ti = slp->sl_Tnexus; 3321 struct lun_info *li = slp->sl_Lnexus; 3322 struct slccb *cb = slp->sl_Qnexus; 3323 int ptr = ti->ti_msgoutlen; 3324 u_int8_t msg; 3325 3326 msg = MSG_IDENTIFY; 3327 if (cb == NULL) 3328 { 3329 slp->sl_error |= FATALIO; 3330 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3331 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown"); 3332 } 3333 else 3334 { 3335 if (scsi_low_is_disconnect_ok(cb) != 0) 3336 msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun); 3337 else 3338 msg |= li->li_lun; 3339 3340 if (ti->ti_phase == PH_MSGOUT) 3341 { 3342 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp); 3343 if (cb->ccb_tag == SCSI_LOW_UNKTAG) 3344 { 3345 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp); 3346 } 3347 } 3348 } 3349 ti->ti_msgoutstr[ptr + 0] = msg; 3350 return 1; 3351} 3352 3353static int 3354scsi_low_msgfunc_abort(slp) 3355 struct scsi_low_softc *slp; 3356{ 3357 3358 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT); 3359 return 1; 3360} 3361 3362static int 3363scsi_low_msgfunc_qabort(slp) 3364 struct scsi_low_softc *slp; 3365{ 3366 3367 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM); 3368 return 1; 3369} 3370 3371static int 3372scsi_low_msgfunc_reset(slp) 3373 struct scsi_low_softc *slp; 3374{ 3375 3376 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET); 3377 return 1; 3378} 3379 3380static int 3381scsi_low_msgfunc_qtag(slp) 3382 struct scsi_low_softc *slp; 3383{ 3384 struct targ_info *ti = slp->sl_Tnexus; 3385 struct slccb *cb = slp->sl_Qnexus; 3386 int ptr = ti->ti_msgoutlen; 3387 3388 if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG) 3389 { 3390 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP; 3391 return 1; 3392 } 3393 else 3394 { 3395 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag; 3396 if (ti->ti_phase == PH_MSGOUT) 3397 { 3398 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp); 3399 } 3400 } 3401 return 2; 3402} 3403 3404/* 3405 * The following functions are called when targets give unexpected 3406 * responces in msgin (after msgout). 3407 */ 3408static int 3409scsi_low_errfunc_identify(slp, msgflags) 3410 struct scsi_low_softc *slp; 3411 u_int msgflags; 3412{ 3413 3414 if (slp->sl_Lnexus != NULL) 3415 { 3416 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC; 3417 scsi_low_calcf_lun(slp->sl_Lnexus); 3418 } 3419 return 0; 3420} 3421 3422static int 3423scsi_low_errfunc_synch(slp, msgflags) 3424 struct scsi_low_softc *slp; 3425 u_int msgflags; 3426{ 3427 struct targ_info *ti = slp->sl_Tnexus; 3428 3429 MSGIN_PERIOD(ti) = 0; 3430 MSGIN_OFFSET(ti) = 0; 3431 scsi_low_synch(slp); 3432 return 0; 3433} 3434 3435static int 3436scsi_low_errfunc_wide(slp, msgflags) 3437 struct scsi_low_softc *slp; 3438 u_int msgflags; 3439{ 3440 struct targ_info *ti = slp->sl_Tnexus; 3441 3442 MSGIN_WIDTHP(ti) = 0; 3443 scsi_low_wide(slp); 3444 return 0; 3445} 3446 3447static int 3448scsi_low_errfunc_qtag(slp, msgflags) 3449 struct scsi_low_softc *slp; 3450 u_int msgflags; 3451{ 3452 3453 if ((msgflags & SCSI_LOW_MSG_REJECT) != 0) 3454 { 3455 if (slp->sl_Qnexus != NULL) 3456 { 3457 scsi_low_deactivate_qtag(slp->sl_Qnexus); 3458 } 3459 if (slp->sl_Lnexus != NULL) 3460 { 3461 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG; 3462 scsi_low_calcf_lun(slp->sl_Lnexus); 3463 } 3464 printf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname); 3465 } 3466 return 0; 3467} 3468 3469 3470int 3471scsi_low_msgout(slp, ti, fl) 3472 struct scsi_low_softc *slp; 3473 struct targ_info *ti; 3474 u_int fl; 3475{ 3476 struct scsi_low_msgout_data *mdp; 3477 int len = 0; 3478 3479#ifdef SCSI_LOW_DIAGNOSTIC 3480 if (ti != slp->sl_Tnexus) 3481 { 3482 scsi_low_print(slp, NULL); 3483 panic("scsi_low_msgout: Target nexus inconsistent"); 3484 } 3485#endif /* SCSI_LOW_DIAGNOSTIC */ 3486 3487 slp->sl_ph_count ++; 3488 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES) 3489 { 3490 printf("%s: too many phase changes\n", slp->sl_xname); 3491 slp->sl_error |= FATALIO; 3492 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3493 } 3494 3495 /* STEP I. 3496 * Scsi phase changes. 3497 * Previously msgs asserted are accepted by our target or 3498 * processed by scsi_low_msgin. 3499 * Thus clear all saved informations. 3500 */ 3501 if ((fl & SCSI_LOW_MSGOUT_INIT) != 0) 3502 { 3503 ti->ti_omsgflags = 0; 3504 ti->ti_emsgflags = 0; 3505 } 3506 else if (slp->sl_atten == 0) 3507 { 3508 /* STEP II. 3509 * We did not assert attention, however still our target required 3510 * msgs. Resend previous msgs. 3511 */ 3512 ti->ti_msgflags |= ti->ti_omsgflags; 3513 ti->ti_omsgflags = 0; 3514#ifdef SCSI_LOW_DIAGNOSTIC 3515 printf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname); 3516#endif /* SCSI_LOW_DIAGNOSTIC */ 3517 } 3518 3519 /* STEP III. 3520 * We have no msgs. send MSG_NOOP (OK?) 3521 */ 3522 if (scsi_low_is_msgout_continue(ti, 0) == 0) 3523 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0); 3524 3525 /* STEP IV. 3526 * Process all msgs 3527 */ 3528 ti->ti_msgoutlen = 0; 3529 slp->sl_clear_atten = 0; 3530 mdp = &scsi_low_msgout_data[0]; 3531 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++) 3532 { 3533 if ((ti->ti_msgflags & mdp->md_flags) != 0) 3534 { 3535 ti->ti_omsgflags |= mdp->md_flags; 3536 ti->ti_msgflags &= ~mdp->md_flags; 3537 ti->ti_emsgflags = mdp->md_flags; 3538 3539 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg; 3540 if (mdp->md_msgfunc != NULL) 3541 len = (*mdp->md_msgfunc) (slp); 3542 else 3543 len = 1; 3544 3545#ifdef SCSI_LOW_DIAGNOSTIC 3546 scsi_low_msg_log_write(&ti->ti_log_msgout, 3547 &ti->ti_msgoutstr[ti->ti_msgoutlen], len); 3548#endif /* SCSI_LOW_DIAGNOSTIC */ 3549 3550 ti->ti_msgoutlen += len; 3551 if ((mdp->md_condition & MSG_RELEASE_ATN) != 0) 3552 { 3553 slp->sl_clear_atten = 1; 3554 break; 3555 } 3556 3557 if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 || 3558 ti->ti_msgflags == 0) 3559 break; 3560 3561 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5) 3562 break; 3563 } 3564 } 3565 3566 if (scsi_low_is_msgout_continue(ti, 0) == 0) 3567 slp->sl_clear_atten = 1; 3568 3569 return ti->ti_msgoutlen; 3570} 3571 3572/************************************************************** 3573 * msgin 3574 **************************************************************/ 3575static int 3576scsi_low_msginfunc_noop(slp) 3577 struct scsi_low_softc *slp; 3578{ 3579 3580 return 0; 3581} 3582 3583static int 3584scsi_low_msginfunc_rejop(slp) 3585 struct scsi_low_softc *slp; 3586{ 3587 struct targ_info *ti = slp->sl_Tnexus; 3588 u_int8_t msg = ti->ti_msgin[0]; 3589 3590 printf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg); 3591 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 3592 return 0; 3593} 3594 3595static int 3596scsi_low_msginfunc_cc(slp) 3597 struct scsi_low_softc *slp; 3598{ 3599 struct lun_info *li; 3600 3601 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC); 3602 3603 /* validate status */ 3604 if (slp->sl_Qnexus == NULL) 3605 return ENOENT; 3606 3607 slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status; 3608 li = slp->sl_Lnexus; 3609 switch (slp->sl_scp.scp_status) 3610 { 3611 case ST_GOOD: 3612 li->li_maxnqio = li->li_maxnexus; 3613 break; 3614 3615 case ST_CHKCOND: 3616 li->li_maxnqio = 0; 3617 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR) 3618 scsi_low_reset_nexus_lun(slp, li, 0); 3619 break; 3620 3621 case ST_BUSY: 3622 li->li_maxnqio = 0; 3623 break; 3624 3625 case ST_QUEFULL: 3626 if (li->li_maxnexus >= li->li_nqio) 3627 li->li_maxnexus = li->li_nqio - 1; 3628 li->li_maxnqio = li->li_maxnexus; 3629 break; 3630 3631 case ST_INTERGOOD: 3632 case ST_INTERMET: 3633 slp->sl_error |= MSGERR; 3634 break; 3635 3636 default: 3637 break; 3638 } 3639 return 0; 3640} 3641 3642static int 3643scsi_low_msginfunc_lcc(slp) 3644 struct scsi_low_softc *slp; 3645{ 3646 struct targ_info *ti; 3647 struct lun_info *li; 3648 struct slccb *ncb, *cb; 3649 3650 ti = slp->sl_Tnexus; 3651 li = slp->sl_Lnexus; 3652 if ((cb = slp->sl_Qnexus) == NULL) 3653 goto bad; 3654 3655 cb->ccb_sscp.scp_status = slp->sl_scp.scp_status; 3656 switch (slp->sl_scp.scp_status) 3657 { 3658 case ST_INTERGOOD: 3659 case ST_INTERMET: 3660 li->li_maxnqio = li->li_maxnexus; 3661 break; 3662 3663 default: 3664 slp->sl_error |= MSGERR; 3665 break; 3666 } 3667 3668 if ((li->li_flags & SCSI_LOW_LINK) == 0) 3669 goto bad; 3670 3671 cb->ccb_error |= slp->sl_error; 3672 if (cb->ccb_error != 0) 3673 goto bad; 3674 3675 for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL; 3676 ncb = TAILQ_NEXT(ncb, ccb_chain)) 3677 { 3678 if (ncb->li == li) 3679 goto cmd_link_start; 3680 } 3681 3682 3683bad: 3684 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM); 3685 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 3686 return EIO; 3687 3688cmd_link_start: 3689 ncb->ccb_flags &= ~CCB_STARTQ; 3690 TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain); 3691 3692 scsi_low_dealloc_qtag(ncb); 3693 ncb->ccb_tag = cb->ccb_tag; 3694 ncb->ccb_otag = cb->ccb_otag; 3695 cb->ccb_tag = SCSI_LOW_UNKTAG; 3696 cb->ccb_otag = SCSI_LOW_UNKTAG; 3697 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY) 3698 panic("%s: linked ccb retried", slp->sl_xname); 3699 3700 slp->sl_Qnexus = ncb; 3701 slp->sl_ph_count = 0; 3702 3703 ncb->ccb_error = 0; 3704 ncb->ccb_datalen = -1; 3705 ncb->ccb_scp.scp_status = ST_UNKNOWN; 3706 ncb->ccb_flags &= ~CCB_INTERNAL; 3707 3708 scsi_low_init_msgsys(slp, ti); 3709 3710 (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb); 3711 3712 if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT) 3713 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 3714 ncb->ccb_tc = ncb->ccb_tcmax; 3715 3716 /* setup saved scsi data pointer */ 3717 ncb->ccb_sscp = ncb->ccb_scp; 3718 slp->sl_scp = ncb->ccb_sscp; 3719 slp->sl_error = ncb->ccb_error; 3720 3721#ifdef SCSI_LOW_DIAGNOSTIC 3722 scsi_low_msg_log_init(&ti->ti_log_msgin); 3723 scsi_low_msg_log_init(&ti->ti_log_msgout); 3724#endif /* SCSI_LOW_DIAGNOSTIC */ 3725 return EJUSTRETURN; 3726} 3727 3728static int 3729scsi_low_msginfunc_disc(slp) 3730 struct scsi_low_softc *slp; 3731{ 3732 3733 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC); 3734 return 0; 3735} 3736 3737static int 3738scsi_low_msginfunc_sdp(slp) 3739 struct scsi_low_softc *slp; 3740{ 3741 struct slccb *cb = slp->sl_Qnexus; 3742 3743 if (cb != NULL) 3744 { 3745 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen; 3746 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data; 3747 } 3748 else 3749 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0); 3750 return 0; 3751} 3752 3753static int 3754scsi_low_msginfunc_rp(slp) 3755 struct scsi_low_softc *slp; 3756{ 3757 3758 if (slp->sl_Qnexus != NULL) 3759 slp->sl_scp = slp->sl_Qnexus->ccb_sscp; 3760 else 3761 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0); 3762 return 0; 3763} 3764 3765static int 3766scsi_low_synch(slp) 3767 struct scsi_low_softc *slp; 3768{ 3769 struct targ_info *ti = slp->sl_Tnexus; 3770 u_int period = 0, offset = 0, speed; 3771 u_char *s; 3772 int error; 3773 3774 if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period && 3775 MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) || 3776 MSGIN_OFFSET(ti) == 0) 3777 { 3778 if ((offset = MSGIN_OFFSET(ti)) != 0) 3779 period = MSGIN_PERIOD(ti); 3780 s = offset ? "synchronous" : "async"; 3781 } 3782 else 3783 { 3784 /* XXX: 3785 * Target seems to be brain damaged. 3786 * Force async transfer. 3787 */ 3788 ti->ti_maxsynch.period = 0; 3789 ti->ti_maxsynch.offset = 0; 3790 printf("%s: target brain damaged. async transfer\n", 3791 slp->sl_xname); 3792 return EINVAL; 3793 } 3794 3795 ti->ti_maxsynch.period = period; 3796 ti->ti_maxsynch.offset = offset; 3797 3798 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH); 3799 if (error != 0) 3800 { 3801 /* XXX: 3802 * Current period and offset are not acceptable 3803 * for our adapter. 3804 * The adapter changes max synch and max offset. 3805 */ 3806 printf("%s: synch neg failed. retry synch msg neg ...\n", 3807 slp->sl_xname); 3808 return error; 3809 } 3810 3811 ti->ti_osynch = ti->ti_maxsynch; 3812 if (offset > 0) 3813 { 3814 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH; 3815 } 3816 3817 /* inform data */ 3818 if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0) 3819 { 3820#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE 3821 struct slccb *cb = slp->sl_Qnexus; 3822 3823 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0) 3824 return 0; 3825#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */ 3826 3827 printf("%s(%d:*): <%s> offset %d period %dns ", 3828 slp->sl_xname, ti->ti_id, s, offset, period * 4); 3829 3830 if (period != 0) 3831 { 3832 speed = 1000 * 10 / (period * 4); 3833 printf("%d.%d M/s", speed / 10, speed % 10); 3834 } 3835 printf("\n"); 3836 } 3837 return 0; 3838} 3839 3840static int 3841scsi_low_wide(slp) 3842 struct scsi_low_softc *slp; 3843{ 3844 struct targ_info *ti = slp->sl_Tnexus; 3845 int error; 3846 3847 ti->ti_width = MSGIN_WIDTHP(ti); 3848 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE); 3849 if (error != 0) 3850 { 3851 /* XXX: 3852 * Current width is not acceptable for our adapter. 3853 * The adapter changes max width. 3854 */ 3855 printf("%s: wide neg failed. retry wide msg neg ...\n", 3856 slp->sl_xname); 3857 return error; 3858 } 3859 3860 ti->ti_owidth = ti->ti_width; 3861 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8) 3862 { 3863 ti->ti_setup_msg_done |= 3864 (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE); 3865 } 3866 3867 /* inform data */ 3868 if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0) 3869 { 3870#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE 3871 struct slccb *cb = slp->sl_Qnexus; 3872 3873 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0) 3874 return 0; 3875#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */ 3876 3877 printf("%s(%d:*): transfer width %d bits\n", 3878 slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width)); 3879 } 3880 return 0; 3881} 3882 3883static int 3884scsi_low_msginfunc_simple_qtag(slp) 3885 struct scsi_low_softc *slp; 3886{ 3887 struct targ_info *ti = slp->sl_Tnexus; 3888 scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1]; 3889 3890 if (slp->sl_Qnexus != NULL) 3891 { 3892 if (slp->sl_Qnexus->ccb_tag != etag) 3893 { 3894 slp->sl_error |= FATALIO; 3895 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3896 SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch"); 3897 } 3898 } 3899 else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL) 3900 { 3901#ifdef SCSI_LOW_DEBUG 3902 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id)) 3903 return 0; 3904#endif /* SCSI_LOW_DEBUG */ 3905 3906 slp->sl_error |= FATALIO; 3907 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0); 3908 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found"); 3909 } 3910 return 0; 3911} 3912 3913static int 3914scsi_low_msginfunc_i_wide_residue(slp) 3915 struct scsi_low_softc *slp; 3916{ 3917 struct targ_info *ti = slp->sl_Tnexus; 3918 struct slccb *cb = slp->sl_Qnexus; 3919 int res = (int) ti->ti_msgin[1]; 3920 3921 if (cb == NULL || res <= 0 || 3922 (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) || 3923 (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3)) 3924 return EINVAL; 3925 3926 if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen) 3927 return EINVAL; 3928 3929 slp->sl_scp.scp_datalen += res; 3930 slp->sl_scp.scp_data -= res; 3931 scsi_low_data_finish(slp); 3932 return 0; 3933} 3934 3935static int 3936scsi_low_msginfunc_ext(slp) 3937 struct scsi_low_softc *slp; 3938{ 3939 struct slccb *cb = slp->sl_Qnexus; 3940 struct lun_info *li = slp->sl_Lnexus; 3941 struct targ_info *ti = slp->sl_Tnexus; 3942 int count, retry; 3943 u_int32_t *ptr; 3944 3945 if (ti->ti_msginptr == 2) 3946 { 3947 ti->ti_msginlen = ti->ti_msgin[1] + 2; 3948 return 0; 3949 } 3950 3951 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2])) 3952 { 3953 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE): 3954 if (cb == NULL) 3955 break; 3956 3957 ptr = (u_int32_t *)(&ti->ti_msgin[3]); 3958 count = (int) htonl((long) (*ptr)); 3959 if(slp->sl_scp.scp_datalen - count < 0 || 3960 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen) 3961 break; 3962 3963 slp->sl_scp.scp_datalen -= count; 3964 slp->sl_scp.scp_data += count; 3965 return 0; 3966 3967 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE): 3968 if (li == NULL) 3969 break; 3970 3971 retry = scsi_low_synch(slp); 3972 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0) 3973 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0); 3974 3975#ifdef SCSI_LOW_DEBUG 3976 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id)) 3977 { 3978 scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH); 3979 } 3980#endif /* SCSI_LOW_DEBUG */ 3981 return 0; 3982 3983 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE): 3984 if (li == NULL) 3985 break; 3986 3987 retry = scsi_low_wide(slp); 3988 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0) 3989 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0); 3990 3991 return 0; 3992 3993 default: 3994 break; 3995 } 3996 3997 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 3998 return EINVAL; 3999} 4000 4001static int 4002scsi_low_msginfunc_parity(slp) 4003 struct scsi_low_softc *slp; 4004{ 4005 struct targ_info *ti = slp->sl_Tnexus; 4006 4007 /* only I -> T, invalid! */ 4008 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 4009 return 0; 4010} 4011 4012static int 4013scsi_low_msginfunc_msg_reject(slp) 4014 struct scsi_low_softc *slp; 4015{ 4016 struct targ_info *ti = slp->sl_Tnexus; 4017 struct scsi_low_msgout_data *mdp; 4018 u_int msgflags; 4019 4020 if (ti->ti_emsgflags != 0) 4021 { 4022 printf("%s: msg flags [0x%x] rejected\n", 4023 slp->sl_xname, ti->ti_emsgflags); 4024 msgflags = SCSI_LOW_MSG_REJECT; 4025 mdp = &scsi_low_msgout_data[0]; 4026 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++) 4027 { 4028 if ((ti->ti_emsgflags & mdp->md_flags) != 0) 4029 { 4030 ti->ti_emsgflags &= ~mdp->md_flags; 4031 if (mdp->md_errfunc != NULL) 4032 (*mdp->md_errfunc) (slp, msgflags); 4033 break; 4034 } 4035 } 4036 return 0; 4037 } 4038 else 4039 { 4040 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found"); 4041 slp->sl_error |= MSGERR; 4042 } 4043 return EINVAL; 4044} 4045 4046int 4047scsi_low_msgin(slp, ti, c) 4048 struct scsi_low_softc *slp; 4049 struct targ_info *ti; 4050 u_int c; 4051{ 4052 struct scsi_low_msgin_data *sdp; 4053 struct lun_info *li; 4054 u_int8_t msg; 4055 4056#ifdef SCSI_LOW_DIAGNOSTIC 4057 if (ti != slp->sl_Tnexus) 4058 { 4059 scsi_low_print(slp, NULL); 4060 panic("scsi_low_msgin: Target nexus inconsistent"); 4061 } 4062#endif /* SCSI_LOW_DIAGNOSTIC */ 4063 4064 /* 4065 * Phase changes, clear the pointer. 4066 */ 4067 if (ti->ti_ophase != ti->ti_phase) 4068 { 4069 MSGINPTR_CLR(ti); 4070 ti->ti_msgin_parity_error = 0; 4071 4072 slp->sl_ph_count ++; 4073 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES) 4074 { 4075 printf("%s: too many phase changes\n", slp->sl_xname); 4076 slp->sl_error |= FATALIO; 4077 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 4078 } 4079 } 4080 4081 /* 4082 * Store a current messages byte into buffer and 4083 * wait for the completion of the current msg. 4084 */ 4085 ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c; 4086 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN) 4087 { 4088 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1; 4089 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 4090 } 4091 4092 /* 4093 * Check parity errors. 4094 */ 4095 if ((c & SCSI_LOW_DATA_PE) != 0) 4096 { 4097 ti->ti_msgin_parity_error ++; 4098 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0); 4099 goto out; 4100 } 4101 4102 if (ti->ti_msgin_parity_error != 0) 4103 goto out; 4104 4105 /* 4106 * Calculate messages length. 4107 */ 4108 msg = ti->ti_msgin[0]; 4109 if (msg < MSGIN_DATA_LAST) 4110 sdp = &scsi_low_msgin_data[msg]; 4111 else 4112 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST]; 4113 4114 if (ti->ti_msginlen == 0) 4115 { 4116 ti->ti_msginlen = sdp->md_len; 4117 } 4118 4119 /* 4120 * Check comletion. 4121 */ 4122 if (ti->ti_msginptr < ti->ti_msginlen) 4123 return EJUSTRETURN; 4124 4125 /* 4126 * Do process. 4127 */ 4128 if ((msg & MSG_IDENTIFY) == 0) 4129 { 4130 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN) 4131 return EJUSTRETURN; 4132 } 4133 else 4134 { 4135 li = slp->sl_Lnexus; 4136 if (li == NULL) 4137 { 4138 li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0); 4139 if (li == NULL) 4140 goto badlun; 4141 slp->sl_Lnexus = li; 4142 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp); 4143 } 4144 else 4145 { 4146 if (MSGCMD_LUN(msg) != li->li_lun) 4147 goto badlun; 4148 } 4149 4150 if (slp->sl_Qnexus == NULL && li->li_nqio == 0) 4151 { 4152 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG)) 4153 { 4154#ifdef SCSI_LOW_DEBUG 4155 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0) 4156 { 4157 goto out; 4158 } 4159#endif /* SCSI_LOW_DEBUG */ 4160 goto badlun; 4161 } 4162 } 4163 } 4164 goto out; 4165 4166 /* 4167 * Msg process completed, reset msgin pointer and assert ATN if desired. 4168 */ 4169badlun: 4170 slp->sl_error |= FATALIO; 4171 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 4172 SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong"); 4173 4174out: 4175 if (ti->ti_msginptr < ti->ti_msginlen) 4176 return EJUSTRETURN; 4177 4178#ifdef SCSI_LOW_DIAGNOSTIC 4179 scsi_low_msg_log_write(&ti->ti_log_msgin, 4180 &ti->ti_msgin[0], ti->ti_msginlen); 4181#endif /* SCSI_LOW_DIAGNOSTIC */ 4182 4183 MSGINPTR_CLR(ti); 4184 return 0; 4185} 4186 4187/********************************************************** 4188 * disconnect 4189 **********************************************************/ 4190int 4191scsi_low_disconnected(slp, ti) 4192 struct scsi_low_softc *slp; 4193 struct targ_info *ti; 4194{ 4195 struct slccb *cb = slp->sl_Qnexus; 4196 4197 /* check phase completion */ 4198 switch (slp->sl_msgphase) 4199 { 4200 case MSGPH_RESET: 4201 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD); 4202 scsi_low_msginfunc_cc(slp); 4203 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0); 4204 goto io_resume; 4205 4206 case MSGPH_ABORT: 4207 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD); 4208 scsi_low_msginfunc_cc(slp); 4209 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0); 4210 goto io_resume; 4211 4212 case MSGPH_TERM: 4213 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD); 4214 scsi_low_msginfunc_cc(slp); 4215 goto io_resume; 4216 4217 case MSGPH_DISC: 4218 if (cb != NULL) 4219 { 4220 struct lun_info *li; 4221 4222 li = cb->li; 4223 TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain); 4224 cb->ccb_flags |= CCB_DISCQ; 4225 cb->ccb_error |= slp->sl_error; 4226 li->li_disc ++; 4227 ti->ti_disc ++; 4228 slp->sl_disc ++; 4229 } 4230 4231#ifdef SCSI_LOW_STATICS 4232 scsi_low_statics.nexus_disconnected ++; 4233#endif /* SCSI_LOW_STATICS */ 4234 4235#ifdef SCSI_LOW_DEBUG 4236 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0) 4237 { 4238 printf("## SCSI_LOW_DISCONNECTED ===============\n"); 4239 scsi_low_print(slp, NULL); 4240 } 4241#endif /* SCSI_LOW_DEBUG */ 4242 break; 4243 4244 case MSGPH_NULL: 4245 slp->sl_error |= FATALIO; 4246 if (ti->ti_phase == PH_SELSTART) 4247 slp->sl_error |= SELTIMEOUTIO; 4248 else 4249 slp->sl_error |= UBFERR; 4250 /* fall through */ 4251 4252 case MSGPH_LCTERM: 4253 case MSGPH_CMDC: 4254io_resume: 4255 if (cb == NULL) 4256 break; 4257 4258#ifdef SCSI_LOW_DEBUG 4259 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id)) 4260 { 4261 if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP && 4262 (cb->ccb_msgoutflag != 0 || 4263 (ti->ti_msgflags & SCSI_LOW_MSG_NOOP))) 4264 { 4265 scsi_low_info(slp, ti, "ATTEN CHECK FAILED"); 4266 } 4267 } 4268#endif /* SCSI_LOW_DEBUG */ 4269 4270 cb->ccb_error |= slp->sl_error; 4271 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY) 4272 { 4273 cb->ccb_flags |= CCB_STARTQ; 4274 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 4275 } 4276 break; 4277 } 4278 4279 scsi_low_bus_release(slp, ti); 4280 scsi_low_start(slp); 4281 return 1; 4282} 4283 4284/********************************************************** 4285 * TAG operations 4286 **********************************************************/ 4287static int 4288scsi_low_alloc_qtag(cb) 4289 struct slccb *cb; 4290{ 4291 struct lun_info *li = cb->li; 4292 scsi_low_tag_t etag; 4293 4294 if (cb->ccb_otag != SCSI_LOW_UNKTAG) 4295 return 0; 4296 4297#ifndef SCSI_LOW_ALT_QTAG_ALLOCATE 4298 etag = ffs(li->li_qtagbits); 4299 if (etag == 0) 4300 return ENOSPC; 4301 4302 li->li_qtagbits &= ~(1 << (etag - 1)); 4303 cb->ccb_otag = etag; 4304 return 0; 4305 4306#else /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 4307 for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++) 4308 if (li->li_qtagarray[li->li_qd] == 0) 4309 goto found; 4310 4311 for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++) 4312 if (li->li_qtagarray[li->li_qd] == 0) 4313 goto found; 4314 4315 return ENOSPC; 4316 4317found: 4318 li->li_qtagarray[li->li_qd] ++; 4319 cb->ccb_otag = (li->li_qd ++); 4320 return 0; 4321#endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 4322} 4323 4324static int 4325scsi_low_dealloc_qtag(cb) 4326 struct slccb *cb; 4327{ 4328 struct lun_info *li = cb->li; 4329 scsi_low_tag_t etag; 4330 4331 if (cb->ccb_otag == SCSI_LOW_UNKTAG) 4332 return 0; 4333 4334#ifndef SCSI_LOW_ALT_QTAG_ALLOCATE 4335 etag = cb->ccb_otag - 1; 4336#ifdef SCSI_LOW_DIAGNOSTIC 4337 if (etag >= sizeof(li->li_qtagbits) * NBBY) 4338 panic("scsi_low_dealloc_tag: illegal tag"); 4339#endif /* SCSI_LOW_DIAGNOSTIC */ 4340 li->li_qtagbits |= (1 << etag); 4341 4342#else /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 4343 etag = cb->ccb_otag; 4344#ifdef SCSI_LOW_DIAGNOSTIC 4345 if (etag >= SCSI_LOW_MAXNEXUS) 4346 panic("scsi_low_dealloc_tag: illegal tag"); 4347#endif /* SCSI_LOW_DIAGNOSTIC */ 4348 li->li_qtagarray[etag] --; 4349#endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 4350 4351 cb->ccb_otag = SCSI_LOW_UNKTAG; 4352 return 0; 4353} 4354 4355static struct slccb * 4356scsi_low_revoke_ccb(slp, cb, fdone) 4357 struct scsi_low_softc *slp; 4358 struct slccb *cb; 4359 int fdone; 4360{ 4361 struct targ_info *ti = cb->ti; 4362 struct lun_info *li = cb->li; 4363 4364#ifdef SCSI_LOW_DIAGNOSTIC 4365 if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) == 4366 (CCB_STARTQ | CCB_DISCQ)) 4367 { 4368 panic("%s: ccb in both queue", slp->sl_xname); 4369 } 4370#endif /* SCSI_LOW_DIAGNOSTIC */ 4371 4372 if ((cb->ccb_flags & CCB_STARTQ) != 0) 4373 { 4374 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain); 4375 } 4376 4377 if ((cb->ccb_flags & CCB_DISCQ) != 0) 4378 { 4379 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain); 4380 li->li_disc --; 4381 ti->ti_disc --; 4382 slp->sl_disc --; 4383 } 4384 4385 cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ | 4386 CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL); 4387 4388 if (fdone != 0 && 4389 (cb->ccb_rcnt ++ >= slp->sl_max_retry || 4390 (cb->ccb_flags & CCB_NORETRY) != 0)) 4391 { 4392 cb->ccb_error |= FATALIO; 4393 cb->ccb_flags &= ~CCB_AUTOSENSE; 4394 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE) 4395 panic("%s: done ccb retried", slp->sl_xname); 4396 return NULL; 4397 } 4398 else 4399 { 4400 cb->ccb_error |= PENDINGIO; 4401 scsi_low_deactivate_qtag(cb); 4402 scsi_low_ccb_message_retry(cb); 4403 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 4404 return cb; 4405 } 4406} 4407 4408static void 4409scsi_low_reset_nexus_lun(slp, li, fdone) 4410 struct scsi_low_softc *slp; 4411 struct lun_info *li; 4412 int fdone; 4413{ 4414 struct slccb *cb, *ncb, *ecb; 4415 4416 if (li == NULL) 4417 return; 4418 4419 ecb = NULL; 4420 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb) 4421 { 4422 ncb = TAILQ_NEXT(cb, ccb_chain); 4423 cb = scsi_low_revoke_ccb(slp, cb, fdone); 4424 if (cb != NULL) 4425 { 4426 /* 4427 * presumely keep ordering of io 4428 */ 4429 cb->ccb_flags |= CCB_STARTQ; 4430 if (ecb == NULL) 4431 { 4432 TAILQ_INSERT_HEAD(&slp->sl_start,\ 4433 cb, ccb_chain); 4434 } 4435 else 4436 { 4437 TAILQ_INSERT_AFTER(&slp->sl_start,\ 4438 ecb, cb, ccb_chain); 4439 } 4440 ecb = cb; 4441 } 4442 } 4443} 4444 4445/************************************************************** 4446 * Qurik setup 4447 **************************************************************/ 4448static void 4449scsi_low_calcf_lun(li) 4450 struct lun_info *li; 4451{ 4452 struct targ_info *ti = li->li_ti; 4453 struct scsi_low_softc *slp = ti->ti_sc; 4454 u_int cfgflags, diskflags; 4455 4456 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID) 4457 cfgflags = li->li_cfgflags; 4458 else 4459 cfgflags = 0; 4460 4461 diskflags = li->li_diskflags & li->li_quirks; 4462 4463 /* disconnect */ 4464 li->li_flags &= ~SCSI_LOW_DISC; 4465 if ((slp->sl_cfgflags & CFG_NODISC) == 0 && 4466 (diskflags & SCSI_LOW_DISK_DISC) != 0 && 4467 (cfgflags & SCSI_LOW_DISC) != 0) 4468 li->li_flags |= SCSI_LOW_DISC; 4469 4470 /* parity */ 4471 li->li_flags |= SCSI_LOW_NOPARITY; 4472 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 && 4473 (diskflags & SCSI_LOW_DISK_PARITY) != 0 && 4474 (cfgflags & SCSI_LOW_NOPARITY) == 0) 4475 li->li_flags &= ~SCSI_LOW_NOPARITY; 4476 4477 /* qtag */ 4478 if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 && 4479 (cfgflags & SCSI_LOW_QTAG) != 0 && 4480 (diskflags & SCSI_LOW_DISK_QTAG) != 0) 4481 { 4482 li->li_flags |= SCSI_LOW_QTAG; 4483 li->li_maxnexus = SCSI_LOW_MAXNEXUS; 4484 li->li_maxnqio = li->li_maxnexus; 4485 } 4486 else 4487 { 4488 li->li_flags &= ~SCSI_LOW_QTAG; 4489 li->li_maxnexus = 0; 4490 li->li_maxnqio = li->li_maxnexus; 4491 } 4492 4493 /* cmd link */ 4494 li->li_flags &= ~SCSI_LOW_LINK; 4495 if ((cfgflags & SCSI_LOW_LINK) != 0 && 4496 (diskflags & SCSI_LOW_DISK_LINK) != 0) 4497 li->li_flags |= SCSI_LOW_LINK; 4498 4499 /* compatible flags */ 4500 li->li_flags &= ~SCSI_LOW_SYNC; 4501 if (ti->ti_maxsynch.offset > 0) 4502 li->li_flags |= SCSI_LOW_SYNC; 4503 4504#ifdef SCSI_LOW_DEBUG 4505 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0) 4506 { 4507 scsi_low_calcf_show(li); 4508 } 4509#endif /* SCSI_LOW_DEBUG */ 4510} 4511 4512static void 4513scsi_low_calcf_target(ti) 4514 struct targ_info *ti; 4515{ 4516 struct scsi_low_softc *slp = ti->ti_sc; 4517 u_int offset, period, diskflags; 4518 4519 diskflags = ti->ti_diskflags & ti->ti_quirks; 4520 4521 /* synch */ 4522 if ((slp->sl_cfgflags & CFG_ASYNC) == 0 && 4523 (diskflags & SCSI_LOW_DISK_SYNC) != 0) 4524 { 4525 offset = ti->ti_maxsynch.offset; 4526 period = ti->ti_maxsynch.period; 4527 if (offset == 0 || period == 0) 4528 offset = period = 0; 4529 } 4530 else 4531 { 4532 offset = period = 0; 4533 } 4534 4535 ti->ti_maxsynch.offset = offset; 4536 ti->ti_maxsynch.period = period; 4537 4538 /* wide */ 4539 if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 && 4540 ti->ti_width > SCSI_LOW_BUS_WIDTH_16) 4541 ti->ti_width = SCSI_LOW_BUS_WIDTH_16; 4542 4543 if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 && 4544 ti->ti_width > SCSI_LOW_BUS_WIDTH_8) 4545 ti->ti_width = SCSI_LOW_BUS_WIDTH_8; 4546 4547 if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID) 4548 { 4549 if (ti->ti_maxsynch.offset != ti->ti_osynch.offset || 4550 ti->ti_maxsynch.period != ti->ti_osynch.period) 4551 ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH; 4552 if (ti->ti_width != ti->ti_owidth) 4553 ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH); 4554 4555 ti->ti_osynch = ti->ti_maxsynch; 4556 ti->ti_owidth = ti->ti_width; 4557 } 4558 4559#ifdef SCSI_LOW_DEBUG 4560 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0) 4561 { 4562 printf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n", 4563 slp->sl_xname, ti->ti_id, 4564 ti->ti_maxsynch.period * 4, 4565 ti->ti_maxsynch.offset, 4566 ti->ti_width); 4567 } 4568#endif /* SCSI_LOW_DEBUG */ 4569} 4570 4571static void 4572scsi_low_calcf_show(li) 4573 struct lun_info *li; 4574{ 4575 struct targ_info *ti = li->li_ti; 4576 struct scsi_low_softc *slp = ti->ti_sc; 4577 4578 printf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n", 4579 slp->sl_xname, ti->ti_id, li->li_lun, 4580 ti->ti_maxsynch.period * 4, 4581 ti->ti_maxsynch.offset, 4582 ti->ti_width, 4583 li->li_flags, SCSI_LOW_BITS); 4584} 4585 4586#ifdef SCSI_LOW_START_UP_CHECK 4587/************************************************************** 4588 * scsi world start up 4589 **************************************************************/ 4590static int scsi_low_poll(struct scsi_low_softc *, struct slccb *); 4591 4592static int 4593scsi_low_start_up(slp) 4594 struct scsi_low_softc *slp; 4595{ 4596 struct targ_info *ti; 4597 struct lun_info *li; 4598 struct slccb *cb; 4599 int target, lun; 4600 4601 printf("%s: scsi_low: probing all devices ....\n", slp->sl_xname); 4602 4603 for (target = 0; target < slp->sl_ntargs; target ++) 4604 { 4605 if (target == slp->sl_hostid) 4606 { 4607 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) 4608 { 4609 printf("%s: scsi_low: target %d (host card)\n", 4610 slp->sl_xname, target); 4611 } 4612 continue; 4613 } 4614 4615 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) 4616 { 4617 printf("%s: scsi_low: target %d lun ", 4618 slp->sl_xname, target); 4619 } 4620 4621 ti = slp->sl_ti[target]; 4622 for (lun = 0; lun < slp->sl_nluns; lun ++) 4623 { 4624 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL) 4625 break; 4626 4627 cb->osdep = NULL; 4628 cb->bp = NULL; 4629 4630 li = scsi_low_alloc_li(ti, lun, 1); 4631 4632 scsi_low_enqueue(slp, ti, li, cb, 4633 CCB_AUTOSENSE | CCB_POLLED, 0); 4634 4635 scsi_low_poll(slp, cb); 4636 4637 if (li->li_state != SCSI_LOW_LUN_OK) 4638 break; 4639 4640 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) 4641 { 4642 printf("%d ", lun); 4643 } 4644 } 4645 4646 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) 4647 { 4648 printf("\n"); 4649 } 4650 } 4651 return 0; 4652} 4653 4654static int 4655scsi_low_poll(slp, cb) 4656 struct scsi_low_softc *slp; 4657 struct slccb *cb; 4658{ 4659 int tcount; 4660 4661 tcount = 0; 4662 while (slp->sl_nio > 0) 4663 { 4664 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ); 4665 4666 (*slp->sl_funcs->scsi_low_poll) (slp); 4667 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ) 4668 continue; 4669 4670 tcount = 0; 4671 scsi_low_timeout_check(slp); 4672 } 4673 4674 return 0; 4675} 4676#endif /* SCSI_LOW_START_UP_CHECK */ 4677 4678/********************************************************** 4679 * DEBUG SECTION 4680 **********************************************************/ 4681#ifdef SCSI_LOW_DEBUG 4682static void 4683scsi_low_test_abort(slp, ti, li) 4684 struct scsi_low_softc *slp; 4685 struct targ_info *ti; 4686 struct lun_info *li; 4687{ 4688 struct slccb *acb; 4689 4690 if (li->li_disc > 1) 4691 { 4692 acb = TAILQ_FIRST(&li->li_discq); 4693 if (scsi_low_abort_ccb(slp, acb) == 0) 4694 { 4695 printf("%s: aborting ccb(0x%lx) start\n", 4696 slp->sl_xname, (u_long) acb); 4697 } 4698 } 4699} 4700 4701static void 4702scsi_low_test_atten(slp, ti, msg) 4703 struct scsi_low_softc *slp; 4704 struct targ_info *ti; 4705 u_int msg; 4706{ 4707 4708 if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK) 4709 scsi_low_assert_msg(slp, ti, msg, 0); 4710 else 4711 printf("%s: atten check OK\n", slp->sl_xname); 4712} 4713 4714static void 4715scsi_low_test_cmdlnk(slp, cb) 4716 struct scsi_low_softc *slp; 4717 struct slccb *cb; 4718{ 4719#define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ) 4720 4721 if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0) 4722 return; 4723 4724 memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd, 4725 slp->sl_scp.scp_cmdlen); 4726 cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1; 4727 slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd; 4728} 4729#endif /* SCSI_LOW_DEBUG */ 4730 4731/* static */ void 4732scsi_low_info(slp, ti, s) 4733 struct scsi_low_softc *slp; 4734 struct targ_info *ti; 4735 u_char *s; 4736{ 4737 4738 if (slp == NULL) 4739 slp = LIST_FIRST(&sl_tab); 4740 if (s == NULL) 4741 s = "no message"; 4742 4743 printf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s); 4744 if (ti == NULL) 4745 { 4746 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL; 4747 ti = TAILQ_NEXT(ti, ti_chain)) 4748 { 4749 scsi_low_print(slp, ti); 4750 } 4751 } 4752 else 4753 { 4754 scsi_low_print(slp, ti); 4755 } 4756} 4757 4758static u_char *phase[] = 4759{ 4760 "FREE", "ARBSTART", "SELSTART", "SELECTED", 4761 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL" 4762}; 4763 4764void 4765scsi_low_print(slp, ti) 4766 struct scsi_low_softc *slp; 4767 struct targ_info *ti; 4768{ 4769 struct lun_info *li; 4770 struct slccb *cb; 4771 struct sc_p *sp; 4772 4773 if (ti == NULL || ti == slp->sl_Tnexus) 4774 { 4775 ti = slp->sl_Tnexus; 4776 li = slp->sl_Lnexus; 4777 cb = slp->sl_Qnexus; 4778 } 4779 else 4780 { 4781 li = LIST_FIRST(&ti->ti_litab); 4782 cb = TAILQ_FIRST(&li->li_discq); 4783 } 4784 sp = &slp->sl_scp; 4785 4786 printf("%s: === NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n", 4787 slp->sl_xname, (u_long) ti, (u_long) li, (u_long) cb, 4788 slp->sl_nio); 4789 4790 /* target stat */ 4791 if (ti != NULL) 4792 { 4793 u_int flags = 0, maxnqio = 0, nqio = 0; 4794 int lun = -1; 4795 4796 if (li != NULL) 4797 { 4798 lun = li->li_lun; 4799 flags = li->li_flags; 4800 maxnqio = li->li_maxnqio; 4801 nqio = li->li_nqio; 4802 } 4803 4804 printf("%s(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n", 4805 slp->sl_xname, 4806 ti->ti_id, lun, phase[(int) ti->ti_ophase], 4807 phase[(int) ti->ti_phase], ti->ti_disc, 4808 nqio, maxnqio); 4809 4810 if (cb != NULL) 4811 { 4812printf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n", 4813 (u_int) cb->ccb_scp.scp_cmd[0], 4814 cb->ccb_scp.scp_cmdlen, 4815 cb->ccb_datalen, 4816 cb->ccb_scp.scp_datalen, 4817 (u_int) cb->ccb_sscp.scp_status, 4818 cb->ccb_error, SCSI_LOW_ERRORBITS); 4819 } 4820 4821printf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n", 4822 (u_int) (ti->ti_msginptr), 4823 (u_int) (ti->ti_msgin[0]), 4824 (u_int) (ti->ti_msgin[1]), 4825 (u_int) (ti->ti_msgin[2]), 4826 (u_int) (ti->ti_msgin[3]), 4827 (u_int) (ti->ti_msgin[4]), 4828 slp->sl_atten); 4829 4830printf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n", 4831 (u_int) ti->ti_msgflags, 4832 (u_int) (ti->ti_msgoutstr[0]), 4833 (u_int) (ti->ti_msgoutstr[1]), 4834 (u_int) (ti->ti_msgoutstr[2]), 4835 (u_int) (ti->ti_msgoutstr[3]), 4836 (u_int) (ti->ti_msgoutstr[4]), 4837 ti->ti_msgoutlen, 4838 flags, SCSI_LOW_BITS); 4839 4840#ifdef SCSI_LOW_DIAGNOSTIC 4841 scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2); 4842 scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2); 4843#endif /* SCSI_LOW_DIAGNOSTIC */ 4844 4845 } 4846 4847 printf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n", 4848 (u_long) sp->scp_data, 4849 sp->scp_datalen, 4850 (u_int) sp->scp_status, 4851 slp->sl_error, SCSI_LOW_ERRORBITS); 4852} 4853