scsi_low.h revision 311402
1262395Sbapt/* $FreeBSD: stable/10/sys/cam/scsi/scsi_low.h 311402 2017-01-05 11:20:31Z mav $ */ 2262395Sbapt/* $NecBSD: scsi_low.h,v 1.24.10.5 2001/06/26 07:31:46 honda Exp $ */ 3262395Sbapt/* $NetBSD$ */ 4262395Sbapt 5262395Sbapt#define SCSI_LOW_DIAGNOSTIC 6262395Sbapt#define SCSI_LOW_ALT_QTAG_ALLOCATE 7262395Sbapt 8262395Sbapt/*- 9262395Sbapt * [NetBSD for NEC PC-98 series] 10262395Sbapt * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001 11262395Sbapt * NetBSD/pc98 porting staff. All rights reserved. 12262395Sbapt * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001 13262395Sbapt * Naofumi HONDA. All rights reserved. 14262395Sbapt * 15262395Sbapt * [Ported for FreeBSD CAM] 16262395Sbapt * Copyright (c) 2000, 2001 17262395Sbapt * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro. 18262395Sbapt * All rights reserved. 19262395Sbapt * 20262395Sbapt * Redistribution and use in source and binary forms, with or without 21262395Sbapt * modification, are permitted provided that the following conditions 22262395Sbapt * are met: 23262395Sbapt * 1. Redistributions of source code must retain the above copyright 24262395Sbapt * notice, this list of conditions and the following disclaimer. 25262395Sbapt * 2. Redistributions in binary form must reproduce the above copyright 26262395Sbapt * notice, this list of conditions and the following disclaimer in the 27262395Sbapt * documentation and/or other materials provided with the distribution. 28262395Sbapt * 3. The name of the author may not be used to endorse or promote products 29262395Sbapt * derived from this software without specific prior written permission. 30262395Sbapt * 31262395Sbapt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 32262395Sbapt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 33262395Sbapt * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 34262395Sbapt * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 35262395Sbapt * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 36262395Sbapt * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 37262395Sbapt * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38262395Sbapt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39262395Sbapt * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 40262395Sbapt * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41262395Sbapt * POSSIBILITY OF SUCH DAMAGE. 42262395Sbapt */ 43262395Sbapt 44262395Sbapt#ifndef _SCSI_LOW_H_ 45262395Sbapt#define _SCSI_LOW_H_ 46262395Sbapt 47262395Sbapt/*================================================ 48262395Sbapt * Scsi low OSDEP 49262395Sbapt * (All os depend structures should be here!) 50262395Sbapt ================================================*/ 51262395Sbapt/******** includes *******************************/ 52262395Sbapt 53262395Sbapt#include <sys/bus.h> 54262395Sbapt#include <sys/kdb.h> 55262395Sbapt#include <cam/cam.h> 56262395Sbapt#include <cam/cam_ccb.h> 57262395Sbapt#include <cam/cam_sim.h> 58262395Sbapt#include <cam/cam_xpt_sim.h> 59262395Sbapt#include <cam/cam_debug.h> 60262395Sbapt 61262395Sbapt#include <cam/scsi/scsi_dvcfg.h> 62262395Sbapt#include <i386/isa/ccbque.h> 63262395Sbapt 64262395Sbapt/******** functions macro ************************/ 65262395Sbapt 66262395Sbapt#undef MSG_IDENTIFY 67262395Sbapt 68262395Sbapt/******** os depend interface structures **********/ 69262395Sbapttypedef struct scsi_sense_data scsi_low_osdep_sense_data_t; 70262395Sbapt 71262395Sbaptstruct scsi_low_osdep_interface { 72262395Sbapt device_t si_dev; 73262395Sbapt 74262395Sbapt struct cam_sim *sim; 75262395Sbapt struct cam_path *path; 76262395Sbapt 77262395Sbapt int si_poll_count; 78262395Sbapt 79262395Sbapt struct callout_handle engage_ch; 80262395Sbapt struct callout_handle timeout_ch; 81262395Sbapt#ifdef SCSI_LOW_POWFUNC 82262395Sbapt struct callout_handle recover_ch; 83262395Sbapt#endif 84262395Sbapt}; 85262395Sbapt 86262395Sbapt/******** os depend interface functions *************/ 87262395Sbaptstruct slccb; 88262395Sbaptstruct scsi_low_softc; 89262395Sbapt#define SCSI_LOW_TIMEOUT_STOP 0 90262395Sbapt#define SCSI_LOW_TIMEOUT_START 1 91262395Sbapt#define SCSI_LOW_TIMEOUT_CH_IO 0 92262395Sbapt#define SCSI_LOW_TIMEOUT_CH_ENGAGE 1 93262395Sbapt#define SCSI_LOW_TIMEOUT_CH_RECOVER 2 94262395Sbapt 95262395Sbaptstruct scsi_low_osdep_funcs { 96262395Sbapt int (*scsi_low_osdep_attach) \ 97262395Sbapt (struct scsi_low_softc *); 98262395Sbapt int (*scsi_low_osdep_world_start) \ 99262395Sbapt (struct scsi_low_softc *); 100262395Sbapt int (*scsi_low_osdep_dettach) \ 101262395Sbapt (struct scsi_low_softc *); 102262395Sbapt int (*scsi_low_osdep_ccb_setup) \ 103262395Sbapt (struct scsi_low_softc *, struct slccb *); 104262395Sbapt int (*scsi_low_osdep_done) \ 105262395Sbapt (struct scsi_low_softc *, struct slccb *); 106262395Sbapt void (*scsi_low_osdep_timeout) \ 107262395Sbapt (struct scsi_low_softc *, int, int); 108262395Sbapt}; 109262395Sbapt 110262395Sbapt/*================================================ 111262395Sbapt * Generic Scsi Low header file 112262395Sbapt * (All os depend structures should be above!) 113262395Sbapt ================================================*/ 114262395Sbapt/************************************************* 115262395Sbapt * Scsi low definitions 116262395Sbapt *************************************************/ 117262395Sbapt#define SCSI_LOW_SYNC DVF_SCSI_SYNC 118262395Sbapt#define SCSI_LOW_DISC DVF_SCSI_DISC 119262395Sbapt#define SCSI_LOW_WAIT DVF_SCSI_WAIT 120262395Sbapt#define SCSI_LOW_LINK DVF_SCSI_LINK 121262395Sbapt#define SCSI_LOW_QTAG DVF_SCSI_QTAG 122262395Sbapt#define SCSI_LOW_NOPARITY DVF_SCSI_NOPARITY 123262395Sbapt#define SCSI_LOW_SAVESP DVF_SCSI_SAVESP 124262395Sbapt#define SCSI_LOW_DEFCFG DVF_SCSI_DEFCFG 125262395Sbapt#define SCSI_LOW_BITS DVF_SCSI_BITS 126262395Sbapt 127262395Sbapt#define SCSI_LOW_PERIOD(n) DVF_SCSI_PERIOD(n) 128262395Sbapt#define SCSI_LOW_OFFSET(n) DVF_SCSI_OFFSET(n) 129262395Sbapt 130262395Sbapt/* host scsi id and targets macro */ 131262395Sbapt#ifndef SCSI_LOW_NTARGETS 132262395Sbapt#define SCSI_LOW_NTARGETS 8 133262395Sbapt#endif /* SCSI_LOW_NTARGETS */ 134262395Sbapt#define SCSI_LOW_NCCB 128 135262395Sbapt 136262395Sbapt#define SCSI_LOW_MAX_RETRY 3 137262395Sbapt#define SCSI_LOW_MAX_SELECTION_RETRY 10 138262395Sbapt 139262395Sbapt/* timeout control macro */ 140262395Sbapt#define SCSI_LOW_TIMEOUT_HZ 10 141262395Sbapt#define SCSI_LOW_MIN_TOUT 12 142262395Sbapt#define SCSI_LOW_TIMEOUT_CHECK_INTERVAL 1 143262395Sbapt#define SCSI_LOW_POWDOWN_TC 15 144262395Sbapt#define SCSI_LOW_MAX_PHCHANGES 256 145262395Sbapt#define SCSI2_RESET_DELAY 5000000 146262395Sbapt 147262395Sbapt/* msg */ 148262395Sbapt#define SCSI_LOW_MAX_MSGLEN 32 149262395Sbapt#define SCSI_LOW_MSG_LOG_DATALEN 8 150262395Sbapt 151262395Sbapt/************************************************* 152262395Sbapt * Scsi Data Pointer 153262395Sbapt *************************************************/ 154262395Sbapt/* scsi pointer */ 155262395Sbaptstruct sc_p { 156262395Sbapt u_int8_t *scp_data; 157262395Sbapt int scp_datalen; 158262395Sbapt 159262395Sbapt u_int8_t *scp_cmd; 160262395Sbapt int scp_cmdlen; 161262395Sbapt 162262395Sbapt u_int8_t scp_direction; 163262395Sbapt#define SCSI_LOW_RWUNK (-1) 164262395Sbapt#define SCSI_LOW_WRITE 0 165262395Sbapt#define SCSI_LOW_READ 1 166262395Sbapt u_int8_t scp_status; 167262395Sbapt u_int8_t scp_spare[2]; 168262395Sbapt}; 169262395Sbapt 170262395Sbapt/************************************************* 171262395Sbapt * Command Control Block Structure 172262395Sbapt *************************************************/ 173262395Sbapttypedef int scsi_low_tag_t; 174262395Sbaptstruct targ_info; 175262395Sbapt 176262395Sbapt#define SCSI_LOW_UNKLUN ((u_int) -1) 177262395Sbapt#define SCSI_LOW_UNKTAG ((scsi_low_tag_t) -1) 178262395Sbapt 179262395Sbaptstruct slccb { 180262395Sbapt TAILQ_ENTRY(slccb) ccb_chain; 181262395Sbapt 182262395Sbapt void *osdep; /* os depend structure */ 183262395Sbapt 184262395Sbapt struct targ_info *ti; /* targ_info */ 185262395Sbapt struct lun_info *li; /* lun info */ 186262395Sbapt struct buf *bp; /* io bufs */ 187262395Sbapt 188262395Sbapt scsi_low_tag_t ccb_tag; /* effective qtag */ 189262395Sbapt scsi_low_tag_t ccb_otag; /* allocated qtag */ 190262395Sbapt 191262395Sbapt /***************************************** 192262395Sbapt * Scsi data pointers (original and saved) 193262395Sbapt *****************************************/ 194262395Sbapt struct sc_p ccb_scp; /* given */ 195262395Sbapt struct sc_p ccb_sscp; /* saved scsi data pointer */ 196262395Sbapt int ccb_datalen; /* transferred data counter */ 197262395Sbapt 198262395Sbapt /***************************************** 199262395Sbapt * Msgout 200262395Sbapt *****************************************/ 201262395Sbapt u_int ccb_msgoutflag; 202262395Sbapt u_int ccb_omsgoutflag; 203262395Sbapt 204262395Sbapt /***************************************** 205262395Sbapt * Error or Timeout counters 206262395Sbapt *****************************************/ 207262395Sbapt u_int ccb_flags; 208262395Sbapt#define CCB_INTERNAL 0x0001 209262395Sbapt#define CCB_SENSE 0x0002 210262395Sbapt#define CCB_CLEARQ 0x0004 211262395Sbapt#define CCB_DISCQ 0x0008 212262395Sbapt#define CCB_STARTQ 0x0010 213262395Sbapt#define CCB_POLLED 0x0100 /* polling ccb */ 214262395Sbapt#define CCB_NORETRY 0x0200 /* do NOT retry */ 215262395Sbapt#define CCB_AUTOSENSE 0x0400 /* do a sense after CA */ 216262395Sbapt#define CCB_URGENT 0x0800 /* an urgent ccb */ 217262395Sbapt#define CCB_NOSDONE 0x1000 /* do not call an os done routine */ 218262395Sbapt#define CCB_SCSIIO 0x2000 /* a normal scsi io coming from upper layer */ 219262395Sbapt#define CCB_SILENT 0x4000 /* no terminate messages */ 220262395Sbapt 221262395Sbapt u_int ccb_error; 222262395Sbapt 223262395Sbapt int ccb_rcnt; /* retry counter */ 224262395Sbapt int ccb_selrcnt; /* selection retry counter */ 225262395Sbapt int ccb_tc; /* timer counter */ 226262395Sbapt int ccb_tcmax; /* max timeout */ 227262395Sbapt 228262395Sbapt /***************************************** 229262395Sbapt * Sense data buffer 230262395Sbapt *****************************************/ 231262395Sbapt u_int8_t ccb_scsi_cmd[12]; 232262395Sbapt scsi_low_osdep_sense_data_t ccb_sense; 233262395Sbapt}; 234262395Sbapt 235262395Sbapt/************************************************* 236262395Sbapt * Slccb functions 237262395Sbapt *************************************************/ 238262395SbaptGENERIC_CCB_ASSERT(scsi_low, slccb) 239262395Sbapt 240262395Sbapt/************************************************* 241262395Sbapt * Target and Lun structures 242262395Sbapt *************************************************/ 243262395Sbaptstruct scsi_low_softc; 244262395SbaptLIST_HEAD(scsi_low_softc_tab, scsi_low_softc); 245262395SbaptTAILQ_HEAD(targ_info_tab, targ_info); 246262395SbaptLIST_HEAD(lun_info_tab, lun_info); 247262395Sbapt 248262395Sbaptstruct lun_info { 249262395Sbapt int li_lun; 250262395Sbapt struct targ_info *li_ti; /* my target */ 251262395Sbapt 252262395Sbapt LIST_ENTRY(lun_info) lun_chain; /* targ_info link */ 253262395Sbapt 254262395Sbapt struct slccbtab li_discq; /* disconnect queue */ 255262395Sbapt 256262395Sbapt /* 257262395Sbapt * qtag control 258262395Sbapt */ 259262395Sbapt int li_maxnexus; 260262395Sbapt int li_maxnqio; 261262395Sbapt int li_nqio; 262262395Sbapt int li_disc; 263262395Sbapt 264262395Sbapt#define SCSI_LOW_MAXNEXUS (sizeof(u_int) * NBBY) 265262395Sbapt u_int li_qtagbits; 266262395Sbapt 267262395Sbapt#ifdef SCSI_LOW_ALT_QTAG_ALLOCATE 268262395Sbapt u_int8_t li_qtagarray[SCSI_LOW_MAXNEXUS]; 269262395Sbapt u_int li_qd; 270262395Sbapt#endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 271262395Sbapt 272262395Sbapt#define SCSI_LOW_QFLAG_CA_QCLEAR 0x01 273262395Sbapt u_int li_qflags; 274262395Sbapt 275262395Sbapt /* 276262395Sbapt * lun state 277262395Sbapt */ 278262395Sbapt#define SCSI_LOW_LUN_SLEEP 0x00 279262395Sbapt#define SCSI_LOW_LUN_START 0x01 280262395Sbapt#define SCSI_LOW_LUN_INQ 0x02 281262395Sbapt#define SCSI_LOW_LUN_MODEQ 0x03 282262395Sbapt#define SCSI_LOW_LUN_OK 0x04 283262395Sbapt u_int li_state; /* target lun state */ 284262395Sbapt 285262395Sbapt /* 286262395Sbapt * lun control flags 287262395Sbapt */ 288262395Sbapt u_int li_flags_valid; /* valid flags */ 289262395Sbapt#define SCSI_LOW_LUN_FLAGS_USER_VALID 0x0001 290262395Sbapt#define SCSI_LOW_LUN_FLAGS_DISK_VALID 0x0002 291262395Sbapt#define SCSI_LOW_LUN_FLAGS_QUIRKS_VALID 0x0004 292262395Sbapt#define SCSI_LOW_LUN_FLAGS_ALL_VALID \ 293262395Sbapt (SCSI_LOW_LUN_FLAGS_USER_VALID | \ 294262395Sbapt SCSI_LOW_LUN_FLAGS_DISK_VALID | SCSI_LOW_LUN_FLAGS_QUIRKS_VALID) 295262395Sbapt 296262395Sbapt u_int li_flags; /* real lun control flags */ 297262395Sbapt u_int li_cfgflags; /* lun control flags given by user */ 298262395Sbapt u_int li_diskflags; /* lun control flags given by hardware info */ 299262395Sbapt u_int li_quirks; /* lun control flags given by upper layer */ 300262395Sbapt 301262395Sbapt /* inq buffer */ 302262395Sbapt struct scsi_low_inq_data { 303262395Sbapt u_int8_t sd_type; 304262395Sbapt u_int8_t sd_sp1; 305262395Sbapt u_int8_t sd_version; 306262395Sbapt u_int8_t sd_resp; 307262395Sbapt u_int8_t sd_len; 308262395Sbapt u_int8_t sd_sp2[2]; 309262395Sbapt u_int8_t sd_support; 310262395Sbapt } __packed li_inq; 311262395Sbapt 312262395Sbapt /* modeq buffer */ 313262395Sbapt struct scsi_low_mode_sense_data { 314262395Sbapt u_int8_t sms_header[4]; 315262395Sbapt struct { 316262395Sbapt u_int8_t cmp_page; 317262395Sbapt u_int8_t cmp_length; 318262395Sbapt u_int8_t cmp_rlec; 319262395Sbapt u_int8_t cmp_qc; 320262395Sbapt u_int8_t cmp_eca; 321262395Sbapt u_int8_t cmp_spare[3]; 322262395Sbapt } __packed sms_cmp; 323262395Sbapt 324262395Sbapt } li_sms; 325262395Sbapt}; 326262395Sbapt 327262395Sbaptstruct scsi_low_msg_log { 328262395Sbapt int slml_ptr; 329262395Sbapt struct { 330262395Sbapt u_int8_t msg[2]; 331262395Sbapt } slml_msg[SCSI_LOW_MSG_LOG_DATALEN]; 332262395Sbapt}; 333262395Sbapt 334262395Sbaptstruct targ_info { 335262395Sbapt TAILQ_ENTRY(targ_info) ti_chain; /* targ_info link */ 336262395Sbapt 337262395Sbapt struct scsi_low_softc *ti_sc; /* our softc */ 338262395Sbapt u_int ti_id; /* scsi id */ 339262395Sbapt 340262395Sbapt /* 341262395Sbapt * Lun chain 342262395Sbapt */ 343262395Sbapt struct lun_info_tab ti_litab; /* lun chain */ 344262395Sbapt 345262395Sbapt /* 346262395Sbapt * total disconnected nexus 347262395Sbapt */ 348262395Sbapt int ti_disc; 349262395Sbapt 350262395Sbapt /* 351262395Sbapt * Scsi phase control 352262395Sbapt */ 353262395Sbapt 354262395Sbapt#define PH_NULL 0x00 355262395Sbapt#define PH_ARBSTART 0x01 356262395Sbapt#define PH_SELSTART 0x02 357262395Sbapt#define PH_SELECTED 0x03 358262395Sbapt#define PH_CMD 0x04 359262395Sbapt#define PH_DATA 0x05 360262395Sbapt#define PH_MSGIN 0x06 361262395Sbapt#define PH_MSGOUT 0x07 362262395Sbapt#define PH_STAT 0x08 363262395Sbapt#define PH_DISC 0x09 364262395Sbapt#define PH_RESEL 0x0a 365262395Sbapt u_int ti_phase; /* scsi phase */ 366262395Sbapt u_int ti_ophase; /* old scsi phase */ 367262395Sbapt 368262395Sbapt /* 369262395Sbapt * Msg in 370262395Sbapt */ 371262395Sbapt u_int ti_msginptr; /* msgin ptr */ 372262395Sbapt u_int ti_msginlen; /* expected msg length */ 373262395Sbapt int ti_msgin_parity_error; /* parity error detected */ 374262395Sbapt u_int8_t ti_msgin[SCSI_LOW_MAX_MSGLEN]; /* msgin buffer */ 375262395Sbapt 376262395Sbapt /* 377262395Sbapt * Msg out 378262395Sbapt */ 379262395Sbapt u_int ti_msgflags; /* msgs to be asserted */ 380262395Sbapt u_int ti_omsgflags; /* msgs asserted */ 381262395Sbapt u_int ti_emsgflags; /* a msg currently asserted */ 382262395Sbapt#define SCSI_LOW_MSG_RESET 0x00000001 383262395Sbapt#define SCSI_LOW_MSG_REJECT 0x00000002 384262395Sbapt#define SCSI_LOW_MSG_PARITY 0x00000004 385262395Sbapt#define SCSI_LOW_MSG_ERROR 0x00000008 386262395Sbapt#define SCSI_LOW_MSG_IDENTIFY 0x00000010 387262395Sbapt#define SCSI_LOW_MSG_ABORT 0x00000020 388262395Sbapt#define SCSI_LOW_MSG_TERMIO 0x00000040 389262395Sbapt#define SCSI_LOW_MSG_SIMPLE_QTAG 0x00000080 390262395Sbapt#define SCSI_LOW_MSG_ORDERED_QTAG 0x00000100 391262395Sbapt#define SCSI_LOW_MSG_HEAD_QTAG 0x00000200 392262395Sbapt#define SCSI_LOW_MSG_ABORT_QTAG 0x00000400 393262395Sbapt#define SCSI_LOW_MSG_CLEAR_QTAG 0x00000800 394262395Sbapt#define SCSI_LOW_MSG_WIDE 0x00001000 395262395Sbapt#define SCSI_LOW_MSG_SYNCH 0x00002000 396262395Sbapt#define SCSI_LOW_MSG_NOOP 0x00004000 397262395Sbapt#define SCSI_LOW_MSG_LAST 0x00008000 398262395Sbapt#define SCSI_LOW_MSG_ALL 0xffffffff 399262395Sbapt 400262395Sbapt /* msgout buffer */ 401262395Sbapt u_int8_t ti_msgoutstr[SCSI_LOW_MAX_MSGLEN]; /* scsi msgout */ 402262395Sbapt u_int ti_msgoutlen; /* msgout strlen */ 403262395Sbapt 404262395Sbapt /* 405262395Sbapt * target initialize msgout 406262395Sbapt */ 407262395Sbapt u_int ti_setup_msg; /* setup msgout requests */ 408262395Sbapt u_int ti_setup_msg_done; 409262395Sbapt 410262395Sbapt /* 411 * synch and wide data info 412 */ 413 u_int ti_flags_valid; /* valid flags */ 414#define SCSI_LOW_TARG_FLAGS_USER_VALID 0x0001 415#define SCSI_LOW_TARG_FLAGS_DISK_VALID 0x0002 416#define SCSI_LOW_TARG_FLAGS_QUIRKS_VALID 0x0004 417#define SCSI_LOW_TARG_FLAGS_ALL_VALID \ 418 (SCSI_LOW_TARG_FLAGS_USER_VALID | \ 419 SCSI_LOW_TARG_FLAGS_DISK_VALID | SCSI_LOW_TARG_FLAGS_QUIRKS_VALID) 420 421 u_int ti_diskflags; /* given target disk flags */ 422 u_int ti_quirks; /* given target quirk */ 423 424 struct synch { 425 u_int8_t offset; 426 u_int8_t period; 427 } ti_osynch, ti_maxsynch; /* synch data */ 428 429#define SCSI_LOW_BUS_WIDTH_8 0 430#define SCSI_LOW_BUS_WIDTH_16 1 431#define SCSI_LOW_BUS_WIDTH_32 2 432 u_int ti_owidth, ti_width; 433 434 /* 435 * lun info size. 436 */ 437 int ti_lunsize; 438 439#ifdef SCSI_LOW_DIAGNOSTIC 440 struct scsi_low_msg_log ti_log_msgout; 441 struct scsi_low_msg_log ti_log_msgin; 442#endif /* SCSI_LOW_DIAGNOSTIC */ 443}; 444 445/************************************************* 446 * COMMON HEADER STRUCTURE 447 *************************************************/ 448struct scsi_low_softc; 449struct proc; 450typedef struct scsi_low_softc *sc_low_t; 451 452#define SCSI_LOW_START_OK 0 453#define SCSI_LOW_START_FAIL 1 454#define SCSI_LOW_INFO_ALLOC 0 455#define SCSI_LOW_INFO_REVOKE 1 456#define SCSI_LOW_INFO_DEALLOC 2 457#define SCSI_LOW_POWDOWN 1 458#define SCSI_LOW_ENGAGE 2 459 460#define SC_LOW_INIT_T (int (*)(sc_low_t, int)) 461#define SC_LOW_BUSRST_T (void (*)(sc_low_t)) 462#define SC_LOW_TARG_INIT_T (int (*)(sc_low_t, struct targ_info *, int)) 463#define SC_LOW_LUN_INIT_T (int (*)(sc_low_t, struct targ_info *, struct lun_info *, int)) 464#define SC_LOW_SELECT_T (int (*)(sc_low_t, struct slccb *)) 465#define SC_LOW_ATTEN_T (void (*)(sc_low_t)) 466#define SC_LOW_NEXUS_T (int (*)(sc_low_t)) 467#define SC_LOW_MSG_T (int (*)(sc_low_t, struct targ_info *, u_int)) 468#define SC_LOW_POLL_T (int (*)(void *)) 469#define SC_LOW_POWER_T (int (*)(sc_low_t, u_int)) 470#define SC_LOW_TIMEOUT_T (int (*)(sc_low_t)) 471 472struct scsi_low_funcs { 473 int (*scsi_low_init)(sc_low_t, int); 474 void (*scsi_low_bus_reset)(sc_low_t); 475 int (*scsi_low_targ_init)(sc_low_t, struct targ_info *, int); 476 int (*scsi_low_lun_init)(sc_low_t, struct targ_info *, struct lun_info *, int); 477 int (*scsi_low_start_bus)(sc_low_t, struct slccb *); 478 int (*scsi_low_establish_lun_nexus)(sc_low_t); 479 int (*scsi_low_establish_ccb_nexus)(sc_low_t); 480 void (*scsi_low_attention)(sc_low_t); 481 int (*scsi_low_msg)(sc_low_t, struct targ_info *, u_int); 482 int (*scsi_low_timeout)(sc_low_t); 483 int (*scsi_low_poll)(void *); 484 int (*scsi_low_power)(sc_low_t, u_int); 485 int (*scsi_low_ioctl)(sc_low_t, u_long, caddr_t, int, struct proc *); 486}; 487 488struct scsi_low_softc { 489 /* os depend structure */ 490 struct scsi_low_osdep_interface sl_si; 491#define sl_dev sl_si.si_dev 492 struct scsi_low_osdep_funcs *sl_osdep_fp; 493 494 /* our chain */ 495 LIST_ENTRY(scsi_low_softc) sl_chain; 496 497 /* my targets */ 498 struct targ_info *sl_ti[SCSI_LOW_NTARGETS]; 499 struct targ_info_tab sl_titab; 500 501 /* current active T_L_Q nexus */ 502 struct targ_info *sl_Tnexus; /* Target nexus */ 503 struct lun_info *sl_Lnexus; /* Lun nexus */ 504 struct slccb *sl_Qnexus; /* Qtag nexus */ 505 int sl_nexus_call; 506 507 /* ccb start queue */ 508 struct slccbtab sl_start; 509 510 /* retry limit and phase change counter */ 511 int sl_max_retry; 512 int sl_ph_count; 513 int sl_timeout_count; 514 515 /* selection & total num disconnect targets */ 516 int sl_nio; 517 int sl_disc; 518 int sl_retry_sel; 519 struct slccb *sl_selid; 520 521 /* attention */ 522 int sl_atten; /* ATN asserted */ 523 int sl_clear_atten; /* negate ATN required */ 524 525 /* scsi phase suggested by scsi msg */ 526 u_int sl_msgphase; 527#define MSGPH_NULL 0x00 /* no msg */ 528#define MSGPH_DISC 0x01 /* disconnect msg */ 529#define MSGPH_CMDC 0x02 /* cmd complete msg */ 530#define MSGPH_ABORT 0x03 /* abort seq */ 531#define MSGPH_TERM 0x04 /* current io terminate */ 532#define MSGPH_LCTERM 0x05 /* cmd link terminated */ 533#define MSGPH_RESET 0x06 /* reset target */ 534 535 /* error */ 536 u_int sl_error; /* error flags */ 537#define FATALIO 0x0001 /* generic io error & retry io */ 538#define ABORTIO 0x0002 /* generic io error & terminate io */ 539#define TIMEOUTIO 0x0004 /* watch dog timeout */ 540#define SELTIMEOUTIO 0x0008 /* selection timeout */ 541#define PDMAERR 0x0010 /* dma xfer error */ 542#define MSGERR 0x0020 /* msgsys error */ 543#define PARITYERR 0x0040 /* parity error */ 544#define BUSYERR 0x0080 /* target busy error */ 545#define STATERR 0x0100 /* status error */ 546#define UACAERR 0x0200 /* target CA state, no sense check */ 547#define SENSEIO 0x1000 /* cmd not excuted but sense data ok */ 548#define SENSEERR 0x2000 /* cmd not excuted and sense data bad */ 549#define UBFERR 0x4000 /* unexpected bus free */ 550#define PENDINGIO 0x8000 /* ccb start not yet */ 551#define SCSI_LOW_ERRORBITS "\020\017ubferr\016senseerr\015senseio\012uacaerr\011staterr\010busy\007parity\006msgerr\005pdmaerr\004seltimeout\003timeout\002abort\001fatal" 552 553 /* current scsi data pointer */ 554 struct sc_p sl_scp; 555 556 /* power control */ 557 u_int sl_active; /* host is busy state */ 558 int sl_powc; /* power down timer counter */ 559 u_int sl_rstep; /* resume step */ 560 561 /* configuration flags */ 562 u_int sl_flags; 563#define HW_POWDOWN 0x0001 564#define HW_RESUME 0x0002 565#define HW_PDMASTART 0x0004 566#define HW_INACTIVE 0x0008 567#define HW_POWERCTRL 0x0010 568#define HW_INITIALIZING 0x0020 569#define HW_READ_PADDING 0x1000 570#define HW_WRITE_PADDING 0x2000 571 572 u_int sl_cfgflags; 573#define CFG_NODISC 0x0001 574#define CFG_NOPARITY 0x0002 575#define CFG_NOATTEN 0x0004 576#define CFG_ASYNC 0x0008 577#define CFG_NOQTAG 0x0010 578 579 int sl_show_result; 580#define SHOW_SYNCH_NEG 0x0001 581#define SHOW_WIDE_NEG 0x0002 582#define SHOW_CALCF_RES 0x0010 583#define SHOW_PROBE_RES 0x0020 584#define SHOW_ALL_NEG -1 585 586 /* host informations */ 587 u_int sl_hostid; 588 int sl_nluns; 589 int sl_ntargs; 590 int sl_openings; 591 592 /* interface functions */ 593 struct scsi_low_funcs *sl_funcs; 594 595 /* targinfo size */ 596 int sl_targsize; 597}; 598 599/************************************************* 600 * SCSI LOW service functions 601 *************************************************/ 602/* 603 * Scsi low attachment function. 604 */ 605int scsi_low_attach(struct scsi_low_softc *, int, int, int, int, int); 606int scsi_low_dettach(struct scsi_low_softc *); 607 608/* 609 * Scsi low interface activate or deactivate functions 610 */ 611int scsi_low_is_busy(struct scsi_low_softc *); 612int scsi_low_activate(struct scsi_low_softc *); 613int scsi_low_deactivate(struct scsi_low_softc *); 614 615/* 616 * Scsi phase "bus service" functions. 617 * These functions are corresponding to each scsi bus phaeses. 618 */ 619/* bus idle phase (other initiators or targets release bus) */ 620void scsi_low_bus_idle(struct scsi_low_softc *); 621 622/* arbitration and selection phase */ 623void scsi_low_arbit_fail(struct scsi_low_softc *, struct slccb *); 624static __inline void scsi_low_arbit_win(struct scsi_low_softc *); 625 626/* msgout phase */ 627#define SCSI_LOW_MSGOUT_INIT 0x00000001 628#define SCSI_LOW_MSGOUT_UNIFY 0x00000002 629int scsi_low_msgout(struct scsi_low_softc *, struct targ_info *, u_int); 630 631/* msgin phase */ 632#define SCSI_LOW_DATA_PE 0x80000000 633int scsi_low_msgin(struct scsi_low_softc *, struct targ_info *, u_int); 634 635/* statusin phase */ 636static __inline int scsi_low_statusin(struct scsi_low_softc *, struct targ_info *, u_int); 637 638/* data phase */ 639int scsi_low_data(struct scsi_low_softc *, struct targ_info *, struct buf **, int); 640static __inline void scsi_low_data_finish(struct scsi_low_softc *); 641 642/* cmd phase */ 643int scsi_low_cmd(struct scsi_low_softc *, struct targ_info *); 644 645/* reselection phase */ 646struct targ_info *scsi_low_reselected(struct scsi_low_softc *, u_int); 647 648/* disconnection phase */ 649int scsi_low_disconnected(struct scsi_low_softc *, struct targ_info *); 650 651/* 652 * Scsi bus restart function. 653 * Canncel all established nexuses => scsi system initialized => restart jobs. 654 */ 655#define SCSI_LOW_RESTART_HARD 1 656#define SCSI_LOW_RESTART_SOFT 0 657int scsi_low_restart(struct scsi_low_softc *, int, u_char *); 658 659/* 660 * Scsi utility fucntions 661 */ 662/* print current status */ 663void scsi_low_print(struct scsi_low_softc *, struct targ_info *); 664 665/* bus reset utility */ 666void scsi_low_bus_reset(struct scsi_low_softc *); 667 668/************************************************* 669 * Message macro defs 670 *************************************************/ 671#define SCSI_LOW_SETUP_PHASE(ti, phase) \ 672{ \ 673 (ti)->ti_ophase = ti->ti_phase; \ 674 (ti)->ti_phase = (phase); \ 675} 676 677#define SCSI_LOW_SETUP_MSGPHASE(slp, PHASE) \ 678{ \ 679 (slp)->sl_msgphase = (PHASE); \ 680} 681 682#define SCSI_LOW_ASSERT_ATN(slp) \ 683{ \ 684 (slp)->sl_atten = 1; \ 685} 686 687#define SCSI_LOW_DEASSERT_ATN(slp) \ 688{ \ 689 (slp)->sl_atten = 0; \ 690} 691 692/************************************************* 693 * Inline functions 694 *************************************************/ 695static __inline void scsi_low_attention(struct scsi_low_softc *); 696static __inline int scsi_low_is_msgout_continue(struct targ_info *, u_int); 697static __inline int scsi_low_assert_msg(struct scsi_low_softc *, struct targ_info *, u_int, int); 698static __inline int scsi_low_is_disconnect_ok(struct slccb *); 699 700static __inline int 701scsi_low_is_msgout_continue(ti, mask) 702 struct targ_info *ti; 703 u_int mask; 704{ 705 706 return ((ti->ti_msgflags & (~mask)) != 0); 707} 708 709static __inline int 710scsi_low_is_disconnect_ok(cb) 711 struct slccb *cb; 712{ 713 714 return ((cb->li->li_flags & SCSI_LOW_DISC) != 0 && 715 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) == 0); 716} 717 718static __inline void 719scsi_low_attention(slp) 720 struct scsi_low_softc *slp; 721{ 722 723 if (slp->sl_atten != 0) 724 return; 725 726 (*slp->sl_funcs->scsi_low_attention) (slp); 727 SCSI_LOW_ASSERT_ATN(slp); 728} 729 730static __inline int 731scsi_low_assert_msg(slp, ti, msg, now) 732 struct scsi_low_softc *slp; 733 struct targ_info *ti; 734 u_int msg; 735 int now; 736{ 737 738 ti->ti_msgflags |= msg; 739 if (now != 0) 740 scsi_low_attention(slp); 741 return 0; 742} 743 744static __inline void 745scsi_low_arbit_win(slp) 746 struct scsi_low_softc *slp; 747{ 748 749 slp->sl_selid = NULL; 750} 751 752static __inline void 753scsi_low_data_finish(slp) 754 struct scsi_low_softc *slp; 755{ 756 757 if (slp->sl_Qnexus != NULL) 758 { 759 slp->sl_Qnexus->ccb_datalen = slp->sl_scp.scp_datalen; 760 } 761} 762 763static __inline int 764scsi_low_statusin(slp, ti, c) 765 struct scsi_low_softc *slp; 766 struct targ_info *ti; 767 u_int c; 768{ 769 770 slp->sl_ph_count ++; 771 if ((c & SCSI_LOW_DATA_PE) != 0) 772 { 773 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ERROR, 0); 774 return EIO; 775 } 776 slp->sl_scp.scp_status = (u_int8_t) c; 777 return 0; 778} 779 780/************************************************* 781 * Message out defs 782 *************************************************/ 783/* XXX: use scsi_message.h */ 784#define ST_GOOD 0x00 785#define ST_CHKCOND 0x02 786#define ST_MET 0x04 787#define ST_BUSY 0x08 788#define ST_INTERGOOD 0x10 789#define ST_INTERMET 0x14 790#define ST_CONFLICT 0x18 791#define ST_CMDTERM 0x22 792#define ST_QUEFULL 0x28 793#define ST_UNKNOWN 0xff 794 795#define MSG_COMP 0x00 796#define MSG_EXTEND 0x01 797 798#define MKMSG_EXTEND(XLEN, XCODE) ((((u_int)(XLEN)) << NBBY) | ((u_int)(XCODE))) 799#define MSG_EXTEND_MDPCODE 0x00 800#define MSG_EXTEND_MDPLEN 0x05 801#define MSG_EXTEND_SYNCHCODE 0x01 802#define MSG_EXTEND_SYNCHLEN 0x03 803#define MSG_EXTEND_WIDECODE 0x03 804#define MSG_EXTEND_WIDELEN 0x02 805 806#define MSG_SAVESP 0x02 807#define MSG_RESTORESP 0x03 808#define MSG_DISCON 0x04 809#define MSG_I_ERROR 0x05 810#define MSG_ABORT 0x06 811#define MSG_REJECT 0x07 812#define MSG_NOOP 0x08 813#define MSG_PARITY 0x09 814#define MSG_LCOMP 0x0a 815#define MSG_LCOMP_F 0x0b 816#define MSG_RESET 0x0c 817#define MSG_ABORT_QTAG 0x0d 818#define MSG_CLEAR_QTAG 0x0e 819#define MSG_TERM_IO 0x11 820#define MSG_SIMPLE_QTAG 0x20 821#define MSG_HEAD_QTAG 0x21 822#define MSG_ORDERED_QTAG 0x22 823#define MSG_IDENTIFY 0x80 824#define MSG_IDENTIFY_DISCPRIV 0x40 825#endif /* !_SCSI_LOW_H_ */ 826