1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27 /*
28 * s1394_csr.c
29 * 1394 Services Layer CSR and Config ROM Routines
30 * Contains all of the CSR callback routines for various required
31 * CSR registers. Also contains routines for their initialization
32 * and destruction, as well as routines to handle the processing
33 * of Config ROM update requests.
34 */
35
36 #include <sys/conf.h>
37 #include <sys/ddi.h>
38 #include <sys/sunddi.h>
39 #include <sys/types.h>
40 #include <sys/kmem.h>
41 #include <sys/1394/t1394.h>
42 #include <sys/1394/s1394.h>
43 #include <sys/1394/h1394.h>
44 #include <sys/1394/ieee1394.h>
45 #include <sys/1394/ieee1212.h>
46
47 static void s1394_CSR_state_clear(cmd1394_cmd_t *req);
48
49 static void s1394_CSR_state_set(cmd1394_cmd_t *req);
50
51 static void s1394_CSR_node_ids(cmd1394_cmd_t *req);
52
53 static void s1394_CSR_reset_start(cmd1394_cmd_t *req);
54
55 static void s1394_CSR_split_timeout(cmd1394_cmd_t *req);
56
57 static void s1394_CSR_argument_regs(cmd1394_cmd_t *req);
58
59 static void s1394_CSR_test_regs(cmd1394_cmd_t *req);
60
61 static void s1394_CSR_interrupt_regs(cmd1394_cmd_t *req);
62
63 static void s1394_CSR_clock_regs(cmd1394_cmd_t *req);
64
65 static void s1394_CSR_message_regs(cmd1394_cmd_t *req);
66
67 static void s1394_CSR_cycle_time(cmd1394_cmd_t *req);
68
69 static void s1394_CSR_bus_time(cmd1394_cmd_t *req);
70
71 static void s1394_CSR_busy_timeout(cmd1394_cmd_t *req);
72
73 static void s1394_CSR_IRM_regs(cmd1394_cmd_t *req);
74
75 static void s1394_CSR_topology_map(cmd1394_cmd_t *req);
76
77 static void s1394_common_CSR_routine(s1394_hal_t *hal, cmd1394_cmd_t *req);
78
79 static int s1394_init_config_rom_structures(s1394_hal_t *hal);
80
81 static int s1394_destroy_config_rom_structures(s1394_hal_t *hal);
82
83 /*
84 * s1394_setup_CSR_space()
85 * setups up the local host's CSR registers and callback routines.
86 */
87 int
s1394_setup_CSR_space(s1394_hal_t * hal)88 s1394_setup_CSR_space(s1394_hal_t *hal)
89 {
90 s1394_addr_space_blk_t *curr_blk;
91 t1394_alloc_addr_t addr;
92 t1394_addr_enable_t rw_flags;
93 int result;
94
95 /*
96 * Although they are not freed up in this routine, if
97 * one of the s1394_claim_addr_blk() routines fails,
98 * all of the previously successful claims will be
99 * freed up in s1394_destroy_addr_space() upon returning
100 * DDI_FAILURE from this routine.
101 */
102
103 rw_flags = T1394_ADDR_RDENBL | T1394_ADDR_WRENBL;
104
105 /*
106 * STATE_CLEAR
107 * see IEEE 1394-1995, Section 8.3.2.2.1 or
108 * IEEE 1212-1994, Section 7.4.1
109 */
110 addr.aa_address = IEEE1394_CSR_STATE_CLEAR;
111 addr.aa_length = IEEE1394_QUADLET;
112 addr.aa_enable = rw_flags;
113 addr.aa_type = T1394_ADDR_FIXED;
114 addr.aa_evts.recv_read_request = s1394_CSR_state_clear;
115 addr.aa_evts.recv_write_request = s1394_CSR_state_clear;
116 addr.aa_evts.recv_lock_request = NULL;
117 addr.aa_kmem_bufp = NULL;
118 addr.aa_arg = hal;
119 result = s1394_claim_addr_blk(hal, &addr);
120 if (result != DDI_SUCCESS) {
121 return (DDI_FAILURE);
122 }
123
124 /*
125 * STATE_SET
126 * see IEEE 1394-1995, Section 8.3.2.2.2 or
127 * IEEE 1212-1994, Section 7.4.2
128 */
129 addr.aa_address = IEEE1394_CSR_STATE_SET;
130 addr.aa_length = IEEE1394_QUADLET;
131 addr.aa_enable = T1394_ADDR_WRENBL;
132 addr.aa_type = T1394_ADDR_FIXED;
133 addr.aa_evts.recv_read_request = NULL;
134 addr.aa_evts.recv_write_request = s1394_CSR_state_set;
135 addr.aa_evts.recv_lock_request = NULL;
136 addr.aa_kmem_bufp = NULL;
137 addr.aa_arg = hal;
138 result = s1394_claim_addr_blk(hal, &addr);
139 if (result != DDI_SUCCESS) {
140 return (DDI_FAILURE);
141 }
142
143 /*
144 * NODE_IDS
145 * see IEEE 1394-1995, Section 8.3.2.2.3 or
146 * IEEE 1212-1994, Section 7.4.3
147 */
148 addr.aa_address = IEEE1394_CSR_NODE_IDS;
149 addr.aa_length = IEEE1394_QUADLET;
150 addr.aa_enable = rw_flags;
151 addr.aa_type = T1394_ADDR_FIXED;
152 addr.aa_evts.recv_read_request = s1394_CSR_node_ids;
153 addr.aa_evts.recv_write_request = s1394_CSR_node_ids;
154 addr.aa_evts.recv_lock_request = NULL;
155 addr.aa_kmem_bufp = NULL;
156 addr.aa_arg = hal;
157 result = s1394_claim_addr_blk(hal, &addr);
158 if (result != DDI_SUCCESS) {
159 return (DDI_FAILURE);
160 }
161
162 /*
163 * RESET_START
164 * see IEEE 1394-1995, Section 8.3.2.2.4 or
165 * IEEE 1212-1994, Section 7.4.4
166 */
167 addr.aa_address = IEEE1394_CSR_RESET_START;
168 addr.aa_length = IEEE1394_QUADLET;
169 addr.aa_enable = T1394_ADDR_WRENBL;
170 addr.aa_type = T1394_ADDR_FIXED;
171 addr.aa_evts.recv_read_request = NULL;
172 addr.aa_evts.recv_write_request = s1394_CSR_reset_start;
173 addr.aa_evts.recv_lock_request = NULL;
174 addr.aa_kmem_bufp = NULL;
175 addr.aa_arg = hal;
176 result = s1394_claim_addr_blk(hal, &addr);
177 if (result != DDI_SUCCESS) {
178 return (DDI_FAILURE);
179 }
180
181 /*
182 * SPLIT_TIMEOUT
183 * see IEEE 1394-1995, Section 8.3.2.2.6 or
184 * IEEE 1212-1994, Section 7.4.7
185 */
186 addr.aa_address = IEEE1394_CSR_SPLIT_TIMEOUT_HI;
187 addr.aa_length = IEEE1394_OCTLET;
188 addr.aa_enable = rw_flags;
189 addr.aa_type = T1394_ADDR_FIXED;
190 addr.aa_evts.recv_read_request = s1394_CSR_split_timeout;
191 addr.aa_evts.recv_write_request = s1394_CSR_split_timeout;
192 addr.aa_evts.recv_lock_request = NULL;
193 addr.aa_kmem_bufp = NULL;
194 addr.aa_arg = hal;
195 result = s1394_claim_addr_blk(hal, &addr);
196 if (result != DDI_SUCCESS) {
197 return (DDI_FAILURE);
198 }
199
200 /*
201 * ARGUMENT_HI and ARGUMENT_LO
202 * see IEEE 1394-1995, Section 8.3.2.2.7 or
203 * IEEE 1212-1994, Section 7.4.8
204 */
205 addr.aa_address = IEEE1394_CSR_ARG_HI;
206 addr.aa_length = 2 * (IEEE1394_QUADLET);
207 addr.aa_enable = rw_flags;
208 addr.aa_type = T1394_ADDR_FIXED;
209 addr.aa_evts.recv_read_request = s1394_CSR_argument_regs;
210 addr.aa_evts.recv_write_request = s1394_CSR_argument_regs;
211 addr.aa_evts.recv_lock_request = NULL;
212 addr.aa_kmem_bufp = NULL;
213 addr.aa_arg = hal;
214 result = s1394_claim_addr_blk(hal, &addr);
215 if (result != DDI_SUCCESS) {
216 return (DDI_FAILURE);
217 }
218
219 /*
220 * TEST_START and TEST_STATUS
221 * see IEEE 1394-1995, Section 8.3.2.2.7 or
222 * IEEE 1212-1994, Section 7.4.9 - 7.4.10
223 */
224 addr.aa_address = IEEE1394_CSR_TEST_START;
225 addr.aa_length = 2 * (IEEE1394_QUADLET);
226 addr.aa_enable = rw_flags;
227 addr.aa_type = T1394_ADDR_FIXED;
228 addr.aa_evts.recv_read_request = s1394_CSR_test_regs;
229 addr.aa_evts.recv_write_request = s1394_CSR_test_regs;
230 addr.aa_evts.recv_lock_request = NULL;
231 addr.aa_kmem_bufp = NULL;
232 addr.aa_arg = hal;
233 result = s1394_claim_addr_blk(hal, &addr);
234 if (result != DDI_SUCCESS) {
235 return (DDI_FAILURE);
236 }
237
238 /*
239 * INTERRUPT_TARGET and INTERRUPT_MASK
240 * see IEEE 1394-1995, Section 8.3.2.2.9 or
241 * IEEE 1212-1994, Section 7.4.15 - 7.4.16
242 */
243 addr.aa_address = IEEE1394_CSR_INTERRUPT_TARGET;
244 addr.aa_length = 2 * (IEEE1394_QUADLET);
245 addr.aa_enable = rw_flags;
246 addr.aa_type = T1394_ADDR_FIXED;
247 addr.aa_evts.recv_read_request = s1394_CSR_interrupt_regs;
248 addr.aa_evts.recv_write_request = s1394_CSR_interrupt_regs;
249 addr.aa_evts.recv_lock_request = NULL;
250 addr.aa_kmem_bufp = NULL;
251 addr.aa_arg = hal;
252 result = s1394_claim_addr_blk(hal, &addr);
253 if (result != DDI_SUCCESS) {
254 return (DDI_FAILURE);
255 }
256
257 /*
258 * CLOCK_VALUE, CLOCK_TICK_PERIOD, CLOCK_INFO, etc.
259 * see IEEE 1394-1995, Section 8.3.2.2.10 or
260 * IEEE 1212-1994, Section 7.4.17 - 7.4.20
261 */
262 addr.aa_address = IEEE1394_CSR_CLOCK_VALUE;
263 addr.aa_length = IEEE1394_CSR_CLOCK_VALUE_SZ;
264 addr.aa_enable = rw_flags;
265 addr.aa_type = T1394_ADDR_FIXED;
266 addr.aa_evts.recv_read_request = s1394_CSR_clock_regs;
267 addr.aa_evts.recv_write_request = s1394_CSR_clock_regs;
268 addr.aa_evts.recv_lock_request = NULL;
269 addr.aa_kmem_bufp = NULL;
270 addr.aa_arg = hal;
271 result = s1394_claim_addr_blk(hal, &addr);
272 if (result != DDI_SUCCESS) {
273 return (DDI_FAILURE);
274 }
275
276 /*
277 * MESSAGE_REQUEST and MESSAGE_RESPONSE
278 * see IEEE 1394-1995, Section 8.3.2.2.11 or
279 * IEEE 1212-1994, Section 7.4.21
280 */
281 addr.aa_address = IEEE1394_CSR_MESSAGE_REQUEST;
282 addr.aa_length = IEEE1394_CSR_MESSAGE_REQUEST_SZ;
283 addr.aa_enable = rw_flags;
284 addr.aa_type = T1394_ADDR_FIXED;
285 addr.aa_evts.recv_read_request = s1394_CSR_message_regs;
286 addr.aa_evts.recv_write_request = s1394_CSR_message_regs;
287 addr.aa_evts.recv_lock_request = NULL;
288 addr.aa_kmem_bufp = NULL;
289 addr.aa_arg = hal;
290 result = s1394_claim_addr_blk(hal, &addr);
291 if (result != DDI_SUCCESS) {
292 return (DDI_FAILURE);
293 }
294
295 /*
296 * CYCLE_TIME
297 * see IEEE 1394-1995, Section 8.3.2.3.1
298 */
299 addr.aa_address = IEEE1394_SCSR_CYCLE_TIME;
300 addr.aa_length = IEEE1394_QUADLET;
301 addr.aa_enable = rw_flags;
302 addr.aa_type = T1394_ADDR_FIXED;
303 addr.aa_evts.recv_read_request = s1394_CSR_cycle_time;
304 addr.aa_evts.recv_write_request = s1394_CSR_cycle_time;
305 addr.aa_evts.recv_lock_request = NULL;
306 addr.aa_kmem_bufp = NULL;
307 addr.aa_arg = hal;
308 result = s1394_claim_addr_blk(hal, &addr);
309 if (result != DDI_SUCCESS) {
310 return (DDI_FAILURE);
311 }
312
313 /*
314 * BUS_TIME
315 * see IEEE 1394-1995, Section 8.3.2.3.2
316 */
317 addr.aa_address = IEEE1394_SCSR_BUS_TIME;
318 addr.aa_length = IEEE1394_QUADLET;
319 addr.aa_enable = rw_flags;
320 addr.aa_type = T1394_ADDR_FIXED;
321 addr.aa_evts.recv_read_request = s1394_CSR_bus_time;
322 addr.aa_evts.recv_write_request = s1394_CSR_bus_time;
323 addr.aa_evts.recv_lock_request = NULL;
324 addr.aa_kmem_bufp = NULL;
325 addr.aa_arg = hal;
326 result = s1394_claim_addr_blk(hal, &addr);
327 if (result != DDI_SUCCESS) {
328 return (DDI_FAILURE);
329 }
330
331 /*
332 * BUSY_TIMEOUT
333 * see IEEE 1394-1995, Section 8.3.2.3.5
334 */
335 addr.aa_address = IEEE1394_SCSR_BUSY_TIMEOUT;
336 addr.aa_length = IEEE1394_QUADLET;
337 addr.aa_enable = rw_flags;
338 addr.aa_type = T1394_ADDR_FIXED;
339 addr.aa_evts.recv_read_request = s1394_CSR_busy_timeout;
340 addr.aa_evts.recv_write_request = s1394_CSR_busy_timeout;
341 addr.aa_evts.recv_lock_request = NULL;
342 addr.aa_kmem_bufp = NULL;
343 addr.aa_arg = hal;
344 result = s1394_claim_addr_blk(hal, &addr);
345 if (result != DDI_SUCCESS) {
346 return (DDI_FAILURE);
347 }
348
349 /*
350 * BUS_MANAGER_ID
351 * BANDWIDTH_AVAILABLE
352 * CHANNELS_AVAILABLE
353 * see IEEE 1394-1995, Section 8.3.2.3.6 - 8.3.2.3.8
354 */
355 addr.aa_address = IEEE1394_SCSR_BUSMGR_ID;
356 addr.aa_length = 3 * (IEEE1394_QUADLET);
357 addr.aa_enable = T1394_ADDR_RDENBL | T1394_ADDR_LKENBL;
358 addr.aa_type = T1394_ADDR_FIXED;
359 addr.aa_evts.recv_read_request = s1394_CSR_IRM_regs;
360 addr.aa_evts.recv_write_request = NULL;
361 addr.aa_evts.recv_lock_request = s1394_CSR_IRM_regs;
362 addr.aa_kmem_bufp = NULL;
363 addr.aa_arg = hal;
364 result = s1394_claim_addr_blk(hal, &addr);
365 if (result != DDI_SUCCESS) {
366 return (DDI_FAILURE);
367 }
368
369 /*
370 * Reserved for Configuration ROM
371 * see IEEE 1394-1995, Section 8.3.2.5.3
372 */
373 addr.aa_address = IEEE1394_CONFIG_ROM_ADDR;
374 addr.aa_length = IEEE1394_CONFIG_ROM_SZ;
375 result = s1394_reserve_addr_blk(hal, &addr);
376 if (result != DDI_SUCCESS) {
377 return (DDI_FAILURE);
378 }
379
380 /*
381 * TOPOLOGY_MAP
382 * see IEEE 1394-1995, Section 8.3.2.4.1
383 */
384 hal->CSR_topology_map = kmem_zalloc(IEEE1394_UCSR_TOPOLOGY_MAP_SZ,
385 KM_SLEEP);
386 addr.aa_address = IEEE1394_UCSR_TOPOLOGY_MAP;
387 addr.aa_length = IEEE1394_UCSR_TOPOLOGY_MAP_SZ;
388 addr.aa_enable = T1394_ADDR_RDENBL;
389 addr.aa_type = T1394_ADDR_FIXED;
390 addr.aa_evts.recv_read_request = s1394_CSR_topology_map;
391 addr.aa_evts.recv_write_request = NULL;
392 addr.aa_evts.recv_lock_request = NULL;
393 addr.aa_kmem_bufp = (caddr_t)hal->CSR_topology_map;
394 addr.aa_arg = hal;
395 result = s1394_claim_addr_blk(hal, &addr);
396 if (result != DDI_SUCCESS) {
397 kmem_free((void *)hal->CSR_topology_map,
398 IEEE1394_UCSR_TOPOLOGY_MAP_SZ);
399 return (DDI_FAILURE);
400 }
401 curr_blk = (s1394_addr_space_blk_t *)(addr.aa_hdl);
402 /* Set up the block so that we free kmem_bufp at detach */
403 curr_blk->free_kmem_bufp = B_TRUE;
404
405 /*
406 * Reserve the SPEED_MAP
407 * see IEEE 1394-1995, Section 8.3.2.4.1
408 * (obsoleted in P1394A)
409 */
410 addr.aa_address = IEEE1394_UCSR_SPEED_MAP;
411 addr.aa_length = IEEE1394_UCSR_SPEED_MAP_SZ;
412 result = s1394_reserve_addr_blk(hal, &addr);
413 if (result != DDI_SUCCESS) {
414 return (DDI_FAILURE);
415 }
416
417 /*
418 * Reserved - Boundary between reserved Serial Bus
419 * dependent registers and other CSR register space.
420 * See IEEE 1394-1995, Table 8-4 for this address.
421 *
422 * This quadlet is reserved as a way of preventing
423 * the inadvertant allocation of a part of CSR space
424 * that will likely be used by future specifications
425 */
426 addr.aa_address = IEEE1394_UCSR_RESERVED_BOUNDARY;
427 addr.aa_length = IEEE1394_QUADLET;
428 result = s1394_reserve_addr_blk(hal, &addr);
429 if (result != DDI_SUCCESS) {
430 return (DDI_FAILURE);
431 }
432
433 return (DDI_SUCCESS);
434 }
435
436 /*
437 * s1394_CSR_state_clear()
438 * handles all requests to the STATE_CLEAR CSR register. It enforces
439 * that certain bits that can be twiddled only by a given node (IRM or
440 * Bus Manager).
441 */
442 static void
s1394_CSR_state_clear(cmd1394_cmd_t * req)443 s1394_CSR_state_clear(cmd1394_cmd_t *req)
444 {
445 s1394_hal_t *hal;
446 uint32_t data;
447 uint_t offset;
448 uint_t is_from;
449 uint_t should_be_from;
450 int result;
451
452 hal = (s1394_hal_t *)req->cmd_callback_arg;
453
454 /* Register offset */
455 offset = req->cmd_addr & IEEE1394_CSR_OFFSET_MASK;
456
457 /* Verify that request is quadlet aligned */
458 if ((offset & 0x3) != 0) {
459 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
460 (void) s1394_send_response(hal, req);
461 return;
462 }
463
464 /* Only writes from IRM or Bus Mgr allowed (in some cases) */
465 mutex_enter(&hal->topology_tree_mutex);
466 is_from = IEEE1394_NODE_NUM(req->nodeID);
467 if (hal->bus_mgr_node != -1)
468 should_be_from = IEEE1394_NODE_NUM(hal->bus_mgr_node);
469 else if (hal->IRM_node != -1)
470 should_be_from = IEEE1394_NODE_NUM(hal->IRM_node);
471 else
472 should_be_from = S1394_INVALID_NODE_NUM;
473 mutex_exit(&hal->topology_tree_mutex);
474
475 switch (req->cmd_type) {
476 case CMD1394_ASYNCH_RD_QUAD:
477 /*
478 * The csr_read() call can return DDI_FAILURE if the HAL
479 * is shutdown or if the register at "offset" is
480 * unimplemented. But although the STATE_CLEAR register
481 * is required to be implemented and readable, we will
482 * return IEEE1394_RESP_ADDRESS_ERROR in the response if
483 * we ever see this error.
484 */
485 result = HAL_CALL(hal).csr_read(hal->halinfo.hal_private,
486 offset, &data);
487 if (result == DDI_SUCCESS) {
488 req->cmd_u.q.quadlet_data = data;
489 req->cmd_result = IEEE1394_RESP_COMPLETE;
490 } else {
491 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR;
492 }
493 break;
494
495 case CMD1394_ASYNCH_WR_QUAD:
496 data = req->cmd_u.q.quadlet_data;
497
498 /* CMSTR bit - request must be from bus_mgr/IRM */
499 if (is_from != should_be_from) {
500 data = data & ~IEEE1394_CSR_STATE_CMSTR;
501 }
502
503 mutex_enter(&hal->topology_tree_mutex);
504 /* DREQ bit - disabling DREQ can come from anyone */
505 if (data & IEEE1394_CSR_STATE_DREQ) {
506 hal->disable_requests_bit = 0;
507 if (hal->hal_state == S1394_HAL_DREQ)
508 hal->hal_state = S1394_HAL_NORMAL;
509 }
510
511 /* ABDICATE bit */
512 if (data & IEEE1394_CSR_STATE_ABDICATE) {
513 hal->abdicate_bus_mgr_bit = 0;
514 }
515 mutex_exit(&hal->topology_tree_mutex);
516 /*
517 * The csr_write() call can return DDI_FAILURE if the HAL
518 * is shutdown or if the register at "offset" is
519 * unimplemented. But although the STATE_CLEAR register
520 * is required to be implemented and writeable, we will
521 * return IEEE1394_RESP_ADDRESS_ERROR in the response if
522 * we ever see this error.
523 */
524 result = HAL_CALL(hal).csr_write(hal->halinfo.hal_private,
525 offset, data);
526 if (result == DDI_SUCCESS) {
527 req->cmd_result = IEEE1394_RESP_COMPLETE;
528 } else {
529 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR;
530 }
531 break;
532
533 default:
534 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
535 }
536
537 (void) s1394_send_response(hal, req);
538 }
539
540 /*
541 * s1394_CSR_state_set()
542 * handles all requests to the STATE_SET CSR register. It enforces that
543 * certain bits that can be twiddled only by a given node (IRM or Bus
544 * Manager).
545 */
546 static void
s1394_CSR_state_set(cmd1394_cmd_t * req)547 s1394_CSR_state_set(cmd1394_cmd_t *req)
548 {
549 s1394_hal_t *hal;
550 uint32_t data;
551 uint_t offset;
552 uint_t is_from;
553 uint_t should_be_from;
554 uint_t hal_node_num;
555 uint_t hal_number_of_nodes;
556 int result;
557
558 hal = (s1394_hal_t *)req->cmd_callback_arg;
559
560 /* Register offset */
561 offset = req->cmd_addr & IEEE1394_CSR_OFFSET_MASK;
562
563 /* Verify that request is quadlet aligned */
564 if ((offset & 0x3) != 0) {
565 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
566 (void) s1394_send_response(hal, req);
567 return;
568 }
569
570 /* Only writes from IRM or Bus Mgr allowed (in some cases) */
571 mutex_enter(&hal->topology_tree_mutex);
572 is_from = IEEE1394_NODE_NUM(req->nodeID);
573 if (hal->bus_mgr_node != -1)
574 should_be_from = IEEE1394_NODE_NUM(hal->bus_mgr_node);
575 else if (hal->IRM_node != -1)
576 should_be_from = IEEE1394_NODE_NUM(hal->IRM_node);
577 else
578 should_be_from = S1394_INVALID_NODE_NUM;
579 hal_node_num = IEEE1394_NODE_NUM(hal->node_id);
580 hal_number_of_nodes = hal->number_of_nodes;
581 mutex_exit(&hal->topology_tree_mutex);
582
583 switch (req->cmd_type) {
584 case CMD1394_ASYNCH_WR_QUAD:
585 data = req->cmd_u.q.quadlet_data;
586
587 /* CMSTR bit - request must be from bus_mgr/IRM */
588 /* & must be root to have bit set */
589 if ((is_from != should_be_from) ||
590 (hal_node_num != (hal_number_of_nodes - 1))) {
591 data = data & ~IEEE1394_CSR_STATE_CMSTR;
592 }
593
594 mutex_enter(&hal->topology_tree_mutex);
595 /* DREQ bit - only bus_mgr/IRM can set this bit */
596 if (is_from != should_be_from) {
597 data = data & ~IEEE1394_CSR_STATE_DREQ;
598
599 } else if (data & IEEE1394_CSR_STATE_DREQ) {
600 hal->disable_requests_bit = 1;
601 if (hal->hal_state == S1394_HAL_NORMAL)
602 hal->hal_state = S1394_HAL_DREQ;
603 }
604 /* ABDICATE bit */
605 if (data & IEEE1394_CSR_STATE_ABDICATE) {
606 hal->abdicate_bus_mgr_bit = 1;
607 }
608 mutex_exit(&hal->topology_tree_mutex);
609 /*
610 * The csr_write() call can return DDI_FAILURE if the HAL
611 * is shutdown or if the register at "offset" is
612 * unimplemented. But although the STATE_SET register
613 * is required to be implemented and writeable, we will
614 * return IEEE1394_RESP_ADDRESS_ERROR in the response if
615 * we ever see this error.
616 */
617 result = HAL_CALL(hal).csr_write(hal->halinfo.hal_private,
618 offset, data);
619 if (result == DDI_SUCCESS) {
620 req->cmd_result = IEEE1394_RESP_COMPLETE;
621 } else {
622 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR;
623 }
624 break;
625
626 default:
627 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
628 }
629
630 (void) s1394_send_response(hal, req);
631 }
632
633 /*
634 * s1394_CSR_node_ids()
635 * handles all requests to the NODE_IDS CSR register. It passes all
636 * requests to the common routine - s1394_common_CSR_routine().
637 */
638 static void
s1394_CSR_node_ids(cmd1394_cmd_t * req)639 s1394_CSR_node_ids(cmd1394_cmd_t *req)
640 {
641 s1394_hal_t *hal;
642
643 hal = (s1394_hal_t *)req->cmd_callback_arg;
644
645 s1394_common_CSR_routine(hal, req);
646 }
647
648 /*
649 * s1394_CSR_reset_start()
650 * handles all requests to the RESET_START CSR register. Only write
651 * requests are legal, everything else gets a type_error response.
652 */
653 static void
s1394_CSR_reset_start(cmd1394_cmd_t * req)654 s1394_CSR_reset_start(cmd1394_cmd_t *req)
655 {
656 s1394_hal_t *hal;
657 uint32_t data;
658 uint_t offset;
659
660 hal = (s1394_hal_t *)req->cmd_callback_arg;
661
662 /* RESET_START register offset */
663 offset = req->cmd_addr & IEEE1394_CSR_OFFSET_MASK;
664
665 /* Verify that request is quadlet aligned */
666 if ((offset & 0x3) != 0) {
667 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
668 (void) s1394_send_response(hal, req);
669 return;
670 }
671
672 switch (req->cmd_type) {
673 case CMD1394_ASYNCH_WR_QUAD:
674 data = req->cmd_u.q.quadlet_data;
675 /*
676 * The csr_write() call can return DDI_FAILURE if the HAL
677 * is shutdown or if the register at "offset" is
678 * unimplemented. Because we don't do any thing with
679 * the RESET_START register we will ignore failures and
680 * return IEEE1394_RESP_COMPLETE regardless.
681 */
682 (void) HAL_CALL(hal).csr_write(hal->halinfo.hal_private,
683 offset, data);
684 req->cmd_result = IEEE1394_RESP_COMPLETE;
685 break;
686
687 default:
688 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
689 }
690
691 (void) s1394_send_response(hal, req);
692 }
693
694 /*
695 * s1394_CSR_split_timeout()
696 * handles all requests to the SPLIT_TIMEOUT CSR register. It passes all
697 * requests to the common routine - s1394_common_CSR_routine().
698 */
699 static void
s1394_CSR_split_timeout(cmd1394_cmd_t * req)700 s1394_CSR_split_timeout(cmd1394_cmd_t *req)
701 {
702 s1394_hal_t *hal;
703
704 hal = (s1394_hal_t *)req->cmd_callback_arg;
705
706 s1394_common_CSR_routine(hal, req);
707 }
708
709 /*
710 * s1394_CSR_argument_regs()
711 * handles all requests to the ARGUMENT CSR registers. It passes all
712 * requests to the common routine - s1394_common_CSR_routine().
713 */
714 static void
s1394_CSR_argument_regs(cmd1394_cmd_t * req)715 s1394_CSR_argument_regs(cmd1394_cmd_t *req)
716 {
717 s1394_hal_t *hal;
718
719 hal = (s1394_hal_t *)req->cmd_callback_arg;
720
721 s1394_common_CSR_routine(hal, req);
722 }
723
724 /*
725 * s1394_CSR_test_regs()
726 * handles all requests to the TEST CSR registers. It passes all requests
727 * to the common routine - s1394_common_CSR_routine().
728 */
729 static void
s1394_CSR_test_regs(cmd1394_cmd_t * req)730 s1394_CSR_test_regs(cmd1394_cmd_t *req)
731 {
732 s1394_hal_t *hal;
733 uint_t offset;
734
735 hal = (s1394_hal_t *)req->cmd_callback_arg;
736
737 /* TEST register offset */
738 offset = req->cmd_addr & IEEE1394_CSR_OFFSET_MASK;
739
740 /* TEST_STATUS is Read-Only */
741 if ((offset == (IEEE1394_CSR_TEST_STATUS & IEEE1394_CSR_OFFSET_MASK)) &&
742 (req->cmd_type == CMD1394_ASYNCH_WR_QUAD)) {
743 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
744 (void) s1394_send_response(hal, req);
745 } else {
746 s1394_common_CSR_routine(hal, req);
747 }
748 }
749
750 /*
751 * s1394_CSR_interrupt_regs()
752 * handles all requests to the INTERRUPT CSR registers. It passes all
753 * requests to the common routine - s1394_common_CSR_routine().
754 */
755 static void
s1394_CSR_interrupt_regs(cmd1394_cmd_t * req)756 s1394_CSR_interrupt_regs(cmd1394_cmd_t *req)
757 {
758 s1394_hal_t *hal;
759
760 hal = (s1394_hal_t *)req->cmd_callback_arg;
761
762 s1394_common_CSR_routine(hal, req);
763 }
764
765 /*
766 * s1394_CSR_clock_regs()
767 * handles all requests to the CLOCK CSR registers. It passes all
768 * requests to the common routine - s1394_common_CSR_routine().
769 */
770 static void
s1394_CSR_clock_regs(cmd1394_cmd_t * req)771 s1394_CSR_clock_regs(cmd1394_cmd_t *req)
772 {
773 s1394_hal_t *hal;
774
775 hal = (s1394_hal_t *)req->cmd_callback_arg;
776
777 s1394_common_CSR_routine(hal, req);
778 }
779
780 /*
781 * s1394_CSR_message_regs()
782 * handles all requests to the MESSAGE CSR registers. It passes all
783 * requests to the common routine - s1394_common_CSR_routine().
784 */
785 static void
s1394_CSR_message_regs(cmd1394_cmd_t * req)786 s1394_CSR_message_regs(cmd1394_cmd_t *req)
787 {
788 s1394_hal_t *hal;
789
790 hal = (s1394_hal_t *)req->cmd_callback_arg;
791
792 s1394_common_CSR_routine(hal, req);
793 }
794
795 /*
796 * s1394_CSR_cycle_time()
797 * handles all requests to the CYCLE_TIME CSR register.
798 */
799 static void
s1394_CSR_cycle_time(cmd1394_cmd_t * req)800 s1394_CSR_cycle_time(cmd1394_cmd_t *req)
801 {
802 s1394_hal_t *hal;
803 uint32_t data;
804 uint_t offset;
805 int result;
806
807 hal = (s1394_hal_t *)req->cmd_callback_arg;
808
809 /* CYCLE_TIME register offset */
810 offset = req->cmd_addr & IEEE1394_CSR_OFFSET_MASK;
811
812 /* Verify that request is quadlet aligned */
813 if ((offset & 0x3) != 0) {
814 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
815 (void) s1394_send_response(hal, req);
816 return;
817 }
818
819 switch (req->cmd_type) {
820 case CMD1394_ASYNCH_RD_QUAD:
821 /*
822 * The csr_read() call can return DDI_FAILURE if the HAL
823 * is shutdown or if the register at "offset" is
824 * unimplemented. But although the CYCLE_TIME register
825 * is required to be implemented on devices capable of
826 * providing isochronous services (like us), we will
827 * return IEEE1394_RESP_ADDRESS_ERROR in the response
828 * if we ever see this error.
829 */
830 result = HAL_CALL(hal).csr_read(hal->halinfo.hal_private,
831 offset, &data);
832 if (result == DDI_SUCCESS) {
833 req->cmd_u.q.quadlet_data = data;
834 req->cmd_result = IEEE1394_RESP_COMPLETE;
835 } else {
836 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR;
837 }
838 break;
839
840 case CMD1394_ASYNCH_WR_QUAD:
841 data = req->cmd_u.q.quadlet_data;
842 /*
843 * The csr_write() call can return DDI_FAILURE if the HAL
844 * is shutdown or if the register at "offset" is
845 * unimplemented. But although the CYCLE_TIME register
846 * is required to be implemented on devices capable of
847 * providing isochronous services (like us), the effects
848 * of a write are "node-dependent" so we will return
849 * IEEE1394_RESP_ADDRESS_ERROR in the response if we
850 * ever see this error.
851 */
852 result = HAL_CALL(hal).csr_write(hal->halinfo.hal_private,
853 offset, data);
854 if (result == DDI_SUCCESS) {
855 req->cmd_result = IEEE1394_RESP_COMPLETE;
856 } else {
857 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR;
858 }
859 break;
860
861 default:
862 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
863 }
864
865 (void) s1394_send_response(hal, req);
866 }
867
868 /*
869 * s1394_CSR_bus_time()
870 * handles all requests to the BUS_TIME CSR register. It enforces that
871 * only a broadcast write request from the IRM or Bus Manager can change
872 * its value.
873 */
874 static void
s1394_CSR_bus_time(cmd1394_cmd_t * req)875 s1394_CSR_bus_time(cmd1394_cmd_t *req)
876 {
877 s1394_hal_t *hal;
878 uint32_t data;
879 uint_t offset;
880 uint_t is_from;
881 uint_t should_be_from;
882 int result;
883
884 hal = (s1394_hal_t *)req->cmd_callback_arg;
885
886 /* BUS_TIME register offset */
887 offset = req->cmd_addr & IEEE1394_CSR_OFFSET_MASK;
888
889 /* Verify that request is quadlet aligned */
890 if ((offset & 0x3) != 0) {
891 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
892 (void) s1394_send_response(hal, req);
893 return;
894 }
895
896 switch (req->cmd_type) {
897 case CMD1394_ASYNCH_RD_QUAD:
898 /*
899 * The csr_read() call can return DDI_FAILURE if the HAL
900 * is shutdown or if the register at "offset" is
901 * unimplemented. But although the BUS_TIME register
902 * is required to be implemented by devices capable of
903 * being cycle master (like us), we will return
904 * IEEE1394_RESP_ADDRESS_ERROR in the response if we
905 * ever see this error.
906 */
907 result = HAL_CALL(hal).csr_read(hal->halinfo.hal_private,
908 offset, &data);
909 if (result == DDI_SUCCESS) {
910 req->cmd_u.q.quadlet_data = data;
911 req->cmd_result = IEEE1394_RESP_COMPLETE;
912 } else {
913 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR;
914 }
915 break;
916
917 case CMD1394_ASYNCH_WR_QUAD:
918 /* Only broadcast writes from IRM or Bus Mgr allowed */
919 mutex_enter(&hal->topology_tree_mutex);
920 is_from = IEEE1394_NODE_NUM(req->nodeID);
921 if (hal->bus_mgr_node != -1)
922 should_be_from = IEEE1394_NODE_NUM(hal->bus_mgr_node);
923 else if (hal->IRM_node != -1)
924 should_be_from = IEEE1394_NODE_NUM(hal->IRM_node);
925 else
926 should_be_from = S1394_INVALID_NODE_NUM;
927 mutex_exit(&hal->topology_tree_mutex);
928
929 if ((req->broadcast != 1) || (is_from != should_be_from)) {
930 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
931 break;
932 }
933
934 data = req->cmd_u.q.quadlet_data;
935 /*
936 * The csr_write() call can return DDI_FAILURE if the HAL
937 * is shutdown or if the register at "offset" is
938 * unimplemented. But although the BUS_TIME register
939 * is required to be implemented on devices capable of
940 * being cycle master (like us), we will return
941 * IEEE1394_RESP_ADDRESS_ERROR in the response if we
942 * ever see this error.
943 */
944 result = HAL_CALL(hal).csr_write(hal->halinfo.hal_private,
945 offset, data);
946 if (result == DDI_SUCCESS) {
947 req->cmd_result = IEEE1394_RESP_COMPLETE;
948 } else {
949 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR;
950 }
951 break;
952
953 default:
954 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
955 }
956
957 (void) s1394_send_response(hal, req);
958 }
959
960 /*
961 * s1394_CSR_busy_timeout()
962 * handles all requests to the BUSY_TIMEOUT CSR register. It passes all
963 * requests to the common routine - s1394_common_CSR_routine().
964 */
965 static void
s1394_CSR_busy_timeout(cmd1394_cmd_t * req)966 s1394_CSR_busy_timeout(cmd1394_cmd_t *req)
967 {
968 s1394_hal_t *hal;
969
970 hal = (s1394_hal_t *)req->cmd_callback_arg;
971
972 s1394_common_CSR_routine(hal, req);
973 }
974
975 /*
976 * s1394_CSR_IRM_regs()
977 * handles all requests to the IRM registers, including BANDWIDTH_AVAILABLE,
978 * CHANNELS_AVAILABLE, and the BUS_MANAGER_ID. Only quadlet read and lock
979 * requests are allowed.
980 */
981 static void
s1394_CSR_IRM_regs(cmd1394_cmd_t * req)982 s1394_CSR_IRM_regs(cmd1394_cmd_t *req)
983 {
984 s1394_hal_t *hal;
985 uint32_t generation;
986 uint32_t data;
987 uint32_t compare;
988 uint32_t swap;
989 uint32_t old;
990 uint_t offset;
991 int result;
992
993 hal = (s1394_hal_t *)req->cmd_callback_arg;
994
995 /* IRM register offset */
996 offset = (req->cmd_addr & IEEE1394_CSR_OFFSET_MASK);
997
998 /* Verify that request is quadlet aligned */
999 if ((offset & 0x3) != 0) {
1000 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
1001 (void) s1394_send_response(hal, req);
1002 return;
1003 }
1004
1005 switch (req->cmd_type) {
1006 case CMD1394_ASYNCH_RD_QUAD:
1007 /*
1008 * The csr_read() call can return DDI_FAILURE if the HAL
1009 * is shutdown or if the register at "offset" is
1010 * unimplemented. In many cases these registers will
1011 * have been implemented in HW. We are not likely to ever
1012 * receive this callback. If we do, though, we will
1013 * return IEEE1394_RESP_ADDRESS_ERROR when we get an error
1014 * and IEEE1394_RESP_COMPLETE for success.
1015 */
1016 result = HAL_CALL(hal).csr_read(hal->halinfo.hal_private,
1017 offset, &data);
1018 if (result == DDI_SUCCESS) {
1019 req->cmd_u.q.quadlet_data = data;
1020 req->cmd_result = IEEE1394_RESP_COMPLETE;
1021 } else {
1022 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR;
1023 }
1024 break;
1025
1026 case CMD1394_ASYNCH_LOCK_32:
1027 mutex_enter(&hal->topology_tree_mutex);
1028 generation = hal->generation_count;
1029 mutex_exit(&hal->topology_tree_mutex);
1030 if (req->cmd_u.l32.lock_type == CMD1394_LOCK_COMPARE_SWAP) {
1031 compare = req->cmd_u.l32.arg_value;
1032 swap = req->cmd_u.l32.data_value;
1033 /*
1034 * The csr_cswap32() call can return DDI_FAILURE if
1035 * the HAL is shutdown, if the register at "offset"
1036 * is unimplemented, or if the generation has changed.
1037 * In the last case, it shouldn't matter because the
1038 * call to s1394_send_response will fail on a bad
1039 * generation and the command will be freed.
1040 */
1041 result = HAL_CALL(hal).csr_cswap32(
1042 hal->halinfo.hal_private, generation,
1043 offset, compare, swap, &old);
1044 if (result == DDI_SUCCESS) {
1045 req->cmd_u.l32.old_value = old;
1046 req->cmd_result = IEEE1394_RESP_COMPLETE;
1047 } else {
1048 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR;
1049 }
1050 break;
1051 } else {
1052 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
1053 }
1054
1055 break;
1056
1057 default:
1058 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
1059 }
1060
1061 (void) s1394_send_response(hal, req);
1062 }
1063
1064 /*
1065 * s1394_CSR_topology_map()
1066 * handles all request for the TOPOLOGY_MAP[]. Since it is implemented
1067 * with backing store, there isn't much to do besides return success or
1068 * failure.
1069 */
1070 static void
s1394_CSR_topology_map(cmd1394_cmd_t * req)1071 s1394_CSR_topology_map(cmd1394_cmd_t *req)
1072 {
1073 s1394_hal_t *hal;
1074
1075 hal = (s1394_hal_t *)req->cmd_callback_arg;
1076
1077 /* Make sure it's a quadlet read request */
1078 if (req->cmd_type == CMD1394_ASYNCH_RD_QUAD)
1079 req->cmd_result = IEEE1394_RESP_COMPLETE;
1080 else
1081 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
1082
1083 (void) s1394_send_response(hal, req);
1084 }
1085
1086 /*
1087 * s1394_CSR_topology_map_update()
1088 * is used to update the local host's TOPOLOGY_MAP[] buffer. It copies in
1089 * the SelfID packets, updates the generation and other fields, and
1090 * computes the necessary CRC values before returning.
1091 * Callers must be holding the topology_tree_mutex.
1092 */
1093 void
s1394_CSR_topology_map_update(s1394_hal_t * hal)1094 s1394_CSR_topology_map_update(s1394_hal_t *hal)
1095 {
1096 s1394_selfid_pkt_t *selfid_packet;
1097 uint32_t *tm_ptr;
1098 uint32_t *data_ptr;
1099 uint32_t node_count;
1100 uint32_t self_id_count;
1101 uint_t CRC;
1102 uint32_t length;
1103 int i, j, c;
1104
1105 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
1106
1107 tm_ptr = (uint32_t *)hal->CSR_topology_map;
1108 data_ptr = (uint32_t *)&(tm_ptr[3]);
1109
1110 c = 0;
1111 for (i = 0; i < hal->number_of_nodes; i++) {
1112 j = -1;
1113 selfid_packet = hal->selfid_ptrs[i];
1114
1115 do {
1116 j++;
1117 data_ptr[c++] = selfid_packet[j].spkt_data;
1118 }
1119 while (IEEE1394_SELFID_ISMORE(&selfid_packet[j]));
1120 }
1121
1122 /* Update Topology Map Generation */
1123 tm_ptr[1] = tm_ptr[1] + 1;
1124
1125 /* Update Node_Count and Self_Id_Count */
1126 node_count = (i & IEEE1394_TOP_MAP_LEN_MASK);
1127 self_id_count = (c & IEEE1394_TOP_MAP_LEN_MASK);
1128 tm_ptr[2] = (node_count << IEEE1394_TOP_MAP_LEN_SHIFT) |
1129 (self_id_count);
1130
1131 /* Calculate CRC-16 */
1132 length = self_id_count + 2;
1133 CRC = s1394_CRC16(&(tm_ptr[1]), length);
1134 tm_ptr[0] = (length << IEEE1394_TOP_MAP_LEN_SHIFT) | CRC;
1135 }
1136
1137 /*
1138 * s1394_CSR_topology_map_disable()
1139 * is used to disable the local host's TOPOLOGY_MAP[] buffer (during bus
1140 * reset processing). It sets the topology map's length to zero to
1141 * indicate that it is invalid.
1142 */
1143 void
s1394_CSR_topology_map_disable(s1394_hal_t * hal)1144 s1394_CSR_topology_map_disable(s1394_hal_t *hal)
1145 {
1146 uint32_t *tm_ptr;
1147
1148 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
1149
1150 tm_ptr = (uint32_t *)hal->CSR_topology_map;
1151
1152 /* Set length = 0 */
1153 tm_ptr[0] = tm_ptr[0] & IEEE1394_TOP_MAP_LEN_MASK;
1154 }
1155
1156 /*
1157 * s1394_common_CSR_routine()
1158 * is used to handle most of the CSR register requests. They are passed
1159 * to the appropriate HAL entry point for further processing. Then they
1160 * are filled in with an appropriate response code, and the response is sent.
1161 */
1162 static void
s1394_common_CSR_routine(s1394_hal_t * hal,cmd1394_cmd_t * req)1163 s1394_common_CSR_routine(s1394_hal_t *hal, cmd1394_cmd_t *req)
1164 {
1165 uint32_t data;
1166 uint_t offset;
1167 int result;
1168
1169 /* Register offset */
1170 offset = (req->cmd_addr & IEEE1394_CSR_OFFSET_MASK);
1171
1172 /* Verify that request is quadlet aligned */
1173 if ((offset & 0x3) != 0) {
1174 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
1175 (void) s1394_send_response(hal, req);
1176 }
1177
1178 switch (req->cmd_type) {
1179 case CMD1394_ASYNCH_RD_QUAD:
1180 /*
1181 * The csr_read() call can return DDI_FAILURE if the HAL
1182 * is shutdown or if the register at "offset" is
1183 * unimplemented. We will return IEEE1394_RESP_ADDRESS_ERROR
1184 * in the response if we see this error.
1185 */
1186 result = HAL_CALL(hal).csr_read(hal->halinfo.hal_private,
1187 offset, &data);
1188 if (result == DDI_SUCCESS) {
1189 req->cmd_u.q.quadlet_data = data;
1190 req->cmd_result = IEEE1394_RESP_COMPLETE;
1191 } else {
1192 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR;
1193 }
1194 break;
1195
1196 case CMD1394_ASYNCH_WR_QUAD:
1197 data = req->cmd_u.q.quadlet_data;
1198 /*
1199 * The csr_read() call can return DDI_FAILURE if the HAL
1200 * is shutdown or if the register at "offset" is
1201 * unimplemented. We will return IEEE1394_RESP_ADDRESS_ERROR
1202 * in the response if we see this error.
1203 */
1204 result = HAL_CALL(hal).csr_write(hal->halinfo.hal_private,
1205 offset, data);
1206 if (result == DDI_SUCCESS) {
1207 req->cmd_result = IEEE1394_RESP_COMPLETE;
1208 } else {
1209 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR;
1210 }
1211 break;
1212
1213 default:
1214 req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
1215 }
1216
1217 (void) s1394_send_response(hal, req);
1218 }
1219
1220 /*
1221 * s1394_init_local_config_rom()
1222 * is called in the HAL attach routine - h1394_attach() - to setup the
1223 * initial Config ROM entries on the local host, including the
1224 * bus_info_block and the root and unit directories.
1225 */
1226 int
s1394_init_local_config_rom(s1394_hal_t * hal)1227 s1394_init_local_config_rom(s1394_hal_t *hal)
1228 {
1229 uint32_t *config_rom;
1230 uint32_t *node_unique_id_leaf;
1231 uint32_t *unit_dir;
1232 uint32_t *text_leaf;
1233 void *n_handle;
1234 uint64_t guid;
1235 uint32_t guid_hi, guid_lo;
1236 uint32_t bus_capabilities;
1237 uint32_t irmc, g;
1238 uint32_t module_vendor_id;
1239 uint32_t node_capabilities;
1240 uint32_t root_dir_len;
1241 uint32_t CRC;
1242 int status, i, ret;
1243
1244 /* Setup Config ROM mutex */
1245 mutex_init(&hal->local_config_rom_mutex,
1246 NULL, MUTEX_DRIVER, hal->halinfo.hw_interrupt);
1247
1248 /* Allocate 1K for the Config ROM buffer */
1249 hal->local_config_rom = (uint32_t *)kmem_zalloc(IEEE1394_CONFIG_ROM_SZ,
1250 KM_SLEEP);
1251
1252 /* Allocate 1K for the temporary buffer */
1253 hal->temp_config_rom_buf = (uint32_t *)kmem_zalloc(
1254 IEEE1394_CONFIG_ROM_SZ, KM_SLEEP);
1255
1256 config_rom = hal->local_config_rom;
1257
1258 /* Lock the Config ROM buffer */
1259 mutex_enter(&hal->local_config_rom_mutex);
1260
1261 /* Build the config ROM structures */
1262 ret = s1394_init_config_rom_structures(hal);
1263 if (ret != DDI_SUCCESS) {
1264 /* Unlock the Config ROM buffer */
1265 mutex_exit(&hal->local_config_rom_mutex);
1266 kmem_free((void *)hal->temp_config_rom_buf,
1267 IEEE1394_CONFIG_ROM_SZ);
1268 kmem_free((void *)hal->local_config_rom,
1269 IEEE1394_CONFIG_ROM_SZ);
1270 mutex_destroy(&hal->local_config_rom_mutex);
1271 return (DDI_FAILURE);
1272 }
1273 /* Build the Bus_Info_Block - see IEEE 1394-1995, Section 8.3.2.5.4 */
1274 bus_capabilities = hal->halinfo.bus_capabilities;
1275
1276 /*
1277 * If we are Isoch Resource Manager capable then we are
1278 * Bus Manager capable too.
1279 */
1280 irmc = (bus_capabilities & IEEE1394_BIB_IRMC_MASK) >>
1281 IEEE1394_BIB_IRMC_SHIFT;
1282 if (irmc)
1283 bus_capabilities = bus_capabilities | IEEE1394_BIB_BMC_MASK;
1284
1285 /*
1286 * Set generation to P1394a valid (but changeable)
1287 * Even if we have a 1995 PHY, we will still provide
1288 * certain P1394A functionality (especially with respect
1289 * to Config ROM updates). So we must publish this
1290 * information.
1291 */
1292 g = 2 << IEEE1394_BIB_GEN_SHIFT;
1293 bus_capabilities = bus_capabilities | g;
1294
1295 /* Get the GUID */
1296 guid = hal->halinfo.guid;
1297 guid_hi = (uint32_t)(guid >> 32);
1298 guid_lo = (uint32_t)(guid & 0x00000000FFFFFFFF);
1299
1300 config_rom[1] = 0x31333934; /* "1394" */
1301 config_rom[2] = bus_capabilities;
1302 config_rom[3] = guid_hi;
1303 config_rom[4] = guid_lo;
1304
1305 /* The CRC covers only our Bus_Info_Block */
1306 CRC = s1394_CRC16(&config_rom[1], 4);
1307 config_rom[0] = (0x04040000) | CRC;
1308
1309 /* Do byte-swapping if necessary (x86) */
1310 for (i = 0; i < IEEE1394_BIB_QUAD_SZ; i++)
1311 config_rom[i] = T1394_DATA32(config_rom[i]);
1312
1313 /* Build the Root_Directory - see IEEE 1394-1995, Section 8.3.2.5.5 */
1314
1315 /* MODULE_VENDOR_ID - see IEEE 1394-1995, Section 8.3.2.5.5.1 */
1316 module_vendor_id = S1394_SUNW_OUI;
1317
1318 /* NODE_CAPABILITIES - see IEEE 1394-1995, Section 8.3.2.5.5.2 */
1319 node_capabilities = hal->halinfo.node_capabilities &
1320 IEEE1212_NODE_CAPABILITIES_MASK;
1321 root_dir_len = 2;
1322
1323 config_rom[6] = (IEEE1212_MODULE_VENDOR_ID <<
1324 IEEE1212_KEY_VALUE_SHIFT) | module_vendor_id;
1325 config_rom[7] = (IEEE1212_NODE_CAPABILITIES <<
1326 IEEE1212_KEY_VALUE_SHIFT) | node_capabilities;
1327
1328 CRC = s1394_CRC16(&config_rom[6], root_dir_len);
1329 config_rom[IEEE1394_BIB_QUAD_SZ] =
1330 (root_dir_len << IEEE1394_CFG_ROM_LEN_SHIFT) | CRC;
1331
1332 /* Do byte-swapping if necessary (x86) */
1333 for (i = IEEE1394_BIB_QUAD_SZ; i < 8; i++)
1334 config_rom[i] = T1394_DATA32(config_rom[i]);
1335
1336 /* Build the Root Text leaf - see IEEE 1394-1995, Section 8.3.2.5.7 */
1337 text_leaf = (uint32_t *)kmem_zalloc(S1394_ROOT_TEXT_LEAF_SZ, KM_SLEEP);
1338 text_leaf[1] = 0x00000000;
1339 text_leaf[2] = 0x00000000;
1340 text_leaf[3] = 0x53756e20; /* "Sun " */
1341 text_leaf[4] = 0x4d696372; /* "Micr" */
1342 text_leaf[5] = 0x6f737973; /* "osys" */
1343 text_leaf[6] = 0x74656d73; /* "tems" */
1344 text_leaf[7] = 0x2c20496e; /* ", In" */
1345 text_leaf[8] = 0x632e0000; /* "c." */
1346 CRC = s1394_CRC16(&text_leaf[1], S1394_ROOT_TEXT_LEAF_QUAD_SZ - 1);
1347 text_leaf[0] = (0x00080000) | CRC;
1348
1349 /* Do byte-swapping if necessary (x86) */
1350 for (i = 0; i < 9; i++)
1351 text_leaf[i] = T1394_DATA32(text_leaf[i]);
1352
1353 ret = s1394_add_config_rom_entry(hal, S1394_ROOT_TEXT_KEY, text_leaf,
1354 S1394_ROOT_TEXT_LEAF_QUAD_SZ, &n_handle, &status);
1355 if (ret != DDI_SUCCESS) {
1356 kmem_free((void *)text_leaf, S1394_ROOT_TEXT_LEAF_SZ);
1357 /* Destroy the config_rom structures */
1358 (void) s1394_destroy_config_rom_structures(hal);
1359 /* Unlock the Config ROM buffer */
1360 mutex_exit(&hal->local_config_rom_mutex);
1361 kmem_free((void *)hal->temp_config_rom_buf,
1362 IEEE1394_CONFIG_ROM_SZ);
1363 kmem_free((void *)hal->local_config_rom,
1364 IEEE1394_CONFIG_ROM_SZ);
1365 mutex_destroy(&hal->local_config_rom_mutex);
1366 return (DDI_FAILURE);
1367 }
1368 kmem_free((void *)text_leaf, S1394_ROOT_TEXT_LEAF_SZ);
1369
1370 /* Build the Node_Unique_Id leaf - IEEE 1394-1995, Sect. 8.3.2.5.7.1 */
1371 node_unique_id_leaf = (uint32_t *)kmem_zalloc(S1394_NODE_UNIQUE_ID_SZ,
1372 KM_SLEEP);
1373 node_unique_id_leaf[1] = guid_hi;
1374 node_unique_id_leaf[2] = guid_lo;
1375 CRC = s1394_CRC16(&node_unique_id_leaf[1],
1376 S1394_NODE_UNIQUE_ID_QUAD_SZ - 1);
1377 node_unique_id_leaf[0] = (0x00020000) | CRC;
1378
1379 /* Do byte-swapping if necessary (x86) */
1380 for (i = 0; i < S1394_NODE_UNIQUE_ID_QUAD_SZ; i++)
1381 node_unique_id_leaf[i] = T1394_DATA32(node_unique_id_leaf[i]);
1382
1383 ret = s1394_add_config_rom_entry(hal, S1394_NODE_UNIQUE_ID_KEY,
1384 node_unique_id_leaf, S1394_NODE_UNIQUE_ID_QUAD_SZ, &n_handle,
1385 &status);
1386 if (ret != DDI_SUCCESS) {
1387 kmem_free((void *)node_unique_id_leaf,
1388 S1394_NODE_UNIQUE_ID_SZ);
1389 /* Destroy the config_rom structures */
1390 (void) s1394_destroy_config_rom_structures(hal);
1391 /* Unlock the Config ROM buffer */
1392 mutex_exit(&hal->local_config_rom_mutex);
1393 kmem_free((void *)hal->temp_config_rom_buf,
1394 IEEE1394_CONFIG_ROM_SZ);
1395 kmem_free((void *)hal->local_config_rom,
1396 IEEE1394_CONFIG_ROM_SZ);
1397 mutex_destroy(&hal->local_config_rom_mutex);
1398 return (DDI_FAILURE);
1399 }
1400 kmem_free((void *)node_unique_id_leaf, S1394_NODE_UNIQUE_ID_SZ);
1401
1402 /* Build the Unit_Directory for 1394 Framework */
1403 unit_dir = (uint32_t *)kmem_zalloc(S1394_UNIT_DIR_SZ, KM_SLEEP);
1404 unit_dir[1] = 0x12080020; /* Sun Microsystems */
1405 unit_dir[2] = 0x13000001; /* Version 1 */
1406 unit_dir[3] = 0x81000001; /* offset to the text leaf */
1407 CRC = s1394_CRC16(&unit_dir[1], 3);
1408 unit_dir[0] = (0x00030000) | CRC;
1409
1410 /* Do byte-swapping if necessary (x86) */
1411 for (i = 0; i < 4; i++)
1412 unit_dir[i] = T1394_DATA32(unit_dir[i]);
1413
1414 /* Build the Unit Directory text leaf */
1415 unit_dir[5] = 0x00000000;
1416 unit_dir[6] = 0x00000000;
1417 unit_dir[7] = 0x536f6c61; /* "Sola" */
1418 unit_dir[8] = 0x72697320; /* "ris " */
1419 unit_dir[9] = 0x31333934; /* "1394" */
1420 unit_dir[10] = 0x20535720; /* " SW " */
1421 unit_dir[11] = 0x4672616d; /* "Fram" */
1422 unit_dir[12] = 0x65576f72; /* "ewor" */
1423 unit_dir[13] = 0x6b000000; /* "k" */
1424 CRC = s1394_CRC16(&unit_dir[5], 9);
1425 unit_dir[4] = (0x00090000) | CRC;
1426
1427 /* Do byte-swapping if necessary (x86) */
1428 for (i = 4; i < S1394_UNIT_DIR_QUAD_SZ; i++)
1429 unit_dir[i] = T1394_DATA32(unit_dir[i]);
1430
1431 ret = s1394_add_config_rom_entry(hal, S1394_UNIT_DIR_KEY, unit_dir,
1432 S1394_UNIT_DIR_QUAD_SZ, &n_handle, &status);
1433 if (ret != DDI_SUCCESS) {
1434 kmem_free((void *)unit_dir, S1394_UNIT_DIR_SZ);
1435 /* Destroy the config_rom structures */
1436 (void) s1394_destroy_config_rom_structures(hal);
1437 /* Unlock the Config ROM buffer */
1438 mutex_exit(&hal->local_config_rom_mutex);
1439 kmem_free((void *)hal->temp_config_rom_buf,
1440 IEEE1394_CONFIG_ROM_SZ);
1441 /* Free the 1K for the Config ROM buffer */
1442 kmem_free((void *)hal->local_config_rom,
1443 IEEE1394_CONFIG_ROM_SZ);
1444 mutex_destroy(&hal->local_config_rom_mutex);
1445 return (DDI_FAILURE);
1446 }
1447 kmem_free((void *)unit_dir, S1394_UNIT_DIR_SZ);
1448
1449 hal->config_rom_update_amount = (IEEE1394_CONFIG_ROM_QUAD_SZ -
1450 hal->free_space);
1451
1452 /* Unlock the Config ROM buffer */
1453 mutex_exit(&hal->local_config_rom_mutex);
1454
1455 /*
1456 * The update_config_rom() call can return DDI_FAILURE if the
1457 * HAL is shutdown.
1458 */
1459 (void) HAL_CALL(hal).update_config_rom(hal->halinfo.hal_private,
1460 config_rom, IEEE1394_CONFIG_ROM_QUAD_SZ);
1461
1462 return (DDI_SUCCESS);
1463 }
1464
1465 /*
1466 * s1394_destroy_local_config_rom()
1467 * is necessary for h1394_detach(). It undoes all the work that
1468 * s1394_init_local_config_rom() had setup and more. By pulling
1469 * everything out of the conig rom structures and freeing them and their
1470 * associated mutexes, the Config ROM is completely cleaned up.
1471 */
1472 void
s1394_destroy_local_config_rom(s1394_hal_t * hal)1473 s1394_destroy_local_config_rom(s1394_hal_t *hal)
1474 {
1475 /* Lock the Config ROM buffer */
1476 mutex_enter(&hal->local_config_rom_mutex);
1477
1478 /* Destroy the config_rom structures */
1479 (void) s1394_destroy_config_rom_structures(hal);
1480
1481 /* Unlock the Config ROM buffer */
1482 mutex_exit(&hal->local_config_rom_mutex);
1483
1484 /* Free the 1K for the temporary buffer */
1485 kmem_free((void *)hal->temp_config_rom_buf, IEEE1394_CONFIG_ROM_SZ);
1486 /* Free the 1K for the Config ROM buffer */
1487 kmem_free((void *)hal->local_config_rom, IEEE1394_CONFIG_ROM_SZ);
1488
1489 /* Setup Config ROM mutex */
1490 mutex_destroy(&hal->local_config_rom_mutex);
1491 }
1492
1493 /*
1494 * s1394_init_config_rom_structures()
1495 * initializes the structures that are used to maintain the local Config ROM.
1496 * Callers must be holding the local_config_rom_mutex.
1497 */
1498 static int
s1394_init_config_rom_structures(s1394_hal_t * hal)1499 s1394_init_config_rom_structures(s1394_hal_t *hal)
1500 {
1501 s1394_config_rom_t *root_directory;
1502 s1394_config_rom_t *rest_of_config_rom;
1503
1504 ASSERT(MUTEX_HELD(&hal->local_config_rom_mutex));
1505
1506 root_directory = (s1394_config_rom_t *)kmem_zalloc(
1507 sizeof (s1394_config_rom_t), KM_SLEEP);
1508
1509 root_directory->cfgrom_used = B_TRUE;
1510 root_directory->cfgrom_addr_lo = IEEE1394_BIB_QUAD_SZ;
1511 root_directory->cfgrom_addr_hi = IEEE1394_BIB_QUAD_SZ + 2;
1512
1513 rest_of_config_rom = (s1394_config_rom_t *)kmem_zalloc(
1514 sizeof (s1394_config_rom_t), KM_SLEEP);
1515
1516 rest_of_config_rom->cfgrom_used = B_FALSE;
1517 rest_of_config_rom->cfgrom_addr_lo = root_directory->cfgrom_addr_hi + 1;
1518 rest_of_config_rom->cfgrom_addr_hi = IEEE1394_CONFIG_ROM_QUAD_SZ - 1;
1519
1520 root_directory->cfgrom_next = rest_of_config_rom;
1521 root_directory->cfgrom_prev = NULL;
1522 rest_of_config_rom->cfgrom_next = NULL;
1523 rest_of_config_rom->cfgrom_prev = root_directory;
1524
1525 hal->root_directory = root_directory;
1526 hal->free_space = IEEE1394_CONFIG_ROM_QUAD_SZ -
1527 (rest_of_config_rom->cfgrom_addr_lo);
1528
1529 return (DDI_SUCCESS);
1530 }
1531
1532 /*
1533 * s1394_destroy_config_rom_structures()
1534 * is used to destroy the structures that maintain the local Config ROM.
1535 * Callers must be holding the local_config_rom_mutex.
1536 */
1537 static int
s1394_destroy_config_rom_structures(s1394_hal_t * hal)1538 s1394_destroy_config_rom_structures(s1394_hal_t *hal)
1539 {
1540 s1394_config_rom_t *curr_blk;
1541 s1394_config_rom_t *next_blk;
1542
1543 ASSERT(MUTEX_HELD(&hal->local_config_rom_mutex));
1544
1545 curr_blk = hal->root_directory;
1546
1547 while (curr_blk != NULL) {
1548 next_blk = curr_blk->cfgrom_next;
1549 kmem_free(curr_blk, sizeof (s1394_config_rom_t));
1550 curr_blk = next_blk;
1551 }
1552
1553 return (DDI_SUCCESS);
1554 }
1555
1556 /*
1557 * s1394_add_config_rom_entry()
1558 * is used to add a new entry to the local host's config ROM. By
1559 * specifying a key and a buffer, it is possible to update the Root
1560 * Directory to point to the new entry (in buffer). Additionally, all
1561 * of the relevant CRCs, lengths, and generations are updated as well.
1562 * By returning a Config ROM "handle", we can allow targets to remove
1563 * the corresponding entry.
1564 * Callers must be holding the local_config_rom_mutex.
1565 */
1566 int
s1394_add_config_rom_entry(s1394_hal_t * hal,uint8_t key,uint32_t * buffer,uint_t size,void ** handle,int * status)1567 s1394_add_config_rom_entry(s1394_hal_t *hal, uint8_t key, uint32_t *buffer,
1568 uint_t size, void **handle, int *status)
1569 {
1570 s1394_config_rom_t *curr_blk;
1571 s1394_config_rom_t *new_blk;
1572 uint32_t *config_rom;
1573 uint32_t *temp_buf;
1574 uint32_t CRC;
1575 uint_t tmp_offset;
1576 uint_t tmp_size, temp;
1577 uint_t last_entry_offset;
1578 int i;
1579
1580 ASSERT(MUTEX_HELD(&hal->local_config_rom_mutex));
1581
1582 if (size > hal->free_space) {
1583 /* Out of space */
1584 *status = CMD1394_ERSRC_CONFLICT;
1585 return (DDI_FAILURE);
1586 }
1587
1588 config_rom = hal->local_config_rom;
1589 temp_buf = hal->temp_config_rom_buf;
1590
1591 /* Copy the Bus_Info_Block */
1592 bcopy(&config_rom[0], &temp_buf[0], IEEE1394_BIB_SZ);
1593
1594 /* Copy and add to the Root_Directory */
1595 tmp_offset = hal->root_directory->cfgrom_addr_lo;
1596 tmp_size = (hal->root_directory->cfgrom_addr_hi - tmp_offset) + 1;
1597 tmp_size = tmp_size + 1; /* For the new entry */
1598 bcopy(&config_rom[tmp_offset], &temp_buf[tmp_offset], tmp_size << 2);
1599 last_entry_offset = hal->root_directory->cfgrom_addr_hi + 1;
1600
1601 curr_blk = hal->root_directory;
1602 curr_blk->cfgrom_addr_hi = curr_blk->cfgrom_addr_hi + 1;
1603 while (curr_blk->cfgrom_next != NULL) {
1604 if (curr_blk->cfgrom_next->cfgrom_used == B_TRUE) {
1605 tmp_offset = curr_blk->cfgrom_next->cfgrom_addr_lo;
1606 tmp_size = (curr_blk->cfgrom_next->cfgrom_addr_hi -
1607 tmp_offset) + 1;
1608
1609 bcopy(&config_rom[tmp_offset],
1610 &temp_buf[tmp_offset + 1], tmp_size << 2);
1611 curr_blk->cfgrom_next->cfgrom_addr_lo++;
1612 curr_blk->cfgrom_next->cfgrom_addr_hi++;
1613 last_entry_offset =
1614 curr_blk->cfgrom_next->cfgrom_addr_hi;
1615
1616 tmp_offset = curr_blk->cfgrom_next->root_dir_offset;
1617
1618 /* Swap... add one... then unswap */
1619 temp = T1394_DATA32(temp_buf[tmp_offset]);
1620 temp++;
1621 temp_buf[tmp_offset] = T1394_DATA32(temp);
1622 } else {
1623 curr_blk->cfgrom_next->cfgrom_addr_lo++;
1624 hal->free_space--;
1625 break;
1626 }
1627
1628 curr_blk = curr_blk->cfgrom_next;
1629 }
1630
1631 /* Get the pointer to the "free" space */
1632 curr_blk = curr_blk->cfgrom_next;
1633
1634 /* Is it an exact fit? */
1635 if (hal->free_space == size) {
1636 curr_blk->cfgrom_used = B_TRUE;
1637
1638 } else { /* Must break this piece */
1639 new_blk = (s1394_config_rom_t *)kmem_zalloc(
1640 sizeof (s1394_config_rom_t), KM_SLEEP);
1641 if (new_blk == NULL) {
1642 return (DDI_FAILURE);
1643 }
1644
1645 new_blk->cfgrom_addr_hi = curr_blk->cfgrom_addr_hi;
1646 new_blk->cfgrom_addr_lo = curr_blk->cfgrom_addr_lo + size;
1647 curr_blk->cfgrom_addr_hi = new_blk->cfgrom_addr_lo - 1;
1648 new_blk->cfgrom_next = curr_blk->cfgrom_next;
1649 curr_blk->cfgrom_next = new_blk;
1650 new_blk->cfgrom_prev = curr_blk;
1651 curr_blk->cfgrom_used = B_TRUE;
1652 last_entry_offset = curr_blk->cfgrom_addr_hi;
1653 }
1654 hal->free_space = hal->free_space - size;
1655
1656 /* Copy in the new entry */
1657 tmp_offset = curr_blk->cfgrom_addr_lo;
1658 bcopy(buffer, &temp_buf[tmp_offset], size << 2);
1659
1660 /* Update root directory */
1661 tmp_offset = hal->root_directory->cfgrom_addr_hi;
1662 tmp_size = tmp_offset - hal->root_directory->cfgrom_addr_lo;
1663 curr_blk->root_dir_offset = tmp_offset;
1664 tmp_offset = curr_blk->cfgrom_addr_lo - tmp_offset;
1665
1666 temp_buf[hal->root_directory->cfgrom_addr_hi] =
1667 T1394_DATA32((((uint32_t)key) << IEEE1212_KEY_VALUE_SHIFT) |
1668 tmp_offset);
1669 tmp_offset = hal->root_directory->cfgrom_addr_lo;
1670
1671 /* Do byte-swapping if necessary (x86) */
1672 for (i = (tmp_offset + 1); i <= hal->root_directory->cfgrom_addr_hi;
1673 i++)
1674 temp_buf[i] = T1394_DATA32(temp_buf[i]);
1675
1676 CRC = s1394_CRC16(&temp_buf[tmp_offset + 1], tmp_size);
1677 temp_buf[tmp_offset] = (tmp_size << IEEE1394_CFG_ROM_LEN_SHIFT) | CRC;
1678
1679 /* Redo byte-swapping if necessary (x86) */
1680 for (i = tmp_offset; i <= hal->root_directory->cfgrom_addr_hi; i++)
1681 temp_buf[i] = T1394_DATA32(temp_buf[i]);
1682
1683 /* Copy it back to config_rom buffer */
1684 last_entry_offset++;
1685 bcopy(&temp_buf[0], &config_rom[0], last_entry_offset << 2);
1686
1687 /* Return a handle to this block */
1688 *handle = curr_blk;
1689
1690 *status = T1394_NOERROR;
1691
1692 return (DDI_SUCCESS);
1693 }
1694
1695 /*
1696 * s1394_remove_config_rom_entry()
1697 * is used to remove an entry from the local host's config ROM. By
1698 * specifying the Config ROM "handle" that was given in the allocation,
1699 * it is possible to remove the entry. Subsequently, the Config ROM is
1700 * updated again.
1701 * Callers must be holding the local_config_rom_mutex.
1702 */
1703 int
s1394_remove_config_rom_entry(s1394_hal_t * hal,void ** handle,int * status)1704 s1394_remove_config_rom_entry(s1394_hal_t *hal, void **handle, int *status)
1705 {
1706 s1394_config_rom_t *del_blk;
1707 s1394_config_rom_t *curr_blk;
1708 s1394_config_rom_t *last_blk;
1709 s1394_config_rom_t *free_blk;
1710 uint32_t *config_rom;
1711 uint32_t *temp_buf;
1712 uint32_t entry;
1713 uint_t CRC;
1714 uint_t root_offset;
1715 uint_t del_offset;
1716 uint_t tmp_offset;
1717 uint_t tmp_size;
1718 int i;
1719
1720 ASSERT(MUTEX_HELD(&hal->local_config_rom_mutex));
1721
1722 del_blk = (s1394_config_rom_t *)(*handle);
1723
1724 config_rom = hal->local_config_rom;
1725 temp_buf = hal->temp_config_rom_buf;
1726
1727 /* Copy the Bus_Info_Block */
1728 bcopy(&config_rom[0], &temp_buf[0], IEEE1394_BIB_SZ);
1729
1730 root_offset = hal->root_directory->cfgrom_addr_lo;
1731 del_offset = del_blk->root_dir_offset;
1732
1733 /* Update Root_Directory entries before the deleted one */
1734 for (i = root_offset; i < del_offset; i++) {
1735 entry = T1394_DATA32(config_rom[i]);
1736
1737 /* If entry is an offset address - update it */
1738 if (entry & 0x80000000)
1739 temp_buf[i] = T1394_DATA32(entry - 1);
1740 else
1741 temp_buf[i] = T1394_DATA32(entry);
1742 }
1743
1744 /* Move all Unit_Directories prior to the deleted one */
1745 curr_blk = hal->root_directory->cfgrom_next;
1746
1747 while (curr_blk != del_blk) {
1748 tmp_offset = curr_blk->cfgrom_addr_lo;
1749 tmp_size = (curr_blk->cfgrom_addr_hi - tmp_offset) + 1;
1750
1751 bcopy(&config_rom[tmp_offset], &temp_buf[tmp_offset - 1],
1752 tmp_size << 2);
1753 curr_blk->cfgrom_addr_lo--;
1754 curr_blk->cfgrom_addr_hi--;
1755 curr_blk = curr_blk->cfgrom_next;
1756 }
1757
1758 /* Move all Unit_Directories after the deleted one */
1759 curr_blk = del_blk->cfgrom_next;
1760 last_blk = del_blk->cfgrom_prev;
1761
1762 del_offset = (del_blk->cfgrom_addr_hi - del_blk->cfgrom_addr_lo) + 1;
1763
1764 while ((curr_blk != NULL) && (curr_blk->cfgrom_used == B_TRUE)) {
1765 tmp_offset = curr_blk->cfgrom_addr_lo;
1766 tmp_size = (curr_blk->cfgrom_addr_hi - tmp_offset) + 1;
1767
1768 bcopy(&config_rom[tmp_offset],
1769 &temp_buf[tmp_offset - (del_offset + 1)], tmp_size << 2);
1770
1771 root_offset = curr_blk->root_dir_offset;
1772 temp_buf[root_offset - 1] =
1773 config_rom[root_offset] - del_offset;
1774 curr_blk->root_dir_offset--;
1775 curr_blk->cfgrom_addr_lo = curr_blk->cfgrom_addr_lo -
1776 (del_offset + 1);
1777 curr_blk->cfgrom_addr_hi = curr_blk->cfgrom_addr_hi -
1778 (del_offset + 1);
1779
1780 last_blk = curr_blk;
1781 curr_blk = curr_blk->cfgrom_next;
1782 }
1783
1784 /* Remove del_blk from the list */
1785 if (del_blk->cfgrom_prev != NULL)
1786 del_blk->cfgrom_prev->cfgrom_next = del_blk->cfgrom_next;
1787
1788 if (del_blk->cfgrom_next != NULL)
1789 del_blk->cfgrom_next->cfgrom_prev = del_blk->cfgrom_prev;
1790
1791 del_blk->cfgrom_prev = NULL;
1792 del_blk->cfgrom_next = NULL;
1793 kmem_free((void *)del_blk, sizeof (s1394_config_rom_t));
1794
1795 /* Update and zero out the "free" block */
1796 if (curr_blk != NULL) {
1797 curr_blk->cfgrom_addr_lo = curr_blk->cfgrom_addr_lo -
1798 (del_offset + 1);
1799
1800 } else {
1801 free_blk = (s1394_config_rom_t *)kmem_zalloc(
1802 sizeof (s1394_config_rom_t), KM_SLEEP);
1803 if (free_blk == NULL) {
1804 return (DDI_FAILURE);
1805 }
1806
1807 free_blk->cfgrom_used = B_FALSE;
1808 free_blk->cfgrom_addr_lo = (IEEE1394_CONFIG_ROM_QUAD_SZ - 1) -
1809 (del_offset + 1);
1810 free_blk->cfgrom_addr_hi = (IEEE1394_CONFIG_ROM_QUAD_SZ - 1);
1811
1812 free_blk->cfgrom_prev = last_blk;
1813 free_blk->cfgrom_next = NULL;
1814 curr_blk = free_blk;
1815 }
1816 hal->free_space = hal->free_space + (del_offset + 1);
1817 tmp_offset = curr_blk->cfgrom_addr_lo;
1818 tmp_size = (curr_blk->cfgrom_addr_hi - tmp_offset) + 1;
1819 bzero(&temp_buf[tmp_offset], tmp_size << 2);
1820
1821
1822 /* Update root directory */
1823 hal->root_directory->cfgrom_addr_hi--;
1824 tmp_offset = hal->root_directory->cfgrom_addr_lo;
1825 tmp_size = hal->root_directory->cfgrom_addr_hi - tmp_offset;
1826
1827 /* Do byte-swapping if necessary (x86) */
1828 for (i = (tmp_offset + 1); i <= hal->root_directory->cfgrom_addr_hi;
1829 i++)
1830 temp_buf[i] = T1394_DATA32(temp_buf[i]);
1831
1832 CRC = s1394_CRC16(&temp_buf[tmp_offset + 1], tmp_size);
1833 temp_buf[tmp_offset] = (tmp_size << IEEE1394_CFG_ROM_LEN_SHIFT) | CRC;
1834
1835 /* Do byte-swapping if necessary (x86) */
1836 for (i = (tmp_offset + 1); i <= hal->root_directory->cfgrom_addr_hi;
1837 i++)
1838 temp_buf[i] = T1394_DATA32(temp_buf[i]);
1839
1840 /* Copy it back to config_rom buffer */
1841 tmp_size = IEEE1394_CONFIG_ROM_SZ - (hal->free_space << 2);
1842 bcopy(&temp_buf[0], &config_rom[0], tmp_size);
1843
1844 /* Return a handle to this block */
1845 *handle = NULL;
1846
1847 *status = T1394_NOERROR;
1848
1849 return (DDI_SUCCESS);
1850 }
1851
1852 /*
1853 * s1394_update_config_rom_callback()
1854 * is the callback used by t1394_add_cfgrom_entry() and
1855 * t1394_rem_cfgrom_entry(). After a target updates the Config ROM, a
1856 * timer is set with this as its callback function. This is to reduce
1857 * the number of bus resets that would be necessary if many targets
1858 * wished to update the Config ROM simultaneously.
1859 */
1860 void
s1394_update_config_rom_callback(void * arg)1861 s1394_update_config_rom_callback(void *arg)
1862 {
1863 s1394_hal_t *hal;
1864 uint32_t *config_rom;
1865 uint32_t bus_capabilities;
1866 uint32_t g;
1867 uint_t CRC;
1868 uint_t last_entry_offset;
1869 int i;
1870
1871 hal = (s1394_hal_t *)arg;
1872
1873 /* Lock the Config ROM buffer */
1874 mutex_enter(&hal->local_config_rom_mutex);
1875
1876 config_rom = hal->local_config_rom;
1877
1878 /* Update Generation and CRC for Bus_Info_Block */
1879
1880 /* Do byte-swapping if necessary (x86) */
1881 for (i = 0; i < IEEE1394_BIB_QUAD_SZ; i++)
1882 config_rom[i] = T1394_DATA32(config_rom[i]);
1883
1884 bus_capabilities = config_rom[IEEE1212_NODE_CAP_QUAD];
1885 g = ((bus_capabilities & IEEE1394_BIB_GEN_MASK) >>
1886 IEEE1394_BIB_GEN_SHIFT) + 1;
1887 if (g > 15)
1888 g = 2;
1889 g = g << IEEE1394_BIB_GEN_SHIFT;
1890
1891 bus_capabilities = (bus_capabilities & (~IEEE1394_BIB_GEN_MASK)) | g;
1892 config_rom[IEEE1212_NODE_CAP_QUAD] = bus_capabilities;
1893
1894 CRC = s1394_CRC16(&config_rom[1], IEEE1394_BIB_QUAD_SZ - 1);
1895 config_rom[0] = (0x04040000) | CRC;
1896
1897 /* Do byte-swapping if necessary (x86) */
1898 for (i = 0; i < IEEE1394_BIB_QUAD_SZ; i++)
1899 config_rom[i] = T1394_DATA32(config_rom[i]);
1900
1901 /* Make sure we update only what is necessary */
1902 last_entry_offset = (IEEE1394_CONFIG_ROM_QUAD_SZ - hal->free_space);
1903 if (last_entry_offset < hal->config_rom_update_amount)
1904 last_entry_offset = hal->config_rom_update_amount;
1905
1906 hal->config_rom_update_amount = (IEEE1394_CONFIG_ROM_QUAD_SZ -
1907 hal->free_space);
1908
1909 /* Clear the timer flag */
1910 hal->config_rom_timer_set = B_FALSE;
1911
1912 /* Unlock the Config ROM buffer */
1913 mutex_exit(&hal->local_config_rom_mutex);
1914
1915 /*
1916 * The update_config_rom() call can return DDI_FAILURE if the
1917 * HAL is shutdown.
1918 */
1919 (void) HAL_CALL(hal).update_config_rom(hal->halinfo.hal_private,\
1920 config_rom, last_entry_offset);
1921
1922 /* Initiate a bus reset */
1923 (void) HAL_CALL(hal).bus_reset(hal->halinfo.hal_private);
1924 }
1925