1 | /* $NetBSD: mfivar.h,v 1.20 2012/09/19 21:24:29 bouyer Exp $ */ |
2 | /* $OpenBSD: mfivar.h,v 1.28 2006/08/31 18:18:46 marco Exp $ */ |
3 | /* |
4 | * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us> |
5 | * |
6 | * Permission to use, copy, modify, and distribute this software for any |
7 | * purpose with or without fee is hereby granted, provided that the above |
8 | * copyright notice and this permission notice appear in all copies. |
9 | * |
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 | */ |
18 | |
19 | #include <dev/sysmon/sysmonvar.h> |
20 | #include <sys/envsys.h> |
21 | #include <sys/workqueue.h> |
22 | |
23 | #define DEVNAME(_s) (device_xname((_s)->sc_dev)) |
24 | |
25 | /* #define MFI_DEBUG */ |
26 | #ifdef MFI_DEBUG |
27 | extern uint32_t mfi_debug; |
28 | #define DPRINTF(x...) do { if (mfi_debug) printf(x); } while(0) |
29 | #define DNPRINTF(n,x...) do { if (mfi_debug & n) printf(x); } while(0) |
30 | #define MFI_D_CMD 0x0001 |
31 | #define MFI_D_INTR 0x0002 |
32 | #define MFI_D_MISC 0x0004 |
33 | #define MFI_D_DMA 0x0008 |
34 | #define MFI_D_IOCTL 0x0010 |
35 | #define MFI_D_RW 0x0020 |
36 | #define MFI_D_MEM 0x0040 |
37 | #define MFI_D_CCB 0x0080 |
38 | #define MFI_D_SYNC 0x0100 |
39 | #else |
40 | #define DPRINTF(x, ...) |
41 | #define DNPRINTF(n, x, ...) |
42 | #endif |
43 | |
44 | struct mfi_mem { |
45 | bus_dmamap_t am_map; |
46 | bus_dma_segment_t am_seg; |
47 | size_t am_size; |
48 | void * am_kva; |
49 | }; |
50 | |
51 | #define MFIMEM_MAP(_am) ((_am)->am_map) |
52 | #define MFIMEM_DVA(_am) ((_am)->am_map->dm_segs[0].ds_addr) |
53 | #define MFIMEM_KVA(_am) ((void *)(_am)->am_kva) |
54 | |
55 | struct mfi_prod_cons { |
56 | uint32_t mpc_producer; |
57 | uint32_t mpc_consumer; |
58 | uint32_t mpc_reply_q[1]; /* compensate for 1 extra reply per spec */ |
59 | }; |
60 | |
61 | struct mfi_ccb { |
62 | struct mfi_softc *ccb_sc; |
63 | |
64 | union mfi_frame *ccb_frame; |
65 | paddr_t ccb_pframe; |
66 | uint32_t ccb_frame_size; |
67 | uint32_t ; |
68 | |
69 | struct mfi_sense *ccb_sense; |
70 | paddr_t ccb_psense; |
71 | |
72 | bus_dmamap_t ccb_dmamap; |
73 | |
74 | union mfi_sgl *ccb_sgl; |
75 | |
76 | /* data for sgl */ |
77 | void *ccb_data; |
78 | uint32_t ccb_len; |
79 | |
80 | uint32_t ccb_direction; |
81 | #define MFI_DATA_NONE 0 |
82 | #define MFI_DATA_IN 1 |
83 | #define MFI_DATA_OUT 2 |
84 | |
85 | /* |
86 | * memory structure used by ThunderBolt controller. |
87 | * The legacy structures above are used too, depending on |
88 | * the command type. |
89 | */ |
90 | union mfi_mpi2_request_descriptor ccb_tb_request_desc; |
91 | struct mfi_mpi2_request_raid_scsi_io *ccb_tb_io_request; |
92 | bus_addr_t ccb_tb_pio_request; |
93 | mpi2_sge_io_union *ccb_tb_sg_frame; |
94 | bus_addr_t ccb_tb_psg_frame; |
95 | |
96 | struct scsipi_xfer *ccb_xs; |
97 | |
98 | void (*ccb_done)(struct mfi_ccb *); |
99 | |
100 | volatile enum { |
101 | MFI_CCB_FREE, |
102 | MFI_CCB_READY, |
103 | MFI_CCB_RUNNING, |
104 | MFI_CCB_DONE |
105 | } ccb_state; |
106 | uint32_t ccb_flags; |
107 | #define MFI_CCB_F_ERR (1<<0) |
108 | #define MFI_CCB_F_TBOLT (1<<1) /* Thunderbolt descriptor */ |
109 | #define MFI_CCB_F_TBOLT_IO (1<<2) /* Thunderbolt I/O descriptor */ |
110 | TAILQ_ENTRY(mfi_ccb) ccb_link; |
111 | }; |
112 | |
113 | TAILQ_HEAD(mfi_ccb_list, mfi_ccb); |
114 | |
115 | enum mfi_iop { |
116 | MFI_IOP_XSCALE, |
117 | MFI_IOP_PPC, |
118 | MFI_IOP_GEN2, |
119 | MFI_IOP_SKINNY, |
120 | MFI_IOP_TBOLT |
121 | }; |
122 | |
123 | struct mfi_iop_ops { |
124 | uint32_t (*mio_fw_state)(struct mfi_softc *); |
125 | void (*mio_intr_dis)(struct mfi_softc *); |
126 | void (*mio_intr_ena)(struct mfi_softc *); |
127 | int (*mio_intr)(struct mfi_softc *); |
128 | void (*mio_post)(struct mfi_softc *, |
129 | struct mfi_ccb *); |
130 | int (*mio_ld_io)(struct mfi_ccb *, |
131 | struct scsipi_xfer *, uint64_t, uint32_t); |
132 | }; |
133 | |
134 | struct mfi_softc { |
135 | device_t sc_dev; |
136 | struct scsipi_channel sc_chan; |
137 | struct scsipi_adapter sc_adapt; |
138 | |
139 | const struct mfi_iop_ops *sc_iop; |
140 | enum mfi_iop sc_ioptype; |
141 | |
142 | void *sc_ih; |
143 | |
144 | bool sc_64bit_dma; |
145 | |
146 | bus_space_tag_t sc_iot; |
147 | bus_space_handle_t sc_ioh; |
148 | bus_size_t sc_size; |
149 | bus_dma_tag_t sc_dmat; |
150 | bus_dma_tag_t sc_datadmat; |
151 | |
152 | /* save some useful information for logical drives that is missing |
153 | * in sc_ld_list |
154 | */ |
155 | struct { |
156 | uint32_t ld_present; |
157 | char ld_dev[16]; /* device name sd? */ |
158 | } sc_ld[MFI_MAX_LD]; |
159 | |
160 | /* firmware determined max, totals and other information*/ |
161 | uint32_t sc_max_cmds; |
162 | uint32_t sc_max_sgl; |
163 | uint32_t sc_sgl_size; |
164 | uint32_t sc_max_ld; |
165 | uint32_t sc_ld_cnt; |
166 | /* XXX these struct should be local to mgmt function */ |
167 | struct mfi_ctrl_info sc_info; |
168 | struct mfi_ld_list sc_ld_list; |
169 | struct mfi_ld_details sc_ld_details; |
170 | |
171 | /* all commands */ |
172 | struct mfi_ccb *sc_ccb; |
173 | |
174 | /* producer/consumer pointers and reply queue */ |
175 | struct mfi_mem *sc_pcq; |
176 | |
177 | /* frame memory */ |
178 | struct mfi_mem *sc_frames; |
179 | uint32_t sc_frames_size; |
180 | |
181 | /* thunderbolt memory */ |
182 | struct mfi_mem *sc_tbolt_reqmsgpool; |
183 | |
184 | struct mfi_mem *sc_tbolt_ioc_init; |
185 | /* Virtual address of reply Frame Pool, part of sc_tbolt_reqmsgpool */ |
186 | int sc_reply_pool_size; |
187 | struct mfi_mpi2_reply_header* sc_reply_frame_pool; |
188 | bus_addr_t sc_reply_frame_busaddr; |
189 | uint8_t *sc_reply_pool_limit; |
190 | bus_addr_t sc_sg_frame_busaddr; |
191 | int sc_last_reply_idx; |
192 | |
193 | struct mfi_mem *sc_tbolt_verbuf; |
194 | |
195 | bool sc_MFA_enabled; |
196 | |
197 | /* workqueue for the ld sync command */ |
198 | struct workqueue *sc_ldsync_wq; |
199 | struct work sc_ldsync_wk; |
200 | struct mfi_ccb *sc_ldsync_ccb; |
201 | |
202 | /* sense memory */ |
203 | struct mfi_mem *sc_sense; |
204 | |
205 | struct mfi_ccb_list sc_ccb_freeq; |
206 | |
207 | struct sysmon_envsys *sc_sme; |
208 | envsys_data_t *sc_sensor; |
209 | bool sc_bbuok; |
210 | bool sc_running; |
211 | |
212 | device_t sc_child; |
213 | |
214 | /* for ioctl interface */ |
215 | bool sc_opened; |
216 | }; |
217 | |
218 | int mfi_rescan(device_t, const char *, const int *); |
219 | void mfi_childdetached(device_t, device_t); |
220 | int mfi_attach(struct mfi_softc *, enum mfi_iop); |
221 | int mfi_detach(struct mfi_softc *, int); |
222 | int mfi_intr(void *); |
223 | int mfi_tbolt_intrh(void *); |
224 | |