xref: /illumos-gate/usr/src/uts/common/io/1394/adapters/hci1394.c (revision d583b39bfb4e2571d3e41097c5c357ffe353ad45)
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 }
199