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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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