xref: /illumos-gate/usr/src/uts/common/io/1394/adapters/hci1394_attach.c (revision 4c87aefe8930bd07275b8dd2e96ea5f24d93a52e)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * hci1394_attach.c
28  *    HBA attach() routine with associated funtions.
29  */
30 
31 #include <sys/types.h>
32 #include <sys/kmem.h>
33 #include <sys/conf.h>
34 #include <sys/ddi.h>
35 #include <sys/modctl.h>
36 #include <sys/stat.h>
37 #include <sys/sunddi.h>
38 #include <sys/cmn_err.h>
39 #include <sys/pci.h>
40 
41 #include <sys/1394/h1394.h>
42 #include <sys/1394/adapters/hci1394.h>
43 #include <sys/1394/adapters/hci1394_extern.h>
44 
45 
46 /*
47  * Attach State Information. These states are used to track the status of the
48  * attach.  They are bit offsets.
49  */
50 #define	STATE_ZALLOC		0
51 #define	STATE_ISR_INIT		1
52 #define	STATE_MINOR_NODE	2
53 #define	STATE_HW_INIT		3
54 #define	STATE_PHASE2		4
55 #define	STATE_POWER_INIT	5
56 #define	STATE_H1394_ATTACH	6
57 #define	STATE_ISR_HANDLER	7
58 #define	STATE_STARTUP		8
59 
60 static void hci1394_statebit_set(uint64_t *state, uint_t statebit);
61 static boolean_t hci1394_statebit_tst(uint64_t state, uint_t statebit);
62 
63 static void hci1394_cleanup(hci1394_state_t *soft_state, uint64_t attach_state);
64 
65 static int hci1394_hardware_init(hci1394_state_t *soft_state);
66 static int hci1394_hardware_resume(hci1394_state_t *soft_state);
67 
68 static int hci1394_pci_init(hci1394_state_t *soft_state);
69 static void hci1394_pci_resume(hci1394_state_t *soft_state);
70 
71 static void hci1394_soft_state_phase1_init(hci1394_state_t *soft_state,
72     dev_info_t *dip, int instance);
73 static void hci1394_soft_state_phase2_init(hci1394_state_t *soft_state);
74 
75 static int hci1394_resmap_get(hci1394_state_t *soft_state);
76 static void hci1394_resmap_free(hci1394_state_t *soft_state);
77 
78 
79 
80 int
81 hci1394_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
82 {
83 	hci1394_state_t *soft_state;
84 	uint64_t attach_state = 0;
85 	int instance;
86 	int status;
87 
88 
89 	TNF_PROBE_0_DEBUG(hci1394_attach_enter, HCI1394_TNF_HAL_STACK, "");
90 
91 	switch (cmd) {
92 	case DDI_ATTACH:
93 		instance = ddi_get_instance(dip);
94 		status = ddi_soft_state_zalloc(hci1394_statep, instance);
95 		if (status != DDI_SUCCESS) {
96 			TNF_PROBE_1(hci1394_attach_ssz_fail,
97 			    HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
98 			    "ddi_soft_state_zalloc() failed");
99 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
100 			    HCI1394_TNF_HAL_STACK, "");
101 			return (DDI_FAILURE);
102 		}
103 		soft_state = ddi_get_soft_state(hci1394_statep, instance);
104 		if (soft_state == NULL) {
105 			ddi_soft_state_free(hci1394_statep, instance);
106 			TNF_PROBE_1(hci1394_attach_gss_fail,
107 			    HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
108 			    "ddi_get_soft_state() failed");
109 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
110 			    HCI1394_TNF_HAL_STACK, "");
111 			return (DDI_FAILURE);
112 		}
113 		hci1394_statebit_set(&attach_state, STATE_ZALLOC);
114 
115 		hci1394_soft_state_phase1_init(soft_state, dip, instance);
116 
117 		/* get iblock cookie, other interrupt init stuff */
118 		status = hci1394_isr_init(soft_state);
119 		if (status != DDI_SUCCESS) {
120 			hci1394_cleanup(soft_state, attach_state);
121 			TNF_PROBE_0(hci1394_attach_isr_fail,
122 			    HCI1394_TNF_HAL_ERROR, "");
123 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
124 			    HCI1394_TNF_HAL_STACK, "");
125 			return (DDI_FAILURE);
126 		}
127 		hci1394_statebit_set(&attach_state, STATE_ISR_INIT);
128 
129 		status = ddi_create_minor_node(dip, "devctl", S_IFCHR,
130 		    instance, DDI_NT_NEXUS, 0);
131 		if (status != DDI_SUCCESS) {
132 			hci1394_cleanup(soft_state, attach_state);
133 			TNF_PROBE_0(hci1394_attach_cmn_fail,
134 			    HCI1394_TNF_HAL_ERROR, "");
135 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
136 			    HCI1394_TNF_HAL_STACK, "");
137 			return (DDI_FAILURE);
138 		}
139 		hci1394_statebit_set(&attach_state, STATE_MINOR_NODE);
140 
141 		status = hci1394_hardware_init(soft_state);
142 		if (status != DDI_SUCCESS) {
143 			hci1394_cleanup(soft_state, attach_state);
144 			TNF_PROBE_0(hci1394_attach_hwi_fail,
145 			    HCI1394_TNF_HAL_ERROR, "");
146 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
147 			    HCI1394_TNF_HAL_STACK, "");
148 			return (DDI_FAILURE);
149 		}
150 		hci1394_statebit_set(&attach_state, STATE_HW_INIT);
151 
152 		hci1394_soft_state_phase2_init(soft_state);
153 		hci1394_statebit_set(&attach_state, STATE_PHASE2);
154 
155 		/* build up the reserved addresses map */
156 		status = hci1394_resmap_get(soft_state);
157 		if (status != DDI_SUCCESS) {
158 			hci1394_cleanup(soft_state, attach_state);
159 			TNF_PROBE_0(hci1394_attach_rmg_fail,
160 			    HCI1394_TNF_HAL_ERROR, "");
161 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
162 			    HCI1394_TNF_HAL_STACK, "");
163 			return (DDI_FAILURE);
164 		}
165 
166 		/* "attach" to the Services Layer */
167 		status = h1394_attach(&soft_state->halinfo, DDI_ATTACH,
168 		    &soft_state->drvinfo.di_sl_private);
169 		if (status != DDI_SUCCESS) {
170 			hci1394_resmap_free(soft_state);
171 			hci1394_cleanup(soft_state, attach_state);
172 			TNF_PROBE_0(hci1394_attach_ha_fail,
173 			    HCI1394_TNF_HAL_ERROR, "");
174 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
175 			    HCI1394_TNF_HAL_STACK, "");
176 			return (DDI_FAILURE);
177 		}
178 		/* free the reserved addresses map */
179 		hci1394_resmap_free(soft_state);
180 
181 		hci1394_statebit_set(&attach_state, STATE_H1394_ATTACH);
182 		status = hci1394_isr_handler_init(soft_state);
183 		if (status != DDI_SUCCESS) {
184 			hci1394_cleanup(soft_state, attach_state);
185 			TNF_PROBE_0(hci1394_attach_ih_fail,
186 			    HCI1394_TNF_HAL_ERROR, "");
187 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
188 			    HCI1394_TNF_HAL_STACK, "");
189 			return (DDI_FAILURE);
190 		}
191 		hci1394_statebit_set(&attach_state, STATE_ISR_HANDLER);
192 
193 		/* Report that driver was loaded */
194 		ddi_report_dev(dip);
195 
196 		/*
197 		 * Turn on link, Reset Bus, enable interrupts.  Should be the
198 		 * last routine called in attach. The statebit for starup must
199 		 * be set before startup is called since startup enables
200 		 * interrupts.
201 		 */
202 		hci1394_statebit_set(&attach_state, STATE_STARTUP);
203 		status = hci1394_ohci_startup(soft_state->ohci);
204 		if (status != DDI_SUCCESS) {
205 			hci1394_cleanup(soft_state, attach_state);
206 			TNF_PROBE_0(hci1394_attach_str_fail,
207 			    HCI1394_TNF_HAL_ERROR, "");
208 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
209 			    HCI1394_TNF_HAL_STACK, "");
210 			return (DDI_FAILURE);
211 		}
212 		TNF_PROBE_0_DEBUG(hci1394_attach_exit, HCI1394_TNF_HAL_STACK,
213 		    "");
214 
215 		return (DDI_SUCCESS);
216 
217 	case DDI_RESUME:
218 		instance = ddi_get_instance(dip);
219 		soft_state = ddi_get_soft_state(hci1394_statep, instance);
220 		if (soft_state == NULL) {
221 			TNF_PROBE_1(hci1394_attach_resgss_fail,
222 			    HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
223 			    "ddi_get_soft_state() failed");
224 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
225 			    HCI1394_TNF_HAL_STACK, "");
226 			return (DDI_FAILURE);
227 		}
228 
229 		status = hci1394_hardware_resume(soft_state);
230 		if (status != DDI_SUCCESS) {
231 			TNF_PROBE_1(hci1394_attach_res_hwr_fail,
232 			    HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
233 			    "hardware failed to resume");
234 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
235 			    HCI1394_TNF_HAL_STACK, "");
236 			return (DDI_FAILURE);
237 		}
238 
239 		/*
240 		 * set our state back to initial.  The next bus reset were
241 		 * about to generate will set us in motion.
242 		 */
243 		soft_state->drvinfo.di_drvstate.ds_state = HCI1394_INITIAL;
244 
245 		/* turn on the link, enable interrupts, reset the bus */
246 		status = hci1394_ohci_startup(soft_state->ohci);
247 		if (status != DDI_SUCCESS) {
248 			TNF_PROBE_1(hci1394_attach_res_str_fail,
249 			    HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
250 			    "hci1394_ohci_startup() failed");
251 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
252 			    HCI1394_TNF_HAL_STACK, "");
253 			return (DDI_FAILURE);
254 		}
255 
256 		/* tell the Services Layer that we are resuming */
257 		status = h1394_attach(&soft_state->halinfo, DDI_RESUME,
258 		    &soft_state->drvinfo.di_sl_private);
259 		if (status != DDI_SUCCESS) {
260 			TNF_PROBE_0(hci1394_attach_res_ha_fail,
261 			    HCI1394_TNF_HAL_ERROR, "");
262 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
263 			    HCI1394_TNF_HAL_STACK, "");
264 			return (DDI_FAILURE);
265 		}
266 
267 		TNF_PROBE_0_DEBUG(hci1394_attach_exit, HCI1394_TNF_HAL_STACK,
268 		    "");
269 		return (DDI_SUCCESS);
270 
271 	default:
272 		TNF_PROBE_0(h1394_attach_default_fail, HCI1394_TNF_HAL_ERROR,
273 		    "");
274 		break;
275 	}
276 
277 	TNF_PROBE_0_DEBUG(hci1394_attach_exit, HCI1394_TNF_HAL_STACK, "");
278 
279 	return (DDI_FAILURE);
280 }
281 
282 
283 /*
284  * hci1394_soft_state_phase1_init()
285  *    First part soft_state initialization.  This should be called before any
286  *    other initialization routines are called.  Anything that requires cleanup
287  *    on detach or after an attach failure should be setup in phase2 init (i.e.
288  *    mutex's, cv's, etc.)
289  */
290 static void
291 hci1394_soft_state_phase1_init(hci1394_state_t *soft_state, dev_info_t *dip,
292     int instance)
293 {
294 	ASSERT(soft_state != NULL);
295 	TNF_PROBE_0_DEBUG(hci1394_soft_state_phase1_init_enter,
296 	    HCI1394_TNF_HAL_STACK, "");
297 
298 	soft_state->drvinfo.di_dip = dip;
299 	soft_state->drvinfo.di_instance = instance;
300 
301 	/* current bus generation */
302 	soft_state->drvinfo.di_gencnt = 0;
303 
304 	soft_state->drvinfo.di_sl_private = NULL;
305 
306 	/* initialize statistics */
307 	soft_state->drvinfo.di_stats.st_bus_reset_count = 0;
308 	soft_state->drvinfo.di_stats.st_selfid_count = 0;
309 	soft_state->drvinfo.di_stats.st_phy_isr = 0;
310 	soft_state->drvinfo.di_stats.st_phy_loop_err = 0;
311 	soft_state->drvinfo.di_stats.st_phy_pwrfail_err = 0;
312 	soft_state->drvinfo.di_stats.st_phy_timeout_err = 0;
313 	soft_state->drvinfo.di_stats.st_phy_portevt_err = 0;
314 
315 	soft_state->swap_data = B_FALSE;
316 	soft_state->sl_selfid_buf = NULL;
317 
318 	/* halinfo is what is passed up to the Services Layer */
319 	soft_state->halinfo.hal_private = soft_state;
320 	soft_state->halinfo.dip = soft_state->drvinfo.di_dip;
321 	soft_state->halinfo.hal_events = hci1394_evts;
322 	soft_state->halinfo.max_generation = OHCI_BUSGEN_MAX;
323 	soft_state->halinfo.addr_map_num_entries = HCI1394_ADDR_MAP_SIZE;
324 	soft_state->halinfo.addr_map = hci1394_addr_map;
325 	hci1394_buf_attr_get(&soft_state->halinfo.dma_attr);
326 
327 	TNF_PROBE_0_DEBUG(hci1394_soft_state_phase1_init_exit,
328 	    HCI1394_TNF_HAL_STACK, "");
329 }
330 
331 
332 /*
333  * hci1394_soft_state_phase2_init()
334  *    Second part of soft_state initialization.  This should be called after a
335  *    successful hardware_init() and before the call to h1394_attach().
336  */
337 static void
338 hci1394_soft_state_phase2_init(hci1394_state_t *soft_state)
339 {
340 	ASSERT(soft_state != NULL);
341 	TNF_PROBE_0_DEBUG(hci1394_soft_state_phase2_init_enter,
342 	    HCI1394_TNF_HAL_STACK, "");
343 
344 	/*
345 	 * Setup our initial driver state.  This requires the HW iblock
346 	 * cookie so this must be setup in phase2_init()
347 	 */
348 	soft_state->drvinfo.di_drvstate.ds_state = HCI1394_INITIAL;
349 	mutex_init(&soft_state->drvinfo.di_drvstate.ds_mutex, NULL,
350 	    MUTEX_DRIVER, soft_state->drvinfo.di_iblock_cookie);
351 
352 	/*
353 	 * halinfo.acc_attr tells the services layer what our buffer access
354 	 * attributes are.  drvinfo.di_buf_attr it initialized in pci_init so
355 	 * this must be setup in phase2_init()
356 	 */
357 	soft_state->halinfo.acc_attr = soft_state->drvinfo.di_buf_attr;
358 
359 	/*
360 	 * halinfo.hw_interrupt tells the services layer what our
361 	 * iblock_cookie is. drvinfo.di_iblock_cookie is setup in isr_init so
362 	 * this must be setup in phase2_init()
363 	 */
364 	soft_state->halinfo.hw_interrupt = soft_state->drvinfo.di_iblock_cookie;
365 
366 	/*
367 	 * Read in our node capabilities.  Since we are calling into csr
368 	 * we must have first called hardware_init().  Therefore, this must
369 	 * be in phase2_init().
370 	 */
371 	hci1394_csr_node_capabilities(soft_state->csr,
372 	    &soft_state->halinfo.node_capabilities);
373 
374 	/*
375 	 * Read in our bus capabilities.  Since we are calling into ohci
376 	 * we must have first called hardware_init().  Therefore, this must
377 	 * be in phase2_init().
378 	 */
379 	hci1394_ohci_bus_capabilities(soft_state->ohci,
380 	    &soft_state->halinfo.bus_capabilities);
381 
382 	/*
383 	 * Setup our async command overhead. When a target driver or the ARREQ
384 	 * engine allocates a command, the services layer will tack on space
385 	 * for itself and the HAL so we do not have to manage memory for every
386 	 * command.  hal_overhead is how much memory the hal requires to track
387 	 * an async command. Since we are calling into async we must have first
388 	 * called hardware_init().  Therefore, this must be in phase2_init().
389 	 */
390 	soft_state->halinfo.hal_overhead = hci1394_async_cmd_overhead();
391 
392 	TNF_PROBE_0_DEBUG(hci1394_soft_state_phase2_init_exit,
393 	    HCI1394_TNF_HAL_STACK, "");
394 }
395 
396 
397 /*
398  * hci1394_hardware_init()
399  *    Initialize the adapter hardware.  This should be called during
400  *    the initial attach().
401  */
402 static int
403 hci1394_hardware_init(hci1394_state_t *soft_state)
404 {
405 	int status;
406 
407 
408 	ASSERT(soft_state != NULL);
409 	TNF_PROBE_0_DEBUG(hci1394_hardware_init_enter, HCI1394_TNF_HAL_STACK,
410 	    "");
411 
412 	/* Initialize PCI config registers */
413 	status = hci1394_pci_init(soft_state);
414 	if (status != DDI_SUCCESS) {
415 		TNF_PROBE_0(hci1394_hardware_init_pci_fail,
416 		    HCI1394_TNF_HAL_ERROR, "");
417 		TNF_PROBE_0_DEBUG(hci1394_hardware_init_exit,
418 		    HCI1394_TNF_HAL_STACK, "");
419 		return (DDI_FAILURE);
420 	}
421 
422 	/* Initialize the OpenHCI Hardware */
423 	status = hci1394_ohci_init(soft_state, &soft_state->drvinfo,
424 	    &soft_state->ohci);
425 	if (status != DDI_SUCCESS) {
426 		hci1394_pci_fini(soft_state);
427 		TNF_PROBE_0(hci1394_hardware_init_ohci_fail,
428 		    HCI1394_TNF_HAL_ERROR, "");
429 		TNF_PROBE_0_DEBUG(hci1394_hardware_init_exit,
430 		    HCI1394_TNF_HAL_STACK, "");
431 		return (DDI_FAILURE);
432 	}
433 
434 	/* Initialize SW based CSR registers */
435 	hci1394_csr_init(&soft_state->drvinfo, soft_state->ohci,
436 	    &soft_state->csr);
437 
438 	/* Initialize the Asynchronous Q's */
439 	status = hci1394_async_init(&soft_state->drvinfo, soft_state->ohci,
440 	    soft_state->csr, &soft_state->async);
441 	if (status != DDI_SUCCESS) {
442 		hci1394_csr_fini(&soft_state->csr);
443 		hci1394_ohci_fini(&soft_state->ohci);
444 		hci1394_pci_fini(soft_state);
445 		TNF_PROBE_0(hci1394_hardware_init_asyn_fail,
446 		    HCI1394_TNF_HAL_ERROR, "");
447 		TNF_PROBE_0_DEBUG(hci1394_hardware_init_exit,
448 		    HCI1394_TNF_HAL_STACK, "");
449 		return (DDI_FAILURE);
450 	}
451 
452 	/* Initialize the Isochronous logic */
453 	hci1394_isoch_init(&soft_state->drvinfo, soft_state->ohci,
454 	    &soft_state->isoch);
455 
456 	/* Initialize any Vendor Specific Registers */
457 	status = hci1394_vendor_init(&soft_state->drvinfo, soft_state->ohci,
458 	    &soft_state->vendor_info, &soft_state->vendor);
459 	if (status != DDI_SUCCESS) {
460 		hci1394_isoch_fini(&soft_state->isoch);
461 		hci1394_async_fini(&soft_state->async);
462 		hci1394_csr_fini(&soft_state->csr);
463 		hci1394_ohci_fini(&soft_state->ohci);
464 		hci1394_pci_fini(soft_state);
465 		TNF_PROBE_0(hci1394_hardware_init_vend_fail,
466 		    HCI1394_TNF_HAL_ERROR, "");
467 		TNF_PROBE_0_DEBUG(hci1394_hardware_init_exit,
468 		    HCI1394_TNF_HAL_STACK, "");
469 		return (DDI_FAILURE);
470 	}
471 
472 	TNF_PROBE_0_DEBUG(hci1394_hardware_init_exit,
473 	    HCI1394_TNF_HAL_STACK, "");
474 
475 	return (DDI_SUCCESS);
476 }
477 
478 
479 /*
480  * hci1394_hardware_resume()
481  *    Resume the adapter HW.  This routine will be called during resume after
482  *    a successful system suspend.  All memory should be in the state it was
483  *    before the suspend.  All we have to do is re-setup the HW.
484  */
485 static int
486 hci1394_hardware_resume(hci1394_state_t *soft_state)
487 {
488 	int status;
489 
490 
491 	ASSERT(soft_state != NULL);
492 	TNF_PROBE_0_DEBUG(hci1394_hardware_resume_enter, HCI1394_TNF_HAL_STACK,
493 	    "");
494 
495 	/* re-enable global byte swap (if we using it) */
496 	hci1394_pci_resume(soft_state);
497 
498 	/* Re-init the OpenHCI HW */
499 	status = hci1394_ohci_resume(soft_state->ohci);
500 	if (status != DDI_SUCCESS) {
501 		TNF_PROBE_0(hci1394_hardware_resume_ohci_fail,
502 		    HCI1394_TNF_HAL_ERROR, "");
503 		TNF_PROBE_0_DEBUG(hci1394_hardware_resume_exit,
504 		    HCI1394_TNF_HAL_STACK, "");
505 		return (DDI_FAILURE);
506 	}
507 
508 	/* re-setup our SW based CSR registers */
509 	hci1394_csr_resume(soft_state->csr);
510 
511 	/* Re-setup the Async Q's */
512 	status = hci1394_async_resume(soft_state->async);
513 	if (status != DDI_SUCCESS) {
514 		TNF_PROBE_0(hci1394_hardware_resume_asyn_fail,
515 		    HCI1394_TNF_HAL_ERROR, "");
516 		TNF_PROBE_0_DEBUG(hci1394_hardware_resume_exit,
517 		    HCI1394_TNF_HAL_STACK, "");
518 		return (DDI_FAILURE);
519 	}
520 
521 	/* Re-setup any Vendor Specific Registers */
522 	status = hci1394_vendor_resume(soft_state->vendor);
523 	if (status != DDI_SUCCESS) {
524 		TNF_PROBE_0(hci1394_hardware_resume_vend_fail,
525 		    HCI1394_TNF_HAL_ERROR, "");
526 		TNF_PROBE_0_DEBUG(hci1394_hardware_resume_exit,
527 		    HCI1394_TNF_HAL_STACK, "");
528 		return (DDI_FAILURE);
529 	}
530 
531 	TNF_PROBE_0_DEBUG(hci1394_hardware_resume_exit,
532 	    HCI1394_TNF_HAL_STACK, "");
533 
534 	return (DDI_SUCCESS);
535 }
536 
537 
538 /*
539  * hci1394_pci_init()
540  *    Map in PCI config space and initialize PCI config space registers.
541  */
542 static int
543 hci1394_pci_init(hci1394_state_t *soft_state)
544 {
545 	int status;
546 #ifndef _LITTLE_ENDIAN
547 	uint32_t global_swap;
548 #endif
549 
550 
551 	ASSERT(soft_state != NULL);
552 	TNF_PROBE_0_DEBUG(hci1394_pci_init_enter, HCI1394_TNF_HAL_STACK, "");
553 
554 	/* Setup PCI configuration space */
555 	status = pci_config_setup(soft_state->drvinfo.di_dip,
556 	    &soft_state->pci_config);
557 	if (status != DDI_SUCCESS) {
558 		TNF_PROBE_0(hci1394_pci_init_cfg_fail, HCI1394_TNF_HAL_ERROR,
559 		    "");
560 		TNF_PROBE_0_DEBUG(hci1394_pci_init_exit, HCI1394_TNF_HAL_STACK,
561 		    "");
562 		return (DDI_FAILURE);
563 	}
564 
565 
566 #ifdef _LITTLE_ENDIAN
567 	/* Start of little endian specific code */
568 	soft_state->drvinfo.di_reg_attr.devacc_attr_version =
569 	    DDI_DEVICE_ATTR_V0;
570 	soft_state->drvinfo.di_reg_attr.devacc_attr_endian_flags =
571 	    DDI_STRUCTURE_LE_ACC;
572 	soft_state->drvinfo.di_reg_attr.devacc_attr_dataorder =
573 	    DDI_STRICTORDER_ACC;
574 	soft_state->drvinfo.di_buf_attr.devacc_attr_version =
575 	    DDI_DEVICE_ATTR_V0;
576 	soft_state->drvinfo.di_buf_attr.devacc_attr_endian_flags =
577 	    DDI_STRUCTURE_LE_ACC;
578 	soft_state->drvinfo.di_buf_attr.devacc_attr_dataorder =
579 	    DDI_STRICTORDER_ACC;
580 	soft_state->swap_data = B_TRUE;
581 	/* End of little endian specific code */
582 #else
583 	/* Start of big endian specific code */
584 	/* If PCI_Global_Swap bit is not set, try to set it */
585 	global_swap = pci_config_get32(soft_state->pci_config,
586 	    OHCI_PCI_HCI_CONTROL_REG);
587 
588 	/* Lets see if the global byte swap feature is supported */
589 	if ((global_swap & OHCI_PCI_GLOBAL_SWAP) == 0) {
590 		global_swap = global_swap | OHCI_PCI_GLOBAL_SWAP;
591 		pci_config_put32(soft_state->pci_config,
592 		    OHCI_PCI_HCI_CONTROL_REG, global_swap);
593 	}
594 
595 	global_swap = pci_config_get32(soft_state->pci_config,
596 	    OHCI_PCI_HCI_CONTROL_REG);
597 
598 	/* If PCI_Global_Swap bit is not set, it is unsupported */
599 	if ((global_swap & OHCI_PCI_GLOBAL_SWAP) == 0) {
600 		TNF_PROBE_0_DEBUG(hci1394_pci_gbs_npresent,
601 		    HCI1394_TNF_HAL_INFO, "global swap not present");
602 		soft_state->drvinfo.di_reg_attr.devacc_attr_version =
603 		    DDI_DEVICE_ATTR_V0;
604 		soft_state->drvinfo.di_reg_attr.devacc_attr_endian_flags =
605 		    DDI_STRUCTURE_LE_ACC;
606 		soft_state->drvinfo.di_reg_attr.devacc_attr_dataorder =
607 		    DDI_STRICTORDER_ACC;
608 		soft_state->drvinfo.di_buf_attr.devacc_attr_version =
609 		    DDI_DEVICE_ATTR_V0;
610 		soft_state->drvinfo.di_buf_attr.devacc_attr_endian_flags =
611 		    DDI_STRUCTURE_LE_ACC;
612 		soft_state->drvinfo.di_buf_attr.devacc_attr_dataorder =
613 		    DDI_STRICTORDER_ACC;
614 		soft_state->swap_data = B_TRUE;
615 	/*
616 	 * global byte swap is supported.  This should be the case
617 	 * for almost all of the adapters.
618 	 */
619 	} else {
620 		TNF_PROBE_0_DEBUG(hci1394_pci_gbs_present,
621 		    HCI1394_TNF_HAL_INFO, "global swap present");
622 		soft_state->drvinfo.di_reg_attr.devacc_attr_version =
623 		    DDI_DEVICE_ATTR_V0;
624 		soft_state->drvinfo.di_reg_attr.devacc_attr_endian_flags =
625 		    DDI_STRUCTURE_BE_ACC;
626 		soft_state->drvinfo.di_reg_attr.devacc_attr_dataorder =
627 		    DDI_STRICTORDER_ACC;
628 		soft_state->drvinfo.di_buf_attr.devacc_attr_version =
629 		    DDI_DEVICE_ATTR_V0;
630 		soft_state->drvinfo.di_buf_attr.devacc_attr_endian_flags =
631 		    DDI_STRUCTURE_BE_ACC;
632 		soft_state->drvinfo.di_buf_attr.devacc_attr_dataorder =
633 		    DDI_STRICTORDER_ACC;
634 		soft_state->swap_data = B_FALSE;
635 	}
636 	/* End of big endian specific code */
637 #endif
638 
639 	/* read in vendor Information */
640 	soft_state->vendor_info.vendor_id =
641 	    (uint_t)pci_config_get16(soft_state->pci_config, PCI_CONF_VENID);
642 	soft_state->vendor_info.device_id =
643 	    (uint_t)pci_config_get16(soft_state->pci_config, PCI_CONF_DEVID);
644 	soft_state->vendor_info.revision_id =
645 	    (uint_t)pci_config_get8(soft_state->pci_config, PCI_CONF_REVID);
646 
647 	TNF_PROBE_0_DEBUG(hci1394_pci_init_exit, HCI1394_TNF_HAL_STACK, "");
648 
649 	return (DDI_SUCCESS);
650 }
651 
652 
653 /*
654  * hci1394_pci_resume()
655  *    Re-Initialize PCI config space registers during a resume.
656  */
657 /* ARGSUSED */
658 static void
659 hci1394_pci_resume(hci1394_state_t *soft_state)
660 {
661 #ifndef _LITTLE_ENDIAN
662 	uint32_t global_swap;
663 #endif
664 
665 
666 	ASSERT(soft_state != NULL);
667 	TNF_PROBE_0_DEBUG(hci1394_pci_resume_enter, HCI1394_TNF_HAL_STACK, "");
668 
669 #ifdef _LITTLE_ENDIAN
670 	/* Start of little endian specific code */
671 	/* nothing to do here yet.  Maybe later?? */
672 	/* End of little endian specific code */
673 #else
674 	/* Start of big endian specific code */
675 	/* If PCI_Global_Swap bit is not set, try to set it */
676 	global_swap = pci_config_get32(soft_state->pci_config,
677 	    OHCI_PCI_HCI_CONTROL_REG);
678 	/* Try and set GlobalByteSwap */
679 	if ((global_swap & OHCI_PCI_GLOBAL_SWAP) == 0) {
680 		global_swap = global_swap | OHCI_PCI_GLOBAL_SWAP;
681 		pci_config_put32(soft_state->pci_config,
682 		    OHCI_PCI_HCI_CONTROL_REG, global_swap);
683 	}
684 	/* End of big endian specific code */
685 #endif
686 	TNF_PROBE_0_DEBUG(hci1394_pci_resume_exit, HCI1394_TNF_HAL_STACK, "");
687 }
688 
689 
690 /*
691  * hci1394_resmap_get()
692  *    Look for adapter property "reserved-addresses".  This property is used to
693  *    reserve 1394 address space so that it will not randomly be given to a
694  *    target driver during a 1394 address space alloc.  Some protocols hard
695  *    code addresses which make us do this.  The target driver must specifically
696  *    ask for these addresses.  This routine should be called before the
697  *    call to h1394_attach().
698  */
699 static int
700 hci1394_resmap_get(hci1394_state_t *soft_state)
701 {
702 	h1394_addr_map_t *resv_map;
703 	int resv_num;
704 	int status;
705 	int reslen;
706 	uint32_t *resptr;
707 	int rescnt;
708 	int mapcnt;
709 
710 
711 	ASSERT(soft_state != NULL);
712 	TNF_PROBE_0_DEBUG(hci1394_resmap_get_enter, HCI1394_TNF_HAL_STACK, "");
713 
714 	/*
715 	 * See if the "reserved-addresses" property is defined.  The format
716 	 * should be:
717 	 *
718 	 * reserved-addresses=	0x0000ffff,0xf0000B00,0x200,
719 	 * 			0x0000ffff,0xf0000D00,0x200,
720 	 * 			0x0000ffff,0xf0000234,0x4;
721 	 * You can have multiple reserved addresses.  Each reserved address
722 	 * takes up 3 integers.
723 	 *    MSWofAddr,LSWofAddr,ByteCount
724 	 */
725 	status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY,
726 	    soft_state->drvinfo.di_dip, DDI_PROP_DONTPASS, "reserved-addresses",
727 	    (int **)&resptr, (uint_t *)&reslen);
728 	if (status != DDI_PROP_SUCCESS) {
729 		/* the property is not defined,  0 reserved addresses */
730 		soft_state->halinfo.resv_map_num_entries = 0;
731 		soft_state->halinfo.resv_map = NULL;
732 		TNF_PROBE_0_DEBUG(hci1394_resmap_get_exit,
733 		    HCI1394_TNF_HAL_STACK, "");
734 		return (DDI_SUCCESS);
735 	} else if ((reslen < 3) || ((reslen % 3) != 0)) {
736 		/*
737 		 * the property is defined but the correct number of integers
738 		 * is not present.
739 		 */
740 		resv_num = 0;
741 		resv_map = NULL;
742 		cmn_err(CE_NOTE, "!%s(%d): Invalid reserved-addresses property."
743 		    " Property ignored", ddi_node_name(
744 		    soft_state->drvinfo.di_dip), ddi_get_instance(
745 		    soft_state->drvinfo.di_dip));
746 	} else {
747 		/* the property is defined. Alloc space to copy data into */
748 		resv_num = reslen / 3;
749 		resv_map = kmem_alloc((sizeof (h1394_addr_map_t) * (resv_num)),
750 		    KM_SLEEP);
751 
752 		/* read in the address, length, and set the type to reserved */
753 		rescnt = 0;
754 		mapcnt = 0;
755 		while (rescnt < reslen) {
756 			resv_map[mapcnt].address =
757 			    (uint64_t)resptr[rescnt] << 32;
758 			rescnt++;
759 			resv_map[mapcnt].address |= (uint64_t)resptr[rescnt];
760 			rescnt++;
761 			resv_map[mapcnt].length = (uint64_t)resptr[rescnt];
762 			rescnt++;
763 			resv_map[mapcnt].addr_type = H1394_ADDR_RESERVED;
764 			mapcnt++;
765 		}
766 	}
767 
768 	ddi_prop_free(resptr);
769 
770 	/*
771 	 * copy the number of reserved address ranges and a pointer to the map
772 	 * into halinfo so we can tell the services layer about them in
773 	 * h1394_attach()
774 	 */
775 	soft_state->halinfo.resv_map_num_entries = resv_num;
776 	soft_state->halinfo.resv_map = resv_map;
777 
778 	TNF_PROBE_0_DEBUG(hci1394_resmap_get_exit, HCI1394_TNF_HAL_STACK, "");
779 
780 	return (DDI_SUCCESS);
781 }
782 
783 
784 /*
785  * hci1394_resmap_free()
786  *    Free up the space alloced in hci1394_resmap_get().  This routine should
787  *    be called after h1394_attach().  The HAL does not need this information
788  *    and the services layer only uses it for a calculation during attach and
789  *    should not refer to the pointer after it returns from h1394_attach().
790  */
791 static void
792 hci1394_resmap_free(hci1394_state_t *soft_state)
793 {
794 	ASSERT(soft_state != NULL);
795 	TNF_PROBE_0_DEBUG(hci1394_resmap_free_enter, HCI1394_TNF_HAL_STACK, "");
796 
797 	/*
798 	 * if we have one or more reserved map entries, free up the space that
799 	 * was allocated to store them
800 	 */
801 	if (soft_state->halinfo.resv_map_num_entries > 0) {
802 		ASSERT(soft_state->halinfo.resv_map != NULL);
803 		kmem_free(soft_state->halinfo.resv_map,
804 		    (sizeof (h1394_addr_map_t) *
805 		    soft_state->halinfo.resv_map_num_entries));
806 	}
807 
808 	TNF_PROBE_0_DEBUG(hci1394_resmap_free_exit, HCI1394_TNF_HAL_STACK, "");
809 }
810 
811 
812 /*
813  * hci1394_statebit_set()
814  *     Set bit "statebit" in "state"
815  */
816 static void
817 hci1394_statebit_set(uint64_t *state, uint_t statebit)
818 {
819 	ASSERT(state != NULL);
820 	ASSERT(statebit < 64);
821 	*state |= (uint64_t)0x1 << statebit;
822 }
823 
824 
825 /*
826  * hci1394_statebit_tst()
827  *    Return status of bit "statebit".  Is it set or not?
828  */
829 static boolean_t
830 hci1394_statebit_tst(uint64_t state, uint_t statebit)
831 {
832 	uint64_t bitset;
833 	int status;
834 
835 
836 	ASSERT(statebit < 64);
837 	bitset = state & ((uint64_t)0x1 << statebit);
838 	if (bitset == 0) {
839 		status = B_FALSE;
840 	} else {
841 		status = B_TRUE;
842 	}
843 	return (status);
844 }
845 
846 
847 /*
848  * hci1394_cleanup()
849  *    Cleanup after a failed attach
850  */
851 static void
852 hci1394_cleanup(hci1394_state_t *soft_state, uint64_t attach_state)
853 {
854 	int status;
855 
856 
857 	ASSERT(soft_state != NULL);
858 	TNF_PROBE_0_DEBUG(hci1394_cleanup_enter, HCI1394_TNF_HAL_STACK, "");
859 
860 
861 	status = hci1394_statebit_tst(attach_state, STATE_STARTUP);
862 	if (status == B_TRUE) {
863 		/* Don't allow the HW to generate any more interrupts */
864 		hci1394_ohci_intr_master_disable(soft_state->ohci);
865 
866 		/* don't accept anymore commands from services layer */
867 		(void) hci1394_state_set(&soft_state->drvinfo,
868 		    HCI1394_SHUTDOWN);
869 
870 		/* Reset the chip */
871 		(void) hci1394_ohci_soft_reset(soft_state->ohci);
872 
873 		/* Flush out async DMA Q's (cancels pendingQ timeouts too) */
874 		hci1394_async_flush(soft_state->async);
875 	}
876 
877 	status = hci1394_statebit_tst(attach_state, STATE_ISR_HANDLER);
878 	if (status == B_TRUE) {
879 		hci1394_isr_handler_fini(soft_state);
880 	}
881 
882 	status = hci1394_statebit_tst(attach_state, STATE_H1394_ATTACH);
883 	if (status == B_TRUE) {
884 		(void) h1394_detach(&soft_state->drvinfo.di_sl_private,
885 		    DDI_DETACH);
886 	}
887 
888 	status = hci1394_statebit_tst(attach_state, STATE_HW_INIT);
889 	if (status == B_TRUE) {
890 		hci1394_detach_hardware(soft_state);
891 	}
892 
893 	status = hci1394_statebit_tst(attach_state, STATE_MINOR_NODE);
894 	if (status == B_TRUE) {
895 		ddi_remove_minor_node(soft_state->drvinfo.di_dip, "devctl");
896 	}
897 
898 	status = hci1394_statebit_tst(attach_state, STATE_ISR_INIT);
899 	if (status == B_TRUE) {
900 		hci1394_isr_fini(soft_state);
901 	}
902 
903 	status = hci1394_statebit_tst(attach_state, STATE_PHASE2);
904 	if (status == B_TRUE) {
905 		hci1394_soft_state_fini(soft_state);
906 	}
907 
908 	status = hci1394_statebit_tst(attach_state, STATE_ZALLOC);
909 	if (status == B_TRUE) {
910 		ddi_soft_state_free(hci1394_statep,
911 		    soft_state->drvinfo.di_instance);
912 	}
913 
914 	TNF_PROBE_0_DEBUG(hci1394_cleanup_exit, HCI1394_TNF_HAL_STACK, "");
915 }
916