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