xref: /freebsd/sys/dev/isci/isci.h (revision 3ef51c5fb9163f2aafb1c14729e06a8bf0c4d113)
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 };
90 
91 struct ISCI_DOMAIN {
92 	struct ISCI_CONTROLLER		*controller;
93 	SCI_DOMAIN_HANDLE_T		sci_object;
94 	uint8_t				index;
95 	struct ISCI_REMOTE_DEVICE	*da_remote_device;
96 };
97 
98 struct ISCI_MEMORY
99 {
100 	bus_addr_t	physical_address;
101 	bus_dma_tag_t	dma_tag;
102 	bus_dmamap_t	dma_map;
103 	POINTER_UINT	virtual_address;
104 	uint32_t	size;
105 	int		error;
106 };
107 
108 struct ISCI_INTERRUPT_INFO
109 {
110 	SCIC_CONTROLLER_HANDLER_METHODS_T 	*handlers;
111 	void					*interrupt_target_handle;
112 	struct resource				*res;
113 	int					rid;
114 	void					*tag;
115 
116 };
117 
118 struct ISCI_CONTROLLER
119 {
120 	struct isci_softc 	*isci;
121 	uint8_t			index;
122 	SCI_CONTROLLER_HANDLE_T	scif_controller_handle;
123 	struct ISCI_DOMAIN	domain[SCI_MAX_DOMAINS];
124 	BOOL			is_started;
125 	BOOL			has_been_scanned;
126 	uint32_t		initial_discovery_mask;
127 	BOOL			is_frozen;
128 	uint8_t			*remote_device_memory;
129 	struct ISCI_MEMORY	cached_controller_memory;
130 	struct ISCI_MEMORY	uncached_controller_memory;
131 	struct ISCI_MEMORY	request_memory;
132 	bus_dma_tag_t		buffer_dma_tag;
133 	struct mtx		lock;
134 	struct cam_sim		*sim;
135 	struct cam_path		*path;
136 	struct ISCI_REMOTE_DEVICE *remote_device[SCI_MAX_REMOTE_DEVICES];
137 	void 			*timer_memory;
138 	SCIC_OEM_PARAMETERS_T	oem_parameters;
139 	uint32_t		oem_parameters_version;
140 	uint32_t		queue_depth;
141 	uint32_t		sim_queue_depth;
142 	SCI_FAST_LIST_T		pending_device_reset_list;
143 
144 	SCI_MEMORY_DESCRIPTOR_LIST_HANDLE_T mdl;
145 
146 	SCI_POOL_CREATE(remote_device_pool, struct ISCI_REMOTE_DEVICE *, SCI_MAX_REMOTE_DEVICES);
147 	SCI_POOL_CREATE(request_pool, struct ISCI_REQUEST *, SCI_MAX_IO_REQUESTS);
148 	SCI_POOL_CREATE(timer_pool, struct ISCI_TIMER *, SCI_MAX_TIMERS);
149 };
150 
151 struct ISCI_REQUEST
152 {
153 	SCI_CONTROLLER_HANDLE_T		controller_handle;
154 	SCI_REMOTE_DEVICE_HANDLE_T	remote_device_handle;
155 	bus_dma_tag_t			dma_tag;
156 	bus_dmamap_t			dma_map;
157 	SCI_PHYSICAL_ADDRESS		physical_address;
158 	struct callout			timer;
159 };
160 
161 struct ISCI_IO_REQUEST
162 {
163 	struct ISCI_REQUEST	parent;
164 	SCI_IO_REQUEST_HANDLE_T	sci_object;
165 	union ccb		*ccb;
166 	uint32_t		num_segments;
167 	uint32_t		current_sge_index;
168 	bus_dma_segment_t	*sge;
169 };
170 
171 struct ISCI_TASK_REQUEST
172 {
173 	struct ISCI_REQUEST		parent;
174 	struct scsi_sense_data		sense_data;
175 	SCI_TASK_REQUEST_HANDLE_T	sci_object;
176 	union ccb			*ccb;
177 
178 };
179 
180 struct ISCI_PCI_BAR {
181 
182 	bus_space_tag_t		bus_tag;
183 	bus_space_handle_t	bus_handle;
184 	int			resource_id;
185 	struct resource		*resource;
186 
187 };
188 
189 /*
190  * One of these per allocated PCI device.
191  */
192 struct isci_softc {
193 
194 	struct ISCI_PCI_BAR			pci_bar[ISCI_NUM_PCI_BARS];
195 	struct ISCI_CONTROLLER			controllers[SCI_MAX_CONTROLLERS];
196 	SCI_LIBRARY_HANDLE_T			sci_library_handle;
197 	void *					sci_library_memory;
198 	SCIC_CONTROLLER_HANDLER_METHODS_T	handlers[4];
199 	struct ISCI_INTERRUPT_INFO		interrupt_info[4];
200 	uint32_t				controller_count;
201 	uint32_t				num_interrupts;
202 	uint32_t				coalesce_number;
203 	uint32_t				coalesce_timeout;
204 	device_t				device;
205 	SCI_PCI_COMMON_HEADER_T			pci_common_header;
206 	BOOL					oem_parameters_found;
207 	struct intr_config_hook			config_hook;
208 };
209 
210 int isci_allocate_resources(device_t device);
211 
212 int isci_allocate_dma_buffer(device_t device, struct ISCI_MEMORY *memory);
213 
214 void isci_remote_device_reset(struct ISCI_REMOTE_DEVICE *remote_device,
215     union ccb *ccb);
216 
217 /**
218  *  Returns the negotiated link rate (in KB/s) for the associated
219  *	remote device.  Used to fill out bitrate field for GET_TRANS_SETTINGS.
220  *	Will match the negotiated link rate for the lowest numbered local phy
221  *	in the port/domain containing this remote device.
222  */
223 uint32_t isci_remote_device_get_bitrate(
224     struct ISCI_REMOTE_DEVICE *remote_device);
225 
226 void isci_remote_device_freeze_lun_queue(
227     struct ISCI_REMOTE_DEVICE *remote_device, lun_id_t lun);
228 
229 void isci_remote_device_release_lun_queue(
230     struct ISCI_REMOTE_DEVICE *remote_device, lun_id_t lun);
231 
232 void isci_remote_device_release_device_queue(
233     struct ISCI_REMOTE_DEVICE * remote_device);
234 
235 void isci_request_construct(struct ISCI_REQUEST *request,
236     SCI_CONTROLLER_HANDLE_T scif_controller_handle,
237     bus_dma_tag_t io_buffer_dma_tag, bus_addr_t physical_address);
238 
239 #define isci_io_request_get_max_io_size() \
240 	((SCI_MAX_SCATTER_GATHER_ELEMENTS - 1) * PAGE_SIZE)
241 
242 #define isci_task_request_get_object_size() \
243 	(sizeof(struct ISCI_TASK_REQUEST) + scif_task_request_get_object_size())
244 
245 #define isci_io_request_get_object_size() \
246 	(sizeof(struct ISCI_IO_REQUEST) + scif_io_request_get_object_size())
247 
248 #define isci_request_get_object_size() \
249 	max( \
250 	    isci_task_request_get_object_size(), \
251 	    isci_io_request_get_object_size() \
252 	)
253 
254 
255 void isci_io_request_execute_scsi_io(union ccb *ccb,
256     struct ISCI_CONTROLLER *controller);
257 
258 #if __FreeBSD_version >= 900026
259 void isci_io_request_execute_smp_io(
260     union ccb *ccb, struct ISCI_CONTROLLER *controller);
261 #endif
262 
263 void isci_io_request_timeout(void *);
264 
265 void isci_get_oem_parameters(struct isci_softc *isci);
266 
267 void isci_io_request_complete(
268     SCI_CONTROLLER_HANDLE_T scif_controller,
269     SCI_REMOTE_DEVICE_HANDLE_T remote_device,
270     struct ISCI_IO_REQUEST * isci_request, SCI_IO_STATUS completion_status);
271 
272 void isci_task_request_complete(
273     SCI_CONTROLLER_HANDLE_T scif_controller,
274     SCI_REMOTE_DEVICE_HANDLE_T remote_device,
275     SCI_TASK_REQUEST_HANDLE_T io_request, SCI_TASK_STATUS completion_status);
276 
277 void isci_sysctl_initialize(struct isci_softc *isci);
278 
279 void isci_controller_construct(struct ISCI_CONTROLLER *controller,
280     struct isci_softc *isci);
281 
282 SCI_STATUS isci_controller_initialize(struct ISCI_CONTROLLER *controller);
283 
284 int isci_controller_allocate_memory(struct ISCI_CONTROLLER *controller);
285 
286 void isci_controller_domain_discovery_complete(
287     struct ISCI_CONTROLLER *isci_controller, struct ISCI_DOMAIN *isci_domain);
288 
289 int isci_controller_attach_to_cam(struct ISCI_CONTROLLER *controller);
290 
291 void isci_controller_start(void *controller);
292 
293 void isci_domain_construct(struct ISCI_DOMAIN *domain, uint32_t domain_index,
294     struct ISCI_CONTROLLER *controller);
295 
296 void isci_interrupt_setup(struct isci_softc *isci);
297 void isci_interrupt_poll_handler(struct ISCI_CONTROLLER *controller);
298 
299 void isci_log_message(uint32_t	verbosity, char *log_message_prefix,
300     char *log_message, ...);
301 
302 extern uint32_t g_isci_debug_level;
303