]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/isci/isci.h
dts: Import DTS for arm64
[FreeBSD/FreeBSD.git] / sys / dev / isci / isci.h
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * BSD LICENSE
5  *
6  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  *   * Redistributions of source code must retain the above copyright
14  *     notice, this list of conditions and the following disclaimer.
15  *   * Redistributions in binary form must reproduce the above copyright
16  *     notice, this list of conditions and the following disclaimer in
17  *     the documentation and/or other materials provided with the
18  *     distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * $FreeBSD$
33  */
34
35 #ifndef _ISCI_H
36 #define _ISCI_H
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/kernel.h>
41 #include <sys/bus.h>
42 #include <sys/lock.h>
43 #include <sys/mutex.h>
44 #include <sys/types.h>
45 #include <sys/malloc.h>
46 #include <sys/rman.h>
47
48 #include <machine/bus.h>
49 #include <machine/resource.h>
50
51 #include <cam/cam.h>
52 #include <cam/cam_ccb.h>
53 #include <cam/cam_sim.h>
54 #include <cam/cam_xpt_sim.h>
55
56 #include <dev/isci/environment.h>
57 #include <dev/isci/scil/intel_pci.h>
58
59 #include <dev/isci/scil/sci_types.h>
60 #include <dev/isci/scil/sci_object.h>
61 #include <dev/isci/scil/sci_status.h>
62 #include <dev/isci/scil/sci_pool.h>
63 #include <dev/isci/scil/sci_fast_list.h>
64
65 #include <dev/isci/scil/sci_controller_constants.h>
66
67 #include <dev/isci/scil/scic_controller.h>
68 #include <dev/isci/scil/scic_config_parameters.h>
69
70 #define DEVICE2SOFTC(dev) ((struct isci_softc *) device_get_softc(dev))
71
72 #define DEVICE_TIMEOUT 1000
73 #define SCI_MAX_TIMERS  32
74
75 #define ISCI_NUM_PCI_BARS  2
76 #define ISCI_MAX_LUN             8
77
78 MALLOC_DECLARE(M_ISCI);
79
80 struct ISCI_TIMER {
81         struct callout          callout;
82         SCI_TIMER_CALLBACK_T    callback;
83         void                    *cookie;
84         BOOL                    is_started;
85 };
86
87 struct ISCI_REMOTE_DEVICE {
88         uint32_t                        index;
89         struct ISCI_DOMAIN              *domain;
90         SCI_REMOTE_DEVICE_HANDLE_T      sci_object;
91         BOOL                            is_resetting;
92         uint32_t                        frozen_lun_mask;
93         SCI_FAST_LIST_ELEMENT_T         pending_device_reset_element;
94
95         /*
96          * This queue maintains CCBs that have been returned with
97          *  SCI_IO_FAILURE_INVALID_STATE from the SCI layer.  These CCBs
98          *  need to be retried, but we cannot return CAM_REQUEUE_REQ because
99          *  this status gets passed all the way back up to users of the pass(4)
100          *  interface and breaks things like smartctl.  So instead, we queue
101          *  these CCBs internally.
102          */
103         TAILQ_HEAD(,ccb_hdr)            queued_ccbs;
104
105         /*
106          * Marker denoting this remote device needs its first queued ccb to
107          *  be retried.
108          */
109         BOOL                            release_queued_ccb;
110
111         /*
112          * Points to a CCB in the queue that is currently being processed by
113          *  SCIL.  This allows us to keep in flight CCBs in the queue so as to
114          *  maintain ordering (i.e. in case we retry an I/O and then find out
115          *  it needs to be retried again - it just keeps its same place in the
116          *  queue.
117          */
118         union ccb *                     queued_ccb_in_progress;
119 };
120
121 struct ISCI_DOMAIN {
122         struct ISCI_CONTROLLER          *controller;
123         SCI_DOMAIN_HANDLE_T             sci_object;
124         uint8_t                         index;
125         struct ISCI_REMOTE_DEVICE       *da_remote_device;
126 };
127
128 struct ISCI_MEMORY
129 {
130         bus_addr_t      physical_address;
131         bus_dma_tag_t   dma_tag;
132         bus_dmamap_t    dma_map;
133         POINTER_UINT    virtual_address;
134         uint32_t        size;
135         int             error;
136 };
137
138 struct ISCI_INTERRUPT_INFO
139 {
140         SCIC_CONTROLLER_HANDLER_METHODS_T       *handlers;
141         void                                    *interrupt_target_handle;
142         struct resource                         *res;
143         int                                     rid;
144         void                                    *tag;
145
146 };
147
148 struct ISCI_PHY
149 {
150         struct cdev             *cdev_fault;
151         struct cdev             *cdev_locate;
152         SCI_CONTROLLER_HANDLE_T handle;
153         int                     index;
154         int                     led_fault;
155         int                     led_locate;
156 };
157
158 struct ISCI_CONTROLLER
159 {
160         struct isci_softc       *isci;
161         uint8_t                 index;
162         SCI_CONTROLLER_HANDLE_T scif_controller_handle;
163         struct ISCI_DOMAIN      domain[SCI_MAX_DOMAINS];
164         BOOL                    is_started;
165         BOOL                    has_been_scanned;
166         uint32_t                initial_discovery_mask;
167         BOOL                    is_frozen;
168         BOOL                    release_queued_ccbs;
169         BOOL                    fail_on_task_timeout;
170         uint8_t                 *remote_device_memory;
171         struct ISCI_MEMORY      cached_controller_memory;
172         struct ISCI_MEMORY      uncached_controller_memory;
173         struct ISCI_MEMORY      request_memory;
174         bus_dma_tag_t           buffer_dma_tag;
175         struct mtx              lock;
176         struct cam_sim          *sim;
177         struct cam_path         *path;
178         struct ISCI_REMOTE_DEVICE *remote_device[SCI_MAX_REMOTE_DEVICES];
179         void                    *timer_memory;
180         SCIC_OEM_PARAMETERS_T   oem_parameters;
181         uint32_t                oem_parameters_version;
182         uint32_t                queue_depth;
183         uint32_t                sim_queue_depth;
184         SCI_FAST_LIST_T         pending_device_reset_list;
185         struct ISCI_PHY         phys[SCI_MAX_PHYS];
186
187         SCI_MEMORY_DESCRIPTOR_LIST_HANDLE_T mdl;
188
189         SCI_POOL_CREATE(remote_device_pool, struct ISCI_REMOTE_DEVICE *, SCI_MAX_REMOTE_DEVICES);
190         SCI_POOL_CREATE(request_pool, struct ISCI_REQUEST *, SCI_MAX_IO_REQUESTS);
191         SCI_POOL_CREATE(timer_pool, struct ISCI_TIMER *, SCI_MAX_TIMERS);
192         SCI_POOL_CREATE(unmap_buffer_pool, void *, SCI_MAX_REMOTE_DEVICES);
193 };
194
195 struct ISCI_REQUEST
196 {
197         SCI_CONTROLLER_HANDLE_T         controller_handle;
198         SCI_REMOTE_DEVICE_HANDLE_T      remote_device_handle;
199         bus_dma_tag_t                   dma_tag;
200         bus_dmamap_t                    dma_map;
201         SCI_PHYSICAL_ADDRESS            physical_address;
202         struct callout                  timer;
203 };
204
205 struct ISCI_IO_REQUEST
206 {
207         struct ISCI_REQUEST     parent;
208         SCI_IO_REQUEST_HANDLE_T sci_object;
209         union ccb               *ccb;
210         uint32_t                num_segments;
211         uint32_t                current_sge_index;
212         bus_dma_segment_t       *sge;
213 };
214
215 struct ISCI_TASK_REQUEST
216 {
217         struct ISCI_REQUEST             parent;
218         struct scsi_sense_data          sense_data;
219         SCI_TASK_REQUEST_HANDLE_T       sci_object;
220         union ccb                       *ccb;
221
222 };
223
224 struct ISCI_PCI_BAR {
225
226         bus_space_tag_t         bus_tag;
227         bus_space_handle_t      bus_handle;
228         int                     resource_id;
229         struct resource         *resource;
230
231 };
232
233 /*
234  * One of these per allocated PCI device.
235  */
236 struct isci_softc {
237
238         struct ISCI_PCI_BAR                     pci_bar[ISCI_NUM_PCI_BARS];
239         struct ISCI_CONTROLLER                  controllers[SCI_MAX_CONTROLLERS];
240         SCI_LIBRARY_HANDLE_T                    sci_library_handle;
241         void *                                  sci_library_memory;
242         SCIC_CONTROLLER_HANDLER_METHODS_T       handlers[4];
243         struct ISCI_INTERRUPT_INFO              interrupt_info[4];
244         uint32_t                                controller_count;
245         uint32_t                                num_interrupts;
246         uint32_t                                coalesce_number;
247         uint32_t                                coalesce_timeout;
248         device_t                                device;
249         SCI_PCI_COMMON_HEADER_T                 pci_common_header;
250         BOOL                                    oem_parameters_found;
251         struct intr_config_hook                 config_hook;
252 };
253
254 int isci_allocate_resources(device_t device);
255
256 int isci_allocate_dma_buffer(device_t device, struct ISCI_MEMORY *memory);
257
258 void isci_remote_device_reset(struct ISCI_REMOTE_DEVICE *remote_device,
259     union ccb *ccb);
260
261 /**
262  *  Returns the negotiated link rate (in KB/s) for the associated
263  *      remote device.  Used to fill out bitrate field for GET_TRANS_SETTINGS.
264  *      Will match the negotiated link rate for the lowest numbered local phy
265  *      in the port/domain containing this remote device.
266  */
267 uint32_t isci_remote_device_get_bitrate(
268     struct ISCI_REMOTE_DEVICE *remote_device);
269
270 void isci_remote_device_freeze_lun_queue(
271     struct ISCI_REMOTE_DEVICE *remote_device, lun_id_t lun);
272
273 void isci_remote_device_release_lun_queue(
274     struct ISCI_REMOTE_DEVICE *remote_device, lun_id_t lun);
275
276 void isci_remote_device_release_device_queue(
277     struct ISCI_REMOTE_DEVICE * remote_device);
278
279 void isci_request_construct(struct ISCI_REQUEST *request,
280     SCI_CONTROLLER_HANDLE_T scif_controller_handle,
281     bus_dma_tag_t io_buffer_dma_tag, bus_addr_t physical_address);
282
283 #define isci_io_request_get_max_io_size() \
284         ((SCI_MAX_SCATTER_GATHER_ELEMENTS - 1) * PAGE_SIZE)
285
286 #define isci_task_request_get_object_size() \
287         (sizeof(struct ISCI_TASK_REQUEST) + scif_task_request_get_object_size())
288
289 #define isci_io_request_get_object_size() \
290         (sizeof(struct ISCI_IO_REQUEST) + scif_io_request_get_object_size())
291
292 #define isci_request_get_object_size() \
293         max( \
294             isci_task_request_get_object_size(), \
295             isci_io_request_get_object_size() \
296         )
297
298
299 void isci_io_request_execute_scsi_io(union ccb *ccb,
300     struct ISCI_CONTROLLER *controller);
301
302 #if __FreeBSD_version >= 900026
303 void isci_io_request_execute_smp_io(
304     union ccb *ccb, struct ISCI_CONTROLLER *controller);
305 #endif
306
307 void isci_io_request_timeout(void *);
308
309 void isci_get_oem_parameters(struct isci_softc *isci);
310
311 void isci_io_request_complete(
312     SCI_CONTROLLER_HANDLE_T scif_controller,
313     SCI_REMOTE_DEVICE_HANDLE_T remote_device,
314     struct ISCI_IO_REQUEST * isci_request, SCI_IO_STATUS completion_status);
315
316 void isci_task_request_complete(
317     SCI_CONTROLLER_HANDLE_T scif_controller,
318     SCI_REMOTE_DEVICE_HANDLE_T remote_device,
319     SCI_TASK_REQUEST_HANDLE_T io_request, SCI_TASK_STATUS completion_status);
320
321 void isci_sysctl_initialize(struct isci_softc *isci);
322
323 void isci_controller_construct(struct ISCI_CONTROLLER *controller,
324     struct isci_softc *isci);
325
326 SCI_STATUS isci_controller_initialize(struct ISCI_CONTROLLER *controller);
327
328 int isci_controller_allocate_memory(struct ISCI_CONTROLLER *controller);
329
330 void isci_controller_domain_discovery_complete(
331     struct ISCI_CONTROLLER *isci_controller, struct ISCI_DOMAIN *isci_domain);
332
333 int isci_controller_attach_to_cam(struct ISCI_CONTROLLER *controller);
334
335 void isci_controller_start(void *controller);
336
337 void isci_controller_release_queued_ccbs(struct ISCI_CONTROLLER *controller);
338
339 void isci_domain_construct(struct ISCI_DOMAIN *domain, uint32_t domain_index,
340     struct ISCI_CONTROLLER *controller);
341
342 void isci_interrupt_setup(struct isci_softc *isci);
343 void isci_interrupt_poll_handler(struct ISCI_CONTROLLER *controller);
344
345 void isci_log_message(uint32_t  verbosity, char *log_message_prefix,
346     char *log_message, ...);
347
348 extern uint32_t g_isci_debug_level;
349
350 #endif /* #ifndef _ISCI_H */