cam.h revision 272461
1193323Sed/*- 2193323Sed * Data structures and definitions for the CAM system. 3193323Sed * 4193323Sed * Copyright (c) 1997 Justin T. Gibbs. 5193323Sed * All rights reserved. 6193323Sed * 7193323Sed * Redistribution and use in source and binary forms, with or without 8193323Sed * modification, are permitted provided that the following conditions 9193323Sed * are met: 10193323Sed * 1. Redistributions of source code must retain the above copyright 11193323Sed * notice, this list of conditions, and the following disclaimer, 12193323Sed * without modification, immediately at the beginning of the file. 13193323Sed * 2. The name of the author may not be used to endorse or promote products 14243830Sdim * derived from this software without specific prior written permission. 15243830Sdim * 16193323Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17239462Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18249423Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19193323Sed * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 20239462Sdim * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21249423Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22249423Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23243830Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24239462Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25239462Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26193323Sed * SUCH DAMAGE. 27239462Sdim * 28239462Sdim * $FreeBSD: releng/10.1/sys/cam/cam.h 259204 2013-12-10 22:55:22Z nwhitehorn $ 29239462Sdim */ 30193323Sed 31193323Sed#ifndef _CAM_CAM_H 32239462Sdim#define _CAM_CAM_H 1 33239462Sdim 34243830Sdim#ifdef _KERNEL 35243830Sdim#include <opt_cam.h> 36243830Sdim#endif 37243830Sdim 38243830Sdim#include <sys/cdefs.h> 39243830Sdim 40243830Sdimtypedef u_int path_id_t; 41243830Sdimtypedef u_int target_id_t; 42243830Sdimtypedef u_int lun_id_t; 43239462Sdimtypedef union { 44243830Sdim u_int64_t lun64; 45243830Sdim u_int8_t lun[8]; 46243830Sdim} lun64_id_t; 47243830Sdim 48243830Sdim#define CAM_XPT_PATH_ID ((path_id_t)~0) 49243830Sdim#define CAM_BUS_WILDCARD ((path_id_t)~0) 50243830Sdim#define CAM_TARGET_WILDCARD ((target_id_t)~0) 51243830Sdim#define CAM_LUN_WILDCARD ((lun_id_t)~0) 52243830Sdim 53243830Sdim#define CAM_EXTLUN_BYTE_SWIZZLE(lun) ( \ 54243830Sdim ((((u_int64_t)lun) & 0xffff000000000000L) >> 48) | \ 55243830Sdim ((((u_int64_t)lun) & 0x0000ffff00000000L) >> 16) | \ 56243830Sdim ((((u_int64_t)lun) & 0x00000000ffff0000L) << 16) | \ 57243830Sdim ((((u_int64_t)lun) & 0x000000000000ffffL) << 48)) 58243830Sdim 59243830Sdim/* 60243830Sdim * Maximum length for a CAM CDB. 61239462Sdim */ 62239462Sdim#define CAM_MAX_CDBLEN 16 63239462Sdim 64239462Sdim/* 65239462Sdim * Definition of a CAM peripheral driver entry. Peripheral drivers instantiate 66239462Sdim * one of these for each device they wish to communicate with and pass it into 67239462Sdim * the xpt layer when they wish to schedule work on that device via the 68239462Sdim * xpt_schedule API. 69239462Sdim */ 70239462Sdimstruct cam_periph; 71239462Sdim 72239462Sdim/* 73239462Sdim * Priority information for a CAM structure. 74239462Sdim */ 75239462Sdimtypedef enum { 76239462Sdim CAM_RL_HOST, 77239462Sdim CAM_RL_BUS, 78239462Sdim CAM_RL_XPT, 79239462Sdim CAM_RL_DEV, 80239462Sdim CAM_RL_NORMAL, 81239462Sdim CAM_RL_VALUES 82239462Sdim} cam_rl; 83239462Sdim/* 84243830Sdim * The generation number is incremented everytime a new entry is entered into 85243830Sdim * the queue giving round robin per priority level scheduling. 86243830Sdim */ 87243830Sdimtypedef struct { 88243830Sdim u_int32_t priority; 89243830Sdim#define CAM_PRIORITY_HOST ((CAM_RL_HOST << 8) + 0x80) 90249423Sdim#define CAM_PRIORITY_BUS ((CAM_RL_BUS << 8) + 0x80) 91249423Sdim#define CAM_PRIORITY_XPT ((CAM_RL_XPT << 8) + 0x80) 92243830Sdim#define CAM_PRIORITY_DEV ((CAM_RL_DEV << 8) + 0x80) 93243830Sdim#define CAM_PRIORITY_OOB (CAM_RL_DEV << 8) 94243830Sdim#define CAM_PRIORITY_NORMAL ((CAM_RL_NORMAL << 8) + 0x80) 95239462Sdim#define CAM_PRIORITY_NONE (u_int32_t)-1 96239462Sdim u_int32_t generation; 97243830Sdim int index; 98239462Sdim#define CAM_UNQUEUED_INDEX -1 99239462Sdim#define CAM_ACTIVE_INDEX -2 100239462Sdim#define CAM_DONEQ_INDEX -3 101239462Sdim#define CAM_EXTRAQ_INDEX INT_MAX 102239462Sdim} cam_pinfo; 103239462Sdim 104239462Sdim/* 105239462Sdim * Macro to compare two generation numbers. It is used like this: 106239462Sdim * 107239462Sdim * if (GENERATIONCMP(a, >=, b)) 108239462Sdim * ...; 109239462Sdim * 110239462Sdim * GERERATIONCMP uses modular arithmetic to guard against wraps 111193323Sed * wraps in the generation number. 112193323Sed */ 113193323Sed#define GENERATIONCMP(x, op, y) ((int32_t)((x) - (y)) op 0) 114195340Sed 115193323Sed/* CAM flags XXX Move to cam_periph.h ??? */ 116193323Sedtypedef enum { 117193323Sed CAM_FLAG_NONE = 0x00, 118193323Sed CAM_EXPECT_INQ_CHANGE = 0x01, 119193323Sed CAM_RETRY_SELTO = 0x02 /* Retry Selection Timeouts */ 120193323Sed} cam_flags; 121221345Sdim 122224145Sdimenum { 123224145Sdim SF_RETRY_UA = 0x01, /* Retry UNIT ATTENTION conditions. */ 124221345Sdim SF_NO_PRINT = 0x02, /* Never print error status. */ 125221345Sdim SF_QUIET_IR = 0x04, /* Be quiet about Illegal Request reponses */ 126221345Sdim SF_PRINT_ALWAYS = 0x08, /* Always print error status. */ 127221345Sdim SF_NO_RECOVERY = 0x10, /* Don't do active error recovery. */ 128221345Sdim SF_NO_RETRY = 0x20 /* Don't do any retries. */ 129224145Sdim}; 130224145Sdim 131234353Sdim/* CAM Status field values */ 132234353Sdimtypedef enum { 133234353Sdim /* CCB request is in progress */ 134234353Sdim CAM_REQ_INPROG = 0x00, 135234353Sdim 136234353Sdim /* CCB request completed without error */ 137234353Sdim CAM_REQ_CMP = 0x01, 138224145Sdim 139234353Sdim /* CCB request aborted by the host */ 140234353Sdim CAM_REQ_ABORTED = 0x02, 141234353Sdim 142234353Sdim /* Unable to abort CCB request */ 143234353Sdim CAM_UA_ABORT = 0x03, 144234353Sdim 145221345Sdim /* CCB request completed with an error */ 146234353Sdim CAM_REQ_CMP_ERR = 0x04, 147234353Sdim 148234353Sdim /* CAM subsystem is busy */ 149234353Sdim CAM_BUSY = 0x05, 150221345Sdim 151234353Sdim /* CCB request was invalid */ 152234353Sdim CAM_REQ_INVALID = 0x06, 153193323Sed 154234353Sdim /* Supplied Path ID is invalid */ 155234353Sdim CAM_PATH_INVALID = 0x07, 156221345Sdim 157234353Sdim /* SCSI Device Not Installed/there */ 158234353Sdim CAM_DEV_NOT_THERE = 0x08, 159234353Sdim 160234353Sdim /* Unable to terminate I/O CCB request */ 161234353Sdim CAM_UA_TERMIO = 0x09, 162234353Sdim 163234353Sdim /* Target Selection Timeout */ 164234353Sdim CAM_SEL_TIMEOUT = 0x0a, 165193323Sed 166221345Sdim /* Command timeout */ 167224145Sdim CAM_CMD_TIMEOUT = 0x0b, 168193323Sed 169193323Sed /* SCSI error, look at error code in CCB */ 170193323Sed CAM_SCSI_STATUS_ERROR = 0x0c, 171193323Sed 172193323Sed /* Message Reject Received */ 173193323Sed CAM_MSG_REJECT_REC = 0x0d, 174224145Sdim 175193323Sed /* SCSI Bus Reset Sent/Received */ 176193323Sed CAM_SCSI_BUS_RESET = 0x0e, 177193323Sed 178224145Sdim /* Uncorrectable parity error occurred */ 179224145Sdim CAM_UNCOR_PARITY = 0x0f, 180224145Sdim 181224145Sdim /* Autosense: request sense cmd fail */ 182193323Sed CAM_AUTOSENSE_FAIL = 0x10, 183193323Sed 184193323Sed /* No HBA Detected error */ 185193323Sed CAM_NO_HBA = 0x11, 186234353Sdim 187234353Sdim /* Data Overrun error */ 188221345Sdim CAM_DATA_RUN_ERR = 0x12, 189193323Sed 190224145Sdim /* Unexpected Bus Free */ 191193323Sed CAM_UNEXP_BUSFREE = 0x13, 192193323Sed 193193323Sed /* Target Bus Phase Sequence Failure */ 194193323Sed CAM_SEQUENCE_FAIL = 0x14, 195193323Sed 196193323Sed /* CCB length supplied is inadequate */ 197193323Sed CAM_CCB_LEN_ERR = 0x15, 198221345Sdim 199193323Sed /* Unable to provide requested capability*/ 200221345Sdim CAM_PROVIDE_FAIL = 0x16, 201193323Sed 202193323Sed /* A SCSI BDR msg was sent to target */ 203193323Sed CAM_BDR_SENT = 0x17, 204193323Sed 205224145Sdim /* CCB request terminated by the host */ 206193323Sed CAM_REQ_TERMIO = 0x18, 207221345Sdim 208193323Sed /* Unrecoverable Host Bus Adapter Error */ 209221345Sdim CAM_UNREC_HBA_ERROR = 0x19, 210193323Sed 211221345Sdim /* Request was too large for this host */ 212193323Sed CAM_REQ_TOO_BIG = 0x1a, 213193323Sed 214224145Sdim /* 215193323Sed * This request should be requeued to preserve 216193323Sed * transaction ordering. This typically occurs 217193323Sed * when the SIM recognizes an error that should 218193323Sed * freeze the queue and must place additional 219193323Sed * requests for the target at the sim level 220224145Sdim * back into the XPT queue. 221221345Sdim */ 222193323Sed CAM_REQUEUE_REQ = 0x1b, 223193323Sed 224221345Sdim /* ATA error, look at error code in CCB */ 225193323Sed CAM_ATA_STATUS_ERROR = 0x1c, 226193323Sed 227221345Sdim /* Initiator/Target Nexus lost. */ 228193323Sed CAM_SCSI_IT_NEXUS_LOST = 0x1d, 229193323Sed 230193323Sed /* SMP error, look at error code in CCB */ 231224145Sdim CAM_SMP_STATUS_ERROR = 0x1e, 232193323Sed 233193323Sed /* 234193323Sed * Command completed without error but exceeded the soft 235193323Sed * timeout threshold. 236193323Sed */ 237193323Sed CAM_REQ_SOFTTIMEOUT = 0x1f, 238224145Sdim 239193323Sed /* 240193323Sed * 0x20 - 0x32 are unassigned 241193323Sed */ 242193323Sed 243193323Sed /* Initiator Detected Error */ 244193323Sed CAM_IDE = 0x33, 245193323Sed 246234353Sdim /* Resource Unavailable */ 247234353Sdim CAM_RESRC_UNAVAIL = 0x34, 248221345Sdim 249193323Sed /* Unacknowledged Event by Host */ 250193323Sed CAM_UNACKED_EVENT = 0x35, 251193323Sed 252193323Sed /* Message Received in Host Target Mode */ 253193323Sed CAM_MESSAGE_RECV = 0x36, 254193323Sed 255221345Sdim /* Invalid CDB received in Host Target Mode */ 256193323Sed CAM_INVALID_CDB = 0x37, 257221345Sdim 258193323Sed /* Lun supplied is invalid */ 259193323Sed CAM_LUN_INVALID = 0x38, 260193323Sed 261193323Sed /* Target ID supplied is invalid */ 262221345Sdim CAM_TID_INVALID = 0x39, 263193323Sed 264221345Sdim /* The requested function is not available */ 265193323Sed CAM_FUNC_NOTAVAIL = 0x3a, 266193323Sed 267224145Sdim /* Nexus is not established */ 268193323Sed CAM_NO_NEXUS = 0x3b, 269193323Sed 270193323Sed /* The initiator ID is invalid */ 271221345Sdim CAM_IID_INVALID = 0x3c, 272193323Sed 273221345Sdim /* The SCSI CDB has been received */ 274221345Sdim CAM_CDB_RECVD = 0x3d, 275193323Sed 276193323Sed /* The LUN is already enabled for target mode */ 277221345Sdim CAM_LUN_ALRDY_ENA = 0x3e, 278193323Sed 279193323Sed /* SCSI Bus Busy */ 280221345Sdim CAM_SCSI_BUSY = 0x3f, 281193323Sed 282193323Sed 283193323Sed /* 284224145Sdim * Flags 285193323Sed */ 286193323Sed 287193323Sed /* The DEV queue is frozen w/this err */ 288198090Srdivacky CAM_DEV_QFRZN = 0x40, 289198090Srdivacky 290198090Srdivacky /* Autosense data valid for target */ 291193323Sed CAM_AUTOSNS_VALID = 0x80, 292207618Srdivacky 293207618Srdivacky /* SIM ready to take more commands */ 294198090Srdivacky CAM_RELEASE_SIMQ = 0x100, 295198090Srdivacky 296193323Sed /* SIM has this command in it's queue */ 297193323Sed CAM_SIM_QUEUED = 0x200, 298193323Sed 299193323Sed /* Quality of service data is valid */ 300193323Sed CAM_QOS_VALID = 0x400, 301193323Sed 302193323Sed /* Mask bits for just the status # */ 303193323Sed CAM_STATUS_MASK = 0x3F, 304193323Sed 305221345Sdim /* 306207618Srdivacky * Target Specific Adjunct Status 307193323Sed */ 308193323Sed 309221345Sdim /* sent sense with status */ 310193323Sed CAM_SENT_SENSE = 0x40000000 311193323Sed} cam_status; 312221345Sdim 313193323Sedtypedef enum { 314193323Sed CAM_ESF_NONE = 0x00, 315193323Sed CAM_ESF_COMMAND = 0x01, 316207618Srdivacky CAM_ESF_CAM_STATUS = 0x02, 317193323Sed CAM_ESF_PROTO_STATUS = 0x04, 318193323Sed CAM_ESF_ALL = 0xff 319221345Sdim} cam_error_string_flags; 320198090Srdivacky 321198090Srdivackytypedef enum { 322198090Srdivacky CAM_EPF_NONE = 0x00, 323207618Srdivacky CAM_EPF_MINIMAL = 0x01, 324207618Srdivacky CAM_EPF_NORMAL = 0x02, 325207618Srdivacky CAM_EPF_ALL = 0x03, 326193323Sed CAM_EPF_LEVEL_MASK = 0x0f 327193323Sed /* All bits above bit 3 are protocol-specific */ 328193323Sed} cam_error_proto_flags; 329193323Sed 330193323Sedtypedef enum { 331193323Sed CAM_ESF_PRINT_NONE = 0x00, 332193323Sed CAM_ESF_PRINT_STATUS = 0x10, 333198090Srdivacky CAM_ESF_PRINT_SENSE = 0x20 334198090Srdivacky} cam_error_scsi_flags; 335198090Srdivacky 336193323Sedtypedef enum { 337198090Srdivacky CAM_ESMF_PRINT_NONE = 0x00, 338198090Srdivacky CAM_ESMF_PRINT_STATUS = 0x10, 339198090Srdivacky CAM_ESMF_PRINT_FULL_CMD = 0x20, 340198090Srdivacky} cam_error_smp_flags; 341198090Srdivacky 342198090Srdivackytypedef enum { 343198090Srdivacky CAM_EAF_PRINT_NONE = 0x00, 344198090Srdivacky CAM_EAF_PRINT_STATUS = 0x10, 345198090Srdivacky CAM_EAF_PRINT_RESULT = 0x20 346198090Srdivacky} cam_error_ata_flags; 347198090Srdivacky 348221345Sdimstruct cam_status_entry 349198090Srdivacky{ 350198090Srdivacky cam_status status_code; 351198090Srdivacky const char *status_text; 352198090Srdivacky}; 353198090Srdivacky 354218893Sdimextern const struct cam_status_entry cam_status_table[]; 355218893Sdimextern const int num_cam_status_entries; 356218893Sdim#ifdef _KERNEL 357218893Sdimextern int cam_sort_io_queues; 358218893Sdim#endif 359218893Sdimunion ccb; 360218893Sdim 361218893Sdim#ifdef SYSCTL_DECL /* from sysctl.h */ 362218893SdimSYSCTL_DECL(_kern_cam); 363218893Sdim#endif 364218893Sdim 365218893Sdim__BEGIN_DECLS 366218893Sdimtypedef int (cam_quirkmatch_t)(caddr_t, caddr_t); 367218893Sdim 368218893Sdimcaddr_t cam_quirkmatch(caddr_t target, caddr_t quirk_table, int num_entries, 369218893Sdim int entry_size, cam_quirkmatch_t *comp_func); 370218893Sdim 371218893Sdimvoid cam_strvis(u_int8_t *dst, const u_int8_t *src, int srclen, int dstlen); 372198090Srdivacky 373239462Sdimint cam_strmatch(const u_int8_t *str, const u_int8_t *pattern, int str_len); 374239462Sdimconst struct cam_status_entry* 375239462Sdim cam_fetch_status_entry(cam_status status); 376198090Srdivacky#ifdef _KERNEL 377239462Sdimchar * cam_error_string(union ccb *ccb, char *str, int str_len, 378239462Sdim cam_error_string_flags flags, 379239462Sdim cam_error_proto_flags proto_flags); 380239462Sdimvoid cam_error_print(union ccb *ccb, cam_error_string_flags flags, 381221345Sdim cam_error_proto_flags proto_flags); 382239462Sdim#else /* _KERNEL */ 383239462Sdimstruct cam_device; 384193323Sed 385207618Srdivackychar * cam_error_string(struct cam_device *device, union ccb *ccb, char *str, 386239462Sdim int str_len, cam_error_string_flags flags, 387239462Sdim cam_error_proto_flags proto_flags); 388207618Srdivackyvoid cam_error_print(struct cam_device *device, union ccb *ccb, 389239462Sdim cam_error_string_flags flags, 390239462Sdim cam_error_proto_flags proto_flags, FILE *ofile); 391239462Sdim#endif /* _KERNEL */ 392239462Sdim__END_DECLS 393207618Srdivacky 394207618Srdivacky#ifdef _KERNEL 395207618Srdivackystatic __inline void cam_init_pinfo(cam_pinfo *pinfo); 396239462Sdim 397239462Sdimstatic __inline void cam_init_pinfo(cam_pinfo *pinfo) 398207618Srdivacky{ 399207618Srdivacky pinfo->priority = CAM_PRIORITY_NONE; 400207618Srdivacky pinfo->index = CAM_UNQUEUED_INDEX; 401207618Srdivacky} 402207618Srdivacky#endif 403207618Srdivacky 404207618Srdivacky#endif /* _CAM_CAM_H */ 405218893Sdim