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