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 (c) 1999-2000 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * hci1394_misc.c 31 * Misc. HBA functions. These include getinfo, open, close, shutdown, and 32 * overall driver state control functions. 33 */ 34 35 #include <sys/conf.h> 36 #include <sys/ddi.h> 37 #include <sys/modctl.h> 38 #include <sys/sunddi.h> 39 #include <sys/types.h> 40 #include <sys/mkdev.h> 41 42 #include <sys/1394/adapters/hci1394.h> 43 #include <sys/1394/adapters/hci1394_extern.h> 44 45 46 47 /* ARGSUSED */ 48 int 49 hci1394_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 50 { 51 dev_t dev; 52 hci1394_state_t *soft_state; 53 minor_t instance; 54 int status; 55 56 57 TNF_PROBE_0_DEBUG(hci1394_getinfo_enter, HCI1394_TNF_HAL_STACK, ""); 58 59 switch (cmd) { 60 case DDI_INFO_DEVT2DEVINFO: 61 dev = (dev_t)arg; 62 instance = getminor(dev); 63 soft_state = ddi_get_soft_state(hci1394_statep, instance); 64 if (soft_state == NULL) { 65 TNF_PROBE_1(hci1394_getinfo_gss_fail, 66 HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg, 67 "ddi_get_soft_state() failed"); 68 TNF_PROBE_0_DEBUG(hci1394_getinfo_exit, 69 HCI1394_TNF_HAL_STACK, ""); 70 return (DDI_FAILURE); 71 } 72 *result = (void *)soft_state->drvinfo.di_dip; 73 status = DDI_SUCCESS; 74 break; 75 76 case DDI_INFO_DEVT2INSTANCE: 77 dev = (dev_t)arg; 78 instance = getminor(dev); 79 *result = (void *)(uintptr_t)instance; 80 status = DDI_SUCCESS; 81 break; 82 83 default: 84 TNF_PROBE_1(hci1394_getinfo_def_fail, HCI1394_TNF_HAL_ERROR, "", 85 tnf_string, errmsg, "reached default in switch"); 86 status = DDI_FAILURE; 87 } 88 89 TNF_PROBE_0_DEBUG(hci1394_getinfo_exit, HCI1394_TNF_HAL_STACK, ""); 90 return (status); 91 } 92 93 94 /* ARGSUSED */ 95 int 96 hci1394_open(dev_t *devp, int flag, int otyp, cred_t *credp) 97 { 98 hci1394_state_t *soft_state; 99 100 101 TNF_PROBE_0_DEBUG(hci1394_open_enter, HCI1394_TNF_HAL_STACK, ""); 102 103 soft_state = ddi_get_soft_state(hci1394_statep, getminor(*devp)); 104 if (soft_state == NULL) { 105 TNF_PROBE_1(hci1394_open_gss_fail, HCI1394_TNF_HAL_ERROR, "", 106 tnf_string, errmsg, "ddi_get_soft_state() failed"); 107 TNF_PROBE_0_DEBUG(hci1394_open_exit, HCI1394_TNF_HAL_STACK, ""); 108 return (ENXIO); 109 } 110 111 TNF_PROBE_0_DEBUG(hci1394_open_exit, HCI1394_TNF_HAL_STACK, ""); 112 return (0); 113 } 114 115 116 /* ARGSUSED */ 117 int 118 hci1394_close(dev_t dev, int flag, int otyp, cred_t *credp) 119 { 120 TNF_PROBE_0_DEBUG(hci1394_close_enter, HCI1394_TNF_HAL_STACK, ""); 121 122 TNF_PROBE_0_DEBUG(hci1394_close_exit, HCI1394_TNF_HAL_STACK, ""); 123 124 return (0); 125 } 126 127 128 /* 129 * hci1394_shutdown() 130 * Shutdown the HW. Something bad that we cannot recover from happened. 131 */ 132 void 133 hci1394_shutdown(dev_info_t *dip) 134 { 135 hci1394_state_t *soft_state; 136 137 138 /* 139 * In the debug version of the driver, we want to do an assert here so 140 * that we don't reset the hardware and can look and see what happened 141 * to cause the shutdown. 142 */ 143 #ifndef TEST_SHUTDOWN 144 ASSERT(0); 145 #endif 146 147 TNF_PROBE_0_DEBUG(hci1394_shutdown_enter, HCI1394_TNF_HAL_STACK, ""); 148 149 soft_state = ddi_get_soft_state(hci1394_statep, ddi_get_instance(dip)); 150 if (soft_state == NULL) { 151 TNF_PROBE_1(hci1394_shutdown_gss_fail, HCI1394_TNF_HAL_ERROR, 152 "", tnf_string, errmsg, "ddi_get_soft_state() failed"); 153 TNF_PROBE_0_DEBUG(hci1394_shutdown_exit, 154 HCI1394_TNF_HAL_STACK, ""); 155 return; 156 } 157 158 /* 159 * Don't allow the HW to generate any more interrupts. Make sure we 160 * disable interrupts before setting the driver state to shutdown. 161 */ 162 hci1394_ohci_intr_master_disable(soft_state->ohci); 163 164 /* don't accept anymore commands from services layer */ 165 (void) hci1394_state_set(&soft_state->drvinfo, HCI1394_SHUTDOWN); 166 167 /* Reset the OHCI HW */ 168 (void) hci1394_ohci_soft_reset(soft_state->ohci); 169 170 /* Flush out async DMA Q's (cancels pendingQ timeouts too) */ 171 hci1394_async_flush(soft_state->async); 172 173 TNF_PROBE_0_DEBUG(hci1394_shutdown_exit, HCI1394_TNF_HAL_STACK, ""); 174 } 175 176 177 /* 178 * hci1394_state() 179 * returns the current state of the driver 180 */ 181 hci1394_statevar_t 182 hci1394_state(hci1394_drvinfo_t *drvinfo) 183 { 184 hci1394_statevar_t hal_state; 185 186 TNF_PROBE_0_DEBUG(hci1394_state_enter, HCI1394_TNF_HAL_STACK, ""); 187 mutex_enter(&drvinfo->di_drvstate.ds_mutex); 188 hal_state = drvinfo->di_drvstate.ds_state; 189 mutex_exit(&drvinfo->di_drvstate.ds_mutex); 190 TNF_PROBE_0_DEBUG(hci1394_state_exit, HCI1394_TNF_HAL_STACK, ""); 191 192 return (hal_state); 193 } 194 195 196 /* 197 * hci1394_state_set() 198 * Set the current state of the driver. This routine will return failure 199 * if the driver state is currently set to HCI1394_SHUTDOWN. We do not 200 * allow a transition out of shutdown. 201 */ 202 int 203 hci1394_state_set(hci1394_drvinfo_t *drvinfo, hci1394_statevar_t state) 204 { 205 TNF_PROBE_0_DEBUG(hci1394_state_set_enter, HCI1394_TNF_HAL_STACK, ""); 206 mutex_enter(&drvinfo->di_drvstate.ds_mutex); 207 208 /* Do not allow a transition out of shutdown */ 209 if (drvinfo->di_drvstate.ds_state == HCI1394_SHUTDOWN) { 210 mutex_exit(&drvinfo->di_drvstate.ds_mutex); 211 TNF_PROBE_1(hci1394_state_set_fail, HCI1394_TNF_HAL_STACK, "", 212 tnf_string, errmsg, "driver shutdown"); 213 TNF_PROBE_0_DEBUG(hci1394_state_set_exit, HCI1394_TNF_HAL_STACK, 214 ""); 215 return (DDI_FAILURE); 216 } 217 218 drvinfo->di_drvstate.ds_state = state; 219 mutex_exit(&drvinfo->di_drvstate.ds_mutex); 220 TNF_PROBE_0_DEBUG(hci1394_state_set_exit, HCI1394_TNF_HAL_STACK, ""); 221 222 return (DDI_SUCCESS); 223 } 224