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