1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2000 Matthew Jacob 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer, 12 * without modification, immediately at the beginning of the file. 13 * 2. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD$ 29 */ 30 31 /* 32 * This file contains definitions only intended for use within 33 * sys/cam/scsi/scsi_enc*.c, and not in other kernel components. 34 */ 35 36 #ifndef __SCSI_ENC_INTERNAL_H__ 37 #define __SCSI_ENC_INTERNAL_H__ 38 39 #include <sys/sysctl.h> 40 41 typedef struct enc_element { 42 u_int elm_idx; /* index of element */ 43 uint8_t elm_type; /* element type */ 44 uint8_t subenclosure; /* subenclosure id */ 45 uint8_t type_elm_idx; /* index of element within type */ 46 uint8_t svalid; /* enclosure information valid */ 47 uint8_t encstat[4]; /* state && stats */ 48 u_int physical_path_len; /* Length of device path data. */ 49 uint8_t *physical_path; /* Device physical path data. */ 50 void *elm_private; /* per-type object data */ 51 uint16_t priv; 52 } enc_element_t; 53 54 typedef enum { 55 ENC_NONE, 56 ENC_SES, 57 ENC_SES_PASSTHROUGH, 58 ENC_SAFT, 59 ENC_SEMB_SES, 60 ENC_SEMB_SAFT 61 } enctyp; 62 63 /* Platform Independent Driver Internal Definitions for enclosure devices. */ 64 typedef struct enc_softc enc_softc_t; 65 66 struct enc_fsm_state; 67 typedef int fsm_fill_handler_t(enc_softc_t *ssc, 68 struct enc_fsm_state *state, 69 union ccb *ccb, 70 uint8_t *buf); 71 typedef int fsm_error_handler_t(union ccb *ccb, uint32_t cflags, 72 uint32_t sflags); 73 typedef int fsm_done_handler_t(enc_softc_t *ssc, 74 struct enc_fsm_state *state, union ccb *ccb, 75 uint8_t **bufp, int error, int xfer_len); 76 77 struct enc_fsm_state { 78 const char *name; 79 int page_code; 80 size_t buf_size; 81 uint32_t timeout; 82 fsm_fill_handler_t *fill; 83 fsm_done_handler_t *done; 84 fsm_error_handler_t *error; 85 }; 86 87 typedef int (enc_softc_init_t)(enc_softc_t *); 88 typedef void (enc_softc_invalidate_t)(enc_softc_t *); 89 typedef void (enc_softc_cleanup_t)(enc_softc_t *); 90 typedef int (enc_init_enc_t)(enc_softc_t *); 91 typedef int (enc_set_enc_status_t)(enc_softc_t *, encioc_enc_status_t, int); 92 typedef int (enc_get_elm_status_t)(enc_softc_t *, encioc_elm_status_t *, int); 93 typedef int (enc_set_elm_status_t)(enc_softc_t *, encioc_elm_status_t *, int); 94 typedef int (enc_get_elm_desc_t)(enc_softc_t *, encioc_elm_desc_t *); 95 typedef int (enc_get_elm_devnames_t)(enc_softc_t *, encioc_elm_devnames_t *); 96 typedef int (enc_handle_string_t)(enc_softc_t *, encioc_string_t *, 97 unsigned long); 98 typedef void (enc_device_found_t)(enc_softc_t *); 99 typedef void (enc_poll_status_t)(enc_softc_t *); 100 101 struct enc_vec { 102 enc_softc_invalidate_t *softc_invalidate; 103 enc_softc_cleanup_t *softc_cleanup; 104 enc_init_enc_t *init_enc; 105 enc_set_enc_status_t *set_enc_status; 106 enc_get_elm_status_t *get_elm_status; 107 enc_set_elm_status_t *set_elm_status; 108 enc_get_elm_desc_t *get_elm_desc; 109 enc_get_elm_devnames_t *get_elm_devnames; 110 enc_handle_string_t *handle_string; 111 enc_device_found_t *device_found; 112 enc_poll_status_t *poll_status; 113 }; 114 115 typedef struct enc_cache { 116 enc_element_t *elm_map; /* objects */ 117 int nelms; /* number of objects */ 118 encioc_enc_status_t enc_status; /* overall status */ 119 void *private; /* per-type private data */ 120 } enc_cache_t; 121 122 /* Enclosure instance toplevel structure */ 123 struct enc_softc { 124 enctyp enc_type; /* type of enclosure */ 125 struct enc_vec enc_vec; /* vector to handlers */ 126 void *enc_private; /* per-type private data */ 127 128 /** 129 * "Published" configuration and state data available to 130 * external consumers. 131 */ 132 enc_cache_t enc_cache; 133 134 /** 135 * Configuration and state data being actively updated 136 * by the enclosure daemon. 137 */ 138 enc_cache_t enc_daemon_cache; 139 140 struct sx enc_cache_lock; 141 uint8_t enc_flags; 142 #define ENC_FLAG_INVALID 0x01 143 #define ENC_FLAG_INITIALIZED 0x02 144 #define ENC_FLAG_SHUTDOWN 0x04 145 struct cdev *enc_dev; 146 struct cam_periph *periph; 147 int open_count; 148 149 /* Bitmap of pending operations. */ 150 uint32_t pending_actions; 151 152 /* The action on which the state machine is currently working. */ 153 uint32_t current_action; 154 #define ENC_UPDATE_NONE 0x00 155 #define ENC_UPDATE_INVALID 0xff 156 157 /* Callout for auto-updating enclosure status */ 158 struct callout status_updater; 159 160 struct proc *enc_daemon; 161 162 struct enc_fsm_state *enc_fsm_states; 163 164 struct root_hold_token enc_rootmount; 165 166 #define ENC_ANNOUNCE_SZ 400 167 char announce_buf[ENC_ANNOUNCE_SZ]; 168 }; 169 170 static inline enc_cache_t * 171 enc_other_cache(enc_softc_t *enc, enc_cache_t *primary) 172 { 173 return (primary == &enc->enc_cache 174 ? &enc->enc_daemon_cache : &enc->enc_cache); 175 } 176 177 /* SES Management mode page - SES2r20 Table 59 */ 178 struct ses_mgmt_mode_page { 179 struct scsi_mode_header_6 header; 180 struct scsi_mode_blk_desc blk_desc; 181 uint8_t byte0; /* ps : 1, spf : 1, page_code : 6 */ 182 #define SES_MGMT_MODE_PAGE_CODE 0x14 183 uint8_t length; 184 #define SES_MGMT_MODE_PAGE_LEN 6 185 uint8_t reserved[3]; 186 uint8_t byte5; /* reserved : 7, enbltc : 1 */ 187 #define SES_MGMT_TIMED_COMP_EN 0x1 188 uint8_t max_comp_time[2]; 189 }; 190 191 /* Enclosure core interface for sub-drivers */ 192 int enc_runcmd(struct enc_softc *, char *, int, char *, int *); 193 void enc_log(struct enc_softc *, const char *, ...); 194 int enc_error(union ccb *, uint32_t, uint32_t); 195 void enc_update_request(enc_softc_t *, uint32_t); 196 197 /* SES Native interface */ 198 enc_softc_init_t ses_softc_init; 199 200 /* SAF-TE interface */ 201 enc_softc_init_t safte_softc_init; 202 203 SYSCTL_DECL(_kern_cam_enc); 204 extern int enc_verbose; 205 206 /* Helper macros */ 207 MALLOC_DECLARE(M_SCSIENC); 208 #define ENC_CFLAGS CAM_RETRY_SELTO 209 #define ENC_FLAGS SF_NO_PRINT | SF_RETRY_UA 210 #define STRNCMP strncmp 211 #define PRINTF printf 212 #define ENC_LOG enc_log 213 #if defined(DEBUG) || defined(ENC_DEBUG) 214 #define ENC_DLOG enc_log 215 #else 216 #define ENC_DLOG if (0) enc_log 217 #endif 218 #define ENC_VLOG if (enc_verbose) enc_log 219 #define ENC_MALLOC(amt) malloc(amt, M_SCSIENC, M_NOWAIT) 220 #define ENC_MALLOCZ(amt) malloc(amt, M_SCSIENC, M_ZERO|M_NOWAIT) 221 /* Cast away const avoiding GCC warnings. */ 222 #define ENC_FREE(ptr) free((void *)((uintptr_t)ptr), M_SCSIENC) 223 #define ENC_FREE_AND_NULL(ptr) do { \ 224 if (ptr != NULL) { \ 225 ENC_FREE(ptr); \ 226 ptr = NULL; \ 227 } \ 228 } while(0) 229 #define MEMZERO bzero 230 #define MEMCPY(dest, src, amt) bcopy(src, dest, amt) 231 232 #endif /* __SCSI_ENC_INTERNAL_H__ */ 233