xref: /illumos-gate/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_proto.h (revision d616ad8ecd9216bbe9e7c0d0b9fb3f00d4cd5505)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  *
21  *
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /*
26  * This file provides prototype function definitions.
27  */
28 #ifndef	_PMCS_PROTO_H
29 #define	_PMCS_PROTO_H
30 #ifdef	__cplusplus
31 extern "C" {
32 #endif
33 
34 
35 typedef enum {
36 	PMCS_PRT_DEBUG = 0,
37 	PMCS_PRT_DEBUG1,
38 	PMCS_PRT_DEBUG2,
39 	PMCS_PRT_DEBUG3,
40 	PMCS_PRT_DEBUG_CONFIG,
41 	PMCS_PRT_DEBUG_IPORT,
42 	PMCS_PRT_DEBUG_MAP,
43 	PMCS_PRT_DEBUG_UNDERFLOW,
44 	PMCS_PRT_DEBUG_SCSI_STATUS,
45 	PMCS_PRT_DEBUG_PHY_LOCKING,
46 	PMCS_PRT_DEBUG_DEV_STATE,
47 	PMCS_PRT_DEBUG_DEVEL,
48 	PMCS_PRT_INFO,
49 	PMCS_PRT_WARN,
50 	PMCS_PRT_ERR
51 } pmcs_prt_level_t;
52 
53 #define	pmcs_prt(pwp, level, fmt...) {			\
54 	int lvl = level;				\
55 	if (((pwp->debug_mask & (1 << lvl)) != 0) ||	\
56 	    (lvl > PMCS_PRT_DEBUG_DEVEL)) {		\
57 		pmcs_prt_impl(pwp, lvl, fmt);		\
58 	}						\
59 }
60 
61 /*PRINTFLIKE3*/
62 void
63 pmcs_prt_impl(pmcs_hw_t *, pmcs_prt_level_t, const char *, ...)
64     __KPRINTFLIKE(3);
65 
66 boolean_t pmcs_assign_device(pmcs_hw_t *, pmcs_xscsi_t *);
67 void pmcs_remove_device(pmcs_hw_t *, pmcs_phy_t *);
68 void pmcs_handle_dead_phys(pmcs_hw_t *);
69 
70 int pmcs_acquire_scratch(pmcs_hw_t *, boolean_t);
71 void pmcs_release_scratch(pmcs_hw_t *);
72 
73 /* get a work structure */
74 pmcwork_t *pmcs_gwork(pmcs_hw_t *, uint32_t, pmcs_phy_t *);
75 
76 /* put a work structure */
77 void pmcs_pwork(pmcs_hw_t *, struct pmcwork *);
78 
79 /* given a tag, find a work structure */
80 pmcwork_t *pmcs_tag2wp(pmcs_hw_t *, uint32_t);
81 
82 /*
83  * Abort function
84  */
85 int pmcs_abort(pmcs_hw_t *, pmcs_phy_t *, uint32_t, int, int);
86 
87 /*
88  * SSP Task Management Function
89  */
90 int pmcs_ssp_tmf(pmcs_hw_t *, pmcs_phy_t *, uint8_t, uint32_t, uint64_t,
91     uint32_t *);
92 
93 /*
94  * Abort NCQ function
95  */
96 int pmcs_sata_abort_ncq(pmcs_hw_t *, pmcs_phy_t *);
97 
98 /*
99  * Interrupt Functions
100  */
101 void pmcs_general_intr(pmcs_hw_t *);
102 void pmcs_iodone_intr(pmcs_hw_t *);
103 void pmcs_event_intr(pmcs_hw_t *);
104 void pmcs_timed_out(pmcs_hw_t *, uint32_t, const char *);
105 
106 /*
107  * Abort handler
108  */
109 int pmcs_abort_handler(pmcs_hw_t *);
110 
111 /*
112  * Deregister all expander connected devices
113  */
114 void pmcs_deregister_devices(pmcs_hw_t *, pmcs_phy_t *);
115 int pmcs_register_device(pmcs_hw_t *, pmcs_phy_t *);
116 void pmcs_deregister_device(pmcs_hw_t *, pmcs_phy_t *);
117 
118 /*
119  * endian transform a data structure
120  */
121 void pmcs_endian_transform(pmcs_hw_t *, void *, void *, const uint8_t *);
122 
123 /* get the connection rate string */
124 const char *pmcs_get_rate(unsigned int);
125 
126 /* get the device type string */
127 const char *pmcs_get_typename(pmcs_dtype_t pmcs_dtype);
128 
129 /* get the SAS Task Management function name */
130 const char *pmcs_tmf2str(int);
131 
132 /* get the PMC status string */
133 const char *pmcs_status_str(uint32_t);
134 
135 /*
136  * WWN to Byte Array and vice versa conversion
137  */
138 uint64_t pmcs_barray2wwn(uint8_t[8]);
139 void pmcs_wwn2barray(uint64_t, uint8_t[8]);
140 
141 /*
142  * Print f/w version
143  */
144 void pmcs_report_fwversion(pmcs_hw_t *);
145 
146 /*
147  * Build a device name.
148  */
149 void pmcs_phy_name(pmcs_hw_t *, pmcs_phy_t *, char *, size_t);
150 
151 /*
152  * Find a PHY by device_id
153  */
154 pmcs_phy_t *pmcs_find_phy_by_devid(pmcs_hw_t *, uint32_t);
155 
156 /*
157  * Find a PHY by wwn
158  */
159 pmcs_phy_t *pmcs_find_phy_by_wwn(pmcs_hw_t *, uint64_t);
160 
161 /*
162  * Find a PHY by sas_address
163  */
164 pmcs_phy_t *pmcs_find_phy_by_sas_address(pmcs_hw_t *, pmcs_iport_t *,
165     pmcs_phy_t *, char *);
166 
167 /*
168  * Print out a FIS
169  */
170 void pmcs_fis_dump(pmcs_hw_t *, fis_t);
171 
172 /*
173  * Print an IOMB
174  */
175 void pmcs_print_entry(pmcs_hw_t *, int, char *, void *);
176 
177 void pmcs_spinup_release(pmcs_hw_t *, pmcs_phy_t *phyp);
178 
179 /*
180  * Handler for events - can be called from interrupt level or from worker thread
181  */
182 void pmcs_ack_events(pmcs_hw_t *);
183 
184 /*
185  * This function does some initial setup and hardware validation
186  */
187 int pmcs_setup(pmcs_hw_t *);
188 
189 /*
190  * These functions start and stop the MPI (message passing interface)
191  */
192 int pmcs_start_mpi(pmcs_hw_t *);
193 int pmcs_stop_mpi(pmcs_hw_t *);
194 
195 /*
196  * This function checks firmware revisions against required revisions
197  * and attempts to flash new firmware (if possible).
198  */
199 int pmcs_firmware_update(pmcs_hw_t *);
200 
201 /*
202  * This function runs ECHO commands to test both interrupts and queues
203  */
204 int pmcs_echo_test(pmcs_hw_t *);
205 
206 /*
207  * These functions start, reset, and stop the physical chip PHYs
208  */
209 int pmcs_start_phy(pmcs_hw_t *, int, int, int);
210 int pmcs_start_phys(pmcs_hw_t *);
211 void pmcs_stop_phy(pmcs_hw_t *, int);
212 void pmcs_stop_phys(pmcs_hw_t *);
213 
214 /*
215  * These functions setup/teardown iport tgtmap
216  */
217 int pmcs_iport_tgtmap_create(pmcs_iport_t *);
218 int pmcs_iport_tgtmap_destroy(pmcs_iport_t *);
219 
220 /*
221  * Utility and wrapper functions for SAS_DIAG_EXECUTE
222  */
223 int pmcs_sas_diag_execute(pmcs_hw_t *, uint32_t, uint32_t, uint8_t);
224 int pmcs_get_diag_report(pmcs_hw_t *, uint32_t, uint8_t);
225 int pmcs_clear_diag_counters(pmcs_hw_t *, uint8_t);
226 
227 /*
228  * Get current firmware timestamp
229  */
230 int pmcs_get_time_stamp(pmcs_hw_t *, uint64_t *);
231 
232 /*
233  * Register Dump (including "internal" registers)
234  */
235 void pmcs_register_dump(pmcs_hw_t *);
236 void pmcs_iqp_trace(pmcs_hw_t *, uint32_t);
237 void pmcs_register_dump_int(pmcs_hw_t *);
238 int pmcs_dump_binary(pmcs_hw_t *, uint32_t *, uint32_t,
239     uint32_t, caddr_t, uint32_t);
240 int pmcs_dump_feregs(pmcs_hw_t *, uint32_t *, uint8_t,
241     caddr_t, uint32_t);
242 
243 /*
244  * This function perform a soft reset.
245  * Hard reset is platform specific.
246  */
247 int pmcs_soft_reset(pmcs_hw_t *, boolean_t);
248 
249 /*
250  * Some more reset functions
251  */
252 int pmcs_reset_dev(pmcs_hw_t *, pmcs_phy_t *, uint64_t);
253 int pmcs_reset_phy(pmcs_hw_t *, pmcs_phy_t *, uint8_t);
254 
255 /*
256  * These functions do topology configuration changes
257  */
258 void pmcs_discover(pmcs_hw_t *);
259 void pmcs_set_changed(pmcs_hw_t *, pmcs_phy_t *, boolean_t, int);
260 void pmcs_kill_changed(pmcs_hw_t *, pmcs_phy_t *, int);
261 void pmcs_clear_phy(pmcs_hw_t *, pmcs_phy_t *);
262 int pmcs_kill_device(pmcs_hw_t *, pmcs_phy_t *);
263 
264 /*
265  * Firmware flash function
266  */
267 int pmcs_fw_flash(pmcs_hw_t *, pmcs_fw_hdr_t *, uint32_t);
268 
269 /*
270  * Set a new value for the interrupt coalescing timer.  If it's being set
271  * to zero (disabling), then re-enable auto clear if necessary.  If it's
272  * being changed from zero, turn off auto clear if it was on.
273  */
274 typedef enum {
275 	DECREASE_TIMER = 0,
276 	INCREASE_TIMER
277 } pmcs_coal_timer_adj_t;
278 
279 void pmcs_check_intr_coal(void *arg);
280 void pmcs_set_intr_coal_timer(pmcs_hw_t *pwp, pmcs_coal_timer_adj_t adj);
281 
282 /*
283  * Misc supporting routines
284  */
285 void pmcs_check_iomb_status(pmcs_hw_t *pwp, uint32_t *iomb);
286 void pmcs_clear_xp(pmcs_hw_t *, pmcs_xscsi_t *);
287 
288 int pmcs_run_sata_cmd(pmcs_hw_t *, pmcs_phy_t *, fis_t, uint32_t,
289     uint32_t, uint32_t);
290 int pmcs_sata_identify(pmcs_hw_t *, pmcs_phy_t *);
291 void pmcs_sata_work(pmcs_hw_t *);
292 boolean_t pmcs_dma_setup(pmcs_hw_t *pwp, ddi_dma_attr_t *dma_attr,
293     ddi_acc_handle_t *acch, ddi_dma_handle_t *dmah, size_t length,
294     caddr_t *kvp, uint64_t *dma_addr);
295 void pmcs_fm_ereport(pmcs_hw_t *pwp, char *detail);
296 int pmcs_check_dma_handle(ddi_dma_handle_t handle);
297 int pmcs_check_acc_handle(ddi_acc_handle_t handle);
298 int pmcs_check_acc_dma_handle(pmcs_hw_t *pwp);
299 int pmcs_get_nvmd(pmcs_hw_t *pwp, pmcs_nvmd_type_t nvmd_type, uint8_t nvmd,
300     uint32_t offset, char *buf, uint32_t size_left);
301 boolean_t pmcs_set_nvmd(pmcs_hw_t *pwp, pmcs_nvmd_type_t nvmd_type,
302     uint8_t *buf, size_t len);
303 void pmcs_complete_work_impl(pmcs_hw_t *pwp, pmcwork_t *pwrk, uint32_t *iomb,
304     size_t amt);
305 void pmcs_flush_target_queues(pmcs_hw_t *, pmcs_xscsi_t *, uint8_t);
306 boolean_t pmcs_iport_has_targets(pmcs_hw_t *, pmcs_iport_t *);
307 void pmcs_free_dma_chunklist(pmcs_hw_t *);
308 int pmcs_get_dev_state(pmcs_hw_t *, pmcs_xscsi_t *, uint8_t *);
309 int pmcs_set_dev_state(pmcs_hw_t *, pmcs_xscsi_t *, uint8_t);
310 void pmcs_dev_state_recovery(pmcs_hw_t *, pmcs_phy_t *);
311 int pmcs_send_err_recovery_cmd(pmcs_hw_t *, uint8_t, pmcs_xscsi_t *);
312 void pmcs_start_ssp_event_recovery(pmcs_hw_t *pwp, pmcwork_t *pwrk,
313     uint32_t *iomb, size_t amt);
314 void pmcs_ssp_event_recovery(pmcs_hw_t *);
315 
316 pmcs_iport_t *pmcs_get_iport_by_phy(pmcs_hw_t *pwp, pmcs_phy_t *pptr);
317 void pmcs_rele_iport(pmcs_iport_t *iport);
318 int pmcs_iport_configure_phys(pmcs_iport_t *iport);
319 
320 void pmcs_lock_phy(pmcs_phy_t *);
321 void pmcs_unlock_phy(pmcs_phy_t *);
322 
323 void pmcs_destroy_target(pmcs_xscsi_t *);
324 void pmcs_phymap_activate(void *, char *, void **);
325 void pmcs_phymap_deactivate(void *, char *, void *);
326 void pmcs_add_phy_to_iport(pmcs_iport_t *, pmcs_phy_t *);
327 void pmcs_remove_phy_from_iport(pmcs_iport_t *, pmcs_phy_t *);
328 void pmcs_free_all_phys(pmcs_hw_t *, pmcs_phy_t *);
329 void pmcs_free_phys(pmcs_hw_t *, pmcs_phy_t *);
330 
331 int pmcs_phy_constructor(void *, void *, int);
332 void pmcs_phy_destructor(void *, void *);
333 
334 void pmcs_inc_phy_ref_count(pmcs_phy_t *);
335 void pmcs_dec_phy_ref_count(pmcs_phy_t *);
336 
337 /* Worker thread */
338 void pmcs_worker(void *);
339 
340 pmcs_phy_t *pmcs_get_root_phy(pmcs_phy_t *);
341 pmcs_xscsi_t *pmcs_get_target(pmcs_iport_t *, char *);
342 
343 void pmcs_fatal_handler(pmcs_hw_t *);
344 
345 /*
346  * Schedule device state recovery for this device immediately
347  */
348 void pmcs_start_dev_state_recovery(pmcs_xscsi_t *, pmcs_phy_t *);
349 
350 #ifdef	__cplusplus
351 }
352 #endif
353 #endif	/* _PMCS_PROTO_H */
354