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
27extern 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
44struct 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
55struct 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
61struct 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 ccb_extra_frames;
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
113TAILQ_HEAD(mfi_ccb_list, mfi_ccb);
114
115enum mfi_iop {
116 MFI_IOP_XSCALE,
117 MFI_IOP_PPC,
118 MFI_IOP_GEN2,
119 MFI_IOP_SKINNY,
120 MFI_IOP_TBOLT
121};
122
123struct 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
134struct 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
218int mfi_rescan(device_t, const char *, const int *);
219void mfi_childdetached(device_t, device_t);
220int mfi_attach(struct mfi_softc *, enum mfi_iop);
221int mfi_detach(struct mfi_softc *, int);
222int mfi_intr(void *);
223int mfi_tbolt_intrh(void *);
224