hptiop.h revision 169412
1/* 2 * HighPoint RR3xxx RAID Driver for FreeBSD 3 * Copyright (C) 2005-2007 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 26#ifndef _HPTIOP_H 27#define _HPTIOP_H 28 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD: head/sys/dev/hptiop/hptiop.h 169412 2007-05-09 07:07:26Z scottl $"); 31 32#ifdef DBG 33int hpt_dbg_level = 0; 34#define KdPrint(x) do { if (hpt_dbg_level) printf x; } while (0) 35#define HPT_ASSERT(x) assert(x) 36#else 37#define KdPrint(x) 38#define HPT_ASSERT(x) 39#endif 40 41#define HPT_SRB_MAX_REQ_SIZE 600 42#define HPT_SRB_MAX_QUEUE_SIZE 0x100 43 44/* beyond 64G mem */ 45#define HPT_SRB_FLAG_HIGH_MEM_ACESS 0x1 46#define HPT_SRB_MAX_SIZE ((sizeof(struct hpt_iop_srb) + 0x1f) & ~0x1f) 47 48#define HPT_IOCTL_MAGIC 0xA1B2C3D4 49#define HPT_IOCTL_MAGIC32 0x1A2B3C4D 50 51 52struct hpt_iopmu 53{ 54 u_int32_t resrved0[4]; 55 u_int32_t inbound_msgaddr0; 56 u_int32_t inbound_msgaddr1; 57 u_int32_t outbound_msgaddr0; 58 u_int32_t outbound_msgaddr1; 59 u_int32_t inbound_doorbell; 60 u_int32_t inbound_intstatus; 61 u_int32_t inbound_intmask; 62 u_int32_t outbound_doorbell; 63 u_int32_t outbound_intstatus; 64 u_int32_t outbound_intmask; 65 u_int32_t reserved1[2]; 66 u_int32_t inbound_queue; 67 u_int32_t outbound_queue; 68}; 69 70struct hpt_iop_ioctl_param { 71 u_int32_t Magic; /* used to check if it's a valid ioctl packet */ 72 u_int32_t dwIoControlCode; /* operation control code */ 73 unsigned long lpInBuffer; /* input data buffer */ 74 u_int32_t nInBufferSize; /* size of input data buffer */ 75 unsigned long lpOutBuffer; /* output data buffer */ 76 u_int32_t nOutBufferSize; /* size of output data buffer */ 77 unsigned long lpBytesReturned; /* count of HPT_U8s returned */ 78} __attribute__((packed)); 79 80 81struct hpt_iop_srb { 82 u_int8_t req[HPT_SRB_MAX_REQ_SIZE]; 83 struct hpt_iop_hba *hba; 84 union ccb *ccb; 85 struct hpt_iop_srb * next; 86 bus_dmamap_t dma_map; 87 u_int32_t phy_addr; 88 u_int32_t srb_flag; 89 int index; 90}; 91 92#define IOPMU_QUEUE_EMPTY 0xffffffff 93#define IOPMU_QUEUE_MASK_HOST_BITS 0xf0000000 94#define IOPMU_QUEUE_ADDR_HOST_BIT 0x80000000 95#define IOPMU_QUEUE_REQUEST_SIZE_BIT 0x40000000 96#define IOPMU_QUEUE_REQUEST_RESULT_BIT 0x40000000 97#define IOPMU_MAX_MEM_SUPPORT_MASK_64G 0xfffffff000000000ull 98#define IOPMU_MAX_MEM_SUPPORT_MASK_32G 0xfffffff800000000ull 99 100#define IOPMU_OUTBOUND_INT_MSG0 1 101#define IOPMU_OUTBOUND_INT_MSG1 2 102#define IOPMU_OUTBOUND_INT_DOORBELL 4 103#define IOPMU_OUTBOUND_INT_POSTQUEUE 8 104#define IOPMU_OUTBOUND_INT_PCI 0x10 105 106#define IOPMU_INBOUND_INT_MSG0 1 107#define IOPMU_INBOUND_INT_MSG1 2 108#define IOPMU_INBOUND_INT_DOORBELL 4 109#define IOPMU_INBOUND_INT_ERROR 8 110#define IOPMU_INBOUND_INT_POSTQUEUE 0x10 111 112enum hpt_iopmu_message { 113 /* host-to-iop messages */ 114 IOPMU_INBOUND_MSG0_NOP = 0, 115 IOPMU_INBOUND_MSG0_RESET, 116 IOPMU_INBOUND_MSG0_FLUSH, 117 IOPMU_INBOUND_MSG0_SHUTDOWN, 118 IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK, 119 IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK, 120 IOPMU_INBOUND_MSG0_MAX = 0xff, 121 /* iop-to-host messages */ 122 IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_0 = 0x100, 123 IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_MAX = 0x1ff, 124 IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_0 = 0x200, 125 IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_MAX = 0x2ff, 126 IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_0 = 0x300, 127 IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_MAX = 0x3ff, 128}; 129 130struct hpt_iop_request_header 131{ 132 u_int32_t size; 133 u_int32_t type; 134 u_int32_t flags; 135 u_int32_t result; 136 u_int32_t context; /* host context */ 137 u_int32_t context_hi32; 138}; 139 140#define IOP_REQUEST_FLAG_SYNC_REQUEST 1 141#define IOP_REQUEST_FLAG_BIST_REQUEST 2 142#define IOP_REQUEST_FLAG_REMAPPED 4 143#define IOP_REQUEST_FLAG_OUTPUT_CONTEXT 8 144 145enum hpt_iop_request_type { 146 IOP_REQUEST_TYPE_GET_CONFIG = 0, 147 IOP_REQUEST_TYPE_SET_CONFIG, 148 IOP_REQUEST_TYPE_BLOCK_COMMAND, 149 IOP_REQUEST_TYPE_SCSI_COMMAND, 150 IOP_REQUEST_TYPE_IOCTL_COMMAND, 151 IOP_REQUEST_TYPE_MAX 152}; 153 154enum hpt_iop_result_type { 155 IOP_RESULT_PENDING = 0, 156 IOP_RESULT_SUCCESS, 157 IOP_RESULT_FAIL, 158 IOP_RESULT_BUSY, 159 IOP_RESULT_RESET, 160 IOP_RESULT_INVALID_REQUEST, 161 IOP_RESULT_BAD_TARGET, 162 IOP_RESULT_MODE_SENSE_CHECK_CONDITION, 163}; 164 165struct hpt_iop_request_get_config 166{ 167 struct hpt_iop_request_header header; 168 u_int32_t interface_version; 169 u_int32_t firmware_version; 170 u_int32_t max_requests; 171 u_int32_t request_size; 172 u_int32_t max_sg_count; 173 u_int32_t data_transfer_length; 174 u_int32_t alignment_mask; 175 u_int32_t max_devices; 176 u_int32_t sdram_size; 177}; 178 179struct hpt_iop_request_set_config 180{ 181 struct hpt_iop_request_header header; 182 u_int32_t iop_id; 183 u_int16_t vbus_id; 184 u_int16_t max_host_request_size; 185 u_int32_t reserve[6]; 186}; 187 188struct hpt_iopsg 189{ 190 u_int32_t size; 191 u_int32_t eot; /* non-zero: end of table */ 192 u_int64_t pci_address; 193}; 194 195struct hpt_iop_request_block_command 196{ 197 struct hpt_iop_request_header header; 198 u_int8_t channel; 199 u_int8_t target; 200 u_int8_t lun; 201 u_int8_t pad1; 202 u_int16_t command; /* IOP_BLOCK_COMMAND_{READ,WRITE} */ 203 u_int16_t sectors; 204 u_int64_t lba; 205 struct hpt_iopsg sg_list[1]; 206}; 207 208#define IOP_BLOCK_COMMAND_READ 1 209#define IOP_BLOCK_COMMAND_WRITE 2 210#define IOP_BLOCK_COMMAND_VERIFY 3 211#define IOP_BLOCK_COMMAND_FLUSH 4 212#define IOP_BLOCK_COMMAND_SHUTDOWN 5 213 214struct hpt_iop_request_scsi_command 215{ 216 struct hpt_iop_request_header header; 217 u_int8_t channel; 218 u_int8_t target; 219 u_int8_t lun; 220 u_int8_t pad1; 221 u_int8_t cdb[16]; 222 u_int32_t dataxfer_length; 223 struct hpt_iopsg sg_list[1]; 224}; 225 226struct hpt_iop_request_ioctl_command 227{ 228 struct hpt_iop_request_header header; 229 u_int32_t ioctl_code; 230 u_int32_t inbuf_size; 231 u_int32_t outbuf_size; 232 u_int32_t bytes_returned; 233 u_int8_t buf[1]; 234 /* out data should be put at buf[(inbuf_size+3)&~3] */ 235}; 236 237#define HPT_CTL_CODE_BSD_TO_IOP(x) ((x)-0xff00) 238 239#if __FreeBSD_version>503000 240typedef struct cdev * ioctl_dev_t; 241#else 242typedef dev_t ioctl_dev_t; 243#endif 244 245#if __FreeBSD_version >= 500000 246typedef struct thread * ioctl_thread_t; 247#else 248typedef struct proc * ioctl_thread_t; 249#endif 250 251struct hpt_iop_hba { 252 struct hpt_iopmu *iop; 253 struct hpt_iop_hba *next; 254 255 u_int32_t firmware_version; 256 u_int32_t interface_version; 257 u_int32_t max_devices; 258 u_int32_t max_requests; 259 u_int32_t max_request_size; 260 u_int32_t max_sg_count; 261 262 int msg_done; 263 264 device_t pcidev; 265 u_int32_t pciunit; 266 ioctl_dev_t ioctl_dev; 267 268 struct resource *bar0_res; 269 int bar0_rid; 270 271 bus_dma_tag_t parent_dmat; 272 bus_dma_tag_t io_dmat; 273 bus_dma_tag_t srb_dmat; 274 bus_dmamap_t srb_dmamap; 275 /* to release */ 276 u_int8_t *uncached_ptr; 277 /* for scsi request block */ 278 struct hpt_iop_srb *srb_list; 279 /* for interrupt */ 280 struct resource *irq_res; 281 void *irq_handle; 282 /* other resources */ 283 struct cam_sim *sim; 284 struct cam_path *path; 285 void *req; 286#if (__FreeBSD_version >= 500000) 287 struct mtx lock; 288#else 289 int hpt_splx; 290#endif 291#define HPT_IOCTL_FLAG_OPEN 1 292 u_int32_t flag; 293 struct hpt_iop_srb* srb[HPT_SRB_MAX_QUEUE_SIZE]; 294}; 295 296#if __FreeBSD_version >= 500000 297#define hptiop_lock_adapter(hba) mtx_lock(&(hba)->lock) 298#define hptiop_unlock_adapter(hba) mtx_unlock(&(hba)->lock) 299#else 300static __inline void hptiop_lock_adapter(struct hpt_iop_hba *hba) 301{ 302 hba->hpt_splx = splcam(); 303} 304static __inline void hptiop_unlock_adapter(struct hpt_iop_hba *hba) 305{ 306 splx(hba->hpt_splx); 307} 308#endif 309 310#define HPT_OSM_TIMEOUT (20*hz) /* timeout value for OS commands */ 311 312#define HPT_DO_IOCONTROL _IOW('H', 0, struct hpt_iop_ioctl_param) 313#define HPT_SCAN_BUS _IO('H', 1) 314 315static __inline int hptiop_sleep(struct hpt_iop_hba *hba, void *ident, 316 int priority, const char *wmesg, int timo) 317{ 318 319 int retval; 320 321#if __FreeBSD_version >= 500000 322 retval = msleep(ident, &hba->lock, priority, wmesg, timo); 323#else 324 asleep(ident, priority, wmesg, timo); 325 hptiop_unlock_adapter(hba); 326 retval = await(priority, timo); 327 hptiop_lock_adapter(hba); 328#endif 329 330 return retval; 331 332} 333 334#if __FreeBSD_version < 501000 335#define READ_16 0x88 336#define WRITE_16 0x8a 337#define SERVICE_ACTION_IN 0x9e 338#endif 339 340#define HPT_DEV_MAJOR 200 341 342#endif 343 344