xref: /titanic_52/usr/src/uts/common/io/1394/adapters/hci1394.c (revision fa9e4066f08beec538e775443c5be79dd423fcab)
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