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