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