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
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]
23 * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
31 * 1394 Services Layer CSR and Config ROM Routines
32 * Contains all of the CSR callback routines for various required
33 * CSR registers. Also contains routines for their initialization
34 * and destruction, as well as routines to handle the processing
35 * of Config ROM update requests.
40 #include <sys/sunddi.h>
41 #include <sys/types.h>
43 #include <sys/tnf_probe.h>
45 #include <sys/1394/t1394.h>
46 #include <sys/1394/s1394.h>
47 #include <sys/1394/h1394.h>
48 #include <sys/1394/ieee1394.h>
49 #include <sys/1394/ieee1212.h>
51 static void s1394_CSR_state_clear(cmd1394_cmd_t
*req
);
53 static void s1394_CSR_state_set(cmd1394_cmd_t
*req
);
55 static void s1394_CSR_node_ids(cmd1394_cmd_t
*req
);
57 static void s1394_CSR_reset_start(cmd1394_cmd_t
*req
);
59 static void s1394_CSR_split_timeout(cmd1394_cmd_t
*req
);
61 static void s1394_CSR_argument_regs(cmd1394_cmd_t
*req
);
63 static void s1394_CSR_test_regs(cmd1394_cmd_t
*req
);
65 static void s1394_CSR_interrupt_regs(cmd1394_cmd_t
*req
);
67 static void s1394_CSR_clock_regs(cmd1394_cmd_t
*req
);
69 static void s1394_CSR_message_regs(cmd1394_cmd_t
*req
);
71 static void s1394_CSR_cycle_time(cmd1394_cmd_t
*req
);
73 static void s1394_CSR_bus_time(cmd1394_cmd_t
*req
);
75 static void s1394_CSR_busy_timeout(cmd1394_cmd_t
*req
);
77 static void s1394_CSR_IRM_regs(cmd1394_cmd_t
*req
);
79 static void s1394_CSR_topology_map(cmd1394_cmd_t
*req
);
81 static void s1394_common_CSR_routine(s1394_hal_t
*hal
, cmd1394_cmd_t
*req
);
83 static int s1394_init_config_rom_structures(s1394_hal_t
*hal
);
85 static int s1394_destroy_config_rom_structures(s1394_hal_t
*hal
);
88 * s1394_setup_CSR_space()
89 * setups up the local host's CSR registers and callback routines.
92 s1394_setup_CSR_space(s1394_hal_t
*hal
)
94 s1394_addr_space_blk_t
*curr_blk
;
95 t1394_alloc_addr_t addr
;
96 t1394_addr_enable_t rw_flags
;
99 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_enter
, S1394_TNF_SL_CSR_STACK
,
103 * Although they are not freed up in this routine, if
104 * one of the s1394_claim_addr_blk() routines fails,
105 * all of the previously successful claims will be
106 * freed up in s1394_destroy_addr_space() upon returning
107 * DDI_FAILURE from this routine.
110 rw_flags
= T1394_ADDR_RDENBL
| T1394_ADDR_WRENBL
;
114 * see IEEE 1394-1995, Section 8.3.2.2.1 or
115 * IEEE 1212-1994, Section 7.4.1
117 addr
.aa_address
= IEEE1394_CSR_STATE_CLEAR
;
118 addr
.aa_length
= IEEE1394_QUADLET
;
119 addr
.aa_enable
= rw_flags
;
120 addr
.aa_type
= T1394_ADDR_FIXED
;
121 addr
.aa_evts
.recv_read_request
= s1394_CSR_state_clear
;
122 addr
.aa_evts
.recv_write_request
= s1394_CSR_state_clear
;
123 addr
.aa_evts
.recv_lock_request
= NULL
;
124 addr
.aa_kmem_bufp
= NULL
;
126 result
= s1394_claim_addr_blk(hal
, &addr
);
127 if (result
!= DDI_SUCCESS
) {
128 TNF_PROBE_1(s1394_setup_CSR_space_error
,
129 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
130 "STATE_CLEAR: CSR setup failed");
131 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
132 S1394_TNF_SL_CSR_STACK
, "");
133 return (DDI_FAILURE
);
138 * see IEEE 1394-1995, Section 8.3.2.2.2 or
139 * IEEE 1212-1994, Section 7.4.2
141 addr
.aa_address
= IEEE1394_CSR_STATE_SET
;
142 addr
.aa_length
= IEEE1394_QUADLET
;
143 addr
.aa_enable
= T1394_ADDR_WRENBL
;
144 addr
.aa_type
= T1394_ADDR_FIXED
;
145 addr
.aa_evts
.recv_read_request
= NULL
;
146 addr
.aa_evts
.recv_write_request
= s1394_CSR_state_set
;
147 addr
.aa_evts
.recv_lock_request
= NULL
;
148 addr
.aa_kmem_bufp
= NULL
;
150 result
= s1394_claim_addr_blk(hal
, &addr
);
151 if (result
!= DDI_SUCCESS
) {
152 TNF_PROBE_1(s1394_setup_CSR_space_error
,
153 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
154 "STATE_SET: CSR setup failed");
155 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
156 S1394_TNF_SL_CSR_STACK
, "");
157 return (DDI_FAILURE
);
162 * see IEEE 1394-1995, Section 8.3.2.2.3 or
163 * IEEE 1212-1994, Section 7.4.3
165 addr
.aa_address
= IEEE1394_CSR_NODE_IDS
;
166 addr
.aa_length
= IEEE1394_QUADLET
;
167 addr
.aa_enable
= rw_flags
;
168 addr
.aa_type
= T1394_ADDR_FIXED
;
169 addr
.aa_evts
.recv_read_request
= s1394_CSR_node_ids
;
170 addr
.aa_evts
.recv_write_request
= s1394_CSR_node_ids
;
171 addr
.aa_evts
.recv_lock_request
= NULL
;
172 addr
.aa_kmem_bufp
= NULL
;
174 result
= s1394_claim_addr_blk(hal
, &addr
);
175 if (result
!= DDI_SUCCESS
) {
176 TNF_PROBE_1(s1394_setup_CSR_space_error
,
177 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
178 "NODE_IDS: CSR setup failed");
179 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
180 S1394_TNF_SL_CSR_STACK
, "");
181 return (DDI_FAILURE
);
186 * see IEEE 1394-1995, Section 8.3.2.2.4 or
187 * IEEE 1212-1994, Section 7.4.4
189 addr
.aa_address
= IEEE1394_CSR_RESET_START
;
190 addr
.aa_length
= IEEE1394_QUADLET
;
191 addr
.aa_enable
= T1394_ADDR_WRENBL
;
192 addr
.aa_type
= T1394_ADDR_FIXED
;
193 addr
.aa_evts
.recv_read_request
= NULL
;
194 addr
.aa_evts
.recv_write_request
= s1394_CSR_reset_start
;
195 addr
.aa_evts
.recv_lock_request
= NULL
;
196 addr
.aa_kmem_bufp
= NULL
;
198 result
= s1394_claim_addr_blk(hal
, &addr
);
199 if (result
!= DDI_SUCCESS
) {
200 TNF_PROBE_1(s1394_setup_CSR_space_error
,
201 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
202 "RESET_START: CSR setup failed");
203 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
204 S1394_TNF_SL_CSR_STACK
, "");
205 return (DDI_FAILURE
);
210 * see IEEE 1394-1995, Section 8.3.2.2.6 or
211 * IEEE 1212-1994, Section 7.4.7
213 addr
.aa_address
= IEEE1394_CSR_SPLIT_TIMEOUT_HI
;
214 addr
.aa_length
= IEEE1394_OCTLET
;
215 addr
.aa_enable
= rw_flags
;
216 addr
.aa_type
= T1394_ADDR_FIXED
;
217 addr
.aa_evts
.recv_read_request
= s1394_CSR_split_timeout
;
218 addr
.aa_evts
.recv_write_request
= s1394_CSR_split_timeout
;
219 addr
.aa_evts
.recv_lock_request
= NULL
;
220 addr
.aa_kmem_bufp
= NULL
;
222 result
= s1394_claim_addr_blk(hal
, &addr
);
223 if (result
!= DDI_SUCCESS
) {
224 TNF_PROBE_1(s1394_setup_CSR_space_error
,
225 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
226 "SPLIT_TIMEOUT: CSR setup failed");
227 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
228 S1394_TNF_SL_CSR_STACK
, "");
229 return (DDI_FAILURE
);
233 * ARGUMENT_HI and ARGUMENT_LO
234 * see IEEE 1394-1995, Section 8.3.2.2.7 or
235 * IEEE 1212-1994, Section 7.4.8
237 addr
.aa_address
= IEEE1394_CSR_ARG_HI
;
238 addr
.aa_length
= 2 * (IEEE1394_QUADLET
);
239 addr
.aa_enable
= rw_flags
;
240 addr
.aa_type
= T1394_ADDR_FIXED
;
241 addr
.aa_evts
.recv_read_request
= s1394_CSR_argument_regs
;
242 addr
.aa_evts
.recv_write_request
= s1394_CSR_argument_regs
;
243 addr
.aa_evts
.recv_lock_request
= NULL
;
244 addr
.aa_kmem_bufp
= NULL
;
246 result
= s1394_claim_addr_blk(hal
, &addr
);
247 if (result
!= DDI_SUCCESS
) {
248 TNF_PROBE_1(s1394_setup_CSR_space_error
,
249 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
250 "ARGUMENT registers: CSR setup failed");
251 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
252 S1394_TNF_SL_CSR_STACK
, "");
253 return (DDI_FAILURE
);
257 * TEST_START and TEST_STATUS
258 * see IEEE 1394-1995, Section 8.3.2.2.7 or
259 * IEEE 1212-1994, Section 7.4.9 - 7.4.10
261 addr
.aa_address
= IEEE1394_CSR_TEST_START
;
262 addr
.aa_length
= 2 * (IEEE1394_QUADLET
);
263 addr
.aa_enable
= rw_flags
;
264 addr
.aa_type
= T1394_ADDR_FIXED
;
265 addr
.aa_evts
.recv_read_request
= s1394_CSR_test_regs
;
266 addr
.aa_evts
.recv_write_request
= s1394_CSR_test_regs
;
267 addr
.aa_evts
.recv_lock_request
= NULL
;
268 addr
.aa_kmem_bufp
= NULL
;
270 result
= s1394_claim_addr_blk(hal
, &addr
);
271 if (result
!= DDI_SUCCESS
) {
272 TNF_PROBE_1(s1394_setup_CSR_space_error
,
273 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
274 "TEST registers: CSR setup failed");
275 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
276 S1394_TNF_SL_CSR_STACK
, "");
277 return (DDI_FAILURE
);
281 * INTERRUPT_TARGET and INTERRUPT_MASK
282 * see IEEE 1394-1995, Section 8.3.2.2.9 or
283 * IEEE 1212-1994, Section 7.4.15 - 7.4.16
285 addr
.aa_address
= IEEE1394_CSR_INTERRUPT_TARGET
;
286 addr
.aa_length
= 2 * (IEEE1394_QUADLET
);
287 addr
.aa_enable
= rw_flags
;
288 addr
.aa_type
= T1394_ADDR_FIXED
;
289 addr
.aa_evts
.recv_read_request
= s1394_CSR_interrupt_regs
;
290 addr
.aa_evts
.recv_write_request
= s1394_CSR_interrupt_regs
;
291 addr
.aa_evts
.recv_lock_request
= NULL
;
292 addr
.aa_kmem_bufp
= NULL
;
294 result
= s1394_claim_addr_blk(hal
, &addr
);
295 if (result
!= DDI_SUCCESS
) {
296 TNF_PROBE_1(s1394_setup_CSR_space_error
,
297 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
298 "INTERRUPT registers: CSR setup failed");
299 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
300 S1394_TNF_SL_CSR_STACK
, "");
301 return (DDI_FAILURE
);
305 * CLOCK_VALUE, CLOCK_TICK_PERIOD, CLOCK_INFO, etc.
306 * see IEEE 1394-1995, Section 8.3.2.2.10 or
307 * IEEE 1212-1994, Section 7.4.17 - 7.4.20
309 addr
.aa_address
= IEEE1394_CSR_CLOCK_VALUE
;
310 addr
.aa_length
= IEEE1394_CSR_CLOCK_VALUE_SZ
;
311 addr
.aa_enable
= rw_flags
;
312 addr
.aa_type
= T1394_ADDR_FIXED
;
313 addr
.aa_evts
.recv_read_request
= s1394_CSR_clock_regs
;
314 addr
.aa_evts
.recv_write_request
= s1394_CSR_clock_regs
;
315 addr
.aa_evts
.recv_lock_request
= NULL
;
316 addr
.aa_kmem_bufp
= NULL
;
318 result
= s1394_claim_addr_blk(hal
, &addr
);
319 if (result
!= DDI_SUCCESS
) {
320 TNF_PROBE_1(s1394_setup_CSR_space_error
,
321 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
322 "CLOCK registers: CSR setup failed");
323 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
324 S1394_TNF_SL_CSR_STACK
, "");
325 return (DDI_FAILURE
);
329 * MESSAGE_REQUEST and MESSAGE_RESPONSE
330 * see IEEE 1394-1995, Section 8.3.2.2.11 or
331 * IEEE 1212-1994, Section 7.4.21
333 addr
.aa_address
= IEEE1394_CSR_MESSAGE_REQUEST
;
334 addr
.aa_length
= IEEE1394_CSR_MESSAGE_REQUEST_SZ
;
335 addr
.aa_enable
= rw_flags
;
336 addr
.aa_type
= T1394_ADDR_FIXED
;
337 addr
.aa_evts
.recv_read_request
= s1394_CSR_message_regs
;
338 addr
.aa_evts
.recv_write_request
= s1394_CSR_message_regs
;
339 addr
.aa_evts
.recv_lock_request
= NULL
;
340 addr
.aa_kmem_bufp
= NULL
;
342 result
= s1394_claim_addr_blk(hal
, &addr
);
343 if (result
!= DDI_SUCCESS
) {
344 TNF_PROBE_1(s1394_setup_CSR_space_error
,
345 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
346 "MESSAGE registers: CSR setup failed");
347 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
348 S1394_TNF_SL_CSR_STACK
, "");
349 return (DDI_FAILURE
);
354 * see IEEE 1394-1995, Section 8.3.2.3.1
356 addr
.aa_address
= IEEE1394_SCSR_CYCLE_TIME
;
357 addr
.aa_length
= IEEE1394_QUADLET
;
358 addr
.aa_enable
= rw_flags
;
359 addr
.aa_type
= T1394_ADDR_FIXED
;
360 addr
.aa_evts
.recv_read_request
= s1394_CSR_cycle_time
;
361 addr
.aa_evts
.recv_write_request
= s1394_CSR_cycle_time
;
362 addr
.aa_evts
.recv_lock_request
= NULL
;
363 addr
.aa_kmem_bufp
= NULL
;
365 result
= s1394_claim_addr_blk(hal
, &addr
);
366 if (result
!= DDI_SUCCESS
) {
367 TNF_PROBE_1(s1394_setup_CSR_space_error
,
368 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
369 "CYCLE_TIME: CSR setup failed");
370 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
371 S1394_TNF_SL_CSR_STACK
, "");
372 return (DDI_FAILURE
);
377 * see IEEE 1394-1995, Section 8.3.2.3.2
379 addr
.aa_address
= IEEE1394_SCSR_BUS_TIME
;
380 addr
.aa_length
= IEEE1394_QUADLET
;
381 addr
.aa_enable
= rw_flags
;
382 addr
.aa_type
= T1394_ADDR_FIXED
;
383 addr
.aa_evts
.recv_read_request
= s1394_CSR_bus_time
;
384 addr
.aa_evts
.recv_write_request
= s1394_CSR_bus_time
;
385 addr
.aa_evts
.recv_lock_request
= NULL
;
386 addr
.aa_kmem_bufp
= NULL
;
388 result
= s1394_claim_addr_blk(hal
, &addr
);
389 if (result
!= DDI_SUCCESS
) {
390 TNF_PROBE_1(s1394_setup_CSR_space_error
,
391 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
392 "BUS_TIME: CSR setup failed");
393 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
394 S1394_TNF_SL_CSR_STACK
, "");
395 return (DDI_FAILURE
);
400 * see IEEE 1394-1995, Section 8.3.2.3.5
402 addr
.aa_address
= IEEE1394_SCSR_BUSY_TIMEOUT
;
403 addr
.aa_length
= IEEE1394_QUADLET
;
404 addr
.aa_enable
= rw_flags
;
405 addr
.aa_type
= T1394_ADDR_FIXED
;
406 addr
.aa_evts
.recv_read_request
= s1394_CSR_busy_timeout
;
407 addr
.aa_evts
.recv_write_request
= s1394_CSR_busy_timeout
;
408 addr
.aa_evts
.recv_lock_request
= NULL
;
409 addr
.aa_kmem_bufp
= NULL
;
411 result
= s1394_claim_addr_blk(hal
, &addr
);
412 if (result
!= DDI_SUCCESS
) {
413 TNF_PROBE_1(s1394_setup_CSR_space_error
,
414 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
415 "BUSY_TIMEOUT: CSR setup failed");
416 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
417 S1394_TNF_SL_CSR_STACK
, "");
418 return (DDI_FAILURE
);
423 * BANDWIDTH_AVAILABLE
425 * see IEEE 1394-1995, Section 8.3.2.3.6 - 8.3.2.3.8
427 addr
.aa_address
= IEEE1394_SCSR_BUSMGR_ID
;
428 addr
.aa_length
= 3 * (IEEE1394_QUADLET
);
429 addr
.aa_enable
= T1394_ADDR_RDENBL
| T1394_ADDR_LKENBL
;
430 addr
.aa_type
= T1394_ADDR_FIXED
;
431 addr
.aa_evts
.recv_read_request
= s1394_CSR_IRM_regs
;
432 addr
.aa_evts
.recv_write_request
= NULL
;
433 addr
.aa_evts
.recv_lock_request
= s1394_CSR_IRM_regs
;
434 addr
.aa_kmem_bufp
= NULL
;
436 result
= s1394_claim_addr_blk(hal
, &addr
);
437 if (result
!= DDI_SUCCESS
) {
438 TNF_PROBE_1(s1394_setup_CSR_space_error
,
439 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
440 "IRM registers: CSR setup failed");
441 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
442 S1394_TNF_SL_CSR_STACK
, "");
443 return (DDI_FAILURE
);
447 * Reserved for Configuration ROM
448 * see IEEE 1394-1995, Section 8.3.2.5.3
450 addr
.aa_address
= IEEE1394_CONFIG_ROM_ADDR
;
451 addr
.aa_length
= IEEE1394_CONFIG_ROM_SZ
;
452 result
= s1394_reserve_addr_blk(hal
, &addr
);
453 if (result
!= DDI_SUCCESS
) {
454 TNF_PROBE_1(s1394_setup_CSR_space_error
,
455 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
456 "Unable to reserve Config ROM");
457 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
458 S1394_TNF_SL_CSR_STACK
, "");
459 return (DDI_FAILURE
);
464 * see IEEE 1394-1995, Section 8.3.2.4.1
466 hal
->CSR_topology_map
= kmem_zalloc(IEEE1394_UCSR_TOPOLOGY_MAP_SZ
,
468 addr
.aa_address
= IEEE1394_UCSR_TOPOLOGY_MAP
;
469 addr
.aa_length
= IEEE1394_UCSR_TOPOLOGY_MAP_SZ
;
470 addr
.aa_enable
= T1394_ADDR_RDENBL
;
471 addr
.aa_type
= T1394_ADDR_FIXED
;
472 addr
.aa_evts
.recv_read_request
= s1394_CSR_topology_map
;
473 addr
.aa_evts
.recv_write_request
= NULL
;
474 addr
.aa_evts
.recv_lock_request
= NULL
;
475 addr
.aa_kmem_bufp
= (caddr_t
)hal
->CSR_topology_map
;
477 result
= s1394_claim_addr_blk(hal
, &addr
);
478 if (result
!= DDI_SUCCESS
) {
479 kmem_free((void *)hal
->CSR_topology_map
,
480 IEEE1394_UCSR_TOPOLOGY_MAP_SZ
);
481 TNF_PROBE_1(s1394_setup_CSR_space_error
,
482 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
483 "TOPOLOGY_MAP: CSR setup failed");
484 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
485 S1394_TNF_SL_CSR_STACK
, "");
486 return (DDI_FAILURE
);
488 curr_blk
= (s1394_addr_space_blk_t
*)(addr
.aa_hdl
);
489 /* Set up the block so that we free kmem_bufp at detach */
490 curr_blk
->free_kmem_bufp
= B_TRUE
;
493 * Reserve the SPEED_MAP
494 * see IEEE 1394-1995, Section 8.3.2.4.1
495 * (obsoleted in P1394A)
497 addr
.aa_address
= IEEE1394_UCSR_SPEED_MAP
;
498 addr
.aa_length
= IEEE1394_UCSR_SPEED_MAP_SZ
;
499 result
= s1394_reserve_addr_blk(hal
, &addr
);
500 if (result
!= DDI_SUCCESS
) {
501 TNF_PROBE_1(s1394_setup_CSR_space_error
,
502 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
503 "SPEED_MAP: CSR setup failed");
504 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
505 S1394_TNF_SL_CSR_STACK
, "");
506 return (DDI_FAILURE
);
510 * Reserved - Boundary between reserved Serial Bus
511 * dependent registers and other CSR register space.
512 * See IEEE 1394-1995, Table 8-4 for this address.
514 * This quadlet is reserved as a way of preventing
515 * the inadvertant allocation of a part of CSR space
516 * that will likely be used by future specifications
518 addr
.aa_address
= IEEE1394_UCSR_RESERVED_BOUNDARY
;
519 addr
.aa_length
= IEEE1394_QUADLET
;
520 result
= s1394_reserve_addr_blk(hal
, &addr
);
521 if (result
!= DDI_SUCCESS
) {
522 TNF_PROBE_1(s1394_setup_CSR_space_error
,
523 S1394_TNF_SL_CSR_ERROR
, "", tnf_string
, msg
,
524 "Unable to reserve boundary quadlet");
525 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
,
526 "stacktrace 1394 s1394", "");
527 return (DDI_FAILURE
);
530 TNF_PROBE_0_DEBUG(s1394_setup_CSR_space_exit
, S1394_TNF_SL_CSR_STACK
,
532 return (DDI_SUCCESS
);
536 * s1394_CSR_state_clear()
537 * handles all requests to the STATE_CLEAR CSR register. It enforces
538 * that certain bits that can be twiddled only by a given node (IRM or
542 s1394_CSR_state_clear(cmd1394_cmd_t
*req
)
548 uint_t should_be_from
;
551 TNF_PROBE_0_DEBUG(s1394_CSR_state_clear_enter
, S1394_TNF_SL_CSR_STACK
,
554 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
556 /* Register offset */
557 offset
= req
->cmd_addr
& IEEE1394_CSR_OFFSET_MASK
;
559 /* Verify that request is quadlet aligned */
560 if ((offset
& 0x3) != 0) {
561 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
562 (void) s1394_send_response(hal
, req
);
563 TNF_PROBE_0_DEBUG(s1394_CSR_state_clear_exit
,
564 S1394_TNF_SL_CSR_STACK
, "");
568 /* Only writes from IRM or Bus Mgr allowed (in some cases) */
569 mutex_enter(&hal
->topology_tree_mutex
);
570 is_from
= IEEE1394_NODE_NUM(req
->nodeID
);
571 if (hal
->bus_mgr_node
!= -1)
572 should_be_from
= IEEE1394_NODE_NUM(hal
->bus_mgr_node
);
573 else if (hal
->IRM_node
!= -1)
574 should_be_from
= IEEE1394_NODE_NUM(hal
->IRM_node
);
576 should_be_from
= S1394_INVALID_NODE_NUM
;
577 mutex_exit(&hal
->topology_tree_mutex
);
579 switch (req
->cmd_type
) {
580 case CMD1394_ASYNCH_RD_QUAD
:
582 * The csr_read() call can return DDI_FAILURE if the HAL
583 * is shutdown or if the register at "offset" is
584 * unimplemented. But although the STATE_CLEAR register
585 * is required to be implemented and readable, we will
586 * return IEEE1394_RESP_ADDRESS_ERROR in the response if
587 * we ever see this error.
589 result
= HAL_CALL(hal
).csr_read(hal
->halinfo
.hal_private
,
591 if (result
== DDI_SUCCESS
) {
592 req
->cmd_u
.q
.quadlet_data
= data
;
593 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
595 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
599 case CMD1394_ASYNCH_WR_QUAD
:
600 data
= req
->cmd_u
.q
.quadlet_data
;
602 /* CMSTR bit - request must be from bus_mgr/IRM */
603 if (is_from
!= should_be_from
) {
604 data
= data
& ~IEEE1394_CSR_STATE_CMSTR
;
607 mutex_enter(&hal
->topology_tree_mutex
);
608 /* DREQ bit - disabling DREQ can come from anyone */
609 if (data
& IEEE1394_CSR_STATE_DREQ
) {
610 hal
->disable_requests_bit
= 0;
611 if (hal
->hal_state
== S1394_HAL_DREQ
)
612 hal
->hal_state
= S1394_HAL_NORMAL
;
616 if (data
& IEEE1394_CSR_STATE_ABDICATE
) {
617 hal
->abdicate_bus_mgr_bit
= 0;
619 mutex_exit(&hal
->topology_tree_mutex
);
621 * The csr_write() call can return DDI_FAILURE if the HAL
622 * is shutdown or if the register at "offset" is
623 * unimplemented. But although the STATE_CLEAR register
624 * is required to be implemented and writeable, we will
625 * return IEEE1394_RESP_ADDRESS_ERROR in the response if
626 * we ever see this error.
628 result
= HAL_CALL(hal
).csr_write(hal
->halinfo
.hal_private
,
630 if (result
== DDI_SUCCESS
) {
631 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
633 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
638 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
641 (void) s1394_send_response(hal
, req
);
642 TNF_PROBE_0_DEBUG(s1394_CSR_state_clear_exit
, S1394_TNF_SL_CSR_STACK
,
647 * s1394_CSR_state_set()
648 * handles all requests to the STATE_SET CSR register. It enforces that
649 * certain bits that can be twiddled only by a given node (IRM or Bus
653 s1394_CSR_state_set(cmd1394_cmd_t
*req
)
659 uint_t should_be_from
;
661 uint_t hal_number_of_nodes
;
664 TNF_PROBE_0_DEBUG(s1394_CSR_state_set_enter
, S1394_TNF_SL_CSR_STACK
,
667 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
669 /* Register offset */
670 offset
= req
->cmd_addr
& IEEE1394_CSR_OFFSET_MASK
;
672 /* Verify that request is quadlet aligned */
673 if ((offset
& 0x3) != 0) {
674 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
675 (void) s1394_send_response(hal
, req
);
676 TNF_PROBE_0_DEBUG(s1394_CSR_state_set_exit
,
677 S1394_TNF_SL_CSR_STACK
, "");
681 /* Only writes from IRM or Bus Mgr allowed (in some cases) */
682 mutex_enter(&hal
->topology_tree_mutex
);
683 is_from
= IEEE1394_NODE_NUM(req
->nodeID
);
684 if (hal
->bus_mgr_node
!= -1)
685 should_be_from
= IEEE1394_NODE_NUM(hal
->bus_mgr_node
);
686 else if (hal
->IRM_node
!= -1)
687 should_be_from
= IEEE1394_NODE_NUM(hal
->IRM_node
);
689 should_be_from
= S1394_INVALID_NODE_NUM
;
690 hal_node_num
= IEEE1394_NODE_NUM(hal
->node_id
);
691 hal_number_of_nodes
= hal
->number_of_nodes
;
692 mutex_exit(&hal
->topology_tree_mutex
);
694 switch (req
->cmd_type
) {
695 case CMD1394_ASYNCH_WR_QUAD
:
696 data
= req
->cmd_u
.q
.quadlet_data
;
698 /* CMSTR bit - request must be from bus_mgr/IRM */
699 /* & must be root to have bit set */
700 if ((is_from
!= should_be_from
) ||
701 (hal_node_num
!= (hal_number_of_nodes
- 1))) {
702 data
= data
& ~IEEE1394_CSR_STATE_CMSTR
;
705 mutex_enter(&hal
->topology_tree_mutex
);
706 /* DREQ bit - only bus_mgr/IRM can set this bit */
707 if (is_from
!= should_be_from
) {
708 data
= data
& ~IEEE1394_CSR_STATE_DREQ
;
710 } else if (data
& IEEE1394_CSR_STATE_DREQ
) {
711 hal
->disable_requests_bit
= 1;
712 if (hal
->hal_state
== S1394_HAL_NORMAL
)
713 hal
->hal_state
= S1394_HAL_DREQ
;
716 if (data
& IEEE1394_CSR_STATE_ABDICATE
) {
717 hal
->abdicate_bus_mgr_bit
= 1;
719 mutex_exit(&hal
->topology_tree_mutex
);
721 * The csr_write() call can return DDI_FAILURE if the HAL
722 * is shutdown or if the register at "offset" is
723 * unimplemented. But although the STATE_SET register
724 * is required to be implemented and writeable, we will
725 * return IEEE1394_RESP_ADDRESS_ERROR in the response if
726 * we ever see this error.
728 result
= HAL_CALL(hal
).csr_write(hal
->halinfo
.hal_private
,
730 if (result
== DDI_SUCCESS
) {
731 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
733 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
738 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
741 (void) s1394_send_response(hal
, req
);
742 TNF_PROBE_0_DEBUG(s1394_CSR_state_set_exit
, S1394_TNF_SL_CSR_STACK
,
747 * s1394_CSR_node_ids()
748 * handles all requests to the NODE_IDS CSR register. It passes all
749 * requests to the common routine - s1394_common_CSR_routine().
752 s1394_CSR_node_ids(cmd1394_cmd_t
*req
)
756 TNF_PROBE_0_DEBUG(s1394_CSR_node_ids_enter
, S1394_TNF_SL_CSR_STACK
, "");
758 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
760 s1394_common_CSR_routine(hal
, req
);
762 TNF_PROBE_0_DEBUG(s1394_CSR_node_ids_exit
, S1394_TNF_SL_CSR_STACK
, "");
766 * s1394_CSR_reset_start()
767 * handles all requests to the RESET_START CSR register. Only write
768 * requests are legal, everything else gets a type_error response.
771 s1394_CSR_reset_start(cmd1394_cmd_t
*req
)
777 TNF_PROBE_0_DEBUG(s1394_CSR_reset_start_enter
, S1394_TNF_SL_CSR_STACK
,
780 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
782 /* RESET_START register offset */
783 offset
= req
->cmd_addr
& IEEE1394_CSR_OFFSET_MASK
;
785 /* Verify that request is quadlet aligned */
786 if ((offset
& 0x3) != 0) {
787 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
788 (void) s1394_send_response(hal
, req
);
789 TNF_PROBE_0_DEBUG(s1394_CSR_reset_start_exit
,
790 S1394_TNF_SL_CSR_STACK
, "");
794 switch (req
->cmd_type
) {
795 case CMD1394_ASYNCH_WR_QUAD
:
796 data
= req
->cmd_u
.q
.quadlet_data
;
798 * The csr_write() call can return DDI_FAILURE if the HAL
799 * is shutdown or if the register at "offset" is
800 * unimplemented. Because we don't do any thing with
801 * the RESET_START register we will ignore failures and
802 * return IEEE1394_RESP_COMPLETE regardless.
804 (void) HAL_CALL(hal
).csr_write(hal
->halinfo
.hal_private
,
806 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
810 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
813 (void) s1394_send_response(hal
, req
);
814 TNF_PROBE_0_DEBUG(s1394_CSR_reset_start_exit
, S1394_TNF_SL_CSR_STACK
,
819 * s1394_CSR_split_timeout()
820 * handles all requests to the SPLIT_TIMEOUT CSR register. It passes all
821 * requests to the common routine - s1394_common_CSR_routine().
824 s1394_CSR_split_timeout(cmd1394_cmd_t
*req
)
828 TNF_PROBE_0_DEBUG(s1394_CSR_split_timeout_enter
,
829 S1394_TNF_SL_CSR_STACK
, "");
831 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
833 s1394_common_CSR_routine(hal
, req
);
835 TNF_PROBE_0_DEBUG(s1394_CSR_split_timeout_exit
,
836 S1394_TNF_SL_CSR_STACK
, "");
840 * s1394_CSR_argument_regs()
841 * handles all requests to the ARGUMENT CSR registers. It passes all
842 * requests to the common routine - s1394_common_CSR_routine().
845 s1394_CSR_argument_regs(cmd1394_cmd_t
*req
)
849 TNF_PROBE_0_DEBUG(s1394_CSR_argument_regs_enter
,
850 S1394_TNF_SL_CSR_STACK
, "");
852 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
854 s1394_common_CSR_routine(hal
, req
);
856 TNF_PROBE_0_DEBUG(s1394_CSR_argument_regs_exit
,
857 S1394_TNF_SL_CSR_STACK
, "");
861 * s1394_CSR_test_regs()
862 * handles all requests to the TEST CSR registers. It passes all requests
863 * to the common routine - s1394_common_CSR_routine().
866 s1394_CSR_test_regs(cmd1394_cmd_t
*req
)
871 TNF_PROBE_0_DEBUG(s1394_CSR_test_regs_enter
,
872 S1394_TNF_SL_CSR_STACK
, "");
874 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
876 /* TEST register offset */
877 offset
= req
->cmd_addr
& IEEE1394_CSR_OFFSET_MASK
;
879 /* TEST_STATUS is Read-Only */
880 if ((offset
== (IEEE1394_CSR_TEST_STATUS
& IEEE1394_CSR_OFFSET_MASK
)) &&
881 (req
->cmd_type
== CMD1394_ASYNCH_WR_QUAD
)) {
882 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
883 (void) s1394_send_response(hal
, req
);
885 s1394_common_CSR_routine(hal
, req
);
888 TNF_PROBE_0_DEBUG(s1394_CSR_test_regs_exit
,
889 S1394_TNF_SL_CSR_STACK
, "");
893 * s1394_CSR_interrupt_regs()
894 * handles all requests to the INTERRUPT CSR registers. It passes all
895 * requests to the common routine - s1394_common_CSR_routine().
898 s1394_CSR_interrupt_regs(cmd1394_cmd_t
*req
)
902 TNF_PROBE_0_DEBUG(s1394_CSR_interrupt_regs_enter
,
903 S1394_TNF_SL_CSR_STACK
, "");
905 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
907 s1394_common_CSR_routine(hal
, req
);
909 TNF_PROBE_0_DEBUG(s1394_CSR_interrupt_regs_exit
,
910 S1394_TNF_SL_CSR_STACK
, "");
914 * s1394_CSR_clock_regs()
915 * handles all requests to the CLOCK CSR registers. It passes all
916 * requests to the common routine - s1394_common_CSR_routine().
919 s1394_CSR_clock_regs(cmd1394_cmd_t
*req
)
923 TNF_PROBE_0_DEBUG(s1394_CSR_clock_regs_enter
,
924 S1394_TNF_SL_CSR_STACK
, "");
926 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
928 s1394_common_CSR_routine(hal
, req
);
930 TNF_PROBE_0_DEBUG(s1394_CSR_clock_regs_exit
,
931 S1394_TNF_SL_CSR_STACK
, "");
935 * s1394_CSR_message_regs()
936 * handles all requests to the MESSAGE CSR registers. It passes all
937 * requests to the common routine - s1394_common_CSR_routine().
940 s1394_CSR_message_regs(cmd1394_cmd_t
*req
)
944 TNF_PROBE_0_DEBUG(s1394_CSR_message_regs_enter
,
945 S1394_TNF_SL_CSR_STACK
, "");
947 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
949 s1394_common_CSR_routine(hal
, req
);
951 TNF_PROBE_0_DEBUG(s1394_CSR_message_regs_exit
,
952 S1394_TNF_SL_CSR_STACK
, "");
956 * s1394_CSR_cycle_time()
957 * handles all requests to the CYCLE_TIME CSR register.
960 s1394_CSR_cycle_time(cmd1394_cmd_t
*req
)
967 TNF_PROBE_0_DEBUG(s1394_CSR_cycle_time_enter
,
968 S1394_TNF_SL_CSR_STACK
, "");
970 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
972 /* CYCLE_TIME register offset */
973 offset
= req
->cmd_addr
& IEEE1394_CSR_OFFSET_MASK
;
975 /* Verify that request is quadlet aligned */
976 if ((offset
& 0x3) != 0) {
977 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
978 (void) s1394_send_response(hal
, req
);
979 TNF_PROBE_0_DEBUG(s1394_CSR_cycle_time_exit
,
980 S1394_TNF_SL_CSR_STACK
, "");
984 switch (req
->cmd_type
) {
985 case CMD1394_ASYNCH_RD_QUAD
:
987 * The csr_read() call can return DDI_FAILURE if the HAL
988 * is shutdown or if the register at "offset" is
989 * unimplemented. But although the CYCLE_TIME register
990 * is required to be implemented on devices capable of
991 * providing isochronous services (like us), we will
992 * return IEEE1394_RESP_ADDRESS_ERROR in the response
993 * if we ever see this error.
995 result
= HAL_CALL(hal
).csr_read(hal
->halinfo
.hal_private
,
997 if (result
== DDI_SUCCESS
) {
998 req
->cmd_u
.q
.quadlet_data
= data
;
999 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
1001 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
1005 case CMD1394_ASYNCH_WR_QUAD
:
1006 data
= req
->cmd_u
.q
.quadlet_data
;
1008 * The csr_write() call can return DDI_FAILURE if the HAL
1009 * is shutdown or if the register at "offset" is
1010 * unimplemented. But although the CYCLE_TIME register
1011 * is required to be implemented on devices capable of
1012 * providing isochronous services (like us), the effects
1013 * of a write are "node-dependent" so we will return
1014 * IEEE1394_RESP_ADDRESS_ERROR in the response if we
1015 * ever see this error.
1017 result
= HAL_CALL(hal
).csr_write(hal
->halinfo
.hal_private
,
1019 if (result
== DDI_SUCCESS
) {
1020 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
1022 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
1027 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
1030 (void) s1394_send_response(hal
, req
);
1031 TNF_PROBE_0_DEBUG(s1394_CSR_cycle_time_exit
,
1032 S1394_TNF_SL_CSR_STACK
, "");
1036 * s1394_CSR_bus_time()
1037 * handles all requests to the BUS_TIME CSR register. It enforces that
1038 * only a broadcast write request from the IRM or Bus Manager can change
1042 s1394_CSR_bus_time(cmd1394_cmd_t
*req
)
1048 uint_t should_be_from
;
1051 TNF_PROBE_0_DEBUG(s1394_CSR_bus_time_enter
, S1394_TNF_SL_CSR_STACK
, "");
1053 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
1055 /* BUS_TIME register offset */
1056 offset
= req
->cmd_addr
& IEEE1394_CSR_OFFSET_MASK
;
1058 /* Verify that request is quadlet aligned */
1059 if ((offset
& 0x3) != 0) {
1060 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
1061 (void) s1394_send_response(hal
, req
);
1062 TNF_PROBE_0_DEBUG(s1394_CSR_bus_time_exit
,
1063 S1394_TNF_SL_CSR_STACK
, "");
1067 switch (req
->cmd_type
) {
1068 case CMD1394_ASYNCH_RD_QUAD
:
1070 * The csr_read() call can return DDI_FAILURE if the HAL
1071 * is shutdown or if the register at "offset" is
1072 * unimplemented. But although the BUS_TIME register
1073 * is required to be implemented by devices capable of
1074 * being cycle master (like us), we will return
1075 * IEEE1394_RESP_ADDRESS_ERROR in the response if we
1076 * ever see this error.
1078 result
= HAL_CALL(hal
).csr_read(hal
->halinfo
.hal_private
,
1080 if (result
== DDI_SUCCESS
) {
1081 req
->cmd_u
.q
.quadlet_data
= data
;
1082 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
1084 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
1088 case CMD1394_ASYNCH_WR_QUAD
:
1089 /* Only broadcast writes from IRM or Bus Mgr allowed */
1090 mutex_enter(&hal
->topology_tree_mutex
);
1091 is_from
= IEEE1394_NODE_NUM(req
->nodeID
);
1092 if (hal
->bus_mgr_node
!= -1)
1093 should_be_from
= IEEE1394_NODE_NUM(hal
->bus_mgr_node
);
1094 else if (hal
->IRM_node
!= -1)
1095 should_be_from
= IEEE1394_NODE_NUM(hal
->IRM_node
);
1097 should_be_from
= S1394_INVALID_NODE_NUM
;
1098 mutex_exit(&hal
->topology_tree_mutex
);
1100 if ((req
->broadcast
!= 1) || (is_from
!= should_be_from
)) {
1101 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
1105 data
= req
->cmd_u
.q
.quadlet_data
;
1107 * The csr_write() call can return DDI_FAILURE if the HAL
1108 * is shutdown or if the register at "offset" is
1109 * unimplemented. But although the BUS_TIME register
1110 * is required to be implemented on devices capable of
1111 * being cycle master (like us), we will return
1112 * IEEE1394_RESP_ADDRESS_ERROR in the response if we
1113 * ever see this error.
1115 result
= HAL_CALL(hal
).csr_write(hal
->halinfo
.hal_private
,
1117 if (result
== DDI_SUCCESS
) {
1118 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
1120 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
1125 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
1128 (void) s1394_send_response(hal
, req
);
1129 TNF_PROBE_0_DEBUG(s1394_CSR_bus_time_exit
, S1394_TNF_SL_CSR_STACK
, "");
1133 * s1394_CSR_busy_timeout()
1134 * handles all requests to the BUSY_TIMEOUT CSR register. It passes all
1135 * requests to the common routine - s1394_common_CSR_routine().
1138 s1394_CSR_busy_timeout(cmd1394_cmd_t
*req
)
1142 TNF_PROBE_0_DEBUG(s1394_CSR_busy_timeout_enter
,
1143 S1394_TNF_SL_CSR_STACK
, "");
1145 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
1147 s1394_common_CSR_routine(hal
, req
);
1149 TNF_PROBE_0_DEBUG(s1394_CSR_busy_timeout_exit
,
1150 S1394_TNF_SL_CSR_STACK
, "");
1154 * s1394_CSR_IRM_regs()
1155 * handles all requests to the IRM registers, including BANDWIDTH_AVAILABLE,
1156 * CHANNELS_AVAILABLE, and the BUS_MANAGER_ID. Only quadlet read and lock
1157 * requests are allowed.
1160 s1394_CSR_IRM_regs(cmd1394_cmd_t
*req
)
1163 uint32_t generation
;
1171 TNF_PROBE_0_DEBUG(s1394_CSR_IRM_regs_enter
, S1394_TNF_SL_CSR_STACK
, "");
1173 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
1175 /* IRM register offset */
1176 offset
= (req
->cmd_addr
& IEEE1394_CSR_OFFSET_MASK
);
1178 /* Verify that request is quadlet aligned */
1179 if ((offset
& 0x3) != 0) {
1180 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
1181 (void) s1394_send_response(hal
, req
);
1182 TNF_PROBE_0_DEBUG(s1394_CSR_IRM_regs_exit
,
1183 S1394_TNF_SL_CSR_STACK
, "");
1187 switch (req
->cmd_type
) {
1188 case CMD1394_ASYNCH_RD_QUAD
:
1190 * The csr_read() call can return DDI_FAILURE if the HAL
1191 * is shutdown or if the register at "offset" is
1192 * unimplemented. In many cases these registers will
1193 * have been implemented in HW. We are not likely to ever
1194 * receive this callback. If we do, though, we will
1195 * return IEEE1394_RESP_ADDRESS_ERROR when we get an error
1196 * and IEEE1394_RESP_COMPLETE for success.
1198 result
= HAL_CALL(hal
).csr_read(hal
->halinfo
.hal_private
,
1200 if (result
== DDI_SUCCESS
) {
1201 req
->cmd_u
.q
.quadlet_data
= data
;
1202 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
1204 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
1208 case CMD1394_ASYNCH_LOCK_32
:
1209 mutex_enter(&hal
->topology_tree_mutex
);
1210 generation
= hal
->generation_count
;
1211 mutex_exit(&hal
->topology_tree_mutex
);
1212 if (req
->cmd_u
.l32
.lock_type
== CMD1394_LOCK_COMPARE_SWAP
) {
1213 compare
= req
->cmd_u
.l32
.arg_value
;
1214 swap
= req
->cmd_u
.l32
.data_value
;
1216 * The csr_cswap32() call can return DDI_FAILURE if
1217 * the HAL is shutdown, if the register at "offset"
1218 * is unimplemented, or if the generation has changed.
1219 * In the last case, it shouldn't matter because the
1220 * call to s1394_send_response will fail on a bad
1221 * generation and the command will be freed.
1223 result
= HAL_CALL(hal
).csr_cswap32(
1224 hal
->halinfo
.hal_private
, generation
,
1225 offset
, compare
, swap
, &old
);
1226 if (result
== DDI_SUCCESS
) {
1227 req
->cmd_u
.l32
.old_value
= old
;
1228 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
1230 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
1234 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
1240 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
1243 (void) s1394_send_response(hal
, req
);
1244 TNF_PROBE_0_DEBUG(s1394_CSR_IRM_regs_exit
, S1394_TNF_SL_CSR_STACK
, "");
1248 * s1394_CSR_topology_map()
1249 * handles all request for the TOPOLOGY_MAP[]. Since it is implemented
1250 * with backing store, there isn't much to do besides return success or
1254 s1394_CSR_topology_map(cmd1394_cmd_t
*req
)
1258 TNF_PROBE_0_DEBUG(s1394_CSR_topology_map_enter
,
1259 S1394_TNF_SL_CSR_STACK
, "");
1261 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
1263 /* Make sure it's a quadlet read request */
1264 if (req
->cmd_type
== CMD1394_ASYNCH_RD_QUAD
)
1265 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
1267 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
1269 (void) s1394_send_response(hal
, req
);
1271 TNF_PROBE_0_DEBUG(s1394_CSR_topology_map_exit
,
1272 S1394_TNF_SL_CSR_STACK
, "");
1276 * s1394_CSR_topology_map_update()
1277 * is used to update the local host's TOPOLOGY_MAP[] buffer. It copies in
1278 * the SelfID packets, updates the generation and other fields, and
1279 * computes the necessary CRC values before returning.
1280 * Callers must be holding the topology_tree_mutex.
1283 s1394_CSR_topology_map_update(s1394_hal_t
*hal
)
1285 s1394_selfid_pkt_t
*selfid_packet
;
1288 uint32_t node_count
;
1289 uint32_t self_id_count
;
1294 TNF_PROBE_0_DEBUG(s1394_CSR_topology_map_update_enter
,
1295 S1394_TNF_SL_BR_CSR_STACK
, "");
1297 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
1299 tm_ptr
= (uint32_t *)hal
->CSR_topology_map
;
1300 data_ptr
= (uint32_t *)&(tm_ptr
[3]);
1303 for (i
= 0; i
< hal
->number_of_nodes
; i
++) {
1305 selfid_packet
= hal
->selfid_ptrs
[i
];
1309 data_ptr
[c
++] = selfid_packet
[j
].spkt_data
;
1311 while (IEEE1394_SELFID_ISMORE(&selfid_packet
[j
]));
1314 /* Update Topology Map Generation */
1315 tm_ptr
[1] = tm_ptr
[1] + 1;
1317 /* Update Node_Count and Self_Id_Count */
1318 node_count
= (i
& IEEE1394_TOP_MAP_LEN_MASK
);
1319 self_id_count
= (c
& IEEE1394_TOP_MAP_LEN_MASK
);
1320 tm_ptr
[2] = (node_count
<< IEEE1394_TOP_MAP_LEN_SHIFT
) |
1323 /* Calculate CRC-16 */
1324 length
= self_id_count
+ 2;
1325 CRC
= s1394_CRC16(&(tm_ptr
[1]), length
);
1326 tm_ptr
[0] = (length
<< IEEE1394_TOP_MAP_LEN_SHIFT
) | CRC
;
1328 TNF_PROBE_0_DEBUG(s1394_CSR_topology_map_update_exit
,
1329 S1394_TNF_SL_BR_CSR_STACK
, "");
1333 * s1394_CSR_topology_map_disable()
1334 * is used to disable the local host's TOPOLOGY_MAP[] buffer (during bus
1335 * reset processing). It sets the topology map's length to zero to
1336 * indicate that it is invalid.
1339 s1394_CSR_topology_map_disable(s1394_hal_t
*hal
)
1343 TNF_PROBE_0_DEBUG(s1394_CSR_topology_map_disable_enter
,
1344 S1394_TNF_SL_BR_CSR_STACK
, "");
1346 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
1348 tm_ptr
= (uint32_t *)hal
->CSR_topology_map
;
1350 /* Set length = 0 */
1351 tm_ptr
[0] = tm_ptr
[0] & IEEE1394_TOP_MAP_LEN_MASK
;
1353 TNF_PROBE_0_DEBUG(s1394_CSR_topology_map_disable_exit
,
1354 S1394_TNF_SL_BR_CSR_STACK
, "");
1358 * s1394_common_CSR_routine()
1359 * is used to handle most of the CSR register requests. They are passed
1360 * to the appropriate HAL entry point for further processing. Then they
1361 * are filled in with an appropriate response code, and the response is sent.
1364 s1394_common_CSR_routine(s1394_hal_t
*hal
, cmd1394_cmd_t
*req
)
1370 TNF_PROBE_0_DEBUG(s1394_common_CSR_routine_enter
,
1371 S1394_TNF_SL_CSR_STACK
, "");
1373 /* Register offset */
1374 offset
= (req
->cmd_addr
& IEEE1394_CSR_OFFSET_MASK
);
1376 /* Verify that request is quadlet aligned */
1377 if ((offset
& 0x3) != 0) {
1378 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
1379 (void) s1394_send_response(hal
, req
);
1382 switch (req
->cmd_type
) {
1383 case CMD1394_ASYNCH_RD_QUAD
:
1385 * The csr_read() call can return DDI_FAILURE if the HAL
1386 * is shutdown or if the register at "offset" is
1387 * unimplemented. We will return IEEE1394_RESP_ADDRESS_ERROR
1388 * in the response if we see this error.
1390 result
= HAL_CALL(hal
).csr_read(hal
->halinfo
.hal_private
,
1392 if (result
== DDI_SUCCESS
) {
1393 req
->cmd_u
.q
.quadlet_data
= data
;
1394 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
1396 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
1400 case CMD1394_ASYNCH_WR_QUAD
:
1401 data
= req
->cmd_u
.q
.quadlet_data
;
1403 * The csr_read() call can return DDI_FAILURE if the HAL
1404 * is shutdown or if the register at "offset" is
1405 * unimplemented. We will return IEEE1394_RESP_ADDRESS_ERROR
1406 * in the response if we see this error.
1408 result
= HAL_CALL(hal
).csr_write(hal
->halinfo
.hal_private
,
1410 if (result
== DDI_SUCCESS
) {
1411 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
1413 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
1418 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
1421 (void) s1394_send_response(hal
, req
);
1422 TNF_PROBE_0_DEBUG(s1394_common_CSR_routine_exit
,
1423 S1394_TNF_SL_CSR_STACK
, "");
1427 * s1394_init_local_config_rom()
1428 * is called in the HAL attach routine - h1394_attach() - to setup the
1429 * initial Config ROM entries on the local host, including the
1430 * bus_info_block and the root and unit directories.
1433 s1394_init_local_config_rom(s1394_hal_t
*hal
)
1435 uint32_t *config_rom
;
1436 uint32_t *node_unique_id_leaf
;
1438 uint32_t *text_leaf
;
1441 uint32_t guid_hi
, guid_lo
;
1442 uint32_t bus_capabilities
;
1444 uint32_t module_vendor_id
;
1445 uint32_t node_capabilities
;
1446 uint32_t root_dir_len
;
1450 TNF_PROBE_0_DEBUG(s1394_init_local_config_rom_enter
,
1451 S1394_TNF_SL_CFGROM_STACK
, "");
1453 /* Setup Config ROM mutex */
1454 mutex_init(&hal
->local_config_rom_mutex
,
1455 NULL
, MUTEX_DRIVER
, hal
->halinfo
.hw_interrupt
);
1457 /* Allocate 1K for the Config ROM buffer */
1458 hal
->local_config_rom
= (uint32_t *)kmem_zalloc(IEEE1394_CONFIG_ROM_SZ
,
1461 /* Allocate 1K for the temporary buffer */
1462 hal
->temp_config_rom_buf
= (uint32_t *)kmem_zalloc(
1463 IEEE1394_CONFIG_ROM_SZ
, KM_SLEEP
);
1465 config_rom
= hal
->local_config_rom
;
1467 /* Lock the Config ROM buffer */
1468 mutex_enter(&hal
->local_config_rom_mutex
);
1470 /* Build the config ROM structures */
1471 ret
= s1394_init_config_rom_structures(hal
);
1472 if (ret
!= DDI_SUCCESS
) {
1473 /* Unlock the Config ROM buffer */
1474 mutex_exit(&hal
->local_config_rom_mutex
);
1475 kmem_free((void *)hal
->temp_config_rom_buf
,
1476 IEEE1394_CONFIG_ROM_SZ
);
1477 kmem_free((void *)hal
->local_config_rom
,
1478 IEEE1394_CONFIG_ROM_SZ
);
1479 mutex_destroy(&hal
->local_config_rom_mutex
);
1480 TNF_PROBE_1(s1394_init_local_config_rom_error
,
1481 S1394_TNF_SL_CFGROM_ERROR
, "", tnf_string
, msg
,
1482 "Failed in s1394_init_config_rom_structures()");
1483 TNF_PROBE_0_DEBUG(s1394_init_local_config_rom_exit
,
1484 S1394_TNF_SL_CFGROM_STACK
, "");
1485 return (DDI_FAILURE
);
1487 /* Build the Bus_Info_Block - see IEEE 1394-1995, Section 8.3.2.5.4 */
1488 bus_capabilities
= hal
->halinfo
.bus_capabilities
;
1491 * If we are Isoch Resource Manager capable then we are
1492 * Bus Manager capable too.
1494 irmc
= (bus_capabilities
& IEEE1394_BIB_IRMC_MASK
) >>
1495 IEEE1394_BIB_IRMC_SHIFT
;
1497 bus_capabilities
= bus_capabilities
| IEEE1394_BIB_BMC_MASK
;
1500 * Set generation to P1394a valid (but changeable)
1501 * Even if we have a 1995 PHY, we will still provide
1502 * certain P1394A functionality (especially with respect
1503 * to Config ROM updates). So we must publish this
1506 g
= 2 << IEEE1394_BIB_GEN_SHIFT
;
1507 bus_capabilities
= bus_capabilities
| g
;
1510 guid
= hal
->halinfo
.guid
;
1511 guid_hi
= (uint32_t)(guid
>> 32);
1512 guid_lo
= (uint32_t)(guid
& 0x00000000FFFFFFFF);
1514 config_rom
[1] = 0x31333934; /* "1394" */
1515 config_rom
[2] = bus_capabilities
;
1516 config_rom
[3] = guid_hi
;
1517 config_rom
[4] = guid_lo
;
1519 /* The CRC covers only our Bus_Info_Block */
1520 CRC
= s1394_CRC16(&config_rom
[1], 4);
1521 config_rom
[0] = (0x04040000) | CRC
;
1523 /* Do byte-swapping if necessary (x86) */
1524 for (i
= 0; i
< IEEE1394_BIB_QUAD_SZ
; i
++)
1525 config_rom
[i
] = T1394_DATA32(config_rom
[i
]);
1527 /* Build the Root_Directory - see IEEE 1394-1995, Section 8.3.2.5.5 */
1529 /* MODULE_VENDOR_ID - see IEEE 1394-1995, Section 8.3.2.5.5.1 */
1530 module_vendor_id
= S1394_SUNW_OUI
;
1532 /* NODE_CAPABILITIES - see IEEE 1394-1995, Section 8.3.2.5.5.2 */
1533 node_capabilities
= hal
->halinfo
.node_capabilities
&
1534 IEEE1212_NODE_CAPABILITIES_MASK
;
1537 config_rom
[6] = (IEEE1212_MODULE_VENDOR_ID
<<
1538 IEEE1212_KEY_VALUE_SHIFT
) | module_vendor_id
;
1539 config_rom
[7] = (IEEE1212_NODE_CAPABILITIES
<<
1540 IEEE1212_KEY_VALUE_SHIFT
) | node_capabilities
;
1542 CRC
= s1394_CRC16(&config_rom
[6], root_dir_len
);
1543 config_rom
[IEEE1394_BIB_QUAD_SZ
] =
1544 (root_dir_len
<< IEEE1394_CFG_ROM_LEN_SHIFT
) | CRC
;
1546 /* Do byte-swapping if necessary (x86) */
1547 for (i
= IEEE1394_BIB_QUAD_SZ
; i
< 8; i
++)
1548 config_rom
[i
] = T1394_DATA32(config_rom
[i
]);
1550 /* Build the Root Text leaf - see IEEE 1394-1995, Section 8.3.2.5.7 */
1551 text_leaf
= (uint32_t *)kmem_zalloc(S1394_ROOT_TEXT_LEAF_SZ
, KM_SLEEP
);
1552 text_leaf
[1] = 0x00000000;
1553 text_leaf
[2] = 0x00000000;
1554 text_leaf
[3] = 0x53756e20; /* "Sun " */
1555 text_leaf
[4] = 0x4d696372; /* "Micr" */
1556 text_leaf
[5] = 0x6f737973; /* "osys" */
1557 text_leaf
[6] = 0x74656d73; /* "tems" */
1558 text_leaf
[7] = 0x2c20496e; /* ", In" */
1559 text_leaf
[8] = 0x632e0000; /* "c." */
1560 CRC
= s1394_CRC16(&text_leaf
[1], S1394_ROOT_TEXT_LEAF_QUAD_SZ
- 1);
1561 text_leaf
[0] = (0x00080000) | CRC
;
1563 /* Do byte-swapping if necessary (x86) */
1564 for (i
= 0; i
< 9; i
++)
1565 text_leaf
[i
] = T1394_DATA32(text_leaf
[i
]);
1567 ret
= s1394_add_config_rom_entry(hal
, S1394_ROOT_TEXT_KEY
, text_leaf
,
1568 S1394_ROOT_TEXT_LEAF_QUAD_SZ
, &n_handle
, &status
);
1569 if (ret
!= DDI_SUCCESS
) {
1570 kmem_free((void *)text_leaf
, S1394_ROOT_TEXT_LEAF_SZ
);
1571 /* Destroy the config_rom structures */
1572 (void) s1394_destroy_config_rom_structures(hal
);
1573 /* Unlock the Config ROM buffer */
1574 mutex_exit(&hal
->local_config_rom_mutex
);
1575 kmem_free((void *)hal
->temp_config_rom_buf
,
1576 IEEE1394_CONFIG_ROM_SZ
);
1577 kmem_free((void *)hal
->local_config_rom
,
1578 IEEE1394_CONFIG_ROM_SZ
);
1579 mutex_destroy(&hal
->local_config_rom_mutex
);
1580 TNF_PROBE_1(s1394_init_local_config_rom_error
,
1581 S1394_TNF_SL_CFGROM_ERROR
, "", tnf_string
, msg
,
1582 "Failure in kmem_zalloc");
1583 TNF_PROBE_0_DEBUG(s1394_init_local_config_rom_exit
,
1584 S1394_TNF_SL_CFGROM_STACK
, "");
1585 return (DDI_FAILURE
);
1587 kmem_free((void *)text_leaf
, S1394_ROOT_TEXT_LEAF_SZ
);
1589 /* Build the Node_Unique_Id leaf - IEEE 1394-1995, Sect. 8.3.2.5.7.1 */
1590 node_unique_id_leaf
= (uint32_t *)kmem_zalloc(S1394_NODE_UNIQUE_ID_SZ
,
1592 node_unique_id_leaf
[1] = guid_hi
;
1593 node_unique_id_leaf
[2] = guid_lo
;
1594 CRC
= s1394_CRC16(&node_unique_id_leaf
[1],
1595 S1394_NODE_UNIQUE_ID_QUAD_SZ
- 1);
1596 node_unique_id_leaf
[0] = (0x00020000) | CRC
;
1598 /* Do byte-swapping if necessary (x86) */
1599 for (i
= 0; i
< S1394_NODE_UNIQUE_ID_QUAD_SZ
; i
++)
1600 node_unique_id_leaf
[i
] = T1394_DATA32(node_unique_id_leaf
[i
]);
1602 ret
= s1394_add_config_rom_entry(hal
, S1394_NODE_UNIQUE_ID_KEY
,
1603 node_unique_id_leaf
, S1394_NODE_UNIQUE_ID_QUAD_SZ
, &n_handle
,
1605 if (ret
!= DDI_SUCCESS
) {
1606 kmem_free((void *)node_unique_id_leaf
,
1607 S1394_NODE_UNIQUE_ID_SZ
);
1608 /* Destroy the config_rom structures */
1609 (void) s1394_destroy_config_rom_structures(hal
);
1610 /* Unlock the Config ROM buffer */
1611 mutex_exit(&hal
->local_config_rom_mutex
);
1612 kmem_free((void *)hal
->temp_config_rom_buf
,
1613 IEEE1394_CONFIG_ROM_SZ
);
1614 kmem_free((void *)hal
->local_config_rom
,
1615 IEEE1394_CONFIG_ROM_SZ
);
1616 mutex_destroy(&hal
->local_config_rom_mutex
);
1617 TNF_PROBE_1(s1394_init_local_config_rom_error
,
1618 S1394_TNF_SL_CFGROM_ERROR
, "", tnf_string
, msg
,
1619 "Failure in kmem_zalloc");
1620 TNF_PROBE_0_DEBUG(s1394_init_local_config_rom_exit
,
1621 S1394_TNF_SL_CFGROM_STACK
, "");
1622 return (DDI_FAILURE
);
1624 kmem_free((void *)node_unique_id_leaf
, S1394_NODE_UNIQUE_ID_SZ
);
1626 /* Build the Unit_Directory for 1394 Framework */
1627 unit_dir
= (uint32_t *)kmem_zalloc(S1394_UNIT_DIR_SZ
, KM_SLEEP
);
1628 unit_dir
[1] = 0x12080020; /* Sun Microsystems */
1629 unit_dir
[2] = 0x13000001; /* Version 1 */
1630 unit_dir
[3] = 0x81000001; /* offset to the text leaf */
1631 CRC
= s1394_CRC16(&unit_dir
[1], 3);
1632 unit_dir
[0] = (0x00030000) | CRC
;
1634 /* Do byte-swapping if necessary (x86) */
1635 for (i
= 0; i
< 4; i
++)
1636 unit_dir
[i
] = T1394_DATA32(unit_dir
[i
]);
1638 /* Build the Unit Directory text leaf */
1639 unit_dir
[5] = 0x00000000;
1640 unit_dir
[6] = 0x00000000;
1641 unit_dir
[7] = 0x536f6c61; /* "Sola" */
1642 unit_dir
[8] = 0x72697320; /* "ris " */
1643 unit_dir
[9] = 0x31333934; /* "1394" */
1644 unit_dir
[10] = 0x20535720; /* " SW " */
1645 unit_dir
[11] = 0x4672616d; /* "Fram" */
1646 unit_dir
[12] = 0x65576f72; /* "ewor" */
1647 unit_dir
[13] = 0x6b000000; /* "k" */
1648 CRC
= s1394_CRC16(&unit_dir
[5], 9);
1649 unit_dir
[4] = (0x00090000) | CRC
;
1651 /* Do byte-swapping if necessary (x86) */
1652 for (i
= 4; i
< S1394_UNIT_DIR_QUAD_SZ
; i
++)
1653 unit_dir
[i
] = T1394_DATA32(unit_dir
[i
]);
1655 ret
= s1394_add_config_rom_entry(hal
, S1394_UNIT_DIR_KEY
, unit_dir
,
1656 S1394_UNIT_DIR_QUAD_SZ
, &n_handle
, &status
);
1657 if (ret
!= DDI_SUCCESS
) {
1658 kmem_free((void *)unit_dir
, S1394_UNIT_DIR_SZ
);
1659 /* Destroy the config_rom structures */
1660 (void) s1394_destroy_config_rom_structures(hal
);
1661 /* Unlock the Config ROM buffer */
1662 mutex_exit(&hal
->local_config_rom_mutex
);
1663 kmem_free((void *)hal
->temp_config_rom_buf
,
1664 IEEE1394_CONFIG_ROM_SZ
);
1665 /* Free the 1K for the Config ROM buffer */
1666 kmem_free((void *)hal
->local_config_rom
,
1667 IEEE1394_CONFIG_ROM_SZ
);
1668 mutex_destroy(&hal
->local_config_rom_mutex
);
1669 TNF_PROBE_1(s1394_init_local_config_rom_error
,
1670 S1394_TNF_SL_CFGROM_ERROR
, "", tnf_string
, msg
,
1671 "Failure in kmem_zalloc");
1672 TNF_PROBE_0_DEBUG(s1394_init_local_config_rom_exit
,
1673 S1394_TNF_SL_CFGROM_STACK
, "");
1674 return (DDI_FAILURE
);
1676 kmem_free((void *)unit_dir
, S1394_UNIT_DIR_SZ
);
1678 hal
->config_rom_update_amount
= (IEEE1394_CONFIG_ROM_QUAD_SZ
-
1681 /* Unlock the Config ROM buffer */
1682 mutex_exit(&hal
->local_config_rom_mutex
);
1685 * The update_config_rom() call can return DDI_FAILURE if the
1688 (void) HAL_CALL(hal
).update_config_rom(hal
->halinfo
.hal_private
,
1689 config_rom
, IEEE1394_CONFIG_ROM_QUAD_SZ
);
1691 TNF_PROBE_0_DEBUG(s1394_init_local_config_rom_exit
,
1692 S1394_TNF_SL_CFGROM_STACK
, "");
1693 return (DDI_SUCCESS
);
1697 * s1394_destroy_local_config_rom()
1698 * is necessary for h1394_detach(). It undoes all the work that
1699 * s1394_init_local_config_rom() had setup and more. By pulling
1700 * everything out of the conig rom structures and freeing them and their
1701 * associated mutexes, the Config ROM is completely cleaned up.
1704 s1394_destroy_local_config_rom(s1394_hal_t
*hal
)
1706 TNF_PROBE_0_DEBUG(s1394_destroy_local_config_rom_enter
,
1707 S1394_TNF_SL_CFGROM_STACK
, "");
1709 /* Lock the Config ROM buffer */
1710 mutex_enter(&hal
->local_config_rom_mutex
);
1712 /* Destroy the config_rom structures */
1713 (void) s1394_destroy_config_rom_structures(hal
);
1715 /* Unlock the Config ROM buffer */
1716 mutex_exit(&hal
->local_config_rom_mutex
);
1718 /* Free the 1K for the temporary buffer */
1719 kmem_free((void *)hal
->temp_config_rom_buf
, IEEE1394_CONFIG_ROM_SZ
);
1720 /* Free the 1K for the Config ROM buffer */
1721 kmem_free((void *)hal
->local_config_rom
, IEEE1394_CONFIG_ROM_SZ
);
1723 /* Setup Config ROM mutex */
1724 mutex_destroy(&hal
->local_config_rom_mutex
);
1726 TNF_PROBE_0_DEBUG(s1394_destroy_local_config_rom_exit
,
1727 S1394_TNF_SL_CFGROM_STACK
, "");
1731 * s1394_init_config_rom_structures()
1732 * initializes the structures that are used to maintain the local Config ROM.
1733 * Callers must be holding the local_config_rom_mutex.
1736 s1394_init_config_rom_structures(s1394_hal_t
*hal
)
1738 s1394_config_rom_t
*root_directory
;
1739 s1394_config_rom_t
*rest_of_config_rom
;
1741 TNF_PROBE_0_DEBUG(s1394_init_config_rom_structures_enter
,
1742 S1394_TNF_SL_CFGROM_STACK
, "");
1744 ASSERT(MUTEX_HELD(&hal
->local_config_rom_mutex
));
1746 root_directory
= (s1394_config_rom_t
*)kmem_zalloc(
1747 sizeof (s1394_config_rom_t
), KM_SLEEP
);
1749 root_directory
->cfgrom_used
= B_TRUE
;
1750 root_directory
->cfgrom_addr_lo
= IEEE1394_BIB_QUAD_SZ
;
1751 root_directory
->cfgrom_addr_hi
= IEEE1394_BIB_QUAD_SZ
+ 2;
1753 rest_of_config_rom
= (s1394_config_rom_t
*)kmem_zalloc(
1754 sizeof (s1394_config_rom_t
), KM_SLEEP
);
1756 rest_of_config_rom
->cfgrom_used
= B_FALSE
;
1757 rest_of_config_rom
->cfgrom_addr_lo
= root_directory
->cfgrom_addr_hi
+ 1;
1758 rest_of_config_rom
->cfgrom_addr_hi
= IEEE1394_CONFIG_ROM_QUAD_SZ
- 1;
1760 root_directory
->cfgrom_next
= rest_of_config_rom
;
1761 root_directory
->cfgrom_prev
= NULL
;
1762 rest_of_config_rom
->cfgrom_next
= NULL
;
1763 rest_of_config_rom
->cfgrom_prev
= root_directory
;
1765 hal
->root_directory
= root_directory
;
1766 hal
->free_space
= IEEE1394_CONFIG_ROM_QUAD_SZ
-
1767 (rest_of_config_rom
->cfgrom_addr_lo
);
1769 TNF_PROBE_0_DEBUG(s1394_init_config_rom_structures_exit
,
1770 S1394_TNF_SL_CFGROM_STACK
, "");
1771 return (DDI_SUCCESS
);
1775 * s1394_destroy_config_rom_structures()
1776 * is used to destroy the structures that maintain the local Config ROM.
1777 * Callers must be holding the local_config_rom_mutex.
1780 s1394_destroy_config_rom_structures(s1394_hal_t
*hal
)
1782 s1394_config_rom_t
*curr_blk
;
1783 s1394_config_rom_t
*next_blk
;
1785 TNF_PROBE_0_DEBUG(s1394_destroy_config_rom_structures_enter
,
1786 S1394_TNF_SL_CFGROM_STACK
, "");
1788 ASSERT(MUTEX_HELD(&hal
->local_config_rom_mutex
));
1790 curr_blk
= hal
->root_directory
;
1792 while (curr_blk
!= NULL
) {
1793 next_blk
= curr_blk
->cfgrom_next
;
1794 kmem_free(curr_blk
, sizeof (s1394_config_rom_t
));
1795 curr_blk
= next_blk
;
1798 TNF_PROBE_0_DEBUG(s1394_destroy_config_rom_structures_exit
,
1799 S1394_TNF_SL_CFGROM_STACK
, "");
1800 return (DDI_SUCCESS
);
1804 * s1394_add_config_rom_entry()
1805 * is used to add a new entry to the local host's config ROM. By
1806 * specifying a key and a buffer, it is possible to update the Root
1807 * Directory to point to the new entry (in buffer). Additionally, all
1808 * of the relevant CRCs, lengths, and generations are updated as well.
1809 * By returning a Config ROM "handle", we can allow targets to remove
1810 * the corresponding entry.
1811 * Callers must be holding the local_config_rom_mutex.
1814 s1394_add_config_rom_entry(s1394_hal_t
*hal
, uint8_t key
, uint32_t *buffer
,
1815 uint_t size
, void **handle
, int *status
)
1817 s1394_config_rom_t
*curr_blk
;
1818 s1394_config_rom_t
*new_blk
;
1819 uint32_t *config_rom
;
1823 uint_t tmp_size
, temp
;
1824 uint_t last_entry_offset
;
1827 TNF_PROBE_0_DEBUG(s1394_add_config_rom_entry_enter
,
1828 "stacktrace 1394 s1394", "");
1830 ASSERT(MUTEX_HELD(&hal
->local_config_rom_mutex
));
1832 if (size
> hal
->free_space
) {
1834 *status
= CMD1394_ERSRC_CONFLICT
;
1835 TNF_PROBE_0_DEBUG(s1394_add_config_rom_entry_exit
,
1836 S1394_TNF_SL_CFGROM_STACK
, "");
1837 return (DDI_FAILURE
);
1840 config_rom
= hal
->local_config_rom
;
1841 temp_buf
= hal
->temp_config_rom_buf
;
1843 /* Copy the Bus_Info_Block */
1844 bcopy(&config_rom
[0], &temp_buf
[0], IEEE1394_BIB_SZ
);
1846 /* Copy and add to the Root_Directory */
1847 tmp_offset
= hal
->root_directory
->cfgrom_addr_lo
;
1848 tmp_size
= (hal
->root_directory
->cfgrom_addr_hi
- tmp_offset
) + 1;
1849 tmp_size
= tmp_size
+ 1; /* For the new entry */
1850 bcopy(&config_rom
[tmp_offset
], &temp_buf
[tmp_offset
], tmp_size
<< 2);
1851 last_entry_offset
= hal
->root_directory
->cfgrom_addr_hi
+ 1;
1853 curr_blk
= hal
->root_directory
;
1854 curr_blk
->cfgrom_addr_hi
= curr_blk
->cfgrom_addr_hi
+ 1;
1855 while (curr_blk
->cfgrom_next
!= NULL
) {
1856 if (curr_blk
->cfgrom_next
->cfgrom_used
== B_TRUE
) {
1857 tmp_offset
= curr_blk
->cfgrom_next
->cfgrom_addr_lo
;
1858 tmp_size
= (curr_blk
->cfgrom_next
->cfgrom_addr_hi
-
1861 bcopy(&config_rom
[tmp_offset
],
1862 &temp_buf
[tmp_offset
+ 1], tmp_size
<< 2);
1863 curr_blk
->cfgrom_next
->cfgrom_addr_lo
++;
1864 curr_blk
->cfgrom_next
->cfgrom_addr_hi
++;
1866 curr_blk
->cfgrom_next
->cfgrom_addr_hi
;
1868 tmp_offset
= curr_blk
->cfgrom_next
->root_dir_offset
;
1870 /* Swap... add one... then unswap */
1871 temp
= T1394_DATA32(temp_buf
[tmp_offset
]);
1873 temp_buf
[tmp_offset
] = T1394_DATA32(temp
);
1875 curr_blk
->cfgrom_next
->cfgrom_addr_lo
++;
1880 curr_blk
= curr_blk
->cfgrom_next
;
1883 /* Get the pointer to the "free" space */
1884 curr_blk
= curr_blk
->cfgrom_next
;
1886 /* Is it an exact fit? */
1887 if (hal
->free_space
== size
) {
1888 curr_blk
->cfgrom_used
= B_TRUE
;
1890 } else { /* Must break this piece */
1891 new_blk
= (s1394_config_rom_t
*)kmem_zalloc(
1892 sizeof (s1394_config_rom_t
), KM_SLEEP
);
1893 if (new_blk
== NULL
) {
1894 TNF_PROBE_0_DEBUG(s1394_add_config_rom_entry_exit
,
1895 S1394_TNF_SL_CFGROM_STACK
, "");
1896 return (DDI_FAILURE
);
1899 new_blk
->cfgrom_addr_hi
= curr_blk
->cfgrom_addr_hi
;
1900 new_blk
->cfgrom_addr_lo
= curr_blk
->cfgrom_addr_lo
+ size
;
1901 curr_blk
->cfgrom_addr_hi
= new_blk
->cfgrom_addr_lo
- 1;
1902 new_blk
->cfgrom_next
= curr_blk
->cfgrom_next
;
1903 curr_blk
->cfgrom_next
= new_blk
;
1904 new_blk
->cfgrom_prev
= curr_blk
;
1905 curr_blk
->cfgrom_used
= B_TRUE
;
1906 last_entry_offset
= curr_blk
->cfgrom_addr_hi
;
1908 hal
->free_space
= hal
->free_space
- size
;
1910 /* Copy in the new entry */
1911 tmp_offset
= curr_blk
->cfgrom_addr_lo
;
1912 bcopy(buffer
, &temp_buf
[tmp_offset
], size
<< 2);
1914 /* Update root directory */
1915 tmp_offset
= hal
->root_directory
->cfgrom_addr_hi
;
1916 tmp_size
= tmp_offset
- hal
->root_directory
->cfgrom_addr_lo
;
1917 curr_blk
->root_dir_offset
= tmp_offset
;
1918 tmp_offset
= curr_blk
->cfgrom_addr_lo
- tmp_offset
;
1920 temp_buf
[hal
->root_directory
->cfgrom_addr_hi
] =
1921 T1394_DATA32((((uint32_t)key
) << IEEE1212_KEY_VALUE_SHIFT
) |
1923 tmp_offset
= hal
->root_directory
->cfgrom_addr_lo
;
1925 /* Do byte-swapping if necessary (x86) */
1926 for (i
= (tmp_offset
+ 1); i
<= hal
->root_directory
->cfgrom_addr_hi
;
1928 temp_buf
[i
] = T1394_DATA32(temp_buf
[i
]);
1930 CRC
= s1394_CRC16(&temp_buf
[tmp_offset
+ 1], tmp_size
);
1931 temp_buf
[tmp_offset
] = (tmp_size
<< IEEE1394_CFG_ROM_LEN_SHIFT
) | CRC
;
1933 /* Redo byte-swapping if necessary (x86) */
1934 for (i
= tmp_offset
; i
<= hal
->root_directory
->cfgrom_addr_hi
; i
++)
1935 temp_buf
[i
] = T1394_DATA32(temp_buf
[i
]);
1937 /* Copy it back to config_rom buffer */
1938 last_entry_offset
++;
1939 bcopy(&temp_buf
[0], &config_rom
[0], last_entry_offset
<< 2);
1941 /* Return a handle to this block */
1944 *status
= T1394_NOERROR
;
1946 TNF_PROBE_0_DEBUG(s1394_add_config_rom_entry_exit
,
1947 S1394_TNF_SL_CFGROM_STACK
, "");
1948 return (DDI_SUCCESS
);
1952 * s1394_remove_config_rom_entry()
1953 * is used to remove an entry from the local host's config ROM. By
1954 * specifying the Config ROM "handle" that was given in the allocation,
1955 * it is possible to remove the entry. Subsequently, the Config ROM is
1957 * Callers must be holding the local_config_rom_mutex.
1960 s1394_remove_config_rom_entry(s1394_hal_t
*hal
, void **handle
, int *status
)
1962 s1394_config_rom_t
*del_blk
;
1963 s1394_config_rom_t
*curr_blk
;
1964 s1394_config_rom_t
*last_blk
;
1965 s1394_config_rom_t
*free_blk
;
1966 uint32_t *config_rom
;
1976 TNF_PROBE_0_DEBUG(s1394_remove_config_rom_entry_enter
,
1977 S1394_TNF_SL_CFGROM_STACK
, "");
1979 ASSERT(MUTEX_HELD(&hal
->local_config_rom_mutex
));
1981 del_blk
= (s1394_config_rom_t
*)(*handle
);
1983 config_rom
= hal
->local_config_rom
;
1984 temp_buf
= hal
->temp_config_rom_buf
;
1986 /* Copy the Bus_Info_Block */
1987 bcopy(&config_rom
[0], &temp_buf
[0], IEEE1394_BIB_SZ
);
1989 root_offset
= hal
->root_directory
->cfgrom_addr_lo
;
1990 del_offset
= del_blk
->root_dir_offset
;
1992 /* Update Root_Directory entries before the deleted one */
1993 for (i
= root_offset
; i
< del_offset
; i
++) {
1994 entry
= T1394_DATA32(config_rom
[i
]);
1996 /* If entry is an offset address - update it */
1997 if (entry
& 0x80000000)
1998 temp_buf
[i
] = T1394_DATA32(entry
- 1);
2000 temp_buf
[i
] = T1394_DATA32(entry
);
2003 /* Move all Unit_Directories prior to the deleted one */
2004 curr_blk
= hal
->root_directory
->cfgrom_next
;
2006 while (curr_blk
!= del_blk
) {
2007 tmp_offset
= curr_blk
->cfgrom_addr_lo
;
2008 tmp_size
= (curr_blk
->cfgrom_addr_hi
- tmp_offset
) + 1;
2010 bcopy(&config_rom
[tmp_offset
], &temp_buf
[tmp_offset
- 1],
2012 curr_blk
->cfgrom_addr_lo
--;
2013 curr_blk
->cfgrom_addr_hi
--;
2014 curr_blk
= curr_blk
->cfgrom_next
;
2017 /* Move all Unit_Directories after the deleted one */
2018 curr_blk
= del_blk
->cfgrom_next
;
2019 last_blk
= del_blk
->cfgrom_prev
;
2021 del_offset
= (del_blk
->cfgrom_addr_hi
- del_blk
->cfgrom_addr_lo
) + 1;
2023 while ((curr_blk
!= NULL
) && (curr_blk
->cfgrom_used
== B_TRUE
)) {
2024 tmp_offset
= curr_blk
->cfgrom_addr_lo
;
2025 tmp_size
= (curr_blk
->cfgrom_addr_hi
- tmp_offset
) + 1;
2027 bcopy(&config_rom
[tmp_offset
],
2028 &temp_buf
[tmp_offset
- (del_offset
+ 1)], tmp_size
<< 2);
2030 root_offset
= curr_blk
->root_dir_offset
;
2031 temp_buf
[root_offset
- 1] =
2032 config_rom
[root_offset
] - del_offset
;
2033 curr_blk
->root_dir_offset
--;
2034 curr_blk
->cfgrom_addr_lo
= curr_blk
->cfgrom_addr_lo
-
2036 curr_blk
->cfgrom_addr_hi
= curr_blk
->cfgrom_addr_hi
-
2039 last_blk
= curr_blk
;
2040 curr_blk
= curr_blk
->cfgrom_next
;
2043 /* Remove del_blk from the list */
2044 if (del_blk
->cfgrom_prev
!= NULL
)
2045 del_blk
->cfgrom_prev
->cfgrom_next
= del_blk
->cfgrom_next
;
2047 if (del_blk
->cfgrom_next
!= NULL
)
2048 del_blk
->cfgrom_next
->cfgrom_prev
= del_blk
->cfgrom_prev
;
2050 del_blk
->cfgrom_prev
= NULL
;
2051 del_blk
->cfgrom_next
= NULL
;
2052 kmem_free((void *)del_blk
, sizeof (s1394_config_rom_t
));
2054 /* Update and zero out the "free" block */
2055 if (curr_blk
!= NULL
) {
2056 curr_blk
->cfgrom_addr_lo
= curr_blk
->cfgrom_addr_lo
-
2060 free_blk
= (s1394_config_rom_t
*)kmem_zalloc(
2061 sizeof (s1394_config_rom_t
), KM_SLEEP
);
2062 if (free_blk
== NULL
) {
2063 TNF_PROBE_0_DEBUG(s1394_remove_config_rom_entry_exit
,
2064 S1394_TNF_SL_CFGROM_STACK
, "");
2065 return (DDI_FAILURE
);
2068 free_blk
->cfgrom_used
= B_FALSE
;
2069 free_blk
->cfgrom_addr_lo
= (IEEE1394_CONFIG_ROM_QUAD_SZ
- 1) -
2071 free_blk
->cfgrom_addr_hi
= (IEEE1394_CONFIG_ROM_QUAD_SZ
- 1);
2073 free_blk
->cfgrom_prev
= last_blk
;
2074 free_blk
->cfgrom_next
= NULL
;
2075 curr_blk
= free_blk
;
2077 hal
->free_space
= hal
->free_space
+ (del_offset
+ 1);
2078 tmp_offset
= curr_blk
->cfgrom_addr_lo
;
2079 tmp_size
= (curr_blk
->cfgrom_addr_hi
- tmp_offset
) + 1;
2080 bzero(&temp_buf
[tmp_offset
], tmp_size
<< 2);
2083 /* Update root directory */
2084 hal
->root_directory
->cfgrom_addr_hi
--;
2085 tmp_offset
= hal
->root_directory
->cfgrom_addr_lo
;
2086 tmp_size
= hal
->root_directory
->cfgrom_addr_hi
- tmp_offset
;
2088 /* Do byte-swapping if necessary (x86) */
2089 for (i
= (tmp_offset
+ 1); i
<= hal
->root_directory
->cfgrom_addr_hi
;
2091 temp_buf
[i
] = T1394_DATA32(temp_buf
[i
]);
2093 CRC
= s1394_CRC16(&temp_buf
[tmp_offset
+ 1], tmp_size
);
2094 temp_buf
[tmp_offset
] = (tmp_size
<< IEEE1394_CFG_ROM_LEN_SHIFT
) | CRC
;
2096 /* Do byte-swapping if necessary (x86) */
2097 for (i
= (tmp_offset
+ 1); i
<= hal
->root_directory
->cfgrom_addr_hi
;
2099 temp_buf
[i
] = T1394_DATA32(temp_buf
[i
]);
2101 /* Copy it back to config_rom buffer */
2102 tmp_size
= IEEE1394_CONFIG_ROM_SZ
- (hal
->free_space
<< 2);
2103 bcopy(&temp_buf
[0], &config_rom
[0], tmp_size
);
2105 /* Return a handle to this block */
2108 *status
= T1394_NOERROR
;
2110 TNF_PROBE_0_DEBUG(s1394_remove_config_rom_entry_exit
,
2111 S1394_TNF_SL_CFGROM_STACK
, "");
2112 return (DDI_SUCCESS
);
2116 * s1394_update_config_rom_callback()
2117 * is the callback used by t1394_add_cfgrom_entry() and
2118 * t1394_rem_cfgrom_entry(). After a target updates the Config ROM, a
2119 * timer is set with this as its callback function. This is to reduce
2120 * the number of bus resets that would be necessary if many targets
2121 * wished to update the Config ROM simultaneously.
2124 s1394_update_config_rom_callback(void *arg
)
2127 uint32_t *config_rom
;
2128 uint32_t bus_capabilities
;
2131 uint_t last_entry_offset
;
2134 TNF_PROBE_0_DEBUG(s1394_update_config_rom_callback_enter
,
2135 S1394_TNF_SL_CFGROM_STACK
, "");
2137 hal
= (s1394_hal_t
*)arg
;
2139 /* Lock the Config ROM buffer */
2140 mutex_enter(&hal
->local_config_rom_mutex
);
2142 config_rom
= hal
->local_config_rom
;
2144 /* Update Generation and CRC for Bus_Info_Block */
2146 /* Do byte-swapping if necessary (x86) */
2147 for (i
= 0; i
< IEEE1394_BIB_QUAD_SZ
; i
++)
2148 config_rom
[i
] = T1394_DATA32(config_rom
[i
]);
2150 bus_capabilities
= config_rom
[IEEE1212_NODE_CAP_QUAD
];
2151 g
= ((bus_capabilities
& IEEE1394_BIB_GEN_MASK
) >>
2152 IEEE1394_BIB_GEN_SHIFT
) + 1;
2155 g
= g
<< IEEE1394_BIB_GEN_SHIFT
;
2157 bus_capabilities
= (bus_capabilities
& (~IEEE1394_BIB_GEN_MASK
)) | g
;
2158 config_rom
[IEEE1212_NODE_CAP_QUAD
] = bus_capabilities
;
2160 CRC
= s1394_CRC16(&config_rom
[1], IEEE1394_BIB_QUAD_SZ
- 1);
2161 config_rom
[0] = (0x04040000) | CRC
;
2163 /* Do byte-swapping if necessary (x86) */
2164 for (i
= 0; i
< IEEE1394_BIB_QUAD_SZ
; i
++)
2165 config_rom
[i
] = T1394_DATA32(config_rom
[i
]);
2167 /* Make sure we update only what is necessary */
2168 last_entry_offset
= (IEEE1394_CONFIG_ROM_QUAD_SZ
- hal
->free_space
);
2169 if (last_entry_offset
< hal
->config_rom_update_amount
)
2170 last_entry_offset
= hal
->config_rom_update_amount
;
2172 hal
->config_rom_update_amount
= (IEEE1394_CONFIG_ROM_QUAD_SZ
-
2175 /* Clear the timer flag */
2176 hal
->config_rom_timer_set
= B_FALSE
;
2178 /* Unlock the Config ROM buffer */
2179 mutex_exit(&hal
->local_config_rom_mutex
);
2182 * The update_config_rom() call can return DDI_FAILURE if the
2185 (void) HAL_CALL(hal
).update_config_rom(hal
->halinfo
.hal_private
,\
2186 config_rom
, last_entry_offset
);
2188 /* Initiate a bus reset */
2189 ret
= HAL_CALL(hal
).bus_reset(hal
->halinfo
.hal_private
);
2190 if (ret
!= DDI_SUCCESS
) {
2191 TNF_PROBE_1(s1394_update_config_rom_callback_error
,
2192 S1394_TNF_SL_ERROR
, "", tnf_string
, msg
,
2193 "Error initiating bus reset");
2196 TNF_PROBE_0_DEBUG(s1394_update_config_rom_callback_exit
,
2197 S1394_TNF_SL_CFGROM_STACK
, "");