1898b0535SWarner Losh /*- 28b8a9b1dSJustin T. Gibbs * Data structures and definitions for the CAM system. 38b8a9b1dSJustin T. Gibbs * 48b8a9b1dSJustin T. Gibbs * Copyright (c) 1997 Justin T. Gibbs. 58b8a9b1dSJustin T. Gibbs * All rights reserved. 68b8a9b1dSJustin T. Gibbs * 78b8a9b1dSJustin T. Gibbs * Redistribution and use in source and binary forms, with or without 88b8a9b1dSJustin T. Gibbs * modification, are permitted provided that the following conditions 98b8a9b1dSJustin T. Gibbs * are met: 108b8a9b1dSJustin T. Gibbs * 1. Redistributions of source code must retain the above copyright 118b8a9b1dSJustin T. Gibbs * notice, this list of conditions, and the following disclaimer, 128b8a9b1dSJustin T. Gibbs * without modification, immediately at the beginning of the file. 138b8a9b1dSJustin T. Gibbs * 2. The name of the author may not be used to endorse or promote products 148b8a9b1dSJustin T. Gibbs * derived from this software without specific prior written permission. 158b8a9b1dSJustin T. Gibbs * 168b8a9b1dSJustin T. Gibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 178b8a9b1dSJustin T. Gibbs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 188b8a9b1dSJustin T. Gibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 198b8a9b1dSJustin T. Gibbs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 208b8a9b1dSJustin T. Gibbs * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 218b8a9b1dSJustin T. Gibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 228b8a9b1dSJustin T. Gibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 238b8a9b1dSJustin T. Gibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 248b8a9b1dSJustin T. Gibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 258b8a9b1dSJustin T. Gibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 268b8a9b1dSJustin T. Gibbs * SUCH DAMAGE. 278b8a9b1dSJustin T. Gibbs * 28c3aac50fSPeter Wemm * $FreeBSD$ 298b8a9b1dSJustin T. Gibbs */ 308b8a9b1dSJustin T. Gibbs 318b8a9b1dSJustin T. Gibbs #ifndef _CAM_CAM_H 328b8a9b1dSJustin T. Gibbs #define _CAM_CAM_H 1 338b8a9b1dSJustin T. Gibbs 34c4473420SPeter Wemm #ifdef _KERNEL 358b8a9b1dSJustin T. Gibbs #include <opt_cam.h> 36c4473420SPeter Wemm #endif 378b8a9b1dSJustin T. Gibbs 388b8a9b1dSJustin T. Gibbs #include <sys/cdefs.h> 398b8a9b1dSJustin T. Gibbs 408b8a9b1dSJustin T. Gibbs typedef u_int path_id_t; 418b8a9b1dSJustin T. Gibbs typedef u_int target_id_t; 428b8a9b1dSJustin T. Gibbs typedef u_int lun_id_t; 438b8a9b1dSJustin T. Gibbs 448b8a9b1dSJustin T. Gibbs #define CAM_XPT_PATH_ID ((path_id_t)~0) 458b8a9b1dSJustin T. Gibbs #define CAM_BUS_WILDCARD ((path_id_t)~0) 468b8a9b1dSJustin T. Gibbs #define CAM_TARGET_WILDCARD ((target_id_t)~0) 478b8a9b1dSJustin T. Gibbs #define CAM_LUN_WILDCARD ((lun_id_t)~0) 488b8a9b1dSJustin T. Gibbs 498b8a9b1dSJustin T. Gibbs /* 508b8a9b1dSJustin T. Gibbs * Maximum length for a CAM CDB. 518b8a9b1dSJustin T. Gibbs */ 528b8a9b1dSJustin T. Gibbs #define CAM_MAX_CDBLEN 16 538b8a9b1dSJustin T. Gibbs 548b8a9b1dSJustin T. Gibbs /* 558b8a9b1dSJustin T. Gibbs * Definition of a CAM peripheral driver entry. Peripheral drivers instantiate 568b8a9b1dSJustin T. Gibbs * one of these for each device they wish to communicate with and pass it into 578b8a9b1dSJustin T. Gibbs * the xpt layer when they wish to schedule work on that device via the 580cdabce0SNick Hibma * xpt_schedule API. 598b8a9b1dSJustin T. Gibbs */ 608b8a9b1dSJustin T. Gibbs struct cam_periph; 618b8a9b1dSJustin T. Gibbs 628b8a9b1dSJustin T. Gibbs /* 6383c5d981SAlexander Motin * Priority information for a CAM structure. 6483c5d981SAlexander Motin */ 6583c5d981SAlexander Motin typedef enum { 6683c5d981SAlexander Motin CAM_RL_HOST, 6783c5d981SAlexander Motin CAM_RL_BUS, 6883c5d981SAlexander Motin CAM_RL_XPT, 6983c5d981SAlexander Motin CAM_RL_DEV, 7083c5d981SAlexander Motin CAM_RL_NORMAL, 7183c5d981SAlexander Motin CAM_RL_VALUES 7283c5d981SAlexander Motin } cam_rl; 7383c5d981SAlexander Motin /* 7483c5d981SAlexander Motin * The generation number is incremented everytime a new entry is entered into 7583c5d981SAlexander Motin * the queue giving round robin per priority level scheduling. 768b8a9b1dSJustin T. Gibbs */ 778b8a9b1dSJustin T. Gibbs typedef struct { 788b8a9b1dSJustin T. Gibbs u_int32_t priority; 7983c5d981SAlexander Motin #define CAM_PRIORITY_HOST ((CAM_RL_HOST << 8) + 0x80) 8083c5d981SAlexander Motin #define CAM_PRIORITY_BUS ((CAM_RL_BUS << 8) + 0x80) 8183c5d981SAlexander Motin #define CAM_PRIORITY_XPT ((CAM_RL_XPT << 8) + 0x80) 8283c5d981SAlexander Motin #define CAM_PRIORITY_DEV ((CAM_RL_DEV << 8) + 0x80) 83cccf4220SAlexander Motin #define CAM_PRIORITY_OOB (CAM_RL_DEV << 8) 8483c5d981SAlexander Motin #define CAM_PRIORITY_NORMAL ((CAM_RL_NORMAL << 8) + 0x80) 858b8a9b1dSJustin T. Gibbs #define CAM_PRIORITY_NONE (u_int32_t)-1 868b8a9b1dSJustin T. Gibbs u_int32_t generation; 878b8a9b1dSJustin T. Gibbs int index; 888b8a9b1dSJustin T. Gibbs #define CAM_UNQUEUED_INDEX -1 898b8a9b1dSJustin T. Gibbs #define CAM_ACTIVE_INDEX -2 908b8a9b1dSJustin T. Gibbs #define CAM_DONEQ_INDEX -3 91*ea541bfdSAlexander Motin #define CAM_EXTRAQ_INDEX INT_MAX 928b8a9b1dSJustin T. Gibbs } cam_pinfo; 938b8a9b1dSJustin T. Gibbs 948bad620dSJustin T. Gibbs /* 958bad620dSJustin T. Gibbs * Macro to compare two generation numbers. It is used like this: 968bad620dSJustin T. Gibbs * 978bad620dSJustin T. Gibbs * if (GENERATIONCMP(a, >=, b)) 988bad620dSJustin T. Gibbs * ...; 998bad620dSJustin T. Gibbs * 1008bad620dSJustin T. Gibbs * GERERATIONCMP uses modular arithmetic to guard against wraps 1018bad620dSJustin T. Gibbs * wraps in the generation number. 1028bad620dSJustin T. Gibbs */ 1038bad620dSJustin T. Gibbs #define GENERATIONCMP(x, op, y) ((int32_t)((x) - (y)) op 0) 1048bad620dSJustin T. Gibbs 1053393f8daSKenneth D. Merry /* CAM flags XXX Move to cam_periph.h ??? */ 1068b8a9b1dSJustin T. Gibbs typedef enum { 1078b8a9b1dSJustin T. Gibbs CAM_FLAG_NONE = 0x00, 1083393f8daSKenneth D. Merry CAM_EXPECT_INQ_CHANGE = 0x01, 1093393f8daSKenneth D. Merry CAM_RETRY_SELTO = 0x02 /* Retry Selection Timeouts */ 1108b8a9b1dSJustin T. Gibbs } cam_flags; 1118b8a9b1dSJustin T. Gibbs 1120191d9b3SAlexander Motin enum { 1130191d9b3SAlexander Motin SF_RETRY_UA = 0x01, /* Retry UNIT ATTENTION conditions. */ 1140191d9b3SAlexander Motin SF_NO_PRINT = 0x02, /* Never print error status. */ 1150191d9b3SAlexander Motin SF_QUIET_IR = 0x04, /* Be quiet about Illegal Request reponses */ 1160191d9b3SAlexander Motin SF_PRINT_ALWAYS = 0x08, /* Always print error status. */ 1170191d9b3SAlexander Motin SF_NO_RECOVERY = 0x10, /* Don't do active error recovery. */ 1180191d9b3SAlexander Motin SF_NO_RETRY = 0x20 /* Don't do any retries. */ 1190191d9b3SAlexander Motin }; 1200191d9b3SAlexander Motin 1218b8a9b1dSJustin T. Gibbs /* CAM Status field values */ 1228b8a9b1dSJustin T. Gibbs typedef enum { 1238b8a9b1dSJustin T. Gibbs CAM_REQ_INPROG, /* CCB request is in progress */ 1248b8a9b1dSJustin T. Gibbs CAM_REQ_CMP, /* CCB request completed without error */ 1258b8a9b1dSJustin T. Gibbs CAM_REQ_ABORTED, /* CCB request aborted by the host */ 1268b8a9b1dSJustin T. Gibbs CAM_UA_ABORT, /* Unable to abort CCB request */ 1278b8a9b1dSJustin T. Gibbs CAM_REQ_CMP_ERR, /* CCB request completed with an error */ 12822a6b412SMurray Stokely CAM_BUSY, /* CAM subsystem is busy */ 1298b8a9b1dSJustin T. Gibbs CAM_REQ_INVALID, /* CCB request was invalid */ 1308b8a9b1dSJustin T. Gibbs CAM_PATH_INVALID, /* Supplied Path ID is invalid */ 1318b8a9b1dSJustin T. Gibbs CAM_DEV_NOT_THERE, /* SCSI Device Not Installed/there */ 1328b8a9b1dSJustin T. Gibbs CAM_UA_TERMIO, /* Unable to terminate I/O CCB request */ 1338b8a9b1dSJustin T. Gibbs CAM_SEL_TIMEOUT, /* Target Selection Timeout */ 1348b8a9b1dSJustin T. Gibbs CAM_CMD_TIMEOUT, /* Command timeout */ 1358b8a9b1dSJustin T. Gibbs CAM_SCSI_STATUS_ERROR, /* SCSI error, look at error code in CCB */ 1360cdabce0SNick Hibma CAM_MSG_REJECT_REC, /* Message Reject Received */ 1378b8a9b1dSJustin T. Gibbs CAM_SCSI_BUS_RESET, /* SCSI Bus Reset Sent/Received */ 1388b8a9b1dSJustin T. Gibbs CAM_UNCOR_PARITY, /* Uncorrectable parity error occurred */ 1398b8a9b1dSJustin T. Gibbs CAM_AUTOSENSE_FAIL = 0x10,/* Autosense: request sense cmd fail */ 1408b8a9b1dSJustin T. Gibbs CAM_NO_HBA, /* No HBA Detected error */ 1418b8a9b1dSJustin T. Gibbs CAM_DATA_RUN_ERR, /* Data Overrun error */ 1428b8a9b1dSJustin T. Gibbs CAM_UNEXP_BUSFREE, /* Unexpected Bus Free */ 1438b8a9b1dSJustin T. Gibbs CAM_SEQUENCE_FAIL, /* Target Bus Phase Sequence Failure */ 1448b8a9b1dSJustin T. Gibbs CAM_CCB_LEN_ERR, /* CCB length supplied is inadequate */ 1458b8a9b1dSJustin T. Gibbs CAM_PROVIDE_FAIL, /* Unable to provide requested capability */ 1468b8a9b1dSJustin T. Gibbs CAM_BDR_SENT, /* A SCSI BDR msg was sent to target */ 1478b8a9b1dSJustin T. Gibbs CAM_REQ_TERMIO, /* CCB request terminated by the host */ 1488b8a9b1dSJustin T. Gibbs CAM_UNREC_HBA_ERROR, /* Unrecoverable Host Bus Adapter Error */ 1498b8a9b1dSJustin T. Gibbs CAM_REQ_TOO_BIG, /* The request was too large for this host */ 1508b8a9b1dSJustin T. Gibbs CAM_REQUEUE_REQ, /* 1518b8a9b1dSJustin T. Gibbs * This request should be requeued to preserve 1528b8a9b1dSJustin T. Gibbs * transaction ordering. This typically occurs 1538b8a9b1dSJustin T. Gibbs * when the SIM recognizes an error that should 1548b8a9b1dSJustin T. Gibbs * freeze the queue and must place additional 1558b8a9b1dSJustin T. Gibbs * requests for the target at the sim level 1568b8a9b1dSJustin T. Gibbs * back into the XPT queue. 1578b8a9b1dSJustin T. Gibbs */ 15852c9ce25SScott Long CAM_ATA_STATUS_ERROR, /* ATA error, look at error code in CCB */ 159954e3640SSean Bruno CAM_SCSI_IT_NEXUS_LOST, /* Initiator/Target Nexus lost. */ 16006e79492SKenneth D. Merry CAM_SMP_STATUS_ERROR, /* SMP error, look at error code in CCB */ 1618b8a9b1dSJustin T. Gibbs CAM_IDE = 0x33, /* Initiator Detected Error */ 1628b8a9b1dSJustin T. Gibbs CAM_RESRC_UNAVAIL, /* Resource Unavailable */ 1638b8a9b1dSJustin T. Gibbs CAM_UNACKED_EVENT, /* Unacknowledged Event by Host */ 1648b8a9b1dSJustin T. Gibbs CAM_MESSAGE_RECV, /* Message Received in Host Target Mode */ 1658b8a9b1dSJustin T. Gibbs CAM_INVALID_CDB, /* Invalid CDB received in Host Target Mode */ 1668b8a9b1dSJustin T. Gibbs CAM_LUN_INVALID, /* Lun supplied is invalid */ 1678b8a9b1dSJustin T. Gibbs CAM_TID_INVALID, /* Target ID supplied is invalid */ 1688b8a9b1dSJustin T. Gibbs CAM_FUNC_NOTAVAIL, /* The requested function is not available */ 1698b8a9b1dSJustin T. Gibbs CAM_NO_NEXUS, /* Nexus is not established */ 1708b8a9b1dSJustin T. Gibbs CAM_IID_INVALID, /* The initiator ID is invalid */ 1718b8a9b1dSJustin T. Gibbs CAM_CDB_RECVD, /* The SCSI CDB has been received */ 1723393f8daSKenneth D. Merry CAM_LUN_ALRDY_ENA, /* The LUN is already enabled for target mode */ 1738b8a9b1dSJustin T. Gibbs CAM_SCSI_BUSY, /* SCSI Bus Busy */ 1748b8a9b1dSJustin T. Gibbs 1758b8a9b1dSJustin T. Gibbs CAM_DEV_QFRZN = 0x40, /* The DEV queue is frozen w/this err */ 1768b8a9b1dSJustin T. Gibbs 1778b8a9b1dSJustin T. Gibbs /* Autosense data valid for target */ 1788b8a9b1dSJustin T. Gibbs CAM_AUTOSNS_VALID = 0x80, 1798b8a9b1dSJustin T. Gibbs CAM_RELEASE_SIMQ = 0x100,/* SIM ready to take more commands */ 1808b8a9b1dSJustin T. Gibbs CAM_SIM_QUEUED = 0x200,/* SIM has this command in it's queue */ 1818b8a9b1dSJustin T. Gibbs 1825fd6140dSMatt Jacob CAM_STATUS_MASK = 0x3F, /* Mask bits for just the status # */ 1835fd6140dSMatt Jacob 1845fd6140dSMatt Jacob /* Target Specific Adjunct Status */ 1855fd6140dSMatt Jacob CAM_SENT_SENSE = 0x40000000 /* sent sense with status */ 1868b8a9b1dSJustin T. Gibbs } cam_status; 1878b8a9b1dSJustin T. Gibbs 1883393f8daSKenneth D. Merry typedef enum { 1893393f8daSKenneth D. Merry CAM_ESF_NONE = 0x00, 1903393f8daSKenneth D. Merry CAM_ESF_COMMAND = 0x01, 1913393f8daSKenneth D. Merry CAM_ESF_CAM_STATUS = 0x02, 1923393f8daSKenneth D. Merry CAM_ESF_PROTO_STATUS = 0x04, 1933393f8daSKenneth D. Merry CAM_ESF_ALL = 0xff 1943393f8daSKenneth D. Merry } cam_error_string_flags; 1953393f8daSKenneth D. Merry 1963393f8daSKenneth D. Merry typedef enum { 1973393f8daSKenneth D. Merry CAM_EPF_NONE = 0x00, 1983393f8daSKenneth D. Merry CAM_EPF_MINIMAL = 0x01, 1993393f8daSKenneth D. Merry CAM_EPF_NORMAL = 0x02, 2003393f8daSKenneth D. Merry CAM_EPF_ALL = 0x03, 2013393f8daSKenneth D. Merry CAM_EPF_LEVEL_MASK = 0x0f 2023393f8daSKenneth D. Merry /* All bits above bit 3 are protocol-specific */ 2033393f8daSKenneth D. Merry } cam_error_proto_flags; 2043393f8daSKenneth D. Merry 2053393f8daSKenneth D. Merry typedef enum { 2063393f8daSKenneth D. Merry CAM_ESF_PRINT_NONE = 0x00, 2073393f8daSKenneth D. Merry CAM_ESF_PRINT_STATUS = 0x10, 2083393f8daSKenneth D. Merry CAM_ESF_PRINT_SENSE = 0x20 2093393f8daSKenneth D. Merry } cam_error_scsi_flags; 2103393f8daSKenneth D. Merry 2118691755dSAlexander Motin typedef enum { 21206e79492SKenneth D. Merry CAM_ESMF_PRINT_NONE = 0x00, 21306e79492SKenneth D. Merry CAM_ESMF_PRINT_STATUS = 0x10, 21406e79492SKenneth D. Merry CAM_ESMF_PRINT_FULL_CMD = 0x20, 21506e79492SKenneth D. Merry } cam_error_smp_flags; 21606e79492SKenneth D. Merry 21706e79492SKenneth D. Merry typedef enum { 2188691755dSAlexander Motin CAM_EAF_PRINT_NONE = 0x00, 2198691755dSAlexander Motin CAM_EAF_PRINT_STATUS = 0x10, 2208691755dSAlexander Motin CAM_EAF_PRINT_RESULT = 0x20 2218691755dSAlexander Motin } cam_error_ata_flags; 2228691755dSAlexander Motin 2233393f8daSKenneth D. Merry struct cam_status_entry 2243393f8daSKenneth D. Merry { 2253393f8daSKenneth D. Merry cam_status status_code; 2263393f8daSKenneth D. Merry const char *status_text; 2273393f8daSKenneth D. Merry }; 2283393f8daSKenneth D. Merry 2293393f8daSKenneth D. Merry extern const struct cam_status_entry cam_status_table[]; 2303393f8daSKenneth D. Merry extern const int num_cam_status_entries; 2315f83aee5SSteven Hartland #ifdef _KERNEL 2325f83aee5SSteven Hartland extern int cam_sort_io_queues; 2335f83aee5SSteven Hartland #endif 2343393f8daSKenneth D. Merry union ccb; 2353393f8daSKenneth D. Merry 23665c38256SMike Smith #ifdef SYSCTL_DECL /* from sysctl.h */ 23765c38256SMike Smith SYSCTL_DECL(_kern_cam); 23865c38256SMike Smith #endif 23965c38256SMike Smith 2408b8a9b1dSJustin T. Gibbs __BEGIN_DECLS 2418b8a9b1dSJustin T. Gibbs typedef int (cam_quirkmatch_t)(caddr_t, caddr_t); 2428b8a9b1dSJustin T. Gibbs 2438b8a9b1dSJustin T. Gibbs caddr_t cam_quirkmatch(caddr_t target, caddr_t quirk_table, int num_entries, 2448b8a9b1dSJustin T. Gibbs int entry_size, cam_quirkmatch_t *comp_func); 2458b8a9b1dSJustin T. Gibbs 2468b8a9b1dSJustin T. Gibbs void cam_strvis(u_int8_t *dst, const u_int8_t *src, int srclen, int dstlen); 2478b8a9b1dSJustin T. Gibbs 2488b8a9b1dSJustin T. Gibbs int cam_strmatch(const u_int8_t *str, const u_int8_t *pattern, int str_len); 2493393f8daSKenneth D. Merry const struct cam_status_entry* 2503393f8daSKenneth D. Merry cam_fetch_status_entry(cam_status status); 2513393f8daSKenneth D. Merry #ifdef _KERNEL 2523393f8daSKenneth D. Merry char * cam_error_string(union ccb *ccb, char *str, int str_len, 2533393f8daSKenneth D. Merry cam_error_string_flags flags, 2543393f8daSKenneth D. Merry cam_error_proto_flags proto_flags); 2553393f8daSKenneth D. Merry void cam_error_print(union ccb *ccb, cam_error_string_flags flags, 2563393f8daSKenneth D. Merry cam_error_proto_flags proto_flags); 2573393f8daSKenneth D. Merry #else /* _KERNEL */ 2583393f8daSKenneth D. Merry struct cam_device; 2593393f8daSKenneth D. Merry 2603393f8daSKenneth D. Merry char * cam_error_string(struct cam_device *device, union ccb *ccb, char *str, 2613393f8daSKenneth D. Merry int str_len, cam_error_string_flags flags, 2623393f8daSKenneth D. Merry cam_error_proto_flags proto_flags); 2633393f8daSKenneth D. Merry void cam_error_print(struct cam_device *device, union ccb *ccb, 2643393f8daSKenneth D. Merry cam_error_string_flags flags, 2653393f8daSKenneth D. Merry cam_error_proto_flags proto_flags, FILE *ofile); 2663393f8daSKenneth D. Merry #endif /* _KERNEL */ 2678b8a9b1dSJustin T. Gibbs __END_DECLS 2688b8a9b1dSJustin T. Gibbs 269c4473420SPeter Wemm #ifdef _KERNEL 2708b8a9b1dSJustin T. Gibbs static __inline void cam_init_pinfo(cam_pinfo *pinfo); 2718b8a9b1dSJustin T. Gibbs 2728b8a9b1dSJustin T. Gibbs static __inline void cam_init_pinfo(cam_pinfo *pinfo) 2738b8a9b1dSJustin T. Gibbs { 2748b8a9b1dSJustin T. Gibbs pinfo->priority = CAM_PRIORITY_NONE; 2758b8a9b1dSJustin T. Gibbs pinfo->index = CAM_UNQUEUED_INDEX; 2768b8a9b1dSJustin T. Gibbs } 277c4473420SPeter Wemm #endif 2788b8a9b1dSJustin T. Gibbs 2798b8a9b1dSJustin T. Gibbs #endif /* _CAM_CAM_H */ 280