isci.h revision 230843
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
73MALLOC_DECLARE(M_ISCI);
74
75struct ISCI_TIMER {
76	struct callout		callout;
77	SCI_TIMER_CALLBACK_T	callback;
78	void			*cookie;
79	BOOL			is_started;
80};
81
82struct 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
91struct ISCI_DOMAIN {
92	struct ISCI_CONTROLLER	*controller;
93	SCI_DOMAIN_HANDLE_T	sci_object;
94	uint8_t			index;
95
96};
97
98struct 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
108struct 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
118struct 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	uint32_t		initial_discovery_mask;
126	BOOL			is_frozen;
127	uint8_t			*remote_device_memory;
128	struct ISCI_MEMORY	cached_controller_memory;
129	struct ISCI_MEMORY	uncached_controller_memory;
130	struct ISCI_MEMORY	request_memory;
131	bus_dma_tag_t		buffer_dma_tag;
132	struct mtx		lock;
133	struct cam_sim		*sim;
134	struct cam_path		*path;
135	struct ISCI_REMOTE_DEVICE *remote_device[SCI_MAX_REMOTE_DEVICES];
136	void 			*timer_memory;
137	SCIC_OEM_PARAMETERS_T	oem_parameters;
138	uint32_t		oem_parameters_version;
139	uint32_t		queue_depth;
140	uint32_t		sim_queue_depth;
141	SCI_FAST_LIST_T		pending_device_reset_list;
142
143	SCI_MEMORY_DESCRIPTOR_LIST_HANDLE_T mdl;
144
145	SCI_POOL_CREATE(remote_device_pool, struct ISCI_REMOTE_DEVICE *, SCI_MAX_REMOTE_DEVICES);
146	SCI_POOL_CREATE(request_pool, struct ISCI_REQUEST *, SCI_MAX_IO_REQUESTS);
147	SCI_POOL_CREATE(timer_pool, struct ISCI_TIMER *, SCI_MAX_TIMERS);
148};
149
150struct ISCI_REQUEST
151{
152	SCI_CONTROLLER_HANDLE_T		controller_handle;
153	SCI_REMOTE_DEVICE_HANDLE_T	remote_device_handle;
154	bus_dma_tag_t			dma_tag;
155	bus_dmamap_t			dma_map;
156	SCI_PHYSICAL_ADDRESS		physical_address;
157	struct callout			timer;
158};
159
160struct ISCI_IO_REQUEST
161{
162	struct ISCI_REQUEST	parent;
163	SCI_STATUS		status;
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
171struct 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
180struct 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 */
192struct 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
210int isci_allocate_resources(device_t device);
211
212int isci_allocate_dma_buffer(device_t device, struct ISCI_MEMORY *memory);
213
214void 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 */
223uint32_t isci_remote_device_get_bitrate(
224    struct ISCI_REMOTE_DEVICE *remote_device);
225
226void isci_remote_device_freeze_lun_queue(
227    struct ISCI_REMOTE_DEVICE *remote_device, lun_id_t lun);
228
229void isci_remote_device_release_lun_queue(
230    struct ISCI_REMOTE_DEVICE *remote_device, lun_id_t lun);
231
232void isci_remote_device_release_device_queue(
233    struct ISCI_REMOTE_DEVICE * remote_device);
234
235void 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
255void isci_io_request_execute_scsi_io(union ccb *ccb,
256    struct ISCI_CONTROLLER *controller);
257
258#if __FreeBSD_version >= 900026
259void isci_io_request_execute_smp_io(
260    union ccb *ccb, struct ISCI_CONTROLLER *controller);
261#endif
262
263void isci_io_request_timeout(void *);
264
265void isci_get_oem_parameters(struct isci_softc *isci);
266
267void 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
272void 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
277void isci_sysctl_initialize(struct isci_softc *isci);
278
279void isci_controller_construct(struct ISCI_CONTROLLER *controller,
280    struct isci_softc *isci);
281
282SCI_STATUS isci_controller_initialize(struct ISCI_CONTROLLER *controller);
283
284int isci_controller_allocate_memory(struct ISCI_CONTROLLER *controller);
285
286void isci_controller_domain_discovery_complete(
287    struct ISCI_CONTROLLER *isci_controller, struct ISCI_DOMAIN *isci_domain);
288
289int isci_controller_attach_to_cam(struct ISCI_CONTROLLER *controller);
290
291void isci_controller_start(void *controller);
292
293void isci_domain_construct(struct ISCI_DOMAIN *domain, uint32_t domain_index,
294    struct ISCI_CONTROLLER *controller);
295
296void isci_interrupt_setup(struct isci_softc *isci);
297void isci_interrupt_poll_handler(struct ISCI_CONTROLLER *controller);
298
299void isci_log_message(uint32_t	verbosity, char *log_message_prefix,
300    char *log_message, ...);
301
302extern uint32_t g_isci_debug_level;
303