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.c 31 * 1394 (firewire) OpenHCI 1.0 HBA driver. This file contains the driver's 32 * _init(), _info(), and _fini(). 33 */ 34 35 #include <sys/modctl.h> 36 #include <sys/conf.h> 37 #include <sys/ddi.h> 38 #include <sys/sunddi.h> 39 40 #include <sys/1394/ieee1394.h> 41 #include <sys/1394/h1394.h> 42 43 #include <sys/1394/adapters/hci1394.h> 44 45 46 /* HAL State Pointer */ 47 void *hci1394_statep; 48 49 /* Character/Block Operations */ 50 static struct cb_ops hci1394_cb_ops = { 51 hci1394_open, /* open */ 52 hci1394_close, /* close */ 53 nodev, /* strategy (block) */ 54 nodev, /* print (block) */ 55 nodev, /* dump (block) */ 56 nodev, /* read */ 57 nodev, /* write */ 58 hci1394_ioctl, /* ioctl */ 59 nodev, /* devmap */ 60 nodev, /* mmap */ 61 nodev, /* segmap */ 62 nochpoll, /* chpoll */ 63 ddi_prop_op, /* prop_op */ 64 NULL, /* streams */ 65 D_NEW | D_MP | 66 D_64BIT | D_HOTPLUG, /* flags */ 67 CB_REV /* rev */ 68 }; 69 70 /* Driver Operations */ 71 static struct dev_ops hci1394_ops = { 72 DEVO_REV, /* struct rev */ 73 0, /* refcnt */ 74 hci1394_getinfo, /* getinfo */ 75 nulldev, /* identify */ 76 nulldev, /* probe */ 77 hci1394_attach, /* attach */ 78 hci1394_detach, /* detach */ 79 nodev, /* reset */ 80 &hci1394_cb_ops, /* cb_ops */ 81 NULL, /* bus_ops */ 82 NULL /* power */ 83 }; 84 85 /* Module Driver Info */ 86 static struct modldrv hci1394_modldrv = { 87 &mod_driverops, 88 "1394 OpenHCI HBA driver v1.0", 89 &hci1394_ops 90 }; 91 92 /* Module Linkage */ 93 static struct modlinkage hci1394_modlinkage = { 94 MODREV_1, 95 &hci1394_modldrv, 96 NULL 97 }; 98 99 #ifndef NPROBE 100 extern int tnf_mod_load(void); 101 extern int tnf_mod_unload(struct modlinkage *mlp); 102 #endif 103 104 int 105 _init() 106 { 107 int status; 108 109 110 #ifndef NPROBE 111 (void) tnf_mod_load(); 112 #endif 113 TNF_PROBE_0_DEBUG(hci1394_init_enter, HCI1394_TNF_HAL_STACK, ""); 114 115 status = ddi_soft_state_init(&hci1394_statep, sizeof (hci1394_state_t), 116 (size_t)HCI1394_INITIAL_STATES); 117 if (status != 0) { 118 TNF_PROBE_2(hci1394_init_ssi_fail, HCI1394_TNF_HAL_ERROR, "", 119 tnf_string, errmsg, "failed in ddi_soft_state_init", 120 tnf_int, error, status); 121 TNF_PROBE_0_DEBUG(hci1394_init_exit, HCI1394_TNF_HAL_STACK, ""); 122 #ifndef NPROBE 123 (void) tnf_mod_unload(&hci1394_modlinkage); 124 #endif 125 return (status); 126 } 127 128 /* Call into services layer to init bus-ops */ 129 status = h1394_init(&hci1394_modlinkage); 130 if (status != 0) { 131 TNF_PROBE_2(hci1394_init_h1394_fail, HCI1394_TNF_HAL_ERROR, "", 132 tnf_string, errmsg, "failed in h1394_init", 133 tnf_int, error, status); 134 TNF_PROBE_0_DEBUG(hci1394_init_exit, HCI1394_TNF_HAL_STACK, ""); 135 #ifndef NPROBE 136 (void) tnf_mod_unload(&hci1394_modlinkage); 137 #endif 138 return (status); 139 } 140 141 status = mod_install(&hci1394_modlinkage); 142 if (status != 0) { 143 TNF_PROBE_2(hci1394_init_modi_fail, HCI1394_TNF_HAL_ERROR, "", 144 tnf_string, errmsg, "failed in mod_install", 145 tnf_int, error, status); 146 ddi_soft_state_fini(&hci1394_statep); 147 #ifndef NPROBE 148 (void) tnf_mod_unload(&hci1394_modlinkage); 149 #endif 150 return (status); 151 } 152 153 TNF_PROBE_0_DEBUG(hci1394_init_exit, HCI1394_TNF_HAL_STACK, ""); 154 155 return (status); 156 } 157 158 159 int 160 _info(struct modinfo *modinfop) 161 { 162 int status; 163 164 TNF_PROBE_0_DEBUG(hci1394_info_enter, HCI1394_TNF_HAL_STACK, ""); 165 status = mod_info(&hci1394_modlinkage, modinfop); 166 TNF_PROBE_0_DEBUG(hci1394_info_exit, HCI1394_TNF_HAL_STACK, ""); 167 168 return (status); 169 } 170 171 172 int 173 _fini() 174 { 175 int status; 176 177 TNF_PROBE_0_DEBUG(hci1394_fini_enter, HCI1394_TNF_HAL_STACK, ""); 178 179 status = mod_remove(&hci1394_modlinkage); 180 if (status != 0) { 181 TNF_PROBE_2(hci1394_fini_modr_fail, HCI1394_TNF_HAL_ERROR, "", 182 tnf_string, errmsg, "failed in mod_remove", 183 tnf_int, error, status); 184 TNF_PROBE_0_DEBUG(hci1394_fini_exit, HCI1394_TNF_HAL_STACK, ""); 185 return (status); 186 } 187 188 /* Call into services layer notify about _fini */ 189 h1394_fini(&hci1394_modlinkage); 190 ddi_soft_state_fini(&hci1394_statep); 191 192 TNF_PROBE_0_DEBUG(hci1394_fini_exit, HCI1394_TNF_HAL_STACK, ""); 193 194 #ifndef NPROBE 195 (void) tnf_mod_unload(&hci1394_modlinkage); 196 #endif 197 198 return (status); 199 } 200