1/* 2 * HighPoint RR3xxx/4xxx controller driver for Linux 3 * Copyright (C) 2006-2012 HighPoint Technologies, Inc. All Rights Reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; version 2 of the License. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * Please report bugs/comments/suggestions to linux@highpoint-tech.com 15 * 16 * For more information, visit http://www.highpoint-tech.com 17 */ 18#ifndef _HPTIOP_H_ 19#define _HPTIOP_H_ 20 21struct hpt_iopmu_itl { 22 __le32 resrved0[4]; 23 __le32 inbound_msgaddr0; 24 __le32 inbound_msgaddr1; 25 __le32 outbound_msgaddr0; 26 __le32 outbound_msgaddr1; 27 __le32 inbound_doorbell; 28 __le32 inbound_intstatus; 29 __le32 inbound_intmask; 30 __le32 outbound_doorbell; 31 __le32 outbound_intstatus; 32 __le32 outbound_intmask; 33 __le32 reserved1[2]; 34 __le32 inbound_queue; 35 __le32 outbound_queue; 36}; 37 38#define IOPMU_QUEUE_EMPTY 0xffffffff 39#define IOPMU_QUEUE_MASK_HOST_BITS 0xf0000000 40#define IOPMU_QUEUE_ADDR_HOST_BIT 0x80000000 41#define IOPMU_QUEUE_REQUEST_SIZE_BIT 0x40000000 42#define IOPMU_QUEUE_REQUEST_RESULT_BIT 0x40000000 43 44#define IOPMU_OUTBOUND_INT_MSG0 1 45#define IOPMU_OUTBOUND_INT_MSG1 2 46#define IOPMU_OUTBOUND_INT_DOORBELL 4 47#define IOPMU_OUTBOUND_INT_POSTQUEUE 8 48#define IOPMU_OUTBOUND_INT_PCI 0x10 49 50#define IOPMU_INBOUND_INT_MSG0 1 51#define IOPMU_INBOUND_INT_MSG1 2 52#define IOPMU_INBOUND_INT_DOORBELL 4 53#define IOPMU_INBOUND_INT_ERROR 8 54#define IOPMU_INBOUND_INT_POSTQUEUE 0x10 55 56#define MVIOP_QUEUE_LEN 512 57 58struct hpt_iopmu_mv { 59 __le32 inbound_head; 60 __le32 inbound_tail; 61 __le32 outbound_head; 62 __le32 outbound_tail; 63 __le32 inbound_msg; 64 __le32 outbound_msg; 65 __le32 reserve[10]; 66 __le64 inbound_q[MVIOP_QUEUE_LEN]; 67 __le64 outbound_q[MVIOP_QUEUE_LEN]; 68}; 69 70struct hpt_iopmv_regs { 71 __le32 reserved[0x20400 / 4]; 72 __le32 inbound_doorbell; 73 __le32 inbound_intmask; 74 __le32 outbound_doorbell; 75 __le32 outbound_intmask; 76}; 77 78#pragma pack(1) 79struct hpt_iopmu_mvfrey { 80 __le32 reserved0[(0x4000 - 0) / 4]; 81 __le32 inbound_base; 82 __le32 inbound_base_high; 83 __le32 reserved1[(0x4018 - 0x4008) / 4]; 84 __le32 inbound_write_ptr; 85 __le32 reserved2[(0x402c - 0x401c) / 4]; 86 __le32 inbound_conf_ctl; 87 __le32 reserved3[(0x4050 - 0x4030) / 4]; 88 __le32 outbound_base; 89 __le32 outbound_base_high; 90 __le32 outbound_shadow_base; 91 __le32 outbound_shadow_base_high; 92 __le32 reserved4[(0x4088 - 0x4060) / 4]; 93 __le32 isr_cause; 94 __le32 isr_enable; 95 __le32 reserved5[(0x1020c - 0x4090) / 4]; 96 __le32 pcie_f0_int_enable; 97 __le32 reserved6[(0x10400 - 0x10210) / 4]; 98 __le32 f0_to_cpu_msg_a; 99 __le32 reserved7[(0x10420 - 0x10404) / 4]; 100 __le32 cpu_to_f0_msg_a; 101 __le32 reserved8[(0x10480 - 0x10424) / 4]; 102 __le32 f0_doorbell; 103 __le32 f0_doorbell_enable; 104}; 105 106struct mvfrey_inlist_entry { 107 dma_addr_t addr; 108 __le32 intrfc_len; 109 __le32 reserved; 110}; 111 112struct mvfrey_outlist_entry { 113 __le32 val; 114}; 115#pragma pack() 116 117#define MVIOP_MU_QUEUE_ADDR_HOST_MASK (~(0x1full)) 118#define MVIOP_MU_QUEUE_ADDR_HOST_BIT 4 119 120#define MVIOP_MU_QUEUE_ADDR_IOP_HIGH32 0xffffffff 121#define MVIOP_MU_QUEUE_REQUEST_RESULT_BIT 1 122#define MVIOP_MU_QUEUE_REQUEST_RETURN_CONTEXT 2 123 124#define MVIOP_MU_INBOUND_INT_MSG 1 125#define MVIOP_MU_INBOUND_INT_POSTQUEUE 2 126#define MVIOP_MU_OUTBOUND_INT_MSG 1 127#define MVIOP_MU_OUTBOUND_INT_POSTQUEUE 2 128 129#define CL_POINTER_TOGGLE 0x00004000 130#define CPU_TO_F0_DRBL_MSG_BIT 0x02000000 131 132enum hpt_iopmu_message { 133 /* host-to-iop messages */ 134 IOPMU_INBOUND_MSG0_NOP = 0, 135 IOPMU_INBOUND_MSG0_RESET, 136 IOPMU_INBOUND_MSG0_FLUSH, 137 IOPMU_INBOUND_MSG0_SHUTDOWN, 138 IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK, 139 IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK, 140 IOPMU_INBOUND_MSG0_RESET_COMM, 141 IOPMU_INBOUND_MSG0_MAX = 0xff, 142 /* iop-to-host messages */ 143 IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_0 = 0x100, 144 IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_MAX = 0x1ff, 145 IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_0 = 0x200, 146 IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_MAX = 0x2ff, 147 IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_0 = 0x300, 148 IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_MAX = 0x3ff, 149}; 150 151struct hpt_iop_request_header { 152 __le32 size; 153 __le32 type; 154 __le32 flags; 155 __le32 result; 156 __le32 context; /* host context */ 157 __le32 context_hi32; 158}; 159 160#define IOP_REQUEST_FLAG_SYNC_REQUEST 1 161#define IOP_REQUEST_FLAG_BIST_REQUEST 2 162#define IOP_REQUEST_FLAG_REMAPPED 4 163#define IOP_REQUEST_FLAG_OUTPUT_CONTEXT 8 164#define IOP_REQUEST_FLAG_ADDR_BITS 0x40 /* flags[31:16] is phy_addr[47:32] */ 165 166enum hpt_iop_request_type { 167 IOP_REQUEST_TYPE_GET_CONFIG = 0, 168 IOP_REQUEST_TYPE_SET_CONFIG, 169 IOP_REQUEST_TYPE_BLOCK_COMMAND, 170 IOP_REQUEST_TYPE_SCSI_COMMAND, 171 IOP_REQUEST_TYPE_IOCTL_COMMAND, 172 IOP_REQUEST_TYPE_MAX 173}; 174 175enum hpt_iop_result_type { 176 IOP_RESULT_PENDING = 0, 177 IOP_RESULT_SUCCESS, 178 IOP_RESULT_FAIL, 179 IOP_RESULT_BUSY, 180 IOP_RESULT_RESET, 181 IOP_RESULT_INVALID_REQUEST, 182 IOP_RESULT_BAD_TARGET, 183 IOP_RESULT_CHECK_CONDITION, 184}; 185 186struct hpt_iop_request_get_config { 187 struct hpt_iop_request_header header; 188 __le32 interface_version; 189 __le32 firmware_version; 190 __le32 max_requests; 191 __le32 request_size; 192 __le32 max_sg_count; 193 __le32 data_transfer_length; 194 __le32 alignment_mask; 195 __le32 max_devices; 196 __le32 sdram_size; 197}; 198 199struct hpt_iop_request_set_config { 200 struct hpt_iop_request_header header; 201 __le32 iop_id; 202 __le16 vbus_id; 203 __le16 max_host_request_size; 204 __le32 reserve[6]; 205}; 206 207struct hpt_iopsg { 208 __le32 size; 209 __le32 eot; /* non-zero: end of table */ 210 __le64 pci_address; 211}; 212 213struct hpt_iop_request_block_command { 214 struct hpt_iop_request_header header; 215 u8 channel; 216 u8 target; 217 u8 lun; 218 u8 pad1; 219 __le16 command; /* IOP_BLOCK_COMMAND_{READ,WRITE} */ 220 __le16 sectors; 221 __le64 lba; 222 struct hpt_iopsg sg_list[1]; 223}; 224 225#define IOP_BLOCK_COMMAND_READ 1 226#define IOP_BLOCK_COMMAND_WRITE 2 227#define IOP_BLOCK_COMMAND_VERIFY 3 228#define IOP_BLOCK_COMMAND_FLUSH 4 229#define IOP_BLOCK_COMMAND_SHUTDOWN 5 230 231struct hpt_iop_request_scsi_command { 232 struct hpt_iop_request_header header; 233 u8 channel; 234 u8 target; 235 u8 lun; 236 u8 pad1; 237 u8 cdb[16]; 238 __le32 dataxfer_length; 239 struct hpt_iopsg sg_list[1]; 240}; 241 242struct hpt_iop_request_ioctl_command { 243 struct hpt_iop_request_header header; 244 __le32 ioctl_code; 245 __le32 inbuf_size; 246 __le32 outbuf_size; 247 __le32 bytes_returned; 248 u8 buf[1]; 249 /* out data should be put at buf[(inbuf_size+3)&~3] */ 250}; 251 252#define HPTIOP_MAX_REQUESTS 256u 253 254struct hptiop_request { 255 struct hptiop_request *next; 256 void *req_virt; 257 u32 req_shifted_phy; 258 struct scsi_cmnd *scp; 259 int index; 260}; 261 262struct hpt_scsi_pointer { 263 int mapped; 264 int sgcnt; 265 dma_addr_t dma_handle; 266}; 267 268#define HPT_SCP(scp) ((struct hpt_scsi_pointer *)&(scp)->SCp) 269 270enum hptiop_family { 271 UNKNOWN_BASED_IOP, 272 INTEL_BASED_IOP, 273 MV_BASED_IOP, 274 MVFREY_BASED_IOP 275} ; 276 277struct hptiop_hba { 278 struct hptiop_adapter_ops *ops; 279 union { 280 struct { 281 struct hpt_iopmu_itl __iomem *iop; 282 void __iomem *plx; 283 } itl; 284 struct { 285 struct hpt_iopmv_regs *regs; 286 struct hpt_iopmu_mv __iomem *mu; 287 void *internal_req; 288 dma_addr_t internal_req_phy; 289 } mv; 290 struct { 291 struct hpt_iop_request_get_config __iomem *config; 292 struct hpt_iopmu_mvfrey __iomem *mu; 293 294 int internal_mem_size; 295 struct hptiop_request internal_req; 296 int list_count; 297 struct mvfrey_inlist_entry *inlist; 298 dma_addr_t inlist_phy; 299 __le32 inlist_wptr; 300 struct mvfrey_outlist_entry *outlist; 301 dma_addr_t outlist_phy; 302 __le32 *outlist_cptr; /* copy pointer shadow */ 303 dma_addr_t outlist_cptr_phy; 304 __le32 outlist_rptr; 305 } mvfrey; 306 } u; 307 308 struct Scsi_Host *host; 309 struct pci_dev *pcidev; 310 311 /* IOP config info */ 312 u32 interface_version; 313 u32 firmware_version; 314 u32 sdram_size; 315 u32 max_devices; 316 u32 max_requests; 317 u32 max_request_size; 318 u32 max_sg_descriptors; 319 320 u32 req_size; /* host-allocated request buffer size */ 321 322 u32 iopintf_v2: 1; 323 u32 initialized: 1; 324 u32 msg_done: 1; 325 326 struct hptiop_request * req_list; 327 struct hptiop_request reqs[HPTIOP_MAX_REQUESTS]; 328 329 /* used to free allocated dma area */ 330 void *dma_coherent; 331 dma_addr_t dma_coherent_handle; 332 333 atomic_t reset_count; 334 atomic_t resetting; 335 336 wait_queue_head_t reset_wq; 337 wait_queue_head_t ioctl_wq; 338}; 339 340struct hpt_ioctl_k { 341 struct hptiop_hba * hba; 342 u32 ioctl_code; 343 u32 inbuf_size; 344 u32 outbuf_size; 345 void *inbuf; 346 void *outbuf; 347 u32 *bytes_returned; 348 void (*done)(struct hpt_ioctl_k *); 349 int result; /* HPT_IOCTL_RESULT_ */ 350}; 351 352struct hptiop_adapter_ops { 353 enum hptiop_family family; 354 int (*iop_wait_ready)(struct hptiop_hba *hba, u32 millisec); 355 int (*internal_memalloc)(struct hptiop_hba *hba); 356 int (*internal_memfree)(struct hptiop_hba *hba); 357 int (*map_pci_bar)(struct hptiop_hba *hba); 358 void (*unmap_pci_bar)(struct hptiop_hba *hba); 359 void (*enable_intr)(struct hptiop_hba *hba); 360 void (*disable_intr)(struct hptiop_hba *hba); 361 int (*get_config)(struct hptiop_hba *hba, 362 struct hpt_iop_request_get_config *config); 363 int (*set_config)(struct hptiop_hba *hba, 364 struct hpt_iop_request_set_config *config); 365 int (*iop_intr)(struct hptiop_hba *hba); 366 void (*post_msg)(struct hptiop_hba *hba, u32 msg); 367 void (*post_req)(struct hptiop_hba *hba, struct hptiop_request *_req); 368 int hw_dma_bit_mask; 369 int (*reset_comm)(struct hptiop_hba *hba); 370 __le64 host_phy_flag; 371}; 372 373#define HPT_IOCTL_RESULT_OK 0 374#define HPT_IOCTL_RESULT_FAILED (-1) 375 376#if 0 377#define dprintk(fmt, args...) do { printk(fmt, ##args); } while(0) 378#else 379#define dprintk(fmt, args...) 380#endif 381 382#endif 383