10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7391SBarry.Harding@Sun.COM * Common Development and Distribution License (the "License").
6*7391SBarry.Harding@Sun.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*7391SBarry.Harding@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate * hci1394_attach.c
280Sstevel@tonic-gate * HBA attach() routine with associated funtions.
290Sstevel@tonic-gate */
300Sstevel@tonic-gate
310Sstevel@tonic-gate #include <sys/types.h>
320Sstevel@tonic-gate #include <sys/kmem.h>
330Sstevel@tonic-gate #include <sys/conf.h>
340Sstevel@tonic-gate #include <sys/ddi.h>
350Sstevel@tonic-gate #include <sys/modctl.h>
360Sstevel@tonic-gate #include <sys/stat.h>
370Sstevel@tonic-gate #include <sys/sunddi.h>
380Sstevel@tonic-gate #include <sys/cmn_err.h>
390Sstevel@tonic-gate #include <sys/pci.h>
400Sstevel@tonic-gate
410Sstevel@tonic-gate #include <sys/1394/h1394.h>
420Sstevel@tonic-gate #include <sys/1394/adapters/hci1394.h>
430Sstevel@tonic-gate #include <sys/1394/adapters/hci1394_extern.h>
440Sstevel@tonic-gate
450Sstevel@tonic-gate
460Sstevel@tonic-gate /*
470Sstevel@tonic-gate * Attach State Information. These states are used to track the status of the
480Sstevel@tonic-gate * attach. They are bit offsets.
490Sstevel@tonic-gate */
500Sstevel@tonic-gate #define STATE_ZALLOC 0
510Sstevel@tonic-gate #define STATE_ISR_INIT 1
520Sstevel@tonic-gate #define STATE_MINOR_NODE 2
530Sstevel@tonic-gate #define STATE_HW_INIT 3
540Sstevel@tonic-gate #define STATE_PHASE2 4
550Sstevel@tonic-gate #define STATE_POWER_INIT 5
560Sstevel@tonic-gate #define STATE_H1394_ATTACH 6
570Sstevel@tonic-gate #define STATE_ISR_HANDLER 7
580Sstevel@tonic-gate #define STATE_STARTUP 8
590Sstevel@tonic-gate
600Sstevel@tonic-gate static void hci1394_statebit_set(uint64_t *state, uint_t statebit);
610Sstevel@tonic-gate static boolean_t hci1394_statebit_tst(uint64_t state, uint_t statebit);
620Sstevel@tonic-gate
630Sstevel@tonic-gate static void hci1394_cleanup(hci1394_state_t *soft_state, uint64_t attach_state);
640Sstevel@tonic-gate
650Sstevel@tonic-gate static int hci1394_hardware_init(hci1394_state_t *soft_state);
660Sstevel@tonic-gate static int hci1394_hardware_resume(hci1394_state_t *soft_state);
670Sstevel@tonic-gate
680Sstevel@tonic-gate static int hci1394_pci_init(hci1394_state_t *soft_state);
690Sstevel@tonic-gate static void hci1394_pci_resume(hci1394_state_t *soft_state);
700Sstevel@tonic-gate
710Sstevel@tonic-gate static void hci1394_soft_state_phase1_init(hci1394_state_t *soft_state,
720Sstevel@tonic-gate dev_info_t *dip, int instance);
730Sstevel@tonic-gate static void hci1394_soft_state_phase2_init(hci1394_state_t *soft_state);
740Sstevel@tonic-gate
750Sstevel@tonic-gate static int hci1394_resmap_get(hci1394_state_t *soft_state);
760Sstevel@tonic-gate static void hci1394_resmap_free(hci1394_state_t *soft_state);
770Sstevel@tonic-gate
780Sstevel@tonic-gate
790Sstevel@tonic-gate
800Sstevel@tonic-gate int
hci1394_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)810Sstevel@tonic-gate hci1394_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
820Sstevel@tonic-gate {
830Sstevel@tonic-gate hci1394_state_t *soft_state;
840Sstevel@tonic-gate uint64_t attach_state = 0;
850Sstevel@tonic-gate int instance;
860Sstevel@tonic-gate int status;
870Sstevel@tonic-gate
880Sstevel@tonic-gate
890Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_attach_enter, HCI1394_TNF_HAL_STACK, "");
900Sstevel@tonic-gate
910Sstevel@tonic-gate switch (cmd) {
920Sstevel@tonic-gate case DDI_ATTACH:
930Sstevel@tonic-gate instance = ddi_get_instance(dip);
940Sstevel@tonic-gate status = ddi_soft_state_zalloc(hci1394_statep, instance);
950Sstevel@tonic-gate if (status != DDI_SUCCESS) {
960Sstevel@tonic-gate TNF_PROBE_1(hci1394_attach_ssz_fail,
970Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
980Sstevel@tonic-gate "ddi_soft_state_zalloc() failed");
990Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_attach_exit,
1000Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
1010Sstevel@tonic-gate return (DDI_FAILURE);
1020Sstevel@tonic-gate }
1030Sstevel@tonic-gate soft_state = ddi_get_soft_state(hci1394_statep, instance);
1040Sstevel@tonic-gate if (soft_state == NULL) {
1050Sstevel@tonic-gate ddi_soft_state_free(hci1394_statep, instance);
1060Sstevel@tonic-gate TNF_PROBE_1(hci1394_attach_gss_fail,
1070Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
1080Sstevel@tonic-gate "ddi_get_soft_state() failed");
1090Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_attach_exit,
1100Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
1110Sstevel@tonic-gate return (DDI_FAILURE);
1120Sstevel@tonic-gate }
1130Sstevel@tonic-gate hci1394_statebit_set(&attach_state, STATE_ZALLOC);
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate hci1394_soft_state_phase1_init(soft_state, dip, instance);
1160Sstevel@tonic-gate
1170Sstevel@tonic-gate /* get iblock cookie, other interrupt init stuff */
1180Sstevel@tonic-gate status = hci1394_isr_init(soft_state);
1190Sstevel@tonic-gate if (status != DDI_SUCCESS) {
1200Sstevel@tonic-gate hci1394_cleanup(soft_state, attach_state);
1210Sstevel@tonic-gate TNF_PROBE_0(hci1394_attach_isr_fail,
1220Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
1230Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_attach_exit,
1240Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
1250Sstevel@tonic-gate return (DDI_FAILURE);
1260Sstevel@tonic-gate }
1270Sstevel@tonic-gate hci1394_statebit_set(&attach_state, STATE_ISR_INIT);
1280Sstevel@tonic-gate
1290Sstevel@tonic-gate status = ddi_create_minor_node(dip, "devctl", S_IFCHR,
1300Sstevel@tonic-gate instance, DDI_NT_NEXUS, 0);
1310Sstevel@tonic-gate if (status != DDI_SUCCESS) {
1320Sstevel@tonic-gate hci1394_cleanup(soft_state, attach_state);
1330Sstevel@tonic-gate TNF_PROBE_0(hci1394_attach_cmn_fail,
1340Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
1350Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_attach_exit,
1360Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
1370Sstevel@tonic-gate return (DDI_FAILURE);
1380Sstevel@tonic-gate }
1390Sstevel@tonic-gate hci1394_statebit_set(&attach_state, STATE_MINOR_NODE);
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate status = hci1394_hardware_init(soft_state);
1420Sstevel@tonic-gate if (status != DDI_SUCCESS) {
1430Sstevel@tonic-gate hci1394_cleanup(soft_state, attach_state);
1440Sstevel@tonic-gate TNF_PROBE_0(hci1394_attach_hwi_fail,
1450Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
1460Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_attach_exit,
1470Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
1480Sstevel@tonic-gate return (DDI_FAILURE);
1490Sstevel@tonic-gate }
1500Sstevel@tonic-gate hci1394_statebit_set(&attach_state, STATE_HW_INIT);
1510Sstevel@tonic-gate
1520Sstevel@tonic-gate hci1394_soft_state_phase2_init(soft_state);
1530Sstevel@tonic-gate hci1394_statebit_set(&attach_state, STATE_PHASE2);
1540Sstevel@tonic-gate
1550Sstevel@tonic-gate /* build up the reserved addresses map */
1560Sstevel@tonic-gate status = hci1394_resmap_get(soft_state);
1570Sstevel@tonic-gate if (status != DDI_SUCCESS) {
1580Sstevel@tonic-gate hci1394_cleanup(soft_state, attach_state);
1590Sstevel@tonic-gate TNF_PROBE_0(hci1394_attach_rmg_fail,
1600Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
1610Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_attach_exit,
1620Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
1630Sstevel@tonic-gate return (DDI_FAILURE);
1640Sstevel@tonic-gate }
1650Sstevel@tonic-gate
1660Sstevel@tonic-gate /* "attach" to the Services Layer */
1670Sstevel@tonic-gate status = h1394_attach(&soft_state->halinfo, DDI_ATTACH,
1680Sstevel@tonic-gate &soft_state->drvinfo.di_sl_private);
1690Sstevel@tonic-gate if (status != DDI_SUCCESS) {
1700Sstevel@tonic-gate hci1394_resmap_free(soft_state);
1710Sstevel@tonic-gate hci1394_cleanup(soft_state, attach_state);
1720Sstevel@tonic-gate TNF_PROBE_0(hci1394_attach_ha_fail,
1730Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
1740Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_attach_exit,
1750Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
1760Sstevel@tonic-gate return (DDI_FAILURE);
1770Sstevel@tonic-gate }
1780Sstevel@tonic-gate /* free the reserved addresses map */
1790Sstevel@tonic-gate hci1394_resmap_free(soft_state);
180*7391SBarry.Harding@Sun.COM
1810Sstevel@tonic-gate hci1394_statebit_set(&attach_state, STATE_H1394_ATTACH);
1820Sstevel@tonic-gate status = hci1394_isr_handler_init(soft_state);
1830Sstevel@tonic-gate if (status != DDI_SUCCESS) {
1840Sstevel@tonic-gate hci1394_cleanup(soft_state, attach_state);
1850Sstevel@tonic-gate TNF_PROBE_0(hci1394_attach_ih_fail,
186*7391SBarry.Harding@Sun.COM HCI1394_TNF_HAL_ERROR, "");
1870Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_attach_exit,
188*7391SBarry.Harding@Sun.COM HCI1394_TNF_HAL_STACK, "");
1890Sstevel@tonic-gate return (DDI_FAILURE);
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate hci1394_statebit_set(&attach_state, STATE_ISR_HANDLER);
1920Sstevel@tonic-gate
1930Sstevel@tonic-gate /* Report that driver was loaded */
1940Sstevel@tonic-gate ddi_report_dev(dip);
1950Sstevel@tonic-gate
1960Sstevel@tonic-gate /*
1970Sstevel@tonic-gate * Turn on link, Reset Bus, enable interrupts. Should be the
1980Sstevel@tonic-gate * last routine called in attach. The statebit for starup must
1990Sstevel@tonic-gate * be set before startup is called since startup enables
2000Sstevel@tonic-gate * interrupts.
2010Sstevel@tonic-gate */
2020Sstevel@tonic-gate hci1394_statebit_set(&attach_state, STATE_STARTUP);
2030Sstevel@tonic-gate status = hci1394_ohci_startup(soft_state->ohci);
2040Sstevel@tonic-gate if (status != DDI_SUCCESS) {
2050Sstevel@tonic-gate hci1394_cleanup(soft_state, attach_state);
2060Sstevel@tonic-gate TNF_PROBE_0(hci1394_attach_str_fail,
2070Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
2080Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_attach_exit,
2090Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
2100Sstevel@tonic-gate return (DDI_FAILURE);
2110Sstevel@tonic-gate }
2120Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_attach_exit, HCI1394_TNF_HAL_STACK,
2130Sstevel@tonic-gate "");
2140Sstevel@tonic-gate
2150Sstevel@tonic-gate return (DDI_SUCCESS);
2160Sstevel@tonic-gate
2170Sstevel@tonic-gate case DDI_RESUME:
2180Sstevel@tonic-gate instance = ddi_get_instance(dip);
2190Sstevel@tonic-gate soft_state = ddi_get_soft_state(hci1394_statep, instance);
2200Sstevel@tonic-gate if (soft_state == NULL) {
2210Sstevel@tonic-gate TNF_PROBE_1(hci1394_attach_resgss_fail,
2220Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
2230Sstevel@tonic-gate "ddi_get_soft_state() failed");
2240Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_attach_exit,
2250Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
2260Sstevel@tonic-gate return (DDI_FAILURE);
2270Sstevel@tonic-gate }
2280Sstevel@tonic-gate
2290Sstevel@tonic-gate status = hci1394_hardware_resume(soft_state);
2300Sstevel@tonic-gate if (status != DDI_SUCCESS) {
2310Sstevel@tonic-gate TNF_PROBE_1(hci1394_attach_res_hwr_fail,
2320Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
2330Sstevel@tonic-gate "hardware failed to resume");
2340Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_attach_exit,
2350Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
2360Sstevel@tonic-gate return (DDI_FAILURE);
2370Sstevel@tonic-gate }
2380Sstevel@tonic-gate
2390Sstevel@tonic-gate /*
2400Sstevel@tonic-gate * set our state back to initial. The next bus reset were
2410Sstevel@tonic-gate * about to generate will set us in motion.
2420Sstevel@tonic-gate */
2430Sstevel@tonic-gate soft_state->drvinfo.di_drvstate.ds_state = HCI1394_INITIAL;
2440Sstevel@tonic-gate
2450Sstevel@tonic-gate /* turn on the link, enable interrupts, reset the bus */
2460Sstevel@tonic-gate status = hci1394_ohci_startup(soft_state->ohci);
2470Sstevel@tonic-gate if (status != DDI_SUCCESS) {
2480Sstevel@tonic-gate TNF_PROBE_1(hci1394_attach_res_str_fail,
2490Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
2500Sstevel@tonic-gate "hci1394_ohci_startup() failed");
2510Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_attach_exit,
2520Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
2530Sstevel@tonic-gate return (DDI_FAILURE);
2540Sstevel@tonic-gate }
2550Sstevel@tonic-gate
256*7391SBarry.Harding@Sun.COM /* tell the Services Layer that we are resuming */
257*7391SBarry.Harding@Sun.COM status = h1394_attach(&soft_state->halinfo, DDI_RESUME,
258*7391SBarry.Harding@Sun.COM &soft_state->drvinfo.di_sl_private);
259*7391SBarry.Harding@Sun.COM if (status != DDI_SUCCESS) {
260*7391SBarry.Harding@Sun.COM TNF_PROBE_0(hci1394_attach_res_ha_fail,
261*7391SBarry.Harding@Sun.COM HCI1394_TNF_HAL_ERROR, "");
262*7391SBarry.Harding@Sun.COM TNF_PROBE_0_DEBUG(hci1394_attach_exit,
263*7391SBarry.Harding@Sun.COM HCI1394_TNF_HAL_STACK, "");
264*7391SBarry.Harding@Sun.COM return (DDI_FAILURE);
265*7391SBarry.Harding@Sun.COM }
266*7391SBarry.Harding@Sun.COM
2670Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_attach_exit, HCI1394_TNF_HAL_STACK,
2680Sstevel@tonic-gate "");
2690Sstevel@tonic-gate return (DDI_SUCCESS);
2700Sstevel@tonic-gate
2710Sstevel@tonic-gate default:
2720Sstevel@tonic-gate TNF_PROBE_0(h1394_attach_default_fail, HCI1394_TNF_HAL_ERROR,
2730Sstevel@tonic-gate "");
2740Sstevel@tonic-gate break;
2750Sstevel@tonic-gate }
2760Sstevel@tonic-gate
2770Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_attach_exit, HCI1394_TNF_HAL_STACK, "");
2780Sstevel@tonic-gate
2790Sstevel@tonic-gate return (DDI_FAILURE);
2800Sstevel@tonic-gate }
2810Sstevel@tonic-gate
2820Sstevel@tonic-gate
2830Sstevel@tonic-gate /*
2840Sstevel@tonic-gate * hci1394_soft_state_phase1_init()
2850Sstevel@tonic-gate * First part soft_state initialization. This should be called before any
2860Sstevel@tonic-gate * other initialization routines are called. Anything that requires cleanup
2870Sstevel@tonic-gate * on detach or after an attach failure should be setup in phase2 init (i.e.
2880Sstevel@tonic-gate * mutex's, cv's, etc.)
2890Sstevel@tonic-gate */
2900Sstevel@tonic-gate static void
hci1394_soft_state_phase1_init(hci1394_state_t * soft_state,dev_info_t * dip,int instance)2910Sstevel@tonic-gate hci1394_soft_state_phase1_init(hci1394_state_t *soft_state, dev_info_t *dip,
2920Sstevel@tonic-gate int instance)
2930Sstevel@tonic-gate {
2940Sstevel@tonic-gate ASSERT(soft_state != NULL);
2950Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_soft_state_phase1_init_enter,
2960Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
2970Sstevel@tonic-gate
2980Sstevel@tonic-gate soft_state->drvinfo.di_dip = dip;
2990Sstevel@tonic-gate soft_state->drvinfo.di_instance = instance;
3000Sstevel@tonic-gate
3010Sstevel@tonic-gate /* current bus generation */
3020Sstevel@tonic-gate soft_state->drvinfo.di_gencnt = 0;
3030Sstevel@tonic-gate
3040Sstevel@tonic-gate soft_state->drvinfo.di_sl_private = NULL;
3050Sstevel@tonic-gate
3060Sstevel@tonic-gate /* initialize statistics */
3070Sstevel@tonic-gate soft_state->drvinfo.di_stats.st_bus_reset_count = 0;
3080Sstevel@tonic-gate soft_state->drvinfo.di_stats.st_selfid_count = 0;
3090Sstevel@tonic-gate soft_state->drvinfo.di_stats.st_phy_isr = 0;
3100Sstevel@tonic-gate soft_state->drvinfo.di_stats.st_phy_loop_err = 0;
3110Sstevel@tonic-gate soft_state->drvinfo.di_stats.st_phy_pwrfail_err = 0;
3120Sstevel@tonic-gate soft_state->drvinfo.di_stats.st_phy_timeout_err = 0;
3130Sstevel@tonic-gate soft_state->drvinfo.di_stats.st_phy_portevt_err = 0;
3140Sstevel@tonic-gate
3150Sstevel@tonic-gate soft_state->swap_data = B_FALSE;
3160Sstevel@tonic-gate soft_state->sl_selfid_buf = NULL;
3170Sstevel@tonic-gate
3180Sstevel@tonic-gate /* halinfo is what is passed up to the Services Layer */
3190Sstevel@tonic-gate soft_state->halinfo.hal_private = soft_state;
3200Sstevel@tonic-gate soft_state->halinfo.dip = soft_state->drvinfo.di_dip;
3210Sstevel@tonic-gate soft_state->halinfo.hal_events = hci1394_evts;
3220Sstevel@tonic-gate soft_state->halinfo.max_generation = OHCI_BUSGEN_MAX;
3230Sstevel@tonic-gate soft_state->halinfo.addr_map_num_entries = HCI1394_ADDR_MAP_SIZE;
3240Sstevel@tonic-gate soft_state->halinfo.addr_map = hci1394_addr_map;
3250Sstevel@tonic-gate hci1394_buf_attr_get(&soft_state->halinfo.dma_attr);
3260Sstevel@tonic-gate
3270Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_soft_state_phase1_init_exit,
3280Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
3290Sstevel@tonic-gate }
3300Sstevel@tonic-gate
3310Sstevel@tonic-gate
3320Sstevel@tonic-gate /*
3330Sstevel@tonic-gate * hci1394_soft_state_phase2_init()
3340Sstevel@tonic-gate * Second part of soft_state initialization. This should be called after a
3350Sstevel@tonic-gate * successful hardware_init() and before the call to h1394_attach().
3360Sstevel@tonic-gate */
3370Sstevel@tonic-gate static void
hci1394_soft_state_phase2_init(hci1394_state_t * soft_state)3380Sstevel@tonic-gate hci1394_soft_state_phase2_init(hci1394_state_t *soft_state)
3390Sstevel@tonic-gate {
3400Sstevel@tonic-gate ASSERT(soft_state != NULL);
3410Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_soft_state_phase2_init_enter,
3420Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
3430Sstevel@tonic-gate
3440Sstevel@tonic-gate /*
3450Sstevel@tonic-gate * Setup our initial driver state. This requires the HW iblock
3460Sstevel@tonic-gate * cookie so this must be setup in phase2_init()
3470Sstevel@tonic-gate */
3480Sstevel@tonic-gate soft_state->drvinfo.di_drvstate.ds_state = HCI1394_INITIAL;
3490Sstevel@tonic-gate mutex_init(&soft_state->drvinfo.di_drvstate.ds_mutex, NULL,
3500Sstevel@tonic-gate MUTEX_DRIVER, soft_state->drvinfo.di_iblock_cookie);
3510Sstevel@tonic-gate
3520Sstevel@tonic-gate /*
3530Sstevel@tonic-gate * halinfo.acc_attr tells the services layer what our buffer access
3540Sstevel@tonic-gate * attributes are. drvinfo.di_buf_attr it initialized in pci_init so
3550Sstevel@tonic-gate * this must be setup in phase2_init()
3560Sstevel@tonic-gate */
3570Sstevel@tonic-gate soft_state->halinfo.acc_attr = soft_state->drvinfo.di_buf_attr;
3580Sstevel@tonic-gate
3590Sstevel@tonic-gate /*
3600Sstevel@tonic-gate * halinfo.hw_interrupt tells the services layer what our
3610Sstevel@tonic-gate * iblock_cookie is. drvinfo.di_iblock_cookie is setup in isr_init so
3620Sstevel@tonic-gate * this must be setup in phase2_init()
3630Sstevel@tonic-gate */
3640Sstevel@tonic-gate soft_state->halinfo.hw_interrupt = soft_state->drvinfo.di_iblock_cookie;
3650Sstevel@tonic-gate
3660Sstevel@tonic-gate /*
3670Sstevel@tonic-gate * Read in our node capabilities. Since we are calling into csr
3680Sstevel@tonic-gate * we must have first called hardware_init(). Therefore, this must
3690Sstevel@tonic-gate * be in phase2_init().
3700Sstevel@tonic-gate */
3710Sstevel@tonic-gate hci1394_csr_node_capabilities(soft_state->csr,
3720Sstevel@tonic-gate &soft_state->halinfo.node_capabilities);
3730Sstevel@tonic-gate
3740Sstevel@tonic-gate /*
3750Sstevel@tonic-gate * Read in our bus capabilities. Since we are calling into ohci
3760Sstevel@tonic-gate * we must have first called hardware_init(). Therefore, this must
3770Sstevel@tonic-gate * be in phase2_init().
3780Sstevel@tonic-gate */
3790Sstevel@tonic-gate hci1394_ohci_bus_capabilities(soft_state->ohci,
3800Sstevel@tonic-gate &soft_state->halinfo.bus_capabilities);
3810Sstevel@tonic-gate
3820Sstevel@tonic-gate /*
3830Sstevel@tonic-gate * Setup our async command overhead. When a target driver or the ARREQ
3840Sstevel@tonic-gate * engine allocates a command, the services layer will tack on space
3850Sstevel@tonic-gate * for itself and the HAL so we do not have to manage memory for every
3860Sstevel@tonic-gate * command. hal_overhead is how much memory the hal requires to track
3870Sstevel@tonic-gate * an async command. Since we are calling into async we must have first
3880Sstevel@tonic-gate * called hardware_init(). Therefore, this must be in phase2_init().
3890Sstevel@tonic-gate */
3900Sstevel@tonic-gate soft_state->halinfo.hal_overhead = hci1394_async_cmd_overhead();
3910Sstevel@tonic-gate
3920Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_soft_state_phase2_init_exit,
3930Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
3940Sstevel@tonic-gate }
3950Sstevel@tonic-gate
3960Sstevel@tonic-gate
3970Sstevel@tonic-gate /*
3980Sstevel@tonic-gate * hci1394_hardware_init()
3990Sstevel@tonic-gate * Initialize the adapter hardware. This should be called during
4000Sstevel@tonic-gate * the initial attach().
4010Sstevel@tonic-gate */
4020Sstevel@tonic-gate static int
hci1394_hardware_init(hci1394_state_t * soft_state)4030Sstevel@tonic-gate hci1394_hardware_init(hci1394_state_t *soft_state)
4040Sstevel@tonic-gate {
4050Sstevel@tonic-gate int status;
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate
4080Sstevel@tonic-gate ASSERT(soft_state != NULL);
4090Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_hardware_init_enter, HCI1394_TNF_HAL_STACK,
4100Sstevel@tonic-gate "");
4110Sstevel@tonic-gate
4120Sstevel@tonic-gate /* Initialize PCI config registers */
4130Sstevel@tonic-gate status = hci1394_pci_init(soft_state);
4140Sstevel@tonic-gate if (status != DDI_SUCCESS) {
4150Sstevel@tonic-gate TNF_PROBE_0(hci1394_hardware_init_pci_fail,
4160Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
4170Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_hardware_init_exit,
4180Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
4190Sstevel@tonic-gate return (DDI_FAILURE);
4200Sstevel@tonic-gate }
4210Sstevel@tonic-gate
4220Sstevel@tonic-gate /* Initialize the OpenHCI Hardware */
4230Sstevel@tonic-gate status = hci1394_ohci_init(soft_state, &soft_state->drvinfo,
4240Sstevel@tonic-gate &soft_state->ohci);
4250Sstevel@tonic-gate if (status != DDI_SUCCESS) {
4260Sstevel@tonic-gate hci1394_pci_fini(soft_state);
4270Sstevel@tonic-gate TNF_PROBE_0(hci1394_hardware_init_ohci_fail,
4280Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
4290Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_hardware_init_exit,
4300Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
4310Sstevel@tonic-gate return (DDI_FAILURE);
4320Sstevel@tonic-gate }
4330Sstevel@tonic-gate
4340Sstevel@tonic-gate /* Initialize SW based CSR registers */
4350Sstevel@tonic-gate hci1394_csr_init(&soft_state->drvinfo, soft_state->ohci,
4360Sstevel@tonic-gate &soft_state->csr);
4370Sstevel@tonic-gate
4380Sstevel@tonic-gate /* Initialize the Asynchronous Q's */
4390Sstevel@tonic-gate status = hci1394_async_init(&soft_state->drvinfo, soft_state->ohci,
4400Sstevel@tonic-gate soft_state->csr, &soft_state->async);
4410Sstevel@tonic-gate if (status != DDI_SUCCESS) {
4420Sstevel@tonic-gate hci1394_csr_fini(&soft_state->csr);
4430Sstevel@tonic-gate hci1394_ohci_fini(&soft_state->ohci);
4440Sstevel@tonic-gate hci1394_pci_fini(soft_state);
4450Sstevel@tonic-gate TNF_PROBE_0(hci1394_hardware_init_asyn_fail,
4460Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
4470Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_hardware_init_exit,
4480Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
4490Sstevel@tonic-gate return (DDI_FAILURE);
4500Sstevel@tonic-gate }
4510Sstevel@tonic-gate
4520Sstevel@tonic-gate /* Initialize the Isochronous logic */
4530Sstevel@tonic-gate hci1394_isoch_init(&soft_state->drvinfo, soft_state->ohci,
4540Sstevel@tonic-gate &soft_state->isoch);
4550Sstevel@tonic-gate
4560Sstevel@tonic-gate /* Initialize any Vendor Specific Registers */
4570Sstevel@tonic-gate status = hci1394_vendor_init(&soft_state->drvinfo, soft_state->ohci,
4580Sstevel@tonic-gate &soft_state->vendor_info, &soft_state->vendor);
4590Sstevel@tonic-gate if (status != DDI_SUCCESS) {
4600Sstevel@tonic-gate hci1394_isoch_fini(&soft_state->isoch);
4610Sstevel@tonic-gate hci1394_async_fini(&soft_state->async);
4620Sstevel@tonic-gate hci1394_csr_fini(&soft_state->csr);
4630Sstevel@tonic-gate hci1394_ohci_fini(&soft_state->ohci);
4640Sstevel@tonic-gate hci1394_pci_fini(soft_state);
4650Sstevel@tonic-gate TNF_PROBE_0(hci1394_hardware_init_vend_fail,
4660Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
4670Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_hardware_init_exit,
4680Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
4690Sstevel@tonic-gate return (DDI_FAILURE);
4700Sstevel@tonic-gate }
4710Sstevel@tonic-gate
4720Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_hardware_init_exit,
4730Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
4740Sstevel@tonic-gate
4750Sstevel@tonic-gate return (DDI_SUCCESS);
4760Sstevel@tonic-gate }
4770Sstevel@tonic-gate
4780Sstevel@tonic-gate
4790Sstevel@tonic-gate /*
4800Sstevel@tonic-gate * hci1394_hardware_resume()
4810Sstevel@tonic-gate * Resume the adapter HW. This routine will be called during resume after
4820Sstevel@tonic-gate * a successful system suspend. All memory should be in the state it was
4830Sstevel@tonic-gate * before the suspend. All we have to do is re-setup the HW.
4840Sstevel@tonic-gate */
4850Sstevel@tonic-gate static int
hci1394_hardware_resume(hci1394_state_t * soft_state)4860Sstevel@tonic-gate hci1394_hardware_resume(hci1394_state_t *soft_state)
4870Sstevel@tonic-gate {
4880Sstevel@tonic-gate int status;
4890Sstevel@tonic-gate
4900Sstevel@tonic-gate
4910Sstevel@tonic-gate ASSERT(soft_state != NULL);
4920Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_hardware_resume_enter, HCI1394_TNF_HAL_STACK,
4930Sstevel@tonic-gate "");
4940Sstevel@tonic-gate
4950Sstevel@tonic-gate /* re-enable global byte swap (if we using it) */
4960Sstevel@tonic-gate hci1394_pci_resume(soft_state);
4970Sstevel@tonic-gate
4980Sstevel@tonic-gate /* Re-init the OpenHCI HW */
4990Sstevel@tonic-gate status = hci1394_ohci_resume(soft_state->ohci);
5000Sstevel@tonic-gate if (status != DDI_SUCCESS) {
5010Sstevel@tonic-gate TNF_PROBE_0(hci1394_hardware_resume_ohci_fail,
5020Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
5030Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_hardware_resume_exit,
5040Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
5050Sstevel@tonic-gate return (DDI_FAILURE);
5060Sstevel@tonic-gate }
5070Sstevel@tonic-gate
5080Sstevel@tonic-gate /* re-setup our SW based CSR registers */
5090Sstevel@tonic-gate hci1394_csr_resume(soft_state->csr);
5100Sstevel@tonic-gate
5110Sstevel@tonic-gate /* Re-setup the Async Q's */
5120Sstevel@tonic-gate status = hci1394_async_resume(soft_state->async);
5130Sstevel@tonic-gate if (status != DDI_SUCCESS) {
5140Sstevel@tonic-gate TNF_PROBE_0(hci1394_hardware_resume_asyn_fail,
5150Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
5160Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_hardware_resume_exit,
5170Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
5180Sstevel@tonic-gate return (DDI_FAILURE);
5190Sstevel@tonic-gate }
5200Sstevel@tonic-gate
5210Sstevel@tonic-gate /* Re-setup any Vendor Specific Registers */
5220Sstevel@tonic-gate status = hci1394_vendor_resume(soft_state->vendor);
5230Sstevel@tonic-gate if (status != DDI_SUCCESS) {
5240Sstevel@tonic-gate TNF_PROBE_0(hci1394_hardware_resume_vend_fail,
5250Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
5260Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_hardware_resume_exit,
5270Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
5280Sstevel@tonic-gate return (DDI_FAILURE);
5290Sstevel@tonic-gate }
5300Sstevel@tonic-gate
5310Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_hardware_resume_exit,
5320Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
5330Sstevel@tonic-gate
5340Sstevel@tonic-gate return (DDI_SUCCESS);
5350Sstevel@tonic-gate }
5360Sstevel@tonic-gate
5370Sstevel@tonic-gate
5380Sstevel@tonic-gate /*
5390Sstevel@tonic-gate * hci1394_pci_init()
5400Sstevel@tonic-gate * Map in PCI config space and initialize PCI config space registers.
5410Sstevel@tonic-gate */
5420Sstevel@tonic-gate static int
hci1394_pci_init(hci1394_state_t * soft_state)5430Sstevel@tonic-gate hci1394_pci_init(hci1394_state_t *soft_state)
5440Sstevel@tonic-gate {
5450Sstevel@tonic-gate int status;
5460Sstevel@tonic-gate #ifndef _LITTLE_ENDIAN
5470Sstevel@tonic-gate uint32_t global_swap;
5480Sstevel@tonic-gate #endif
5490Sstevel@tonic-gate
5500Sstevel@tonic-gate
5510Sstevel@tonic-gate ASSERT(soft_state != NULL);
5520Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_pci_init_enter, HCI1394_TNF_HAL_STACK, "");
5530Sstevel@tonic-gate
5540Sstevel@tonic-gate /* Setup PCI configuration space */
5550Sstevel@tonic-gate status = pci_config_setup(soft_state->drvinfo.di_dip,
5560Sstevel@tonic-gate &soft_state->pci_config);
5570Sstevel@tonic-gate if (status != DDI_SUCCESS) {
5580Sstevel@tonic-gate TNF_PROBE_0(hci1394_pci_init_cfg_fail, HCI1394_TNF_HAL_ERROR,
5590Sstevel@tonic-gate "");
5600Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_pci_init_exit, HCI1394_TNF_HAL_STACK,
5610Sstevel@tonic-gate "");
5620Sstevel@tonic-gate return (DDI_FAILURE);
5630Sstevel@tonic-gate }
5640Sstevel@tonic-gate
5650Sstevel@tonic-gate
5660Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
5670Sstevel@tonic-gate /* Start of little endian specific code */
5680Sstevel@tonic-gate soft_state->drvinfo.di_reg_attr.devacc_attr_version =
5690Sstevel@tonic-gate DDI_DEVICE_ATTR_V0;
5700Sstevel@tonic-gate soft_state->drvinfo.di_reg_attr.devacc_attr_endian_flags =
5710Sstevel@tonic-gate DDI_STRUCTURE_LE_ACC;
5720Sstevel@tonic-gate soft_state->drvinfo.di_reg_attr.devacc_attr_dataorder =
5730Sstevel@tonic-gate DDI_STRICTORDER_ACC;
5740Sstevel@tonic-gate soft_state->drvinfo.di_buf_attr.devacc_attr_version =
5750Sstevel@tonic-gate DDI_DEVICE_ATTR_V0;
5760Sstevel@tonic-gate soft_state->drvinfo.di_buf_attr.devacc_attr_endian_flags =
5770Sstevel@tonic-gate DDI_STRUCTURE_LE_ACC;
5780Sstevel@tonic-gate soft_state->drvinfo.di_buf_attr.devacc_attr_dataorder =
5790Sstevel@tonic-gate DDI_STRICTORDER_ACC;
5800Sstevel@tonic-gate soft_state->swap_data = B_TRUE;
5810Sstevel@tonic-gate /* End of little endian specific code */
5820Sstevel@tonic-gate #else
5830Sstevel@tonic-gate /* Start of big endian specific code */
5840Sstevel@tonic-gate /* If PCI_Global_Swap bit is not set, try to set it */
5850Sstevel@tonic-gate global_swap = pci_config_get32(soft_state->pci_config,
5860Sstevel@tonic-gate OHCI_PCI_HCI_CONTROL_REG);
5870Sstevel@tonic-gate
5880Sstevel@tonic-gate /* Lets see if the global byte swap feature is supported */
5890Sstevel@tonic-gate if ((global_swap & OHCI_PCI_GLOBAL_SWAP) == 0) {
5900Sstevel@tonic-gate global_swap = global_swap | OHCI_PCI_GLOBAL_SWAP;
5910Sstevel@tonic-gate pci_config_put32(soft_state->pci_config,
5920Sstevel@tonic-gate OHCI_PCI_HCI_CONTROL_REG, global_swap);
5930Sstevel@tonic-gate }
5940Sstevel@tonic-gate
5950Sstevel@tonic-gate global_swap = pci_config_get32(soft_state->pci_config,
5960Sstevel@tonic-gate OHCI_PCI_HCI_CONTROL_REG);
5970Sstevel@tonic-gate
5980Sstevel@tonic-gate /* If PCI_Global_Swap bit is not set, it is unsupported */
5990Sstevel@tonic-gate if ((global_swap & OHCI_PCI_GLOBAL_SWAP) == 0) {
6000Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_pci_gbs_npresent,
6010Sstevel@tonic-gate HCI1394_TNF_HAL_INFO, "global swap not present");
6020Sstevel@tonic-gate soft_state->drvinfo.di_reg_attr.devacc_attr_version =
6030Sstevel@tonic-gate DDI_DEVICE_ATTR_V0;
6040Sstevel@tonic-gate soft_state->drvinfo.di_reg_attr.devacc_attr_endian_flags =
6050Sstevel@tonic-gate DDI_STRUCTURE_LE_ACC;
6060Sstevel@tonic-gate soft_state->drvinfo.di_reg_attr.devacc_attr_dataorder =
6070Sstevel@tonic-gate DDI_STRICTORDER_ACC;
6080Sstevel@tonic-gate soft_state->drvinfo.di_buf_attr.devacc_attr_version =
6090Sstevel@tonic-gate DDI_DEVICE_ATTR_V0;
6100Sstevel@tonic-gate soft_state->drvinfo.di_buf_attr.devacc_attr_endian_flags =
6110Sstevel@tonic-gate DDI_STRUCTURE_LE_ACC;
6120Sstevel@tonic-gate soft_state->drvinfo.di_buf_attr.devacc_attr_dataorder =
6130Sstevel@tonic-gate DDI_STRICTORDER_ACC;
6140Sstevel@tonic-gate soft_state->swap_data = B_TRUE;
6150Sstevel@tonic-gate /*
6160Sstevel@tonic-gate * global byte swap is supported. This should be the case
6170Sstevel@tonic-gate * for almost all of the adapters.
6180Sstevel@tonic-gate */
6190Sstevel@tonic-gate } else {
6200Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_pci_gbs_present,
6210Sstevel@tonic-gate HCI1394_TNF_HAL_INFO, "global swap present");
6220Sstevel@tonic-gate soft_state->drvinfo.di_reg_attr.devacc_attr_version =
6230Sstevel@tonic-gate DDI_DEVICE_ATTR_V0;
6240Sstevel@tonic-gate soft_state->drvinfo.di_reg_attr.devacc_attr_endian_flags =
6250Sstevel@tonic-gate DDI_STRUCTURE_BE_ACC;
6260Sstevel@tonic-gate soft_state->drvinfo.di_reg_attr.devacc_attr_dataorder =
6270Sstevel@tonic-gate DDI_STRICTORDER_ACC;
6280Sstevel@tonic-gate soft_state->drvinfo.di_buf_attr.devacc_attr_version =
6290Sstevel@tonic-gate DDI_DEVICE_ATTR_V0;
6300Sstevel@tonic-gate soft_state->drvinfo.di_buf_attr.devacc_attr_endian_flags =
6310Sstevel@tonic-gate DDI_STRUCTURE_BE_ACC;
6320Sstevel@tonic-gate soft_state->drvinfo.di_buf_attr.devacc_attr_dataorder =
6330Sstevel@tonic-gate DDI_STRICTORDER_ACC;
6340Sstevel@tonic-gate soft_state->swap_data = B_FALSE;
6350Sstevel@tonic-gate }
6360Sstevel@tonic-gate /* End of big endian specific code */
6370Sstevel@tonic-gate #endif
6380Sstevel@tonic-gate
6390Sstevel@tonic-gate /* read in vendor Information */
6400Sstevel@tonic-gate soft_state->vendor_info.vendor_id =
6410Sstevel@tonic-gate (uint_t)pci_config_get16(soft_state->pci_config, PCI_CONF_VENID);
6420Sstevel@tonic-gate soft_state->vendor_info.device_id =
6430Sstevel@tonic-gate (uint_t)pci_config_get16(soft_state->pci_config, PCI_CONF_DEVID);
6440Sstevel@tonic-gate soft_state->vendor_info.revision_id =
6450Sstevel@tonic-gate (uint_t)pci_config_get8(soft_state->pci_config, PCI_CONF_REVID);
6460Sstevel@tonic-gate
6470Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_pci_init_exit, HCI1394_TNF_HAL_STACK, "");
6480Sstevel@tonic-gate
6490Sstevel@tonic-gate return (DDI_SUCCESS);
6500Sstevel@tonic-gate }
6510Sstevel@tonic-gate
6520Sstevel@tonic-gate
6530Sstevel@tonic-gate /*
6540Sstevel@tonic-gate * hci1394_pci_resume()
6550Sstevel@tonic-gate * Re-Initialize PCI config space registers during a resume.
6560Sstevel@tonic-gate */
6570Sstevel@tonic-gate /* ARGSUSED */
6580Sstevel@tonic-gate static void
hci1394_pci_resume(hci1394_state_t * soft_state)6590Sstevel@tonic-gate hci1394_pci_resume(hci1394_state_t *soft_state)
6600Sstevel@tonic-gate {
6610Sstevel@tonic-gate #ifndef _LITTLE_ENDIAN
6620Sstevel@tonic-gate uint32_t global_swap;
6630Sstevel@tonic-gate #endif
6640Sstevel@tonic-gate
6650Sstevel@tonic-gate
6660Sstevel@tonic-gate ASSERT(soft_state != NULL);
6670Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_pci_resume_enter, HCI1394_TNF_HAL_STACK, "");
6680Sstevel@tonic-gate
6690Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
6700Sstevel@tonic-gate /* Start of little endian specific code */
6710Sstevel@tonic-gate /* nothing to do here yet. Maybe later?? */
6720Sstevel@tonic-gate /* End of little endian specific code */
6730Sstevel@tonic-gate #else
6740Sstevel@tonic-gate /* Start of big endian specific code */
6750Sstevel@tonic-gate /* If PCI_Global_Swap bit is not set, try to set it */
6760Sstevel@tonic-gate global_swap = pci_config_get32(soft_state->pci_config,
6770Sstevel@tonic-gate OHCI_PCI_HCI_CONTROL_REG);
6780Sstevel@tonic-gate /* Try and set GlobalByteSwap */
6790Sstevel@tonic-gate if ((global_swap & OHCI_PCI_GLOBAL_SWAP) == 0) {
6800Sstevel@tonic-gate global_swap = global_swap | OHCI_PCI_GLOBAL_SWAP;
6810Sstevel@tonic-gate pci_config_put32(soft_state->pci_config,
6820Sstevel@tonic-gate OHCI_PCI_HCI_CONTROL_REG, global_swap);
6830Sstevel@tonic-gate }
6840Sstevel@tonic-gate /* End of big endian specific code */
6850Sstevel@tonic-gate #endif
6860Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_pci_resume_exit, HCI1394_TNF_HAL_STACK, "");
6870Sstevel@tonic-gate }
6880Sstevel@tonic-gate
6890Sstevel@tonic-gate
6900Sstevel@tonic-gate /*
6910Sstevel@tonic-gate * hci1394_resmap_get()
6920Sstevel@tonic-gate * Look for adapter property "reserved-addresses". This property is used to
6930Sstevel@tonic-gate * reserve 1394 address space so that it will not randomly be given to a
6940Sstevel@tonic-gate * target driver during a 1394 address space alloc. Some protocols hard
6950Sstevel@tonic-gate * code addresses which make us do this. The target driver must specifically
6960Sstevel@tonic-gate * ask for these addresses. This routine should be called before the
6970Sstevel@tonic-gate * call to h1394_attach().
6980Sstevel@tonic-gate */
6990Sstevel@tonic-gate static int
hci1394_resmap_get(hci1394_state_t * soft_state)7000Sstevel@tonic-gate hci1394_resmap_get(hci1394_state_t *soft_state)
7010Sstevel@tonic-gate {
7020Sstevel@tonic-gate h1394_addr_map_t *resv_map;
7030Sstevel@tonic-gate int resv_num;
7040Sstevel@tonic-gate int status;
7050Sstevel@tonic-gate int reslen;
7060Sstevel@tonic-gate uint32_t *resptr;
7070Sstevel@tonic-gate int rescnt;
7080Sstevel@tonic-gate int mapcnt;
7090Sstevel@tonic-gate
7100Sstevel@tonic-gate
7110Sstevel@tonic-gate ASSERT(soft_state != NULL);
7120Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_resmap_get_enter, HCI1394_TNF_HAL_STACK, "");
7130Sstevel@tonic-gate
7140Sstevel@tonic-gate /*
7150Sstevel@tonic-gate * See if the "reserved-addresses" property is defined. The format
7160Sstevel@tonic-gate * should be:
7170Sstevel@tonic-gate *
7180Sstevel@tonic-gate * reserved-addresses= 0x0000ffff,0xf0000B00,0x200,
7190Sstevel@tonic-gate * 0x0000ffff,0xf0000D00,0x200,
7200Sstevel@tonic-gate * 0x0000ffff,0xf0000234,0x4;
7210Sstevel@tonic-gate * You can have multiple reserved addresses. Each reserved address
7220Sstevel@tonic-gate * takes up 3 integers.
7230Sstevel@tonic-gate * MSWofAddr,LSWofAddr,ByteCount
7240Sstevel@tonic-gate */
7250Sstevel@tonic-gate status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY,
7260Sstevel@tonic-gate soft_state->drvinfo.di_dip, DDI_PROP_DONTPASS, "reserved-addresses",
7270Sstevel@tonic-gate (int **)&resptr, (uint_t *)&reslen);
7280Sstevel@tonic-gate if (status != DDI_PROP_SUCCESS) {
7290Sstevel@tonic-gate /* the property is not defined, 0 reserved addresses */
7300Sstevel@tonic-gate soft_state->halinfo.resv_map_num_entries = 0;
7310Sstevel@tonic-gate soft_state->halinfo.resv_map = NULL;
7320Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_resmap_get_exit,
7330Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
7340Sstevel@tonic-gate return (DDI_SUCCESS);
7350Sstevel@tonic-gate } else if ((reslen < 3) || ((reslen % 3) != 0)) {
7360Sstevel@tonic-gate /*
7370Sstevel@tonic-gate * the property is defined but the correct number of integers
7380Sstevel@tonic-gate * is not present.
7390Sstevel@tonic-gate */
7400Sstevel@tonic-gate resv_num = 0;
7410Sstevel@tonic-gate resv_map = NULL;
7420Sstevel@tonic-gate cmn_err(CE_NOTE, "!%s(%d): Invalid reserved-addresses property."
7430Sstevel@tonic-gate " Property ignored", ddi_node_name(
7440Sstevel@tonic-gate soft_state->drvinfo.di_dip), ddi_get_instance(
7450Sstevel@tonic-gate soft_state->drvinfo.di_dip));
7460Sstevel@tonic-gate } else {
7470Sstevel@tonic-gate /* the property is defined. Alloc space to copy data into */
7480Sstevel@tonic-gate resv_num = reslen / 3;
7490Sstevel@tonic-gate resv_map = kmem_alloc((sizeof (h1394_addr_map_t) * (resv_num)),
7500Sstevel@tonic-gate KM_SLEEP);
7510Sstevel@tonic-gate
7520Sstevel@tonic-gate /* read in the address, length, and set the type to reserved */
7530Sstevel@tonic-gate rescnt = 0;
7540Sstevel@tonic-gate mapcnt = 0;
7550Sstevel@tonic-gate while (rescnt < reslen) {
7560Sstevel@tonic-gate resv_map[mapcnt].address =
7570Sstevel@tonic-gate (uint64_t)resptr[rescnt] << 32;
7580Sstevel@tonic-gate rescnt++;
7590Sstevel@tonic-gate resv_map[mapcnt].address |= (uint64_t)resptr[rescnt];
7600Sstevel@tonic-gate rescnt++;
7610Sstevel@tonic-gate resv_map[mapcnt].length = (uint64_t)resptr[rescnt];
7620Sstevel@tonic-gate rescnt++;
7630Sstevel@tonic-gate resv_map[mapcnt].addr_type = H1394_ADDR_RESERVED;
7640Sstevel@tonic-gate mapcnt++;
7650Sstevel@tonic-gate }
7660Sstevel@tonic-gate }
7670Sstevel@tonic-gate
7680Sstevel@tonic-gate ddi_prop_free(resptr);
7690Sstevel@tonic-gate
7700Sstevel@tonic-gate /*
7710Sstevel@tonic-gate * copy the number of reserved address ranges and a pointer to the map
7720Sstevel@tonic-gate * into halinfo so we can tell the services layer about them in
7730Sstevel@tonic-gate * h1394_attach()
7740Sstevel@tonic-gate */
7750Sstevel@tonic-gate soft_state->halinfo.resv_map_num_entries = resv_num;
7760Sstevel@tonic-gate soft_state->halinfo.resv_map = resv_map;
7770Sstevel@tonic-gate
7780Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_resmap_get_exit, HCI1394_TNF_HAL_STACK, "");
7790Sstevel@tonic-gate
7800Sstevel@tonic-gate return (DDI_SUCCESS);
7810Sstevel@tonic-gate }
7820Sstevel@tonic-gate
7830Sstevel@tonic-gate
7840Sstevel@tonic-gate /*
7850Sstevel@tonic-gate * hci1394_resmap_free()
7860Sstevel@tonic-gate * Free up the space alloced in hci1394_resmap_get(). This routine should
7870Sstevel@tonic-gate * be called after h1394_attach(). The HAL does not need this information
7880Sstevel@tonic-gate * and the services layer only uses it for a calculation during attach and
7890Sstevel@tonic-gate * should not refer to the pointer after it returns from h1394_attach().
7900Sstevel@tonic-gate */
7910Sstevel@tonic-gate static void
hci1394_resmap_free(hci1394_state_t * soft_state)7920Sstevel@tonic-gate hci1394_resmap_free(hci1394_state_t *soft_state)
7930Sstevel@tonic-gate {
7940Sstevel@tonic-gate ASSERT(soft_state != NULL);
7950Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_resmap_free_enter, HCI1394_TNF_HAL_STACK, "");
7960Sstevel@tonic-gate
7970Sstevel@tonic-gate /*
7980Sstevel@tonic-gate * if we have one or more reserved map entries, free up the space that
7990Sstevel@tonic-gate * was allocated to store them
8000Sstevel@tonic-gate */
8010Sstevel@tonic-gate if (soft_state->halinfo.resv_map_num_entries > 0) {
8020Sstevel@tonic-gate ASSERT(soft_state->halinfo.resv_map != NULL);
8030Sstevel@tonic-gate kmem_free(soft_state->halinfo.resv_map,
8040Sstevel@tonic-gate (sizeof (h1394_addr_map_t) *
8050Sstevel@tonic-gate soft_state->halinfo.resv_map_num_entries));
8060Sstevel@tonic-gate }
8070Sstevel@tonic-gate
8080Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_resmap_free_exit, HCI1394_TNF_HAL_STACK, "");
8090Sstevel@tonic-gate }
8100Sstevel@tonic-gate
8110Sstevel@tonic-gate
8120Sstevel@tonic-gate /*
8130Sstevel@tonic-gate * hci1394_statebit_set()
8140Sstevel@tonic-gate * Set bit "statebit" in "state"
8150Sstevel@tonic-gate */
8160Sstevel@tonic-gate static void
hci1394_statebit_set(uint64_t * state,uint_t statebit)8170Sstevel@tonic-gate hci1394_statebit_set(uint64_t *state, uint_t statebit)
8180Sstevel@tonic-gate {
8190Sstevel@tonic-gate ASSERT(state != NULL);
8200Sstevel@tonic-gate ASSERT(statebit < 64);
8210Sstevel@tonic-gate *state |= (uint64_t)0x1 << statebit;
8220Sstevel@tonic-gate }
8230Sstevel@tonic-gate
8240Sstevel@tonic-gate
8250Sstevel@tonic-gate /*
8260Sstevel@tonic-gate * hci1394_statebit_tst()
8270Sstevel@tonic-gate * Return status of bit "statebit". Is it set or not?
8280Sstevel@tonic-gate */
8290Sstevel@tonic-gate static boolean_t
hci1394_statebit_tst(uint64_t state,uint_t statebit)8300Sstevel@tonic-gate hci1394_statebit_tst(uint64_t state, uint_t statebit)
8310Sstevel@tonic-gate {
8320Sstevel@tonic-gate uint64_t bitset;
8330Sstevel@tonic-gate int status;
8340Sstevel@tonic-gate
8350Sstevel@tonic-gate
8360Sstevel@tonic-gate ASSERT(statebit < 64);
8370Sstevel@tonic-gate bitset = state & ((uint64_t)0x1 << statebit);
8380Sstevel@tonic-gate if (bitset == 0) {
8390Sstevel@tonic-gate status = B_FALSE;
8400Sstevel@tonic-gate } else {
8410Sstevel@tonic-gate status = B_TRUE;
8420Sstevel@tonic-gate }
8430Sstevel@tonic-gate return (status);
8440Sstevel@tonic-gate }
8450Sstevel@tonic-gate
8460Sstevel@tonic-gate
8470Sstevel@tonic-gate /*
8480Sstevel@tonic-gate * hci1394_cleanup()
8490Sstevel@tonic-gate * Cleanup after a failed attach
8500Sstevel@tonic-gate */
8510Sstevel@tonic-gate static void
hci1394_cleanup(hci1394_state_t * soft_state,uint64_t attach_state)8520Sstevel@tonic-gate hci1394_cleanup(hci1394_state_t *soft_state, uint64_t attach_state)
8530Sstevel@tonic-gate {
8540Sstevel@tonic-gate int status;
8550Sstevel@tonic-gate
8560Sstevel@tonic-gate
8570Sstevel@tonic-gate ASSERT(soft_state != NULL);
8580Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_cleanup_enter, HCI1394_TNF_HAL_STACK, "");
8590Sstevel@tonic-gate
8600Sstevel@tonic-gate
8610Sstevel@tonic-gate status = hci1394_statebit_tst(attach_state, STATE_STARTUP);
8620Sstevel@tonic-gate if (status == B_TRUE) {
8630Sstevel@tonic-gate /* Don't allow the HW to generate any more interrupts */
8640Sstevel@tonic-gate hci1394_ohci_intr_master_disable(soft_state->ohci);
8650Sstevel@tonic-gate
8660Sstevel@tonic-gate /* don't accept anymore commands from services layer */
8670Sstevel@tonic-gate (void) hci1394_state_set(&soft_state->drvinfo,
8680Sstevel@tonic-gate HCI1394_SHUTDOWN);
8690Sstevel@tonic-gate
8700Sstevel@tonic-gate /* Reset the chip */
8710Sstevel@tonic-gate (void) hci1394_ohci_soft_reset(soft_state->ohci);
8720Sstevel@tonic-gate
8730Sstevel@tonic-gate /* Flush out async DMA Q's (cancels pendingQ timeouts too) */
8740Sstevel@tonic-gate hci1394_async_flush(soft_state->async);
8750Sstevel@tonic-gate }
8760Sstevel@tonic-gate
8770Sstevel@tonic-gate status = hci1394_statebit_tst(attach_state, STATE_ISR_HANDLER);
8780Sstevel@tonic-gate if (status == B_TRUE) {
8790Sstevel@tonic-gate hci1394_isr_handler_fini(soft_state);
8800Sstevel@tonic-gate }
8810Sstevel@tonic-gate
8820Sstevel@tonic-gate status = hci1394_statebit_tst(attach_state, STATE_H1394_ATTACH);
8830Sstevel@tonic-gate if (status == B_TRUE) {
8840Sstevel@tonic-gate (void) h1394_detach(&soft_state->drvinfo.di_sl_private,
8850Sstevel@tonic-gate DDI_DETACH);
8860Sstevel@tonic-gate }
8870Sstevel@tonic-gate
8880Sstevel@tonic-gate status = hci1394_statebit_tst(attach_state, STATE_HW_INIT);
8890Sstevel@tonic-gate if (status == B_TRUE) {
8900Sstevel@tonic-gate hci1394_detach_hardware(soft_state);
8910Sstevel@tonic-gate }
8920Sstevel@tonic-gate
8930Sstevel@tonic-gate status = hci1394_statebit_tst(attach_state, STATE_MINOR_NODE);
8940Sstevel@tonic-gate if (status == B_TRUE) {
8950Sstevel@tonic-gate ddi_remove_minor_node(soft_state->drvinfo.di_dip, "devctl");
8960Sstevel@tonic-gate }
8970Sstevel@tonic-gate
8980Sstevel@tonic-gate status = hci1394_statebit_tst(attach_state, STATE_ISR_INIT);
8990Sstevel@tonic-gate if (status == B_TRUE) {
9000Sstevel@tonic-gate hci1394_isr_fini(soft_state);
9010Sstevel@tonic-gate }
9020Sstevel@tonic-gate
9030Sstevel@tonic-gate status = hci1394_statebit_tst(attach_state, STATE_PHASE2);
9040Sstevel@tonic-gate if (status == B_TRUE) {
9050Sstevel@tonic-gate hci1394_soft_state_fini(soft_state);
9060Sstevel@tonic-gate }
9070Sstevel@tonic-gate
9080Sstevel@tonic-gate status = hci1394_statebit_tst(attach_state, STATE_ZALLOC);
9090Sstevel@tonic-gate if (status == B_TRUE) {
9100Sstevel@tonic-gate ddi_soft_state_free(hci1394_statep,
9110Sstevel@tonic-gate soft_state->drvinfo.di_instance);
9120Sstevel@tonic-gate }
9130Sstevel@tonic-gate
9140Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_cleanup_exit, HCI1394_TNF_HAL_STACK, "");
9150Sstevel@tonic-gate }
916