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
;
100 * Although they are not freed up in this routine, if
101 * one of the s1394_claim_addr_blk() routines fails,
102 * all of the previously successful claims will be
103 * freed up in s1394_destroy_addr_space() upon returning
104 * DDI_FAILURE from this routine.
107 rw_flags
= T1394_ADDR_RDENBL
| T1394_ADDR_WRENBL
;
111 * see IEEE 1394-1995, Section 8.3.2.2.1 or
112 * IEEE 1212-1994, Section 7.4.1
114 addr
.aa_address
= IEEE1394_CSR_STATE_CLEAR
;
115 addr
.aa_length
= IEEE1394_QUADLET
;
116 addr
.aa_enable
= rw_flags
;
117 addr
.aa_type
= T1394_ADDR_FIXED
;
118 addr
.aa_evts
.recv_read_request
= s1394_CSR_state_clear
;
119 addr
.aa_evts
.recv_write_request
= s1394_CSR_state_clear
;
120 addr
.aa_evts
.recv_lock_request
= NULL
;
121 addr
.aa_kmem_bufp
= NULL
;
123 result
= s1394_claim_addr_blk(hal
, &addr
);
124 if (result
!= DDI_SUCCESS
) {
125 return (DDI_FAILURE
);
130 * see IEEE 1394-1995, Section 8.3.2.2.2 or
131 * IEEE 1212-1994, Section 7.4.2
133 addr
.aa_address
= IEEE1394_CSR_STATE_SET
;
134 addr
.aa_length
= IEEE1394_QUADLET
;
135 addr
.aa_enable
= T1394_ADDR_WRENBL
;
136 addr
.aa_type
= T1394_ADDR_FIXED
;
137 addr
.aa_evts
.recv_read_request
= NULL
;
138 addr
.aa_evts
.recv_write_request
= s1394_CSR_state_set
;
139 addr
.aa_evts
.recv_lock_request
= NULL
;
140 addr
.aa_kmem_bufp
= NULL
;
142 result
= s1394_claim_addr_blk(hal
, &addr
);
143 if (result
!= DDI_SUCCESS
) {
144 return (DDI_FAILURE
);
149 * see IEEE 1394-1995, Section 8.3.2.2.3 or
150 * IEEE 1212-1994, Section 7.4.3
152 addr
.aa_address
= IEEE1394_CSR_NODE_IDS
;
153 addr
.aa_length
= IEEE1394_QUADLET
;
154 addr
.aa_enable
= rw_flags
;
155 addr
.aa_type
= T1394_ADDR_FIXED
;
156 addr
.aa_evts
.recv_read_request
= s1394_CSR_node_ids
;
157 addr
.aa_evts
.recv_write_request
= s1394_CSR_node_ids
;
158 addr
.aa_evts
.recv_lock_request
= NULL
;
159 addr
.aa_kmem_bufp
= NULL
;
161 result
= s1394_claim_addr_blk(hal
, &addr
);
162 if (result
!= DDI_SUCCESS
) {
163 return (DDI_FAILURE
);
168 * see IEEE 1394-1995, Section 8.3.2.2.4 or
169 * IEEE 1212-1994, Section 7.4.4
171 addr
.aa_address
= IEEE1394_CSR_RESET_START
;
172 addr
.aa_length
= IEEE1394_QUADLET
;
173 addr
.aa_enable
= T1394_ADDR_WRENBL
;
174 addr
.aa_type
= T1394_ADDR_FIXED
;
175 addr
.aa_evts
.recv_read_request
= NULL
;
176 addr
.aa_evts
.recv_write_request
= s1394_CSR_reset_start
;
177 addr
.aa_evts
.recv_lock_request
= NULL
;
178 addr
.aa_kmem_bufp
= NULL
;
180 result
= s1394_claim_addr_blk(hal
, &addr
);
181 if (result
!= DDI_SUCCESS
) {
182 return (DDI_FAILURE
);
187 * see IEEE 1394-1995, Section 8.3.2.2.6 or
188 * IEEE 1212-1994, Section 7.4.7
190 addr
.aa_address
= IEEE1394_CSR_SPLIT_TIMEOUT_HI
;
191 addr
.aa_length
= IEEE1394_OCTLET
;
192 addr
.aa_enable
= rw_flags
;
193 addr
.aa_type
= T1394_ADDR_FIXED
;
194 addr
.aa_evts
.recv_read_request
= s1394_CSR_split_timeout
;
195 addr
.aa_evts
.recv_write_request
= s1394_CSR_split_timeout
;
196 addr
.aa_evts
.recv_lock_request
= NULL
;
197 addr
.aa_kmem_bufp
= NULL
;
199 result
= s1394_claim_addr_blk(hal
, &addr
);
200 if (result
!= DDI_SUCCESS
) {
201 return (DDI_FAILURE
);
205 * ARGUMENT_HI and ARGUMENT_LO
206 * see IEEE 1394-1995, Section 8.3.2.2.7 or
207 * IEEE 1212-1994, Section 7.4.8
209 addr
.aa_address
= IEEE1394_CSR_ARG_HI
;
210 addr
.aa_length
= 2 * (IEEE1394_QUADLET
);
211 addr
.aa_enable
= rw_flags
;
212 addr
.aa_type
= T1394_ADDR_FIXED
;
213 addr
.aa_evts
.recv_read_request
= s1394_CSR_argument_regs
;
214 addr
.aa_evts
.recv_write_request
= s1394_CSR_argument_regs
;
215 addr
.aa_evts
.recv_lock_request
= NULL
;
216 addr
.aa_kmem_bufp
= NULL
;
218 result
= s1394_claim_addr_blk(hal
, &addr
);
219 if (result
!= DDI_SUCCESS
) {
220 return (DDI_FAILURE
);
224 * TEST_START and TEST_STATUS
225 * see IEEE 1394-1995, Section 8.3.2.2.7 or
226 * IEEE 1212-1994, Section 7.4.9 - 7.4.10
228 addr
.aa_address
= IEEE1394_CSR_TEST_START
;
229 addr
.aa_length
= 2 * (IEEE1394_QUADLET
);
230 addr
.aa_enable
= rw_flags
;
231 addr
.aa_type
= T1394_ADDR_FIXED
;
232 addr
.aa_evts
.recv_read_request
= s1394_CSR_test_regs
;
233 addr
.aa_evts
.recv_write_request
= s1394_CSR_test_regs
;
234 addr
.aa_evts
.recv_lock_request
= NULL
;
235 addr
.aa_kmem_bufp
= NULL
;
237 result
= s1394_claim_addr_blk(hal
, &addr
);
238 if (result
!= DDI_SUCCESS
) {
239 return (DDI_FAILURE
);
243 * INTERRUPT_TARGET and INTERRUPT_MASK
244 * see IEEE 1394-1995, Section 8.3.2.2.9 or
245 * IEEE 1212-1994, Section 7.4.15 - 7.4.16
247 addr
.aa_address
= IEEE1394_CSR_INTERRUPT_TARGET
;
248 addr
.aa_length
= 2 * (IEEE1394_QUADLET
);
249 addr
.aa_enable
= rw_flags
;
250 addr
.aa_type
= T1394_ADDR_FIXED
;
251 addr
.aa_evts
.recv_read_request
= s1394_CSR_interrupt_regs
;
252 addr
.aa_evts
.recv_write_request
= s1394_CSR_interrupt_regs
;
253 addr
.aa_evts
.recv_lock_request
= NULL
;
254 addr
.aa_kmem_bufp
= NULL
;
256 result
= s1394_claim_addr_blk(hal
, &addr
);
257 if (result
!= DDI_SUCCESS
) {
258 return (DDI_FAILURE
);
262 * CLOCK_VALUE, CLOCK_TICK_PERIOD, CLOCK_INFO, etc.
263 * see IEEE 1394-1995, Section 8.3.2.2.10 or
264 * IEEE 1212-1994, Section 7.4.17 - 7.4.20
266 addr
.aa_address
= IEEE1394_CSR_CLOCK_VALUE
;
267 addr
.aa_length
= IEEE1394_CSR_CLOCK_VALUE_SZ
;
268 addr
.aa_enable
= rw_flags
;
269 addr
.aa_type
= T1394_ADDR_FIXED
;
270 addr
.aa_evts
.recv_read_request
= s1394_CSR_clock_regs
;
271 addr
.aa_evts
.recv_write_request
= s1394_CSR_clock_regs
;
272 addr
.aa_evts
.recv_lock_request
= NULL
;
273 addr
.aa_kmem_bufp
= NULL
;
275 result
= s1394_claim_addr_blk(hal
, &addr
);
276 if (result
!= DDI_SUCCESS
) {
277 return (DDI_FAILURE
);
281 * MESSAGE_REQUEST and MESSAGE_RESPONSE
282 * see IEEE 1394-1995, Section 8.3.2.2.11 or
283 * IEEE 1212-1994, Section 7.4.21
285 addr
.aa_address
= IEEE1394_CSR_MESSAGE_REQUEST
;
286 addr
.aa_length
= IEEE1394_CSR_MESSAGE_REQUEST_SZ
;
287 addr
.aa_enable
= rw_flags
;
288 addr
.aa_type
= T1394_ADDR_FIXED
;
289 addr
.aa_evts
.recv_read_request
= s1394_CSR_message_regs
;
290 addr
.aa_evts
.recv_write_request
= s1394_CSR_message_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 return (DDI_FAILURE
);
301 * see IEEE 1394-1995, Section 8.3.2.3.1
303 addr
.aa_address
= IEEE1394_SCSR_CYCLE_TIME
;
304 addr
.aa_length
= IEEE1394_QUADLET
;
305 addr
.aa_enable
= rw_flags
;
306 addr
.aa_type
= T1394_ADDR_FIXED
;
307 addr
.aa_evts
.recv_read_request
= s1394_CSR_cycle_time
;
308 addr
.aa_evts
.recv_write_request
= s1394_CSR_cycle_time
;
309 addr
.aa_evts
.recv_lock_request
= NULL
;
310 addr
.aa_kmem_bufp
= NULL
;
312 result
= s1394_claim_addr_blk(hal
, &addr
);
313 if (result
!= DDI_SUCCESS
) {
314 return (DDI_FAILURE
);
319 * see IEEE 1394-1995, Section 8.3.2.3.2
321 addr
.aa_address
= IEEE1394_SCSR_BUS_TIME
;
322 addr
.aa_length
= IEEE1394_QUADLET
;
323 addr
.aa_enable
= rw_flags
;
324 addr
.aa_type
= T1394_ADDR_FIXED
;
325 addr
.aa_evts
.recv_read_request
= s1394_CSR_bus_time
;
326 addr
.aa_evts
.recv_write_request
= s1394_CSR_bus_time
;
327 addr
.aa_evts
.recv_lock_request
= NULL
;
328 addr
.aa_kmem_bufp
= NULL
;
330 result
= s1394_claim_addr_blk(hal
, &addr
);
331 if (result
!= DDI_SUCCESS
) {
332 return (DDI_FAILURE
);
337 * see IEEE 1394-1995, Section 8.3.2.3.5
339 addr
.aa_address
= IEEE1394_SCSR_BUSY_TIMEOUT
;
340 addr
.aa_length
= IEEE1394_QUADLET
;
341 addr
.aa_enable
= rw_flags
;
342 addr
.aa_type
= T1394_ADDR_FIXED
;
343 addr
.aa_evts
.recv_read_request
= s1394_CSR_busy_timeout
;
344 addr
.aa_evts
.recv_write_request
= s1394_CSR_busy_timeout
;
345 addr
.aa_evts
.recv_lock_request
= NULL
;
346 addr
.aa_kmem_bufp
= NULL
;
348 result
= s1394_claim_addr_blk(hal
, &addr
);
349 if (result
!= DDI_SUCCESS
) {
350 return (DDI_FAILURE
);
355 * BANDWIDTH_AVAILABLE
357 * see IEEE 1394-1995, Section 8.3.2.3.6 - 8.3.2.3.8
359 addr
.aa_address
= IEEE1394_SCSR_BUSMGR_ID
;
360 addr
.aa_length
= 3 * (IEEE1394_QUADLET
);
361 addr
.aa_enable
= T1394_ADDR_RDENBL
| T1394_ADDR_LKENBL
;
362 addr
.aa_type
= T1394_ADDR_FIXED
;
363 addr
.aa_evts
.recv_read_request
= s1394_CSR_IRM_regs
;
364 addr
.aa_evts
.recv_write_request
= NULL
;
365 addr
.aa_evts
.recv_lock_request
= s1394_CSR_IRM_regs
;
366 addr
.aa_kmem_bufp
= NULL
;
368 result
= s1394_claim_addr_blk(hal
, &addr
);
369 if (result
!= DDI_SUCCESS
) {
370 return (DDI_FAILURE
);
374 * Reserved for Configuration ROM
375 * see IEEE 1394-1995, Section 8.3.2.5.3
377 addr
.aa_address
= IEEE1394_CONFIG_ROM_ADDR
;
378 addr
.aa_length
= IEEE1394_CONFIG_ROM_SZ
;
379 result
= s1394_reserve_addr_blk(hal
, &addr
);
380 if (result
!= DDI_SUCCESS
) {
381 return (DDI_FAILURE
);
386 * see IEEE 1394-1995, Section 8.3.2.4.1
388 hal
->CSR_topology_map
= kmem_zalloc(IEEE1394_UCSR_TOPOLOGY_MAP_SZ
,
390 addr
.aa_address
= IEEE1394_UCSR_TOPOLOGY_MAP
;
391 addr
.aa_length
= IEEE1394_UCSR_TOPOLOGY_MAP_SZ
;
392 addr
.aa_enable
= T1394_ADDR_RDENBL
;
393 addr
.aa_type
= T1394_ADDR_FIXED
;
394 addr
.aa_evts
.recv_read_request
= s1394_CSR_topology_map
;
395 addr
.aa_evts
.recv_write_request
= NULL
;
396 addr
.aa_evts
.recv_lock_request
= NULL
;
397 addr
.aa_kmem_bufp
= (caddr_t
)hal
->CSR_topology_map
;
399 result
= s1394_claim_addr_blk(hal
, &addr
);
400 if (result
!= DDI_SUCCESS
) {
401 kmem_free((void *)hal
->CSR_topology_map
,
402 IEEE1394_UCSR_TOPOLOGY_MAP_SZ
);
403 return (DDI_FAILURE
);
405 curr_blk
= (s1394_addr_space_blk_t
*)(addr
.aa_hdl
);
406 /* Set up the block so that we free kmem_bufp at detach */
407 curr_blk
->free_kmem_bufp
= B_TRUE
;
410 * Reserve the SPEED_MAP
411 * see IEEE 1394-1995, Section 8.3.2.4.1
412 * (obsoleted in P1394A)
414 addr
.aa_address
= IEEE1394_UCSR_SPEED_MAP
;
415 addr
.aa_length
= IEEE1394_UCSR_SPEED_MAP_SZ
;
416 result
= s1394_reserve_addr_blk(hal
, &addr
);
417 if (result
!= DDI_SUCCESS
) {
418 return (DDI_FAILURE
);
422 * Reserved - Boundary between reserved Serial Bus
423 * dependent registers and other CSR register space.
424 * See IEEE 1394-1995, Table 8-4 for this address.
426 * This quadlet is reserved as a way of preventing
427 * the inadvertant allocation of a part of CSR space
428 * that will likely be used by future specifications
430 addr
.aa_address
= IEEE1394_UCSR_RESERVED_BOUNDARY
;
431 addr
.aa_length
= IEEE1394_QUADLET
;
432 result
= s1394_reserve_addr_blk(hal
, &addr
);
433 if (result
!= DDI_SUCCESS
) {
434 return (DDI_FAILURE
);
437 return (DDI_SUCCESS
);
441 * s1394_CSR_state_clear()
442 * handles all requests to the STATE_CLEAR CSR register. It enforces
443 * that certain bits that can be twiddled only by a given node (IRM or
447 s1394_CSR_state_clear(cmd1394_cmd_t
*req
)
453 uint_t should_be_from
;
456 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
458 /* Register offset */
459 offset
= req
->cmd_addr
& IEEE1394_CSR_OFFSET_MASK
;
461 /* Verify that request is quadlet aligned */
462 if ((offset
& 0x3) != 0) {
463 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
464 (void) s1394_send_response(hal
, req
);
468 /* Only writes from IRM or Bus Mgr allowed (in some cases) */
469 mutex_enter(&hal
->topology_tree_mutex
);
470 is_from
= IEEE1394_NODE_NUM(req
->nodeID
);
471 if (hal
->bus_mgr_node
!= -1)
472 should_be_from
= IEEE1394_NODE_NUM(hal
->bus_mgr_node
);
473 else if (hal
->IRM_node
!= -1)
474 should_be_from
= IEEE1394_NODE_NUM(hal
->IRM_node
);
476 should_be_from
= S1394_INVALID_NODE_NUM
;
477 mutex_exit(&hal
->topology_tree_mutex
);
479 switch (req
->cmd_type
) {
480 case CMD1394_ASYNCH_RD_QUAD
:
482 * The csr_read() call can return DDI_FAILURE if the HAL
483 * is shutdown or if the register at "offset" is
484 * unimplemented. But although the STATE_CLEAR register
485 * is required to be implemented and readable, we will
486 * return IEEE1394_RESP_ADDRESS_ERROR in the response if
487 * we ever see this error.
489 result
= HAL_CALL(hal
).csr_read(hal
->halinfo
.hal_private
,
491 if (result
== DDI_SUCCESS
) {
492 req
->cmd_u
.q
.quadlet_data
= data
;
493 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
495 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
499 case CMD1394_ASYNCH_WR_QUAD
:
500 data
= req
->cmd_u
.q
.quadlet_data
;
502 /* CMSTR bit - request must be from bus_mgr/IRM */
503 if (is_from
!= should_be_from
) {
504 data
= data
& ~IEEE1394_CSR_STATE_CMSTR
;
507 mutex_enter(&hal
->topology_tree_mutex
);
508 /* DREQ bit - disabling DREQ can come from anyone */
509 if (data
& IEEE1394_CSR_STATE_DREQ
) {
510 hal
->disable_requests_bit
= 0;
511 if (hal
->hal_state
== S1394_HAL_DREQ
)
512 hal
->hal_state
= S1394_HAL_NORMAL
;
516 if (data
& IEEE1394_CSR_STATE_ABDICATE
) {
517 hal
->abdicate_bus_mgr_bit
= 0;
519 mutex_exit(&hal
->topology_tree_mutex
);
521 * The csr_write() call can return DDI_FAILURE if the HAL
522 * is shutdown or if the register at "offset" is
523 * unimplemented. But although the STATE_CLEAR register
524 * is required to be implemented and writeable, we will
525 * return IEEE1394_RESP_ADDRESS_ERROR in the response if
526 * we ever see this error.
528 result
= HAL_CALL(hal
).csr_write(hal
->halinfo
.hal_private
,
530 if (result
== DDI_SUCCESS
) {
531 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
533 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
538 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
541 (void) s1394_send_response(hal
, req
);
545 * s1394_CSR_state_set()
546 * handles all requests to the STATE_SET CSR register. It enforces that
547 * certain bits that can be twiddled only by a given node (IRM or Bus
551 s1394_CSR_state_set(cmd1394_cmd_t
*req
)
557 uint_t should_be_from
;
559 uint_t hal_number_of_nodes
;
562 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
564 /* Register offset */
565 offset
= req
->cmd_addr
& IEEE1394_CSR_OFFSET_MASK
;
567 /* Verify that request is quadlet aligned */
568 if ((offset
& 0x3) != 0) {
569 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
570 (void) s1394_send_response(hal
, req
);
574 /* Only writes from IRM or Bus Mgr allowed (in some cases) */
575 mutex_enter(&hal
->topology_tree_mutex
);
576 is_from
= IEEE1394_NODE_NUM(req
->nodeID
);
577 if (hal
->bus_mgr_node
!= -1)
578 should_be_from
= IEEE1394_NODE_NUM(hal
->bus_mgr_node
);
579 else if (hal
->IRM_node
!= -1)
580 should_be_from
= IEEE1394_NODE_NUM(hal
->IRM_node
);
582 should_be_from
= S1394_INVALID_NODE_NUM
;
583 hal_node_num
= IEEE1394_NODE_NUM(hal
->node_id
);
584 hal_number_of_nodes
= hal
->number_of_nodes
;
585 mutex_exit(&hal
->topology_tree_mutex
);
587 switch (req
->cmd_type
) {
588 case CMD1394_ASYNCH_WR_QUAD
:
589 data
= req
->cmd_u
.q
.quadlet_data
;
591 /* CMSTR bit - request must be from bus_mgr/IRM */
592 /* & must be root to have bit set */
593 if ((is_from
!= should_be_from
) ||
594 (hal_node_num
!= (hal_number_of_nodes
- 1))) {
595 data
= data
& ~IEEE1394_CSR_STATE_CMSTR
;
598 mutex_enter(&hal
->topology_tree_mutex
);
599 /* DREQ bit - only bus_mgr/IRM can set this bit */
600 if (is_from
!= should_be_from
) {
601 data
= data
& ~IEEE1394_CSR_STATE_DREQ
;
603 } else if (data
& IEEE1394_CSR_STATE_DREQ
) {
604 hal
->disable_requests_bit
= 1;
605 if (hal
->hal_state
== S1394_HAL_NORMAL
)
606 hal
->hal_state
= S1394_HAL_DREQ
;
609 if (data
& IEEE1394_CSR_STATE_ABDICATE
) {
610 hal
->abdicate_bus_mgr_bit
= 1;
612 mutex_exit(&hal
->topology_tree_mutex
);
614 * The csr_write() call can return DDI_FAILURE if the HAL
615 * is shutdown or if the register at "offset" is
616 * unimplemented. But although the STATE_SET register
617 * is required to be implemented and writeable, we will
618 * return IEEE1394_RESP_ADDRESS_ERROR in the response if
619 * we ever see this error.
621 result
= HAL_CALL(hal
).csr_write(hal
->halinfo
.hal_private
,
623 if (result
== DDI_SUCCESS
) {
624 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
626 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
631 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
634 (void) s1394_send_response(hal
, req
);
638 * s1394_CSR_node_ids()
639 * handles all requests to the NODE_IDS CSR register. It passes all
640 * requests to the common routine - s1394_common_CSR_routine().
643 s1394_CSR_node_ids(cmd1394_cmd_t
*req
)
647 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
649 s1394_common_CSR_routine(hal
, req
);
653 * s1394_CSR_reset_start()
654 * handles all requests to the RESET_START CSR register. Only write
655 * requests are legal, everything else gets a type_error response.
658 s1394_CSR_reset_start(cmd1394_cmd_t
*req
)
664 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
666 /* RESET_START register offset */
667 offset
= req
->cmd_addr
& IEEE1394_CSR_OFFSET_MASK
;
669 /* Verify that request is quadlet aligned */
670 if ((offset
& 0x3) != 0) {
671 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
672 (void) s1394_send_response(hal
, req
);
676 switch (req
->cmd_type
) {
677 case CMD1394_ASYNCH_WR_QUAD
:
678 data
= req
->cmd_u
.q
.quadlet_data
;
680 * The csr_write() call can return DDI_FAILURE if the HAL
681 * is shutdown or if the register at "offset" is
682 * unimplemented. Because we don't do any thing with
683 * the RESET_START register we will ignore failures and
684 * return IEEE1394_RESP_COMPLETE regardless.
686 (void) HAL_CALL(hal
).csr_write(hal
->halinfo
.hal_private
,
688 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
692 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
695 (void) s1394_send_response(hal
, req
);
699 * s1394_CSR_split_timeout()
700 * handles all requests to the SPLIT_TIMEOUT CSR register. It passes all
701 * requests to the common routine - s1394_common_CSR_routine().
704 s1394_CSR_split_timeout(cmd1394_cmd_t
*req
)
708 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
710 s1394_common_CSR_routine(hal
, req
);
714 * s1394_CSR_argument_regs()
715 * handles all requests to the ARGUMENT CSR registers. It passes all
716 * requests to the common routine - s1394_common_CSR_routine().
719 s1394_CSR_argument_regs(cmd1394_cmd_t
*req
)
723 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
725 s1394_common_CSR_routine(hal
, req
);
729 * s1394_CSR_test_regs()
730 * handles all requests to the TEST CSR registers. It passes all requests
731 * to the common routine - s1394_common_CSR_routine().
734 s1394_CSR_test_regs(cmd1394_cmd_t
*req
)
739 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
741 /* TEST register offset */
742 offset
= req
->cmd_addr
& IEEE1394_CSR_OFFSET_MASK
;
744 /* TEST_STATUS is Read-Only */
745 if ((offset
== (IEEE1394_CSR_TEST_STATUS
& IEEE1394_CSR_OFFSET_MASK
)) &&
746 (req
->cmd_type
== CMD1394_ASYNCH_WR_QUAD
)) {
747 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
748 (void) s1394_send_response(hal
, req
);
750 s1394_common_CSR_routine(hal
, req
);
755 * s1394_CSR_interrupt_regs()
756 * handles all requests to the INTERRUPT CSR registers. It passes all
757 * requests to the common routine - s1394_common_CSR_routine().
760 s1394_CSR_interrupt_regs(cmd1394_cmd_t
*req
)
764 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
766 s1394_common_CSR_routine(hal
, req
);
770 * s1394_CSR_clock_regs()
771 * handles all requests to the CLOCK CSR registers. It passes all
772 * requests to the common routine - s1394_common_CSR_routine().
775 s1394_CSR_clock_regs(cmd1394_cmd_t
*req
)
779 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
781 s1394_common_CSR_routine(hal
, req
);
785 * s1394_CSR_message_regs()
786 * handles all requests to the MESSAGE CSR registers. It passes all
787 * requests to the common routine - s1394_common_CSR_routine().
790 s1394_CSR_message_regs(cmd1394_cmd_t
*req
)
794 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
796 s1394_common_CSR_routine(hal
, req
);
800 * s1394_CSR_cycle_time()
801 * handles all requests to the CYCLE_TIME CSR register.
804 s1394_CSR_cycle_time(cmd1394_cmd_t
*req
)
811 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
813 /* CYCLE_TIME register offset */
814 offset
= req
->cmd_addr
& IEEE1394_CSR_OFFSET_MASK
;
816 /* Verify that request is quadlet aligned */
817 if ((offset
& 0x3) != 0) {
818 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
819 (void) s1394_send_response(hal
, req
);
823 switch (req
->cmd_type
) {
824 case CMD1394_ASYNCH_RD_QUAD
:
826 * The csr_read() call can return DDI_FAILURE if the HAL
827 * is shutdown or if the register at "offset" is
828 * unimplemented. But although the CYCLE_TIME register
829 * is required to be implemented on devices capable of
830 * providing isochronous services (like us), we will
831 * return IEEE1394_RESP_ADDRESS_ERROR in the response
832 * if we ever see this error.
834 result
= HAL_CALL(hal
).csr_read(hal
->halinfo
.hal_private
,
836 if (result
== DDI_SUCCESS
) {
837 req
->cmd_u
.q
.quadlet_data
= data
;
838 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
840 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
844 case CMD1394_ASYNCH_WR_QUAD
:
845 data
= req
->cmd_u
.q
.quadlet_data
;
847 * The csr_write() call can return DDI_FAILURE if the HAL
848 * is shutdown or if the register at "offset" is
849 * unimplemented. But although the CYCLE_TIME register
850 * is required to be implemented on devices capable of
851 * providing isochronous services (like us), the effects
852 * of a write are "node-dependent" so we will return
853 * IEEE1394_RESP_ADDRESS_ERROR in the response if we
854 * ever see this error.
856 result
= HAL_CALL(hal
).csr_write(hal
->halinfo
.hal_private
,
858 if (result
== DDI_SUCCESS
) {
859 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
861 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
866 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
869 (void) s1394_send_response(hal
, req
);
873 * s1394_CSR_bus_time()
874 * handles all requests to the BUS_TIME CSR register. It enforces that
875 * only a broadcast write request from the IRM or Bus Manager can change
879 s1394_CSR_bus_time(cmd1394_cmd_t
*req
)
885 uint_t should_be_from
;
888 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
890 /* BUS_TIME register offset */
891 offset
= req
->cmd_addr
& IEEE1394_CSR_OFFSET_MASK
;
893 /* Verify that request is quadlet aligned */
894 if ((offset
& 0x3) != 0) {
895 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
896 (void) s1394_send_response(hal
, req
);
900 switch (req
->cmd_type
) {
901 case CMD1394_ASYNCH_RD_QUAD
:
903 * The csr_read() call can return DDI_FAILURE if the HAL
904 * is shutdown or if the register at "offset" is
905 * unimplemented. But although the BUS_TIME register
906 * is required to be implemented by devices capable of
907 * being cycle master (like us), we will return
908 * IEEE1394_RESP_ADDRESS_ERROR in the response if we
909 * ever see this error.
911 result
= HAL_CALL(hal
).csr_read(hal
->halinfo
.hal_private
,
913 if (result
== DDI_SUCCESS
) {
914 req
->cmd_u
.q
.quadlet_data
= data
;
915 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
917 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
921 case CMD1394_ASYNCH_WR_QUAD
:
922 /* Only broadcast writes from IRM or Bus Mgr allowed */
923 mutex_enter(&hal
->topology_tree_mutex
);
924 is_from
= IEEE1394_NODE_NUM(req
->nodeID
);
925 if (hal
->bus_mgr_node
!= -1)
926 should_be_from
= IEEE1394_NODE_NUM(hal
->bus_mgr_node
);
927 else if (hal
->IRM_node
!= -1)
928 should_be_from
= IEEE1394_NODE_NUM(hal
->IRM_node
);
930 should_be_from
= S1394_INVALID_NODE_NUM
;
931 mutex_exit(&hal
->topology_tree_mutex
);
933 if ((req
->broadcast
!= 1) || (is_from
!= should_be_from
)) {
934 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
938 data
= req
->cmd_u
.q
.quadlet_data
;
940 * The csr_write() call can return DDI_FAILURE if the HAL
941 * is shutdown or if the register at "offset" is
942 * unimplemented. But although the BUS_TIME register
943 * is required to be implemented on devices capable of
944 * being cycle master (like us), we will return
945 * IEEE1394_RESP_ADDRESS_ERROR in the response if we
946 * ever see this error.
948 result
= HAL_CALL(hal
).csr_write(hal
->halinfo
.hal_private
,
950 if (result
== DDI_SUCCESS
) {
951 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
953 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
958 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
961 (void) s1394_send_response(hal
, req
);
965 * s1394_CSR_busy_timeout()
966 * handles all requests to the BUSY_TIMEOUT CSR register. It passes all
967 * requests to the common routine - s1394_common_CSR_routine().
970 s1394_CSR_busy_timeout(cmd1394_cmd_t
*req
)
974 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
976 s1394_common_CSR_routine(hal
, req
);
980 * s1394_CSR_IRM_regs()
981 * handles all requests to the IRM registers, including BANDWIDTH_AVAILABLE,
982 * CHANNELS_AVAILABLE, and the BUS_MANAGER_ID. Only quadlet read and lock
983 * requests are allowed.
986 s1394_CSR_IRM_regs(cmd1394_cmd_t
*req
)
997 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
999 /* IRM register offset */
1000 offset
= (req
->cmd_addr
& IEEE1394_CSR_OFFSET_MASK
);
1002 /* Verify that request is quadlet aligned */
1003 if ((offset
& 0x3) != 0) {
1004 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
1005 (void) s1394_send_response(hal
, req
);
1009 switch (req
->cmd_type
) {
1010 case CMD1394_ASYNCH_RD_QUAD
:
1012 * The csr_read() call can return DDI_FAILURE if the HAL
1013 * is shutdown or if the register at "offset" is
1014 * unimplemented. In many cases these registers will
1015 * have been implemented in HW. We are not likely to ever
1016 * receive this callback. If we do, though, we will
1017 * return IEEE1394_RESP_ADDRESS_ERROR when we get an error
1018 * and IEEE1394_RESP_COMPLETE for success.
1020 result
= HAL_CALL(hal
).csr_read(hal
->halinfo
.hal_private
,
1022 if (result
== DDI_SUCCESS
) {
1023 req
->cmd_u
.q
.quadlet_data
= data
;
1024 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
1026 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
1030 case CMD1394_ASYNCH_LOCK_32
:
1031 mutex_enter(&hal
->topology_tree_mutex
);
1032 generation
= hal
->generation_count
;
1033 mutex_exit(&hal
->topology_tree_mutex
);
1034 if (req
->cmd_u
.l32
.lock_type
== CMD1394_LOCK_COMPARE_SWAP
) {
1035 compare
= req
->cmd_u
.l32
.arg_value
;
1036 swap
= req
->cmd_u
.l32
.data_value
;
1038 * The csr_cswap32() call can return DDI_FAILURE if
1039 * the HAL is shutdown, if the register at "offset"
1040 * is unimplemented, or if the generation has changed.
1041 * In the last case, it shouldn't matter because the
1042 * call to s1394_send_response will fail on a bad
1043 * generation and the command will be freed.
1045 result
= HAL_CALL(hal
).csr_cswap32(
1046 hal
->halinfo
.hal_private
, generation
,
1047 offset
, compare
, swap
, &old
);
1048 if (result
== DDI_SUCCESS
) {
1049 req
->cmd_u
.l32
.old_value
= old
;
1050 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
1052 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
1056 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
1062 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
1065 (void) s1394_send_response(hal
, req
);
1069 * s1394_CSR_topology_map()
1070 * handles all request for the TOPOLOGY_MAP[]. Since it is implemented
1071 * with backing store, there isn't much to do besides return success or
1075 s1394_CSR_topology_map(cmd1394_cmd_t
*req
)
1079 hal
= (s1394_hal_t
*)req
->cmd_callback_arg
;
1081 /* Make sure it's a quadlet read request */
1082 if (req
->cmd_type
== CMD1394_ASYNCH_RD_QUAD
)
1083 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
1085 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
1087 (void) s1394_send_response(hal
, req
);
1091 * s1394_CSR_topology_map_update()
1092 * is used to update the local host's TOPOLOGY_MAP[] buffer. It copies in
1093 * the SelfID packets, updates the generation and other fields, and
1094 * computes the necessary CRC values before returning.
1095 * Callers must be holding the topology_tree_mutex.
1098 s1394_CSR_topology_map_update(s1394_hal_t
*hal
)
1100 s1394_selfid_pkt_t
*selfid_packet
;
1103 uint32_t node_count
;
1104 uint32_t self_id_count
;
1109 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
1111 tm_ptr
= (uint32_t *)hal
->CSR_topology_map
;
1112 data_ptr
= (uint32_t *)&(tm_ptr
[3]);
1115 for (i
= 0; i
< hal
->number_of_nodes
; i
++) {
1117 selfid_packet
= hal
->selfid_ptrs
[i
];
1121 data_ptr
[c
++] = selfid_packet
[j
].spkt_data
;
1123 while (IEEE1394_SELFID_ISMORE(&selfid_packet
[j
]));
1126 /* Update Topology Map Generation */
1127 tm_ptr
[1] = tm_ptr
[1] + 1;
1129 /* Update Node_Count and Self_Id_Count */
1130 node_count
= (i
& IEEE1394_TOP_MAP_LEN_MASK
);
1131 self_id_count
= (c
& IEEE1394_TOP_MAP_LEN_MASK
);
1132 tm_ptr
[2] = (node_count
<< IEEE1394_TOP_MAP_LEN_SHIFT
) |
1135 /* Calculate CRC-16 */
1136 length
= self_id_count
+ 2;
1137 CRC
= s1394_CRC16(&(tm_ptr
[1]), length
);
1138 tm_ptr
[0] = (length
<< IEEE1394_TOP_MAP_LEN_SHIFT
) | CRC
;
1142 * s1394_CSR_topology_map_disable()
1143 * is used to disable the local host's TOPOLOGY_MAP[] buffer (during bus
1144 * reset processing). It sets the topology map's length to zero to
1145 * indicate that it is invalid.
1148 s1394_CSR_topology_map_disable(s1394_hal_t
*hal
)
1152 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
1154 tm_ptr
= (uint32_t *)hal
->CSR_topology_map
;
1156 /* Set length = 0 */
1157 tm_ptr
[0] = tm_ptr
[0] & IEEE1394_TOP_MAP_LEN_MASK
;
1161 * s1394_common_CSR_routine()
1162 * is used to handle most of the CSR register requests. They are passed
1163 * to the appropriate HAL entry point for further processing. Then they
1164 * are filled in with an appropriate response code, and the response is sent.
1167 s1394_common_CSR_routine(s1394_hal_t
*hal
, cmd1394_cmd_t
*req
)
1173 /* Register offset */
1174 offset
= (req
->cmd_addr
& IEEE1394_CSR_OFFSET_MASK
);
1176 /* Verify that request is quadlet aligned */
1177 if ((offset
& 0x3) != 0) {
1178 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
1179 (void) s1394_send_response(hal
, req
);
1182 switch (req
->cmd_type
) {
1183 case CMD1394_ASYNCH_RD_QUAD
:
1185 * The csr_read() call can return DDI_FAILURE if the HAL
1186 * is shutdown or if the register at "offset" is
1187 * unimplemented. We will return IEEE1394_RESP_ADDRESS_ERROR
1188 * in the response if we see this error.
1190 result
= HAL_CALL(hal
).csr_read(hal
->halinfo
.hal_private
,
1192 if (result
== DDI_SUCCESS
) {
1193 req
->cmd_u
.q
.quadlet_data
= data
;
1194 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
1196 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
1200 case CMD1394_ASYNCH_WR_QUAD
:
1201 data
= req
->cmd_u
.q
.quadlet_data
;
1203 * The csr_read() call can return DDI_FAILURE if the HAL
1204 * is shutdown or if the register at "offset" is
1205 * unimplemented. We will return IEEE1394_RESP_ADDRESS_ERROR
1206 * in the response if we see this error.
1208 result
= HAL_CALL(hal
).csr_write(hal
->halinfo
.hal_private
,
1210 if (result
== DDI_SUCCESS
) {
1211 req
->cmd_result
= IEEE1394_RESP_COMPLETE
;
1213 req
->cmd_result
= IEEE1394_RESP_ADDRESS_ERROR
;
1218 req
->cmd_result
= IEEE1394_RESP_TYPE_ERROR
;
1221 (void) s1394_send_response(hal
, req
);
1225 * s1394_init_local_config_rom()
1226 * is called in the HAL attach routine - h1394_attach() - to setup the
1227 * initial Config ROM entries on the local host, including the
1228 * bus_info_block and the root and unit directories.
1231 s1394_init_local_config_rom(s1394_hal_t
*hal
)
1233 uint32_t *config_rom
;
1234 uint32_t *node_unique_id_leaf
;
1236 uint32_t *text_leaf
;
1239 uint32_t guid_hi
, guid_lo
;
1240 uint32_t bus_capabilities
;
1242 uint32_t module_vendor_id
;
1243 uint32_t node_capabilities
;
1244 uint32_t root_dir_len
;
1248 /* Setup Config ROM mutex */
1249 mutex_init(&hal
->local_config_rom_mutex
,
1250 NULL
, MUTEX_DRIVER
, hal
->halinfo
.hw_interrupt
);
1252 /* Allocate 1K for the Config ROM buffer */
1253 hal
->local_config_rom
= kmem_zalloc(IEEE1394_CONFIG_ROM_SZ
,
1256 /* Allocate 1K for the temporary buffer */
1257 hal
->temp_config_rom_buf
= kmem_zalloc(
1258 IEEE1394_CONFIG_ROM_SZ
, KM_SLEEP
);
1260 config_rom
= hal
->local_config_rom
;
1262 /* Lock the Config ROM buffer */
1263 mutex_enter(&hal
->local_config_rom_mutex
);
1265 /* Build the config ROM structures */
1266 ret
= s1394_init_config_rom_structures(hal
);
1267 if (ret
!= DDI_SUCCESS
) {
1268 /* Unlock the Config ROM buffer */
1269 mutex_exit(&hal
->local_config_rom_mutex
);
1270 kmem_free((void *)hal
->temp_config_rom_buf
,
1271 IEEE1394_CONFIG_ROM_SZ
);
1272 kmem_free((void *)hal
->local_config_rom
,
1273 IEEE1394_CONFIG_ROM_SZ
);
1274 mutex_destroy(&hal
->local_config_rom_mutex
);
1275 return (DDI_FAILURE
);
1277 /* Build the Bus_Info_Block - see IEEE 1394-1995, Section 8.3.2.5.4 */
1278 bus_capabilities
= hal
->halinfo
.bus_capabilities
;
1281 * If we are Isoch Resource Manager capable then we are
1282 * Bus Manager capable too.
1284 irmc
= (bus_capabilities
& IEEE1394_BIB_IRMC_MASK
) >>
1285 IEEE1394_BIB_IRMC_SHIFT
;
1287 bus_capabilities
= bus_capabilities
| IEEE1394_BIB_BMC_MASK
;
1290 * Set generation to P1394a valid (but changeable)
1291 * Even if we have a 1995 PHY, we will still provide
1292 * certain P1394A functionality (especially with respect
1293 * to Config ROM updates). So we must publish this
1296 g
= 2 << IEEE1394_BIB_GEN_SHIFT
;
1297 bus_capabilities
= bus_capabilities
| g
;
1300 guid
= hal
->halinfo
.guid
;
1301 guid_hi
= (uint32_t)(guid
>> 32);
1302 guid_lo
= (uint32_t)(guid
& 0x00000000FFFFFFFF);
1304 config_rom
[1] = 0x31333934; /* "1394" */
1305 config_rom
[2] = bus_capabilities
;
1306 config_rom
[3] = guid_hi
;
1307 config_rom
[4] = guid_lo
;
1309 /* The CRC covers only our Bus_Info_Block */
1310 CRC
= s1394_CRC16(&config_rom
[1], 4);
1311 config_rom
[0] = (0x04040000) | CRC
;
1313 /* Do byte-swapping if necessary (x86) */
1314 for (i
= 0; i
< IEEE1394_BIB_QUAD_SZ
; i
++)
1315 config_rom
[i
] = T1394_DATA32(config_rom
[i
]);
1317 /* Build the Root_Directory - see IEEE 1394-1995, Section 8.3.2.5.5 */
1319 /* MODULE_VENDOR_ID - see IEEE 1394-1995, Section 8.3.2.5.5.1 */
1320 module_vendor_id
= S1394_SUNW_OUI
;
1322 /* NODE_CAPABILITIES - see IEEE 1394-1995, Section 8.3.2.5.5.2 */
1323 node_capabilities
= hal
->halinfo
.node_capabilities
&
1324 IEEE1212_NODE_CAPABILITIES_MASK
;
1327 config_rom
[6] = (IEEE1212_MODULE_VENDOR_ID
<<
1328 IEEE1212_KEY_VALUE_SHIFT
) | module_vendor_id
;
1329 config_rom
[7] = (IEEE1212_NODE_CAPABILITIES
<<
1330 IEEE1212_KEY_VALUE_SHIFT
) | node_capabilities
;
1332 CRC
= s1394_CRC16(&config_rom
[6], root_dir_len
);
1333 config_rom
[IEEE1394_BIB_QUAD_SZ
] =
1334 (root_dir_len
<< IEEE1394_CFG_ROM_LEN_SHIFT
) | CRC
;
1336 /* Do byte-swapping if necessary (x86) */
1337 for (i
= IEEE1394_BIB_QUAD_SZ
; i
< 8; i
++)
1338 config_rom
[i
] = T1394_DATA32(config_rom
[i
]);
1340 /* Build the Root Text leaf - see IEEE 1394-1995, Section 8.3.2.5.7 */
1341 text_leaf
= kmem_zalloc(S1394_ROOT_TEXT_LEAF_SZ
, KM_SLEEP
);
1342 text_leaf
[1] = 0x00000000;
1343 text_leaf
[2] = 0x00000000;
1344 text_leaf
[3] = 0x53756e20; /* "Sun " */
1345 text_leaf
[4] = 0x4d696372; /* "Micr" */
1346 text_leaf
[5] = 0x6f737973; /* "osys" */
1347 text_leaf
[6] = 0x74656d73; /* "tems" */
1348 text_leaf
[7] = 0x2c20496e; /* ", In" */
1349 text_leaf
[8] = 0x632e0000; /* "c." */
1350 CRC
= s1394_CRC16(&text_leaf
[1], S1394_ROOT_TEXT_LEAF_QUAD_SZ
- 1);
1351 text_leaf
[0] = (0x00080000) | CRC
;
1353 /* Do byte-swapping if necessary (x86) */
1354 for (i
= 0; i
< 9; i
++)
1355 text_leaf
[i
] = T1394_DATA32(text_leaf
[i
]);
1357 ret
= s1394_add_config_rom_entry(hal
, S1394_ROOT_TEXT_KEY
, text_leaf
,
1358 S1394_ROOT_TEXT_LEAF_QUAD_SZ
, &n_handle
, &status
);
1359 if (ret
!= DDI_SUCCESS
) {
1360 kmem_free((void *)text_leaf
, S1394_ROOT_TEXT_LEAF_SZ
);
1361 /* Destroy the config_rom structures */
1362 (void) s1394_destroy_config_rom_structures(hal
);
1363 /* Unlock the Config ROM buffer */
1364 mutex_exit(&hal
->local_config_rom_mutex
);
1365 kmem_free((void *)hal
->temp_config_rom_buf
,
1366 IEEE1394_CONFIG_ROM_SZ
);
1367 kmem_free((void *)hal
->local_config_rom
,
1368 IEEE1394_CONFIG_ROM_SZ
);
1369 mutex_destroy(&hal
->local_config_rom_mutex
);
1370 return (DDI_FAILURE
);
1372 kmem_free((void *)text_leaf
, S1394_ROOT_TEXT_LEAF_SZ
);
1374 /* Build the Node_Unique_Id leaf - IEEE 1394-1995, Sect. 8.3.2.5.7.1 */
1375 node_unique_id_leaf
= kmem_zalloc(S1394_NODE_UNIQUE_ID_SZ
,
1377 node_unique_id_leaf
[1] = guid_hi
;
1378 node_unique_id_leaf
[2] = guid_lo
;
1379 CRC
= s1394_CRC16(&node_unique_id_leaf
[1],
1380 S1394_NODE_UNIQUE_ID_QUAD_SZ
- 1);
1381 node_unique_id_leaf
[0] = (0x00020000) | CRC
;
1383 /* Do byte-swapping if necessary (x86) */
1384 for (i
= 0; i
< S1394_NODE_UNIQUE_ID_QUAD_SZ
; i
++)
1385 node_unique_id_leaf
[i
] = T1394_DATA32(node_unique_id_leaf
[i
]);
1387 ret
= s1394_add_config_rom_entry(hal
, S1394_NODE_UNIQUE_ID_KEY
,
1388 node_unique_id_leaf
, S1394_NODE_UNIQUE_ID_QUAD_SZ
, &n_handle
,
1390 if (ret
!= DDI_SUCCESS
) {
1391 kmem_free((void *)node_unique_id_leaf
,
1392 S1394_NODE_UNIQUE_ID_SZ
);
1393 /* Destroy the config_rom structures */
1394 (void) s1394_destroy_config_rom_structures(hal
);
1395 /* Unlock the Config ROM buffer */
1396 mutex_exit(&hal
->local_config_rom_mutex
);
1397 kmem_free((void *)hal
->temp_config_rom_buf
,
1398 IEEE1394_CONFIG_ROM_SZ
);
1399 kmem_free((void *)hal
->local_config_rom
,
1400 IEEE1394_CONFIG_ROM_SZ
);
1401 mutex_destroy(&hal
->local_config_rom_mutex
);
1402 return (DDI_FAILURE
);
1404 kmem_free((void *)node_unique_id_leaf
, S1394_NODE_UNIQUE_ID_SZ
);
1406 /* Build the Unit_Directory for 1394 Framework */
1407 unit_dir
= kmem_zalloc(S1394_UNIT_DIR_SZ
, KM_SLEEP
);
1408 unit_dir
[1] = 0x12080020; /* Sun Microsystems */
1409 unit_dir
[2] = 0x13000001; /* Version 1 */
1410 unit_dir
[3] = 0x81000001; /* offset to the text leaf */
1411 CRC
= s1394_CRC16(&unit_dir
[1], 3);
1412 unit_dir
[0] = (0x00030000) | CRC
;
1414 /* Do byte-swapping if necessary (x86) */
1415 for (i
= 0; i
< 4; i
++)
1416 unit_dir
[i
] = T1394_DATA32(unit_dir
[i
]);
1418 /* Build the Unit Directory text leaf */
1419 unit_dir
[5] = 0x00000000;
1420 unit_dir
[6] = 0x00000000;
1421 unit_dir
[7] = 0x536f6c61; /* "Sola" */
1422 unit_dir
[8] = 0x72697320; /* "ris " */
1423 unit_dir
[9] = 0x31333934; /* "1394" */
1424 unit_dir
[10] = 0x20535720; /* " SW " */
1425 unit_dir
[11] = 0x4672616d; /* "Fram" */
1426 unit_dir
[12] = 0x65576f72; /* "ewor" */
1427 unit_dir
[13] = 0x6b000000; /* "k" */
1428 CRC
= s1394_CRC16(&unit_dir
[5], 9);
1429 unit_dir
[4] = (0x00090000) | CRC
;
1431 /* Do byte-swapping if necessary (x86) */
1432 for (i
= 4; i
< S1394_UNIT_DIR_QUAD_SZ
; i
++)
1433 unit_dir
[i
] = T1394_DATA32(unit_dir
[i
]);
1435 ret
= s1394_add_config_rom_entry(hal
, S1394_UNIT_DIR_KEY
, unit_dir
,
1436 S1394_UNIT_DIR_QUAD_SZ
, &n_handle
, &status
);
1437 if (ret
!= DDI_SUCCESS
) {
1438 kmem_free((void *)unit_dir
, S1394_UNIT_DIR_SZ
);
1439 /* Destroy the config_rom structures */
1440 (void) s1394_destroy_config_rom_structures(hal
);
1441 /* Unlock the Config ROM buffer */
1442 mutex_exit(&hal
->local_config_rom_mutex
);
1443 kmem_free((void *)hal
->temp_config_rom_buf
,
1444 IEEE1394_CONFIG_ROM_SZ
);
1445 /* Free the 1K for the Config ROM buffer */
1446 kmem_free((void *)hal
->local_config_rom
,
1447 IEEE1394_CONFIG_ROM_SZ
);
1448 mutex_destroy(&hal
->local_config_rom_mutex
);
1449 return (DDI_FAILURE
);
1451 kmem_free((void *)unit_dir
, S1394_UNIT_DIR_SZ
);
1453 hal
->config_rom_update_amount
= (IEEE1394_CONFIG_ROM_QUAD_SZ
-
1456 /* Unlock the Config ROM buffer */
1457 mutex_exit(&hal
->local_config_rom_mutex
);
1460 * The update_config_rom() call can return DDI_FAILURE if the
1463 (void) HAL_CALL(hal
).update_config_rom(hal
->halinfo
.hal_private
,
1464 config_rom
, IEEE1394_CONFIG_ROM_QUAD_SZ
);
1466 return (DDI_SUCCESS
);
1470 * s1394_destroy_local_config_rom()
1471 * is necessary for h1394_detach(). It undoes all the work that
1472 * s1394_init_local_config_rom() had setup and more. By pulling
1473 * everything out of the conig rom structures and freeing them and their
1474 * associated mutexes, the Config ROM is completely cleaned up.
1477 s1394_destroy_local_config_rom(s1394_hal_t
*hal
)
1479 /* Lock the Config ROM buffer */
1480 mutex_enter(&hal
->local_config_rom_mutex
);
1482 /* Destroy the config_rom structures */
1483 (void) s1394_destroy_config_rom_structures(hal
);
1485 /* Unlock the Config ROM buffer */
1486 mutex_exit(&hal
->local_config_rom_mutex
);
1488 /* Free the 1K for the temporary buffer */
1489 kmem_free((void *)hal
->temp_config_rom_buf
, IEEE1394_CONFIG_ROM_SZ
);
1490 /* Free the 1K for the Config ROM buffer */
1491 kmem_free((void *)hal
->local_config_rom
, IEEE1394_CONFIG_ROM_SZ
);
1493 /* Setup Config ROM mutex */
1494 mutex_destroy(&hal
->local_config_rom_mutex
);
1498 * s1394_init_config_rom_structures()
1499 * initializes the structures that are used to maintain the local Config ROM.
1500 * Callers must be holding the local_config_rom_mutex.
1503 s1394_init_config_rom_structures(s1394_hal_t
*hal
)
1505 s1394_config_rom_t
*root_directory
;
1506 s1394_config_rom_t
*rest_of_config_rom
;
1508 ASSERT(MUTEX_HELD(&hal
->local_config_rom_mutex
));
1510 root_directory
= (s1394_config_rom_t
*)kmem_zalloc(
1511 sizeof (s1394_config_rom_t
), KM_SLEEP
);
1513 root_directory
->cfgrom_used
= B_TRUE
;
1514 root_directory
->cfgrom_addr_lo
= IEEE1394_BIB_QUAD_SZ
;
1515 root_directory
->cfgrom_addr_hi
= IEEE1394_BIB_QUAD_SZ
+ 2;
1517 rest_of_config_rom
= (s1394_config_rom_t
*)kmem_zalloc(
1518 sizeof (s1394_config_rom_t
), KM_SLEEP
);
1520 rest_of_config_rom
->cfgrom_used
= B_FALSE
;
1521 rest_of_config_rom
->cfgrom_addr_lo
= root_directory
->cfgrom_addr_hi
+ 1;
1522 rest_of_config_rom
->cfgrom_addr_hi
= IEEE1394_CONFIG_ROM_QUAD_SZ
- 1;
1524 root_directory
->cfgrom_next
= rest_of_config_rom
;
1525 root_directory
->cfgrom_prev
= NULL
;
1526 rest_of_config_rom
->cfgrom_next
= NULL
;
1527 rest_of_config_rom
->cfgrom_prev
= root_directory
;
1529 hal
->root_directory
= root_directory
;
1530 hal
->free_space
= IEEE1394_CONFIG_ROM_QUAD_SZ
-
1531 (rest_of_config_rom
->cfgrom_addr_lo
);
1533 return (DDI_SUCCESS
);
1537 * s1394_destroy_config_rom_structures()
1538 * is used to destroy the structures that maintain the local Config ROM.
1539 * Callers must be holding the local_config_rom_mutex.
1542 s1394_destroy_config_rom_structures(s1394_hal_t
*hal
)
1544 s1394_config_rom_t
*curr_blk
;
1545 s1394_config_rom_t
*next_blk
;
1547 ASSERT(MUTEX_HELD(&hal
->local_config_rom_mutex
));
1549 curr_blk
= hal
->root_directory
;
1551 while (curr_blk
!= NULL
) {
1552 next_blk
= curr_blk
->cfgrom_next
;
1553 kmem_free(curr_blk
, sizeof (s1394_config_rom_t
));
1554 curr_blk
= next_blk
;
1557 return (DDI_SUCCESS
);
1561 * s1394_add_config_rom_entry()
1562 * is used to add a new entry to the local host's config ROM. By
1563 * specifying a key and a buffer, it is possible to update the Root
1564 * Directory to point to the new entry (in buffer). Additionally, all
1565 * of the relevant CRCs, lengths, and generations are updated as well.
1566 * By returning a Config ROM "handle", we can allow targets to remove
1567 * the corresponding entry.
1568 * Callers must be holding the local_config_rom_mutex.
1571 s1394_add_config_rom_entry(s1394_hal_t
*hal
, uint8_t key
, uint32_t *buffer
,
1572 uint_t size
, void **handle
, int *status
)
1574 s1394_config_rom_t
*curr_blk
;
1575 s1394_config_rom_t
*new_blk
;
1576 uint32_t *config_rom
;
1580 uint_t tmp_size
, temp
;
1581 uint_t last_entry_offset
;
1584 ASSERT(MUTEX_HELD(&hal
->local_config_rom_mutex
));
1586 if (size
> hal
->free_space
) {
1588 *status
= CMD1394_ERSRC_CONFLICT
;
1589 return (DDI_FAILURE
);
1592 config_rom
= hal
->local_config_rom
;
1593 temp_buf
= hal
->temp_config_rom_buf
;
1595 /* Copy the Bus_Info_Block */
1596 bcopy(&config_rom
[0], &temp_buf
[0], IEEE1394_BIB_SZ
);
1598 /* Copy and add to the Root_Directory */
1599 tmp_offset
= hal
->root_directory
->cfgrom_addr_lo
;
1600 tmp_size
= (hal
->root_directory
->cfgrom_addr_hi
- tmp_offset
) + 1;
1601 tmp_size
= tmp_size
+ 1; /* For the new entry */
1602 bcopy(&config_rom
[tmp_offset
], &temp_buf
[tmp_offset
], tmp_size
<< 2);
1603 last_entry_offset
= hal
->root_directory
->cfgrom_addr_hi
+ 1;
1605 curr_blk
= hal
->root_directory
;
1606 curr_blk
->cfgrom_addr_hi
= curr_blk
->cfgrom_addr_hi
+ 1;
1607 while (curr_blk
->cfgrom_next
!= NULL
) {
1608 if (curr_blk
->cfgrom_next
->cfgrom_used
== B_TRUE
) {
1609 tmp_offset
= curr_blk
->cfgrom_next
->cfgrom_addr_lo
;
1610 tmp_size
= (curr_blk
->cfgrom_next
->cfgrom_addr_hi
-
1613 bcopy(&config_rom
[tmp_offset
],
1614 &temp_buf
[tmp_offset
+ 1], tmp_size
<< 2);
1615 curr_blk
->cfgrom_next
->cfgrom_addr_lo
++;
1616 curr_blk
->cfgrom_next
->cfgrom_addr_hi
++;
1618 curr_blk
->cfgrom_next
->cfgrom_addr_hi
;
1620 tmp_offset
= curr_blk
->cfgrom_next
->root_dir_offset
;
1622 /* Swap... add one... then unswap */
1623 temp
= T1394_DATA32(temp_buf
[tmp_offset
]);
1625 temp_buf
[tmp_offset
] = T1394_DATA32(temp
);
1627 curr_blk
->cfgrom_next
->cfgrom_addr_lo
++;
1632 curr_blk
= curr_blk
->cfgrom_next
;
1635 /* Get the pointer to the "free" space */
1636 curr_blk
= curr_blk
->cfgrom_next
;
1638 /* Is it an exact fit? */
1639 if (hal
->free_space
== size
) {
1640 curr_blk
->cfgrom_used
= B_TRUE
;
1642 } else { /* Must break this piece */
1643 new_blk
= (s1394_config_rom_t
*)kmem_zalloc(
1644 sizeof (s1394_config_rom_t
), KM_SLEEP
);
1645 if (new_blk
== NULL
) {
1646 return (DDI_FAILURE
);
1649 new_blk
->cfgrom_addr_hi
= curr_blk
->cfgrom_addr_hi
;
1650 new_blk
->cfgrom_addr_lo
= curr_blk
->cfgrom_addr_lo
+ size
;
1651 curr_blk
->cfgrom_addr_hi
= new_blk
->cfgrom_addr_lo
- 1;
1652 new_blk
->cfgrom_next
= curr_blk
->cfgrom_next
;
1653 curr_blk
->cfgrom_next
= new_blk
;
1654 new_blk
->cfgrom_prev
= curr_blk
;
1655 curr_blk
->cfgrom_used
= B_TRUE
;
1656 last_entry_offset
= curr_blk
->cfgrom_addr_hi
;
1658 hal
->free_space
= hal
->free_space
- size
;
1660 /* Copy in the new entry */
1661 tmp_offset
= curr_blk
->cfgrom_addr_lo
;
1662 bcopy(buffer
, &temp_buf
[tmp_offset
], size
<< 2);
1664 /* Update root directory */
1665 tmp_offset
= hal
->root_directory
->cfgrom_addr_hi
;
1666 tmp_size
= tmp_offset
- hal
->root_directory
->cfgrom_addr_lo
;
1667 curr_blk
->root_dir_offset
= tmp_offset
;
1668 tmp_offset
= curr_blk
->cfgrom_addr_lo
- tmp_offset
;
1670 temp_buf
[hal
->root_directory
->cfgrom_addr_hi
] =
1671 T1394_DATA32((((uint32_t)key
) << IEEE1212_KEY_VALUE_SHIFT
) |
1673 tmp_offset
= hal
->root_directory
->cfgrom_addr_lo
;
1675 /* Do byte-swapping if necessary (x86) */
1676 for (i
= (tmp_offset
+ 1); i
<= hal
->root_directory
->cfgrom_addr_hi
;
1678 temp_buf
[i
] = T1394_DATA32(temp_buf
[i
]);
1680 CRC
= s1394_CRC16(&temp_buf
[tmp_offset
+ 1], tmp_size
);
1681 temp_buf
[tmp_offset
] = (tmp_size
<< IEEE1394_CFG_ROM_LEN_SHIFT
) | CRC
;
1683 /* Redo byte-swapping if necessary (x86) */
1684 for (i
= tmp_offset
; i
<= hal
->root_directory
->cfgrom_addr_hi
; i
++)
1685 temp_buf
[i
] = T1394_DATA32(temp_buf
[i
]);
1687 /* Copy it back to config_rom buffer */
1688 last_entry_offset
++;
1689 bcopy(&temp_buf
[0], &config_rom
[0], last_entry_offset
<< 2);
1691 /* Return a handle to this block */
1694 *status
= T1394_NOERROR
;
1696 return (DDI_SUCCESS
);
1700 * s1394_remove_config_rom_entry()
1701 * is used to remove an entry from the local host's config ROM. By
1702 * specifying the Config ROM "handle" that was given in the allocation,
1703 * it is possible to remove the entry. Subsequently, the Config ROM is
1705 * Callers must be holding the local_config_rom_mutex.
1708 s1394_remove_config_rom_entry(s1394_hal_t
*hal
, void **handle
, int *status
)
1710 s1394_config_rom_t
*del_blk
;
1711 s1394_config_rom_t
*curr_blk
;
1712 s1394_config_rom_t
*last_blk
;
1713 s1394_config_rom_t
*free_blk
;
1714 uint32_t *config_rom
;
1724 ASSERT(MUTEX_HELD(&hal
->local_config_rom_mutex
));
1726 del_blk
= (s1394_config_rom_t
*)(*handle
);
1728 config_rom
= hal
->local_config_rom
;
1729 temp_buf
= hal
->temp_config_rom_buf
;
1731 /* Copy the Bus_Info_Block */
1732 bcopy(&config_rom
[0], &temp_buf
[0], IEEE1394_BIB_SZ
);
1734 root_offset
= hal
->root_directory
->cfgrom_addr_lo
;
1735 del_offset
= del_blk
->root_dir_offset
;
1737 /* Update Root_Directory entries before the deleted one */
1738 for (i
= root_offset
; i
< del_offset
; i
++) {
1739 entry
= T1394_DATA32(config_rom
[i
]);
1741 /* If entry is an offset address - update it */
1742 if (entry
& 0x80000000)
1743 temp_buf
[i
] = T1394_DATA32(entry
- 1);
1745 temp_buf
[i
] = T1394_DATA32(entry
);
1748 /* Move all Unit_Directories prior to the deleted one */
1749 curr_blk
= hal
->root_directory
->cfgrom_next
;
1751 while (curr_blk
!= del_blk
) {
1752 tmp_offset
= curr_blk
->cfgrom_addr_lo
;
1753 tmp_size
= (curr_blk
->cfgrom_addr_hi
- tmp_offset
) + 1;
1755 bcopy(&config_rom
[tmp_offset
], &temp_buf
[tmp_offset
- 1],
1757 curr_blk
->cfgrom_addr_lo
--;
1758 curr_blk
->cfgrom_addr_hi
--;
1759 curr_blk
= curr_blk
->cfgrom_next
;
1762 /* Move all Unit_Directories after the deleted one */
1763 curr_blk
= del_blk
->cfgrom_next
;
1764 last_blk
= del_blk
->cfgrom_prev
;
1766 del_offset
= (del_blk
->cfgrom_addr_hi
- del_blk
->cfgrom_addr_lo
) + 1;
1768 while ((curr_blk
!= NULL
) && (curr_blk
->cfgrom_used
== B_TRUE
)) {
1769 tmp_offset
= curr_blk
->cfgrom_addr_lo
;
1770 tmp_size
= (curr_blk
->cfgrom_addr_hi
- tmp_offset
) + 1;
1772 bcopy(&config_rom
[tmp_offset
],
1773 &temp_buf
[tmp_offset
- (del_offset
+ 1)], tmp_size
<< 2);
1775 root_offset
= curr_blk
->root_dir_offset
;
1776 temp_buf
[root_offset
- 1] =
1777 config_rom
[root_offset
] - del_offset
;
1778 curr_blk
->root_dir_offset
--;
1779 curr_blk
->cfgrom_addr_lo
= curr_blk
->cfgrom_addr_lo
-
1781 curr_blk
->cfgrom_addr_hi
= curr_blk
->cfgrom_addr_hi
-
1784 last_blk
= curr_blk
;
1785 curr_blk
= curr_blk
->cfgrom_next
;
1788 /* Remove del_blk from the list */
1789 if (del_blk
->cfgrom_prev
!= NULL
)
1790 del_blk
->cfgrom_prev
->cfgrom_next
= del_blk
->cfgrom_next
;
1792 if (del_blk
->cfgrom_next
!= NULL
)
1793 del_blk
->cfgrom_next
->cfgrom_prev
= del_blk
->cfgrom_prev
;
1795 del_blk
->cfgrom_prev
= NULL
;
1796 del_blk
->cfgrom_next
= NULL
;
1797 kmem_free((void *)del_blk
, sizeof (s1394_config_rom_t
));
1799 /* Update and zero out the "free" block */
1800 if (curr_blk
!= NULL
) {
1801 curr_blk
->cfgrom_addr_lo
= curr_blk
->cfgrom_addr_lo
-
1805 free_blk
= (s1394_config_rom_t
*)kmem_zalloc(
1806 sizeof (s1394_config_rom_t
), KM_SLEEP
);
1807 if (free_blk
== NULL
) {
1808 return (DDI_FAILURE
);
1811 free_blk
->cfgrom_used
= B_FALSE
;
1812 free_blk
->cfgrom_addr_lo
= (IEEE1394_CONFIG_ROM_QUAD_SZ
- 1) -
1814 free_blk
->cfgrom_addr_hi
= (IEEE1394_CONFIG_ROM_QUAD_SZ
- 1);
1816 free_blk
->cfgrom_prev
= last_blk
;
1817 free_blk
->cfgrom_next
= NULL
;
1818 curr_blk
= free_blk
;
1820 hal
->free_space
= hal
->free_space
+ (del_offset
+ 1);
1821 tmp_offset
= curr_blk
->cfgrom_addr_lo
;
1822 tmp_size
= (curr_blk
->cfgrom_addr_hi
- tmp_offset
) + 1;
1823 bzero(&temp_buf
[tmp_offset
], tmp_size
<< 2);
1826 /* Update root directory */
1827 hal
->root_directory
->cfgrom_addr_hi
--;
1828 tmp_offset
= hal
->root_directory
->cfgrom_addr_lo
;
1829 tmp_size
= hal
->root_directory
->cfgrom_addr_hi
- tmp_offset
;
1831 /* Do byte-swapping if necessary (x86) */
1832 for (i
= (tmp_offset
+ 1); i
<= hal
->root_directory
->cfgrom_addr_hi
;
1834 temp_buf
[i
] = T1394_DATA32(temp_buf
[i
]);
1836 CRC
= s1394_CRC16(&temp_buf
[tmp_offset
+ 1], tmp_size
);
1837 temp_buf
[tmp_offset
] = (tmp_size
<< IEEE1394_CFG_ROM_LEN_SHIFT
) | CRC
;
1839 /* Do byte-swapping if necessary (x86) */
1840 for (i
= (tmp_offset
+ 1); i
<= hal
->root_directory
->cfgrom_addr_hi
;
1842 temp_buf
[i
] = T1394_DATA32(temp_buf
[i
]);
1844 /* Copy it back to config_rom buffer */
1845 tmp_size
= IEEE1394_CONFIG_ROM_SZ
- (hal
->free_space
<< 2);
1846 bcopy(&temp_buf
[0], &config_rom
[0], tmp_size
);
1848 /* Return a handle to this block */
1851 *status
= T1394_NOERROR
;
1853 return (DDI_SUCCESS
);
1857 * s1394_update_config_rom_callback()
1858 * is the callback used by t1394_add_cfgrom_entry() and
1859 * t1394_rem_cfgrom_entry(). After a target updates the Config ROM, a
1860 * timer is set with this as its callback function. This is to reduce
1861 * the number of bus resets that would be necessary if many targets
1862 * wished to update the Config ROM simultaneously.
1865 s1394_update_config_rom_callback(void *arg
)
1868 uint32_t *config_rom
;
1869 uint32_t bus_capabilities
;
1872 uint_t last_entry_offset
;
1875 hal
= (s1394_hal_t
*)arg
;
1877 /* Lock the Config ROM buffer */
1878 mutex_enter(&hal
->local_config_rom_mutex
);
1880 config_rom
= hal
->local_config_rom
;
1882 /* Update Generation and CRC for Bus_Info_Block */
1884 /* Do byte-swapping if necessary (x86) */
1885 for (i
= 0; i
< IEEE1394_BIB_QUAD_SZ
; i
++)
1886 config_rom
[i
] = T1394_DATA32(config_rom
[i
]);
1888 bus_capabilities
= config_rom
[IEEE1212_NODE_CAP_QUAD
];
1889 g
= ((bus_capabilities
& IEEE1394_BIB_GEN_MASK
) >>
1890 IEEE1394_BIB_GEN_SHIFT
) + 1;
1893 g
= g
<< IEEE1394_BIB_GEN_SHIFT
;
1895 bus_capabilities
= (bus_capabilities
& (~IEEE1394_BIB_GEN_MASK
)) | g
;
1896 config_rom
[IEEE1212_NODE_CAP_QUAD
] = bus_capabilities
;
1898 CRC
= s1394_CRC16(&config_rom
[1], IEEE1394_BIB_QUAD_SZ
- 1);
1899 config_rom
[0] = (0x04040000) | CRC
;
1901 /* Do byte-swapping if necessary (x86) */
1902 for (i
= 0; i
< IEEE1394_BIB_QUAD_SZ
; i
++)
1903 config_rom
[i
] = T1394_DATA32(config_rom
[i
]);
1905 /* Make sure we update only what is necessary */
1906 last_entry_offset
= (IEEE1394_CONFIG_ROM_QUAD_SZ
- hal
->free_space
);
1907 if (last_entry_offset
< hal
->config_rom_update_amount
)
1908 last_entry_offset
= hal
->config_rom_update_amount
;
1910 hal
->config_rom_update_amount
= (IEEE1394_CONFIG_ROM_QUAD_SZ
-
1913 /* Clear the timer flag */
1914 hal
->config_rom_timer_set
= B_FALSE
;
1916 /* Unlock the Config ROM buffer */
1917 mutex_exit(&hal
->local_config_rom_mutex
);
1920 * The update_config_rom() call can return DDI_FAILURE if the
1923 (void) HAL_CALL(hal
).update_config_rom(hal
->halinfo
.hal_private
,\
1924 config_rom
, last_entry_offset
);
1926 /* Initiate a bus reset */
1927 (void) HAL_CALL(hal
).bus_reset(hal
->halinfo
.hal_private
);