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