PageRenderTime 45ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/sys/dev/hptiop/hptiop.h

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