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