1/* $FreeBSD: releng/11.0/sys/cam/scsi/scsi_low.h 298810 2016-04-29 21:05:48Z pfg $ */ 2/* $NecBSD: scsi_low.h,v 1.24.10.5 2001/06/26 07:31:46 honda Exp $ */ 3/* $NetBSD$ */ 4 5#define SCSI_LOW_DIAGNOSTIC 6#define SCSI_LOW_ALT_QTAG_ALLOCATE 7 8/*- 9 * [NetBSD for NEC PC-98 series] 10 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001 11 * NetBSD/pc98 porting staff. All rights reserved. 12 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001 13 * Naofumi HONDA. All rights reserved. 14 * 15 * [Ported for FreeBSD CAM] 16 * Copyright (c) 2000, 2001 17 * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro. 18 * All rights reserved. 19 * 20 * Redistribution and use in source and binary forms, with or without 21 * modification, are permitted provided that the following conditions 22 * are met: 23 * 1. Redistributions of source code must retain the above copyright 24 * notice, this list of conditions and the following disclaimer. 25 * 2. Redistributions in binary form must reproduce the above copyright 26 * notice, this list of conditions and the following disclaimer in the 27 * documentation and/or other materials provided with the distribution. 28 * 3. The name of the author may not be used to endorse or promote products 29 * derived from this software without specific prior written permission. 30 * 31 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 32 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 33 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 34 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 35 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 40 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGE. 42 */ 43 44#ifndef _SCSI_LOW_H_ 45#define _SCSI_LOW_H_ 46 47/******** includes *******************************/ 48 49#include <sys/bus.h> 50#include <sys/kdb.h> 51#include <cam/cam.h> 52#include <cam/cam_ccb.h> 53#include <cam/cam_sim.h> 54#include <cam/cam_xpt_sim.h> 55#include <cam/cam_debug.h> 56 57#include <cam/scsi/scsi_dvcfg.h> 58#include <i386/isa/ccbque.h> 59 60/******** functions macro ************************/ 61 62#undef MSG_IDENTIFY 63 64/*================================================ 65 * Generic Scsi Low header file 66 ================================================*/ 67/************************************************* 68 * Scsi low definitions 69 *************************************************/ 70#define SCSI_LOW_SYNC DVF_SCSI_SYNC 71#define SCSI_LOW_DISC DVF_SCSI_DISC 72#define SCSI_LOW_WAIT DVF_SCSI_WAIT 73#define SCSI_LOW_LINK DVF_SCSI_LINK 74#define SCSI_LOW_QTAG DVF_SCSI_QTAG 75#define SCSI_LOW_NOPARITY DVF_SCSI_NOPARITY 76#define SCSI_LOW_SAVESP DVF_SCSI_SAVESP 77#define SCSI_LOW_DEFCFG DVF_SCSI_DEFCFG 78#define SCSI_LOW_BITS DVF_SCSI_BITS 79 80#define SCSI_LOW_PERIOD(n) DVF_SCSI_PERIOD(n) 81#define SCSI_LOW_OFFSET(n) DVF_SCSI_OFFSET(n) 82 83/* host scsi id and targets macro */ 84#ifndef SCSI_LOW_NTARGETS 85#define SCSI_LOW_NTARGETS 8 86#endif /* SCSI_LOW_NTARGETS */ 87#define SCSI_LOW_NCCB 128 88 89#define SCSI_LOW_MAX_RETRY 3 90#define SCSI_LOW_MAX_SELECTION_RETRY 10 91 92/* timeout control macro */ 93#define SCSI_LOW_TIMEOUT_HZ 10 94#define SCSI_LOW_MIN_TOUT 12 95#define SCSI_LOW_TIMEOUT_CHECK_INTERVAL 1 96#define SCSI_LOW_POWDOWN_TC 15 97#define SCSI_LOW_MAX_PHCHANGES 256 98#define SCSI2_RESET_DELAY 5000000 99 100/* msg */ 101#define SCSI_LOW_MAX_MSGLEN 32 102#define SCSI_LOW_MSG_LOG_DATALEN 8 103 104/************************************************* 105 * Scsi Data Pointer 106 *************************************************/ 107/* scsi pointer */ 108struct sc_p { 109 u_int8_t *scp_data; 110 int scp_datalen; 111 112 u_int8_t *scp_cmd; 113 int scp_cmdlen; 114 115 u_int8_t scp_direction; 116#define SCSI_LOW_RWUNK (-1) 117#define SCSI_LOW_WRITE 0 118#define SCSI_LOW_READ 1 119 u_int8_t scp_status; 120 u_int8_t scp_spare[2]; 121}; 122 123/************************************************* 124 * Command Control Block Structure 125 *************************************************/ 126typedef int scsi_low_tag_t; 127struct targ_info; 128 129#define SCSI_LOW_UNKLUN ((u_int) -1) 130#define SCSI_LOW_UNKTAG ((scsi_low_tag_t) -1) 131 132struct slccb { 133 TAILQ_ENTRY(slccb) ccb_chain; 134 135 void *osdep; /* os depend structure */ 136 137 struct targ_info *ti; /* targ_info */ 138 struct lun_info *li; /* lun info */ 139 struct buf *bp; /* io bufs */ 140 141 scsi_low_tag_t ccb_tag; /* effective qtag */ 142 scsi_low_tag_t ccb_otag; /* allocated qtag */ 143 144 /***************************************** 145 * Scsi data pointers (original and saved) 146 *****************************************/ 147 struct sc_p ccb_scp; /* given */ 148 struct sc_p ccb_sscp; /* saved scsi data pointer */ 149 int ccb_datalen; /* transferred data counter */ 150 151 /***************************************** 152 * Msgout 153 *****************************************/ 154 u_int ccb_msgoutflag; 155 u_int ccb_omsgoutflag; 156 157 /***************************************** 158 * Error or Timeout counters 159 *****************************************/ 160 u_int ccb_flags; 161#define CCB_INTERNAL 0x0001 162#define CCB_SENSE 0x0002 163#define CCB_CLEARQ 0x0004 164#define CCB_DISCQ 0x0008 165#define CCB_STARTQ 0x0010 166#define CCB_POLLED 0x0100 /* polling ccb */ 167#define CCB_NORETRY 0x0200 /* do NOT retry */ 168#define CCB_AUTOSENSE 0x0400 /* do a sense after CA */ 169#define CCB_URGENT 0x0800 /* an urgent ccb */ 170#define CCB_NOSDONE 0x1000 /* do not call an os done routine */ 171#define CCB_SCSIIO 0x2000 /* a normal scsi io coming from upper layer */ 172#define CCB_SILENT 0x4000 /* no terminate messages */ 173 174 u_int ccb_error; 175 176 int ccb_rcnt; /* retry counter */ 177 int ccb_selrcnt; /* selection retry counter */ 178 int ccb_tc; /* timer counter */ 179 int ccb_tcmax; /* max timeout */ 180 181 /***************************************** 182 * Sense data buffer 183 *****************************************/ 184 u_int8_t ccb_scsi_cmd[12]; 185 struct scsi_sense_data ccb_sense; 186}; 187 188/************************************************* 189 * Slccb functions 190 *************************************************/ 191GENERIC_CCB_ASSERT(scsi_low, slccb) 192 193/************************************************* 194 * Target and Lun structures 195 *************************************************/ 196struct scsi_low_softc; 197LIST_HEAD(scsi_low_softc_tab, scsi_low_softc); 198TAILQ_HEAD(targ_info_tab, targ_info); 199LIST_HEAD(lun_info_tab, lun_info); 200 201struct lun_info { 202 int li_lun; 203 struct targ_info *li_ti; /* my target */ 204 205 LIST_ENTRY(lun_info) lun_chain; /* targ_info link */ 206 207 struct slccbtab li_discq; /* disconnect queue */ 208 209 /* 210 * qtag control 211 */ 212 int li_maxnexus; 213 int li_maxnqio; 214 int li_nqio; 215 int li_disc; 216 217#define SCSI_LOW_MAXNEXUS (sizeof(u_int) * NBBY) 218 u_int li_qtagbits; 219 220#ifdef SCSI_LOW_ALT_QTAG_ALLOCATE 221 u_int8_t li_qtagarray[SCSI_LOW_MAXNEXUS]; 222 u_int li_qd; 223#endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 224 225#define SCSI_LOW_QFLAG_CA_QCLEAR 0x01 226 u_int li_qflags; 227 228 /* 229 * lun state 230 */ 231#define SCSI_LOW_LUN_SLEEP 0x00 232#define SCSI_LOW_LUN_START 0x01 233#define SCSI_LOW_LUN_INQ 0x02 234#define SCSI_LOW_LUN_MODEQ 0x03 235#define SCSI_LOW_LUN_OK 0x04 236 u_int li_state; /* target lun state */ 237 238 /* 239 * lun control flags 240 */ 241 u_int li_flags_valid; /* valid flags */ 242#define SCSI_LOW_LUN_FLAGS_USER_VALID 0x0001 243#define SCSI_LOW_LUN_FLAGS_DISK_VALID 0x0002 244#define SCSI_LOW_LUN_FLAGS_QUIRKS_VALID 0x0004 245#define SCSI_LOW_LUN_FLAGS_ALL_VALID \ 246 (SCSI_LOW_LUN_FLAGS_USER_VALID | \ 247 SCSI_LOW_LUN_FLAGS_DISK_VALID | SCSI_LOW_LUN_FLAGS_QUIRKS_VALID) 248 249 u_int li_flags; /* real lun control flags */ 250 u_int li_cfgflags; /* lun control flags given by user */ 251 u_int li_diskflags; /* lun control flags given by hardware info */ 252 u_int li_quirks; /* lun control flags given by upper layer */ 253 254 /* inq buffer */ 255 struct scsi_low_inq_data { 256 u_int8_t sd_type; 257 u_int8_t sd_sp1; 258 u_int8_t sd_version; 259 u_int8_t sd_resp; 260 u_int8_t sd_len; 261 u_int8_t sd_sp2[2]; 262 u_int8_t sd_support; 263 } __packed li_inq; 264 265 /* modeq buffer */ 266 struct scsi_low_mode_sense_data { 267 u_int8_t sms_header[4]; 268 struct { 269 u_int8_t cmp_page; 270 u_int8_t cmp_length; 271 u_int8_t cmp_rlec; 272 u_int8_t cmp_qc; 273 u_int8_t cmp_eca; 274 u_int8_t cmp_spare[3]; 275 } __packed sms_cmp; 276 277 } li_sms; 278}; 279 280struct scsi_low_msg_log { 281 int slml_ptr; 282 struct { 283 u_int8_t msg[2]; 284 } slml_msg[SCSI_LOW_MSG_LOG_DATALEN]; 285}; 286 287struct targ_info { 288 TAILQ_ENTRY(targ_info) ti_chain; /* targ_info link */ 289 290 struct scsi_low_softc *ti_sc; /* our softc */ 291 u_int ti_id; /* scsi id */ 292 293 /* 294 * Lun chain 295 */ 296 struct lun_info_tab ti_litab; /* lun chain */ 297 298 /* 299 * total disconnected nexus 300 */ 301 int ti_disc; 302 303 /* 304 * Scsi phase control 305 */ 306 307#define PH_NULL 0x00 308#define PH_ARBSTART 0x01 309#define PH_SELSTART 0x02 310#define PH_SELECTED 0x03 311#define PH_CMD 0x04 312#define PH_DATA 0x05 313#define PH_MSGIN 0x06 314#define PH_MSGOUT 0x07 315#define PH_STAT 0x08 316#define PH_DISC 0x09 317#define PH_RESEL 0x0a 318 u_int ti_phase; /* scsi phase */ 319 u_int ti_ophase; /* old scsi phase */ 320 321 /* 322 * Msg in 323 */ 324 u_int ti_msginptr; /* msgin ptr */ 325 u_int ti_msginlen; /* expected msg length */ 326 int ti_msgin_parity_error; /* parity error detected */ 327 u_int8_t ti_msgin[SCSI_LOW_MAX_MSGLEN]; /* msgin buffer */ 328 329 /* 330 * Msg out 331 */ 332 u_int ti_msgflags; /* msgs to be asserted */ 333 u_int ti_omsgflags; /* msgs asserted */ 334 u_int ti_emsgflags; /* a msg currently asserted */ 335#define SCSI_LOW_MSG_RESET 0x00000001 336#define SCSI_LOW_MSG_REJECT 0x00000002 337#define SCSI_LOW_MSG_PARITY 0x00000004 338#define SCSI_LOW_MSG_ERROR 0x00000008 339#define SCSI_LOW_MSG_IDENTIFY 0x00000010 340#define SCSI_LOW_MSG_ABORT 0x00000020 341#define SCSI_LOW_MSG_TERMIO 0x00000040 342#define SCSI_LOW_MSG_SIMPLE_QTAG 0x00000080 343#define SCSI_LOW_MSG_ORDERED_QTAG 0x00000100 344#define SCSI_LOW_MSG_HEAD_QTAG 0x00000200 345#define SCSI_LOW_MSG_ABORT_QTAG 0x00000400 346#define SCSI_LOW_MSG_CLEAR_QTAG 0x00000800 347#define SCSI_LOW_MSG_WIDE 0x00001000 348#define SCSI_LOW_MSG_SYNCH 0x00002000 349#define SCSI_LOW_MSG_NOOP 0x00004000 350#define SCSI_LOW_MSG_LAST 0x00008000 351#define SCSI_LOW_MSG_ALL 0xffffffff 352 353 /* msgout buffer */ 354 u_int8_t ti_msgoutstr[SCSI_LOW_MAX_MSGLEN]; /* scsi msgout */ 355 u_int ti_msgoutlen; /* msgout strlen */ 356 357 /* 358 * target initialize msgout 359 */ 360 u_int ti_setup_msg; /* setup msgout requests */ 361 u_int ti_setup_msg_done; 362 363 /* 364 * synch and wide data info 365 */ 366 u_int ti_flags_valid; /* valid flags */ 367#define SCSI_LOW_TARG_FLAGS_USER_VALID 0x0001 368#define SCSI_LOW_TARG_FLAGS_DISK_VALID 0x0002 369#define SCSI_LOW_TARG_FLAGS_QUIRKS_VALID 0x0004 370#define SCSI_LOW_TARG_FLAGS_ALL_VALID \ 371 (SCSI_LOW_TARG_FLAGS_USER_VALID | \ 372 SCSI_LOW_TARG_FLAGS_DISK_VALID | SCSI_LOW_TARG_FLAGS_QUIRKS_VALID) 373 374 u_int ti_diskflags; /* given target disk flags */ 375 u_int ti_quirks; /* given target quirk */ 376 377 struct synch { 378 u_int8_t offset; 379 u_int8_t period; 380 } ti_osynch, ti_maxsynch; /* synch data */ 381 382#define SCSI_LOW_BUS_WIDTH_8 0 383#define SCSI_LOW_BUS_WIDTH_16 1 384#define SCSI_LOW_BUS_WIDTH_32 2 385 u_int ti_owidth, ti_width; 386 387 /* 388 * lun info size. 389 */ 390 int ti_lunsize; 391 392#ifdef SCSI_LOW_DIAGNOSTIC 393 struct scsi_low_msg_log ti_log_msgout; 394 struct scsi_low_msg_log ti_log_msgin; 395#endif /* SCSI_LOW_DIAGNOSTIC */ 396}; 397 398/************************************************* 399 * COMMON HEADER STRUCTURE 400 *************************************************/ 401struct scsi_low_softc; 402struct proc; 403typedef struct scsi_low_softc *sc_low_t; 404 405#define SCSI_LOW_START_OK 0 406#define SCSI_LOW_START_FAIL 1 407#define SCSI_LOW_INFO_ALLOC 0 408#define SCSI_LOW_INFO_REVOKE 1 409#define SCSI_LOW_INFO_DEALLOC 2 410#define SCSI_LOW_POWDOWN 1 411#define SCSI_LOW_ENGAGE 2 412 413#define SC_LOW_INIT_T (int (*)(sc_low_t, int)) 414#define SC_LOW_BUSRST_T (void (*)(sc_low_t)) 415#define SC_LOW_TARG_INIT_T (int (*)(sc_low_t, struct targ_info *, int)) 416#define SC_LOW_LUN_INIT_T (int (*)(sc_low_t, struct targ_info *, struct lun_info *, int)) 417#define SC_LOW_SELECT_T (int (*)(sc_low_t, struct slccb *)) 418#define SC_LOW_ATTEN_T (void (*)(sc_low_t)) 419#define SC_LOW_NEXUS_T (int (*)(sc_low_t)) 420#define SC_LOW_MSG_T (int (*)(sc_low_t, struct targ_info *, u_int)) 421#define SC_LOW_POLL_T (int (*)(void *)) 422#define SC_LOW_POWER_T (int (*)(sc_low_t, u_int)) 423#define SC_LOW_TIMEOUT_T (int (*)(sc_low_t)) 424 425struct scsi_low_funcs { 426 int (*scsi_low_init)(sc_low_t, int); 427 void (*scsi_low_bus_reset)(sc_low_t); 428 int (*scsi_low_targ_init)(sc_low_t, struct targ_info *, int); 429 int (*scsi_low_lun_init)(sc_low_t, struct targ_info *, struct lun_info *, int); 430 int (*scsi_low_start_bus)(sc_low_t, struct slccb *); 431 int (*scsi_low_establish_lun_nexus)(sc_low_t); 432 int (*scsi_low_establish_ccb_nexus)(sc_low_t); 433 void (*scsi_low_attention)(sc_low_t); 434 int (*scsi_low_msg)(sc_low_t, struct targ_info *, u_int); 435 int (*scsi_low_timeout)(sc_low_t); 436 int (*scsi_low_poll)(void *); 437 int (*scsi_low_power)(sc_low_t, u_int); 438 int (*scsi_low_ioctl)(sc_low_t, u_long, caddr_t, int, struct proc *); 439}; 440 441struct scsi_low_softc { 442 device_t sl_dev; 443 444 struct cam_sim *sl_sim; 445 struct cam_path *sl_path; 446 447 int sl_poll_count; 448 449 struct mtx sl_lock; 450 struct callout sl_engage_timer; 451 struct callout sl_timeout_timer; 452#ifdef SCSI_LOW_POWFUNC 453 struct callout sl_recover_timer; 454#endif 455 456 /* our chain */ 457 LIST_ENTRY(scsi_low_softc) sl_chain; 458 459 /* my targets */ 460 struct targ_info *sl_ti[SCSI_LOW_NTARGETS]; 461 struct targ_info_tab sl_titab; 462 463 /* current active T_L_Q nexus */ 464 struct targ_info *sl_Tnexus; /* Target nexus */ 465 struct lun_info *sl_Lnexus; /* Lun nexus */ 466 struct slccb *sl_Qnexus; /* Qtag nexus */ 467 int sl_nexus_call; 468 469 /* ccb start queue */ 470 struct slccbtab sl_start; 471 472 /* retry limit and phase change counter */ 473 int sl_max_retry; 474 int sl_ph_count; 475 int sl_timeout_count; 476 477 /* selection & total num disconnect targets */ 478 int sl_nio; 479 int sl_disc; 480 int sl_retry_sel; 481 struct slccb *sl_selid; 482 483 /* attention */ 484 int sl_atten; /* ATN asserted */ 485 int sl_clear_atten; /* negate ATN required */ 486 487 /* scsi phase suggested by scsi msg */ 488 u_int sl_msgphase; 489#define MSGPH_NULL 0x00 /* no msg */ 490#define MSGPH_DISC 0x01 /* disconnect msg */ 491#define MSGPH_CMDC 0x02 /* cmd complete msg */ 492#define MSGPH_ABORT 0x03 /* abort seq */ 493#define MSGPH_TERM 0x04 /* current io terminate */ 494#define MSGPH_LCTERM 0x05 /* cmd link terminated */ 495#define MSGPH_RESET 0x06 /* reset target */ 496 497 /* error */ 498 u_int sl_error; /* error flags */ 499#define FATALIO 0x0001 /* generic io error & retry io */ 500#define ABORTIO 0x0002 /* generic io error & terminate io */ 501#define TIMEOUTIO 0x0004 /* watch dog timeout */ 502#define SELTIMEOUTIO 0x0008 /* selection timeout */ 503#define PDMAERR 0x0010 /* dma xfer error */ 504#define MSGERR 0x0020 /* msgsys error */ 505#define PARITYERR 0x0040 /* parity error */ 506#define BUSYERR 0x0080 /* target busy error */ 507#define STATERR 0x0100 /* status error */ 508#define UACAERR 0x0200 /* target CA state, no sense check */ 509#define SENSEIO 0x1000 /* cmd not excuted but sense data ok */ 510#define SENSEERR 0x2000 /* cmd not excuted and sense data bad */ 511#define UBFERR 0x4000 /* unexpected bus free */ 512#define PENDINGIO 0x8000 /* ccb start not yet */ 513#define SCSI_LOW_ERRORBITS "\020\017ubferr\016senseerr\015senseio\012uacaerr\011staterr\010busy\007parity\006msgerr\005pdmaerr\004seltimeout\003timeout\002abort\001fatal" 514 515 /* current scsi data pointer */ 516 struct sc_p sl_scp; 517 518 /* power control */ 519 u_int sl_active; /* host is busy state */ 520 int sl_powc; /* power down timer counter */ 521 u_int sl_rstep; /* resume step */ 522 523 /* configuration flags */ 524 u_int sl_flags; 525#define HW_POWDOWN 0x0001 526#define HW_RESUME 0x0002 527#define HW_PDMASTART 0x0004 528#define HW_INACTIVE 0x0008 529#define HW_POWERCTRL 0x0010 530#define HW_INITIALIZING 0x0020 531#define HW_READ_PADDING 0x1000 532#define HW_WRITE_PADDING 0x2000 533 534 u_int sl_cfgflags; 535#define CFG_NODISC 0x0001 536#define CFG_NOPARITY 0x0002 537#define CFG_NOATTEN 0x0004 538#define CFG_ASYNC 0x0008 539#define CFG_NOQTAG 0x0010 540 541 int sl_show_result; 542#define SHOW_SYNCH_NEG 0x0001 543#define SHOW_WIDE_NEG 0x0002 544#define SHOW_CALCF_RES 0x0010 545#define SHOW_PROBE_RES 0x0020 546#define SHOW_ALL_NEG -1 547 548 /* host informations */ 549 u_int sl_hostid; 550 int sl_nluns; 551 int sl_ntargs; 552 int sl_openings; 553 554 /* interface functions */ 555 struct scsi_low_funcs *sl_funcs; 556 557 /* targinfo size */ 558 int sl_targsize; 559}; 560 561#define SCSI_LOW_LOCK(sl) mtx_lock(&(sl)->sl_lock) 562#define SCSI_LOW_UNLOCK(sl) mtx_unlock(&(sl)->sl_lock) 563#define SCSI_LOW_ASSERT_LOCKED(sl) mtx_assert(&(sl)->sl_lock, MA_OWNED) 564 565/************************************************* 566 * SCSI LOW service functions 567 *************************************************/ 568/* 569 * Scsi low attachment function. 570 */ 571int scsi_low_attach(struct scsi_low_softc *, int, int, int, int, int); 572int scsi_low_detach(struct scsi_low_softc *); 573 574/* 575 * Scsi low interface activate or deactivate functions 576 */ 577int scsi_low_is_busy(struct scsi_low_softc *); 578int scsi_low_activate(struct scsi_low_softc *); 579int scsi_low_deactivate(struct scsi_low_softc *); 580 581/* 582 * Scsi phase "bus service" functions. 583 * These functions are corresponding to each scsi bus phaeses. 584 */ 585/* bus idle phase (other initiators or targets release bus) */ 586void scsi_low_bus_idle(struct scsi_low_softc *); 587 588/* arbitration and selection phase */ 589void scsi_low_arbit_fail(struct scsi_low_softc *, struct slccb *); 590static __inline void scsi_low_arbit_win(struct scsi_low_softc *); 591 592/* msgout phase */ 593#define SCSI_LOW_MSGOUT_INIT 0x00000001 594#define SCSI_LOW_MSGOUT_UNIFY 0x00000002 595int scsi_low_msgout(struct scsi_low_softc *, struct targ_info *, u_int); 596 597/* msgin phase */ 598#define SCSI_LOW_DATA_PE 0x80000000 599int scsi_low_msgin(struct scsi_low_softc *, struct targ_info *, u_int); 600 601/* statusin phase */ 602static __inline int scsi_low_statusin(struct scsi_low_softc *, struct targ_info *, u_int); 603 604/* data phase */ 605int scsi_low_data(struct scsi_low_softc *, struct targ_info *, struct buf **, int); 606static __inline void scsi_low_data_finish(struct scsi_low_softc *); 607 608/* cmd phase */ 609int scsi_low_cmd(struct scsi_low_softc *, struct targ_info *); 610 611/* reselection phase */ 612struct targ_info *scsi_low_reselected(struct scsi_low_softc *, u_int); 613 614/* disconnection phase */ 615int scsi_low_disconnected(struct scsi_low_softc *, struct targ_info *); 616 617/* 618 * Scsi bus restart function. 619 * Canncel all established nexuses => scsi system initialized => restart jobs. 620 */ 621#define SCSI_LOW_RESTART_HARD 1 622#define SCSI_LOW_RESTART_SOFT 0 623int scsi_low_restart(struct scsi_low_softc *, int, u_char *); 624 625/* 626 * Scsi utility fucntions 627 */ 628/* print current status */ 629void scsi_low_print(struct scsi_low_softc *, struct targ_info *); 630 631/* bus reset utility */ 632void scsi_low_bus_reset(struct scsi_low_softc *); 633 634/************************************************* 635 * Message macro defs 636 *************************************************/ 637#define SCSI_LOW_SETUP_PHASE(ti, phase) \ 638{ \ 639 (ti)->ti_ophase = ti->ti_phase; \ 640 (ti)->ti_phase = (phase); \ 641} 642 643#define SCSI_LOW_SETUP_MSGPHASE(slp, PHASE) \ 644{ \ 645 (slp)->sl_msgphase = (PHASE); \ 646} 647 648#define SCSI_LOW_ASSERT_ATN(slp) \ 649{ \ 650 (slp)->sl_atten = 1; \ 651} 652 653#define SCSI_LOW_DEASSERT_ATN(slp) \ 654{ \ 655 (slp)->sl_atten = 0; \ 656} 657 658/************************************************* 659 * Inline functions 660 *************************************************/ 661static __inline void scsi_low_attention(struct scsi_low_softc *); 662static __inline int scsi_low_is_msgout_continue(struct targ_info *, u_int); 663static __inline int scsi_low_assert_msg(struct scsi_low_softc *, struct targ_info *, u_int, int); 664static __inline int scsi_low_is_disconnect_ok(struct slccb *); 665 666static __inline int 667scsi_low_is_msgout_continue(ti, mask) 668 struct targ_info *ti; 669 u_int mask; 670{ 671 672 return ((ti->ti_msgflags & (~mask)) != 0); 673} 674 675static __inline int 676scsi_low_is_disconnect_ok(cb) 677 struct slccb *cb; 678{ 679 680 return ((cb->li->li_flags & SCSI_LOW_DISC) != 0 && 681 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) == 0); 682} 683 684static __inline void 685scsi_low_attention(slp) 686 struct scsi_low_softc *slp; 687{ 688 689 if (slp->sl_atten != 0) 690 return; 691 692 (*slp->sl_funcs->scsi_low_attention) (slp); 693 SCSI_LOW_ASSERT_ATN(slp); 694} 695 696static __inline int 697scsi_low_assert_msg(slp, ti, msg, now) 698 struct scsi_low_softc *slp; 699 struct targ_info *ti; 700 u_int msg; 701 int now; 702{ 703 704 ti->ti_msgflags |= msg; 705 if (now != 0) 706 scsi_low_attention(slp); 707 return 0; 708} 709 710static __inline void 711scsi_low_arbit_win(slp) 712 struct scsi_low_softc *slp; 713{ 714 715 slp->sl_selid = NULL; 716} 717 718static __inline void 719scsi_low_data_finish(slp) 720 struct scsi_low_softc *slp; 721{ 722 723 if (slp->sl_Qnexus != NULL) 724 { 725 slp->sl_Qnexus->ccb_datalen = slp->sl_scp.scp_datalen; 726 } 727} 728 729static __inline int 730scsi_low_statusin(slp, ti, c) 731 struct scsi_low_softc *slp; 732 struct targ_info *ti; 733 u_int c; 734{ 735 736 slp->sl_ph_count ++; 737 if ((c & SCSI_LOW_DATA_PE) != 0) 738 { 739 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ERROR, 0); 740 return EIO; 741 } 742 slp->sl_scp.scp_status = (u_int8_t) c; 743 return 0; 744} 745 746/************************************************* 747 * Message out defs 748 *************************************************/ 749/* XXX: use scsi_message.h */ 750#define ST_GOOD 0x00 751#define ST_CHKCOND 0x02 752#define ST_MET 0x04 753#define ST_BUSY 0x08 754#define ST_INTERGOOD 0x10 755#define ST_INTERMET 0x14 756#define ST_CONFLICT 0x18 757#define ST_CMDTERM 0x22 758#define ST_QUEFULL 0x28 759#define ST_UNKNOWN 0xff 760 761#define MSG_COMP 0x00 762#define MSG_EXTEND 0x01 763 764#define MKMSG_EXTEND(XLEN, XCODE) ((((u_int)(XLEN)) << NBBY) | ((u_int)(XCODE))) 765#define MSG_EXTEND_MDPCODE 0x00 766#define MSG_EXTEND_MDPLEN 0x05 767#define MSG_EXTEND_SYNCHCODE 0x01 768#define MSG_EXTEND_SYNCHLEN 0x03 769#define MSG_EXTEND_WIDECODE 0x03 770#define MSG_EXTEND_WIDELEN 0x02 771 772#define MSG_SAVESP 0x02 773#define MSG_RESTORESP 0x03 774#define MSG_DISCON 0x04 775#define MSG_I_ERROR 0x05 776#define MSG_ABORT 0x06 777#define MSG_REJECT 0x07 778#define MSG_NOOP 0x08 779#define MSG_PARITY 0x09 780#define MSG_LCOMP 0x0a 781#define MSG_LCOMP_F 0x0b 782#define MSG_RESET 0x0c 783#define MSG_ABORT_QTAG 0x0d 784#define MSG_CLEAR_QTAG 0x0e 785#define MSG_TERM_IO 0x11 786#define MSG_SIMPLE_QTAG 0x20 787#define MSG_HEAD_QTAG 0x21 788#define MSG_ORDERED_QTAG 0x22 789#define MSG_IDENTIFY 0x80 790#define MSG_IDENTIFY_DISCPRIV 0x40 791#endif /* !_SCSI_LOW_H_ */ 792