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
_init()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
_info(struct modinfo * modinfop)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
_fini()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 }
199