5255 uts shouldn't open-code ISP2
[illumos-gate.git] / usr / src / uts / common / io / 1394 / s1394_fa.c
blob04a6f4ec7f08fdcb65d8816af73519b9094f9473
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
23 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * s1394_fa.c
31 * 1394 Services Layer Fixed Address Support Routines
32 * Currently used for FCP support.
35 #include <sys/conf.h>
36 #include <sys/ddi.h>
37 #include <sys/sunddi.h>
38 #include <sys/cmn_err.h>
39 #include <sys/types.h>
40 #include <sys/kmem.h>
41 #include <sys/tnf_probe.h>
43 #include <sys/1394/t1394.h>
44 #include <sys/1394/s1394.h>
45 #include <sys/1394/h1394.h>
47 static void s1394_fa_completion_cb(cmd1394_cmd_t *cmd);
50 * s1394_fa_claim_addr_blk()
51 * Claim fixed address block.
53 int
54 s1394_fa_claim_addr(s1394_hal_t *hal, s1394_fa_type_t type,
55 s1394_fa_descr_t *descr)
57 t1394_alloc_addr_t addr;
58 s1394_fa_hal_t *falp = &hal->hal_fa[type];
59 int ret;
61 TNF_PROBE_0_DEBUG(s1394_fa_claim_addr_enter, S1394_TNF_SL_FA_STACK, "");
63 /* Might have been claimed already */
64 if (falp->fal_addr_blk != NULL) {
65 TNF_PROBE_0_DEBUG(s1394_fa_claim_addr_exit,
66 S1394_TNF_SL_FA_STACK, "");
67 return (DDI_SUCCESS);
70 falp->fal_descr = descr;
72 bzero(&addr, sizeof (addr));
73 addr.aa_type = T1394_ADDR_FIXED;
74 addr.aa_address = descr->fd_addr;
75 addr.aa_length = descr->fd_size;
76 addr.aa_enable = descr->fd_enable;
77 addr.aa_evts = descr->fd_evts;
78 addr.aa_arg = hal;
80 ret = s1394_claim_addr_blk(hal, &addr);
81 if (ret != DDI_SUCCESS) {
82 TNF_PROBE_2(s1394_fa_claim_addr_error, S1394_TNF_SL_FA_ERROR,
83 "", tnf_int, type, type, tnf_int, ret, ret);
84 } else {
85 falp->fal_addr_blk = (s1394_addr_space_blk_t *)addr.aa_hdl;
88 TNF_PROBE_0_DEBUG(s1394_fa_claim_addr_exit, S1394_TNF_SL_FA_STACK, "");
89 return (ret);
93 * s1394_fa_free_addr_blk()
94 * Free fixed address block.
96 void
97 s1394_fa_free_addr(s1394_hal_t *hal, s1394_fa_type_t type)
99 s1394_fa_hal_t *falp = &hal->hal_fa[type];
100 int ret;
102 TNF_PROBE_0_DEBUG(s1394_fa_free_addr_enter, S1394_TNF_SL_FA_STACK, "");
104 /* Might have been freed already */
105 if (falp->fal_addr_blk != NULL) {
106 ret = s1394_free_addr_blk(hal, falp->fal_addr_blk);
107 if (ret != DDI_SUCCESS) {
108 TNF_PROBE_1(s1394_fa_free_addr_error,
109 S1394_TNF_SL_FA_STACK, "", tnf_int, ret, ret);
111 falp->fal_addr_blk = NULL;
114 TNF_PROBE_0_DEBUG(s1394_fa_free_addr_exit, S1394_TNF_SL_FA_STACK, "");
118 * s1394_fa_list_add()
119 * Add target to the list of FA clients.
120 * target_list_rwlock should be writer-held.
122 void
123 s1394_fa_list_add(s1394_hal_t *hal, s1394_target_t *target,
124 s1394_fa_type_t type)
126 s1394_fa_hal_t *fal = &hal->hal_fa[type];
128 if (fal->fal_head == NULL) {
129 ASSERT(fal->fal_tail == NULL);
130 fal->fal_head = fal->fal_tail = target;
131 } else {
132 fal->fal_tail->target_fa[type].fat_next = target;
133 fal->fal_tail = target;
135 fal->fal_gen++;
139 * s1394_fa_list_remove()
140 * Remove target from the list of FA clients.
141 * target_list_rwlock should be writer-held.
144 s1394_fa_list_remove(s1394_hal_t *hal, s1394_target_t *target,
145 s1394_fa_type_t type)
147 s1394_fa_hal_t *fal = &hal->hal_fa[type];
148 s1394_target_t *curp, **nextp, *prevp = NULL;
150 for (nextp = &fal->fal_head; (curp = *nextp) != NULL; ) {
151 if (curp == target) {
152 *nextp = target->target_fa[type].fat_next;
153 if (target == fal->fal_tail) {
154 fal->fal_tail = prevp;
156 fal->fal_gen++;
157 return (DDI_SUCCESS);
159 nextp = &curp->target_fa[type].fat_next;
160 prevp = curp;
162 return (DDI_FAILURE);
166 * s1394_fa_list_is_empty()
167 * Returns B_TRUE if the target list is empty
168 * target_list_rwlock should be at least reader-held.
170 boolean_t
171 s1394_fa_list_is_empty(s1394_hal_t *hal, s1394_fa_type_t type)
173 s1394_fa_hal_t *fal = &hal->hal_fa[type];
175 return (fal->fal_head == NULL);
179 * s1394_fa_list_gen()
180 * Returns list generation number.
181 * target_list_rwlock should be at least reader-held.
183 uint_t
184 s1394_fa_list_gen(s1394_hal_t *hal, s1394_fa_type_t type)
186 s1394_fa_hal_t *fal = &hal->hal_fa[type];
188 return (fal->fal_gen);
192 * s1394_fa_init_cmd()
193 * initialize the FA specific part of the command
195 void
196 s1394_fa_init_cmd(s1394_cmd_priv_t *s_priv, s1394_fa_type_t type)
198 s_priv->cmd_ext_type = S1394_CMD_EXT_FA;
199 s_priv->cmd_ext.fa.type = type;
203 * s1394_fa_convert_cmd()
204 * convert an FA command (with a relative address) to a regular 1394 command
206 void
207 s1394_fa_convert_cmd(s1394_hal_t *hal, cmd1394_cmd_t *cmd)
209 s1394_fa_cmd_priv_t *fa_priv = S1394_GET_FA_CMD_PRIV(cmd);
211 cmd->cmd_addr += hal->hal_fa[fa_priv->type].fal_descr->fd_conv_base;
212 fa_priv->completion_callback = cmd->completion_callback;
213 fa_priv->callback_arg = cmd->cmd_callback_arg;
214 cmd->completion_callback = s1394_fa_completion_cb;
215 cmd->cmd_callback_arg = hal;
219 * s1394_fa_restore_cmd()
220 * opposite of s1394_fa_convert_cmd(): regular 1394 command to FA command
222 void
223 s1394_fa_restore_cmd(s1394_hal_t *hal, cmd1394_cmd_t *cmd)
225 s1394_fa_cmd_priv_t *fa_priv = S1394_GET_FA_CMD_PRIV(cmd);
227 ASSERT(fa_priv->type < S1394_FA_NTYPES);
229 cmd->cmd_addr -= hal->hal_fa[fa_priv->type].fal_descr->fd_conv_base;
230 cmd->completion_callback = fa_priv->completion_callback;
231 cmd->cmd_callback_arg = fa_priv->callback_arg;
235 * s1394_fa_check_restore_cmd()
236 * if a command has FA extension, do s1394_fa_restore_cmd()
238 void
239 s1394_fa_check_restore_cmd(s1394_hal_t *hal, cmd1394_cmd_t *cmd)
241 s1394_cmd_priv_t *s_priv = S1394_GET_CMD_PRIV(cmd);
243 if (s_priv->cmd_ext_type == S1394_CMD_EXT_FA) {
244 s1394_fa_restore_cmd(hal, cmd);
249 * s1394_fa_completion_cb()
250 * FA completion callback: restore command and call original callback
252 static void
253 s1394_fa_completion_cb(cmd1394_cmd_t *cmd)
255 s1394_hal_t *hal = cmd->cmd_callback_arg;
257 TNF_PROBE_0_DEBUG(s1394_fa_completion_cb_enter,
258 S1394_TNF_SL_FA_STACK, "");
260 s1394_fa_restore_cmd(hal, cmd);
262 if (cmd->completion_callback) {
263 cmd->completion_callback(cmd);
266 TNF_PROBE_0_DEBUG(s1394_fa_completion_cb_exit,
267 S1394_TNF_SL_FA_STACK, "");