1 /* 2 * HighPoint RR3xxx/4xxx RAID Driver for FreeBSD 3 * Copyright (C) 2007-2008 HighPoint Technologies, Inc. All Rights Reserved. 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 * 25 * $FreeBSD: src/sys/dev/hptiop/hptiop.h,v 1.5 2009/03/25 06:27:56 delphij Exp $ 26 */ 27 28 #ifndef _HPTIOP_H 29 #define _HPTIOP_H 30 31 #define DBG 0 32 33 #ifdef DBG 34 int hpt_iop_dbg_level = 0; 35 #define KdPrint(x) do { if (hpt_iop_dbg_level) kprintf x; } while (0) 36 #else 37 #define KdPrint(x) 38 #endif 39 40 #define HPT_SRB_MAX_REQ_SIZE 600 41 #define HPT_SRB_MAX_QUEUE_SIZE 0x100 42 43 /* beyond 64G mem */ 44 #define HPT_SRB_FLAG_HIGH_MEM_ACESS 0x1 45 #define HPT_SRB_MAX_SIZE ((sizeof(struct hpt_iop_srb) + 0x1f) & ~0x1f) 46 #ifndef offsetof 47 #define offsetof(TYPE, MEM) ((size_t)&((TYPE*)0)->MEM) 48 #endif 49 50 #ifndef MIN 51 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 52 #endif 53 54 #define HPT_IOCTL_MAGIC 0xA1B2C3D4 55 #define HPT_IOCTL_MAGIC32 0x1A2B3C4D 56 57 struct hpt_iopmu_itl { 58 u_int32_t resrved0[4]; 59 u_int32_t inbound_msgaddr0; 60 u_int32_t inbound_msgaddr1; 61 u_int32_t outbound_msgaddr0; 62 u_int32_t outbound_msgaddr1; 63 u_int32_t inbound_doorbell; 64 u_int32_t inbound_intstatus; 65 u_int32_t inbound_intmask; 66 u_int32_t outbound_doorbell; 67 u_int32_t outbound_intstatus; 68 u_int32_t outbound_intmask; 69 u_int32_t reserved1[2]; 70 u_int32_t inbound_queue; 71 u_int32_t outbound_queue; 72 }; 73 74 #define IOPMU_QUEUE_EMPTY 0xffffffff 75 #define IOPMU_QUEUE_MASK_HOST_BITS 0xf0000000 76 #define IOPMU_QUEUE_ADDR_HOST_BIT 0x80000000 77 #define IOPMU_QUEUE_REQUEST_SIZE_BIT 0x40000000 78 #define IOPMU_QUEUE_REQUEST_RESULT_BIT 0x40000000 79 #define IOPMU_MAX_MEM_SUPPORT_MASK_64G 0xfffffff000000000ull 80 #define IOPMU_MAX_MEM_SUPPORT_MASK_32G 0xfffffff800000000ull 81 82 #define IOPMU_OUTBOUND_INT_MSG0 1 83 #define IOPMU_OUTBOUND_INT_MSG1 2 84 #define IOPMU_OUTBOUND_INT_DOORBELL 4 85 #define IOPMU_OUTBOUND_INT_POSTQUEUE 8 86 #define IOPMU_OUTBOUND_INT_PCI 0x10 87 88 #define IOPMU_INBOUND_INT_MSG0 1 89 #define IOPMU_INBOUND_INT_MSG1 2 90 #define IOPMU_INBOUND_INT_DOORBELL 4 91 #define IOPMU_INBOUND_INT_ERROR 8 92 #define IOPMU_INBOUND_INT_POSTQUEUE 0x10 93 94 #define MVIOP_QUEUE_LEN 512 95 struct hpt_iopmu_mv { 96 u_int32_t inbound_head; 97 u_int32_t inbound_tail; 98 u_int32_t outbound_head; 99 u_int32_t outbound_tail; 100 u_int32_t inbound_msg; 101 u_int32_t outbound_msg; 102 u_int32_t reserve[10]; 103 u_int64_t inbound_q[MVIOP_QUEUE_LEN]; 104 u_int64_t outbound_q[MVIOP_QUEUE_LEN]; 105 }; 106 107 struct hpt_iopmv_regs { 108 u_int32_t reserved[0x20400 / 4]; 109 u_int32_t inbound_doorbell; 110 u_int32_t inbound_intmask; 111 u_int32_t outbound_doorbell; 112 u_int32_t outbound_intmask; 113 }; 114 115 #define MVIOP_IOCTLCFG_SIZE 0x800 116 #define MVIOP_MU_QUEUE_ADDR_HOST_MASK (~(0x1full)) 117 #define MVIOP_MU_QUEUE_ADDR_HOST_BIT 4 118 119 #define MVIOP_MU_QUEUE_ADDR_IOP_HIGH32 0xffffffff 120 #define MVIOP_MU_QUEUE_REQUEST_RESULT_BIT 1 121 #define MVIOP_MU_QUEUE_REQUEST_RETURN_CONTEXT 2 122 123 #define MVIOP_MU_INBOUND_INT_MSG 1 124 #define MVIOP_MU_INBOUND_INT_POSTQUEUE 2 125 #define MVIOP_MU_OUTBOUND_INT_MSG 1 126 #define MVIOP_MU_OUTBOUND_INT_POSTQUEUE 2 127 128 #define MVIOP_CMD_TYPE_GET_CONFIG (1 << 5) 129 #define MVIOP_CMD_TYPE_SET_CONFIG (1 << 6) 130 #define MVIOP_CMD_TYPE_SCSI (1 << 7) 131 #define MVIOP_CMD_TYPE_IOCTL (1 << 8) 132 #define MVIOP_CMD_TYPE_BLOCK (1 << 9) 133 134 #define MVIOP_REQUEST_NUMBER_START_BIT 16 135 136 enum hpt_iopmu_message { 137 /* host-to-iop messages */ 138 IOPMU_INBOUND_MSG0_NOP = 0, 139 IOPMU_INBOUND_MSG0_RESET, 140 IOPMU_INBOUND_MSG0_FLUSH, 141 IOPMU_INBOUND_MSG0_SHUTDOWN, 142 IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK, 143 IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK, 144 IOPMU_INBOUND_MSG0_MAX = 0xff, 145 /* iop-to-host messages */ 146 IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_0 = 0x100, 147 IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_MAX = 0x1ff, 148 IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_0 = 0x200, 149 IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_MAX = 0x2ff, 150 IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_0 = 0x300, 151 IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_MAX = 0x3ff, 152 }; 153 154 #define IOP_REQUEST_FLAG_SYNC_REQUEST 1 155 #define IOP_REQUEST_FLAG_BIST_REQUEST 2 156 #define IOP_REQUEST_FLAG_REMAPPED 4 157 #define IOP_REQUEST_FLAG_OUTPUT_CONTEXT 8 158 159 enum hpt_iop_request_type { 160 IOP_REQUEST_TYPE_GET_CONFIG = 0, 161 IOP_REQUEST_TYPE_SET_CONFIG, 162 IOP_REQUEST_TYPE_BLOCK_COMMAND, 163 IOP_REQUEST_TYPE_SCSI_COMMAND, 164 IOP_REQUEST_TYPE_IOCTL_COMMAND, 165 IOP_REQUEST_TYPE_MAX 166 }; 167 168 enum hpt_iop_result_type { 169 IOP_RESULT_PENDING = 0, 170 IOP_RESULT_SUCCESS, 171 IOP_RESULT_FAIL, 172 IOP_RESULT_BUSY, 173 IOP_RESULT_RESET, 174 IOP_RESULT_INVALID_REQUEST, 175 IOP_RESULT_BAD_TARGET, 176 IOP_RESULT_CHECK_CONDITION, 177 }; 178 179 struct hpt_iop_request_header { 180 u_int32_t size; 181 u_int32_t type; 182 u_int32_t flags; 183 u_int32_t result; 184 u_int64_t context; /* host context */ 185 }; 186 187 struct hpt_iop_request_get_config { 188 struct hpt_iop_request_header header; 189 u_int32_t interface_version; 190 u_int32_t firmware_version; 191 u_int32_t max_requests; 192 u_int32_t request_size; 193 u_int32_t max_sg_count; 194 u_int32_t data_transfer_length; 195 u_int32_t alignment_mask; 196 u_int32_t max_devices; 197 u_int32_t sdram_size; 198 }; 199 200 struct hpt_iop_request_set_config { 201 struct hpt_iop_request_header header; 202 u_int32_t iop_id; 203 u_int16_t vbus_id; 204 u_int16_t max_host_request_size; 205 u_int32_t reserve[6]; 206 }; 207 208 struct hpt_iopsg { 209 u_int32_t size; 210 u_int32_t eot; /* non-zero: end of table */ 211 u_int64_t pci_address; 212 }; 213 214 #define IOP_BLOCK_COMMAND_READ 1 215 #define IOP_BLOCK_COMMAND_WRITE 2 216 #define IOP_BLOCK_COMMAND_VERIFY 3 217 #define IOP_BLOCK_COMMAND_FLUSH 4 218 #define IOP_BLOCK_COMMAND_SHUTDOWN 5 219 struct hpt_iop_request_block_command { 220 struct hpt_iop_request_header header; 221 u_int8_t channel; 222 u_int8_t target; 223 u_int8_t lun; 224 u_int8_t pad1; 225 u_int16_t command; /* IOP_BLOCK_COMMAND_{READ,WRITE} */ 226 u_int16_t sectors; 227 u_int64_t lba; 228 struct hpt_iopsg sg_list[1]; 229 }; 230 231 struct hpt_iop_request_scsi_command { 232 struct hpt_iop_request_header header; 233 u_int8_t channel; 234 u_int8_t target; 235 u_int8_t lun; 236 u_int8_t pad1; 237 u_int8_t cdb[16]; 238 u_int32_t dataxfer_length; 239 struct hpt_iopsg sg_list[1]; 240 }; 241 242 struct hpt_iop_request_ioctl_command { 243 struct hpt_iop_request_header header; 244 u_int32_t ioctl_code; 245 u_int32_t inbuf_size; 246 u_int32_t outbuf_size; 247 u_int32_t bytes_returned; 248 u_int8_t buf[1]; 249 /* out data should be put at buf[(inbuf_size+3)&~3] */ 250 }; 251 252 struct hpt_iop_ioctl_param { 253 u_int32_t Magic; /* used to check if it's a valid ioctl packet */ 254 u_int32_t dwIoControlCode; /* operation control code */ 255 unsigned long lpInBuffer; /* input data buffer */ 256 u_int32_t nInBufferSize; /* size of input data buffer */ 257 unsigned long lpOutBuffer; /* output data buffer */ 258 u_int32_t nOutBufferSize; /* size of output data buffer */ 259 unsigned long lpBytesReturned; /* count of HPT_U8s returned */ 260 } __packed; 261 262 #define HPT_IOCTL_FLAG_OPEN 1 263 #define HPT_CTL_CODE_BSD_TO_IOP(x) ((x)-0xff00) 264 265 typedef struct cdev * ioctl_dev_t; 266 267 typedef struct thread * ioctl_thread_t; 268 269 struct hpt_iop_hba { 270 struct hptiop_adapter_ops *ops; 271 union { 272 struct { 273 struct hpt_iopmu_itl *mu; 274 } itl; 275 struct { 276 struct hpt_iopmv_regs *regs; 277 struct hpt_iopmu_mv *mu; 278 } mv; 279 } u; 280 281 struct hpt_iop_hba *next; 282 283 u_int32_t firmware_version; 284 u_int32_t interface_version; 285 u_int32_t max_devices; 286 u_int32_t max_requests; 287 u_int32_t max_request_size; 288 u_int32_t max_sg_count; 289 290 u_int32_t msg_done; 291 292 device_t pcidev; 293 ioctl_dev_t ioctl_dev; 294 295 bus_dma_tag_t parent_dmat; 296 bus_dma_tag_t io_dmat; 297 bus_dma_tag_t srb_dmat; 298 bus_dma_tag_t ctlcfg_dmat; 299 300 bus_dmamap_t srb_dmamap; 301 bus_dmamap_t ctlcfg_dmamap; 302 303 struct resource *bar0_res; 304 bus_space_tag_t bar0t; 305 bus_space_handle_t bar0h; 306 int bar0_rid; 307 308 struct resource *bar2_res; 309 bus_space_tag_t bar2t; 310 bus_space_handle_t bar2h; 311 int bar2_rid; 312 313 /* to release */ 314 u_int8_t *uncached_ptr; 315 void *ctlcfg_ptr; 316 /* for scsi request block */ 317 struct hpt_iop_srb *srb_list; 318 /* for interrupt */ 319 struct resource *irq_res; 320 void *irq_handle; 321 322 /* for ioctl and set/get config */ 323 struct resource *ctlcfg_res; 324 void *ctlcfg_handle; 325 u_int64_t ctlcfgcmd_phy; 326 u_int32_t config_done; 327 328 /* other resources */ 329 struct cam_sim *sim; 330 struct cam_path *path; 331 void *req; 332 struct lock lock; 333 #define HPT_IOCTL_FLAG_OPEN 1 334 u_int32_t flag; 335 struct hpt_iop_srb* srb[HPT_SRB_MAX_QUEUE_SIZE]; 336 }; 337 338 struct hptiop_adapter_ops { 339 int (*iop_wait_ready)(struct hpt_iop_hba *hba, u_int32_t millisec); 340 int (*internal_memalloc)(struct hpt_iop_hba *hba); 341 int (*internal_memfree)(struct hpt_iop_hba *hba); 342 int (*alloc_pci_res)(struct hpt_iop_hba *hba); 343 void (*release_pci_res)(struct hpt_iop_hba *hba); 344 void (*enable_intr)(struct hpt_iop_hba *hba); 345 void (*disable_intr)(struct hpt_iop_hba *hba); 346 int (*get_config)(struct hpt_iop_hba *hba, 347 struct hpt_iop_request_get_config *config); 348 int (*set_config)(struct hpt_iop_hba *hba, 349 struct hpt_iop_request_set_config *config); 350 int (*iop_intr)(struct hpt_iop_hba *hba); 351 void (*post_msg)(struct hpt_iop_hba *hba, u_int32_t msg); 352 void (*post_req)(struct hpt_iop_hba *hba, struct hpt_iop_srb *srb, bus_dma_segment_t *segs, int nsegs); 353 int (*do_ioctl)(struct hpt_iop_hba *hba, struct hpt_iop_ioctl_param * pParams); 354 }; 355 356 struct hpt_iop_srb { 357 u_int8_t req[HPT_SRB_MAX_REQ_SIZE]; 358 struct hpt_iop_hba *hba; 359 union ccb *ccb; 360 struct hpt_iop_srb *next; 361 bus_dmamap_t dma_map; 362 u_int64_t phy_addr; 363 u_int32_t srb_flag; 364 int index; 365 }; 366 367 #define hptiop_lock_adapter(hba) lockmgr(&(hba)->lock, LK_EXCLUSIVE) 368 #define hptiop_unlock_adapter(hba) lockmgr(&(hba)->lock, LK_RELEASE) 369 370 #define HPT_OSM_TIMEOUT (20*hz) /* timeout value for OS commands */ 371 372 #define HPT_DO_IOCONTROL _IOW('H', 0, struct hpt_iop_ioctl_param) 373 #define HPT_SCAN_BUS _IO('H', 1) 374 375 static __inline int hptiop_sleep(struct hpt_iop_hba *hba, void *ident, 376 int priority, const char *wmesg, int timo) 377 { 378 379 int retval; 380 381 retval = lksleep(ident, &hba->lock, priority, wmesg, timo); 382 383 return retval; 384 385 } 386 387 #endif 388