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            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 
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