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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * hci1394_attach.c 28 * HBA attach() routine with associated funtions. 29 */ 30 31 #include <sys/types.h> 32 #include <sys/kmem.h> 33 #include <sys/conf.h> 34 #include <sys/ddi.h> 35 #include <sys/modctl.h> 36 #include <sys/stat.h> 37 #include <sys/sunddi.h> 38 #include <sys/cmn_err.h> 39 #include <sys/pci.h> 40 41 #include <sys/1394/h1394.h> 42 #include <sys/1394/adapters/hci1394.h> 43 #include <sys/1394/adapters/hci1394_extern.h> 44 45 46 /* 47 * Attach State Information. These states are used to track the status of the 48 * attach. They are bit offsets. 49 */ 50 #define STATE_ZALLOC 0 51 #define STATE_ISR_INIT 1 52 #define STATE_MINOR_NODE 2 53 #define STATE_HW_INIT 3 54 #define STATE_PHASE2 4 55 #define STATE_POWER_INIT 5 56 #define STATE_H1394_ATTACH 6 57 #define STATE_ISR_HANDLER 7 58 #define STATE_STARTUP 8 59 60 static void hci1394_statebit_set(uint64_t *state, uint_t statebit); 61 static boolean_t hci1394_statebit_tst(uint64_t state, uint_t statebit); 62 63 static void hci1394_cleanup(hci1394_state_t *soft_state, uint64_t attach_state); 64 65 static int hci1394_hardware_init(hci1394_state_t *soft_state); 66 static int hci1394_hardware_resume(hci1394_state_t *soft_state); 67 68 static int hci1394_pci_init(hci1394_state_t *soft_state); 69 static void hci1394_pci_resume(hci1394_state_t *soft_state); 70 71 static void hci1394_soft_state_phase1_init(hci1394_state_t *soft_state, 72 dev_info_t *dip, int instance); 73 static void hci1394_soft_state_phase2_init(hci1394_state_t *soft_state); 74 75 static int hci1394_resmap_get(hci1394_state_t *soft_state); 76 static void hci1394_resmap_free(hci1394_state_t *soft_state); 77 78 79 80 int 81 hci1394_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 82 { 83 hci1394_state_t *soft_state; 84 uint64_t attach_state = 0; 85 int instance; 86 int status; 87 88 switch (cmd) { 89 case DDI_ATTACH: 90 instance = ddi_get_instance(dip); 91 status = ddi_soft_state_zalloc(hci1394_statep, instance); 92 if (status != DDI_SUCCESS) { 93 return (DDI_FAILURE); 94 } 95 soft_state = ddi_get_soft_state(hci1394_statep, instance); 96 if (soft_state == NULL) { 97 ddi_soft_state_free(hci1394_statep, instance); 98 return (DDI_FAILURE); 99 } 100 hci1394_statebit_set(&attach_state, STATE_ZALLOC); 101 102 hci1394_soft_state_phase1_init(soft_state, dip, instance); 103 104 /* get iblock cookie, other interrupt init stuff */ 105 status = hci1394_isr_init(soft_state); 106 if (status != DDI_SUCCESS) { 107 hci1394_cleanup(soft_state, attach_state); 108 return (DDI_FAILURE); 109 } 110 hci1394_statebit_set(&attach_state, STATE_ISR_INIT); 111 112 status = ddi_create_minor_node(dip, "devctl", S_IFCHR, 113 instance, DDI_NT_NEXUS, 0); 114 if (status != DDI_SUCCESS) { 115 hci1394_cleanup(soft_state, attach_state); 116 return (DDI_FAILURE); 117 } 118 hci1394_statebit_set(&attach_state, STATE_MINOR_NODE); 119 120 status = hci1394_hardware_init(soft_state); 121 if (status != DDI_SUCCESS) { 122 hci1394_cleanup(soft_state, attach_state); 123 return (DDI_FAILURE); 124 } 125 hci1394_statebit_set(&attach_state, STATE_HW_INIT); 126 127 hci1394_soft_state_phase2_init(soft_state); 128 hci1394_statebit_set(&attach_state, STATE_PHASE2); 129 130 /* build up the reserved addresses map */ 131 status = hci1394_resmap_get(soft_state); 132 if (status != DDI_SUCCESS) { 133 hci1394_cleanup(soft_state, attach_state); 134 return (DDI_FAILURE); 135 } 136 137 /* "attach" to the Services Layer */ 138 status = h1394_attach(&soft_state->halinfo, DDI_ATTACH, 139 &soft_state->drvinfo.di_sl_private); 140 if (status != DDI_SUCCESS) { 141 hci1394_resmap_free(soft_state); 142 hci1394_cleanup(soft_state, attach_state); 143 return (DDI_FAILURE); 144 } 145 /* free the reserved addresses map */ 146 hci1394_resmap_free(soft_state); 147 148 hci1394_statebit_set(&attach_state, STATE_H1394_ATTACH); 149 status = hci1394_isr_handler_init(soft_state); 150 if (status != DDI_SUCCESS) { 151 hci1394_cleanup(soft_state, attach_state); 152 return (DDI_FAILURE); 153 } 154 hci1394_statebit_set(&attach_state, STATE_ISR_HANDLER); 155 156 /* Report that driver was loaded */ 157 ddi_report_dev(dip); 158 159 /* 160 * Turn on link, Reset Bus, enable interrupts. Should be the 161 * last routine called in attach. The statebit for starup must 162 * be set before startup is called since startup enables 163 * interrupts. 164 */ 165 hci1394_statebit_set(&attach_state, STATE_STARTUP); 166 status = hci1394_ohci_startup(soft_state->ohci); 167 if (status != DDI_SUCCESS) { 168 hci1394_cleanup(soft_state, attach_state); 169 return (DDI_FAILURE); 170 } 171 172 return (DDI_SUCCESS); 173 174 case DDI_RESUME: 175 instance = ddi_get_instance(dip); 176 soft_state = ddi_get_soft_state(hci1394_statep, instance); 177 if (soft_state == NULL) { 178 return (DDI_FAILURE); 179 } 180 181 status = hci1394_hardware_resume(soft_state); 182 if (status != DDI_SUCCESS) { 183 return (DDI_FAILURE); 184 } 185 186 /* 187 * set our state back to initial. The next bus reset were 188 * about to generate will set us in motion. 189 */ 190 soft_state->drvinfo.di_drvstate.ds_state = HCI1394_INITIAL; 191 192 /* turn on the link, enable interrupts, reset the bus */ 193 status = hci1394_ohci_startup(soft_state->ohci); 194 if (status != DDI_SUCCESS) { 195 return (DDI_FAILURE); 196 } 197 198 /* tell the Services Layer that we are resuming */ 199 status = h1394_attach(&soft_state->halinfo, DDI_RESUME, 200 &soft_state->drvinfo.di_sl_private); 201 if (status != DDI_SUCCESS) { 202 return (DDI_FAILURE); 203 } 204 205 return (DDI_SUCCESS); 206 207 default: 208 break; 209 } 210 211 return (DDI_FAILURE); 212 } 213 214 215 /* 216 * hci1394_soft_state_phase1_init() 217 * First part soft_state initialization. This should be called before any 218 * other initialization routines are called. Anything that requires cleanup 219 * on detach or after an attach failure should be setup in phase2 init (i.e. 220 * mutex's, cv's, etc.) 221 */ 222 static void 223 hci1394_soft_state_phase1_init(hci1394_state_t *soft_state, dev_info_t *dip, 224 int instance) 225 { 226 ASSERT(soft_state != NULL); 227 228 soft_state->drvinfo.di_dip = dip; 229 soft_state->drvinfo.di_instance = instance; 230 231 /* current bus generation */ 232 soft_state->drvinfo.di_gencnt = 0; 233 234 soft_state->drvinfo.di_sl_private = NULL; 235 236 /* initialize statistics */ 237 soft_state->drvinfo.di_stats.st_bus_reset_count = 0; 238 soft_state->drvinfo.di_stats.st_selfid_count = 0; 239 soft_state->drvinfo.di_stats.st_phy_isr = 0; 240 soft_state->drvinfo.di_stats.st_phy_loop_err = 0; 241 soft_state->drvinfo.di_stats.st_phy_pwrfail_err = 0; 242 soft_state->drvinfo.di_stats.st_phy_timeout_err = 0; 243 soft_state->drvinfo.di_stats.st_phy_portevt_err = 0; 244 245 soft_state->swap_data = B_FALSE; 246 soft_state->sl_selfid_buf = NULL; 247 248 /* halinfo is what is passed up to the Services Layer */ 249 soft_state->halinfo.hal_private = soft_state; 250 soft_state->halinfo.dip = soft_state->drvinfo.di_dip; 251 soft_state->halinfo.hal_events = hci1394_evts; 252 soft_state->halinfo.max_generation = OHCI_BUSGEN_MAX; 253 soft_state->halinfo.addr_map_num_entries = HCI1394_ADDR_MAP_SIZE; 254 soft_state->halinfo.addr_map = hci1394_addr_map; 255 hci1394_buf_attr_get(&soft_state->halinfo.dma_attr); 256 } 257 258 259 /* 260 * hci1394_soft_state_phase2_init() 261 * Second part of soft_state initialization. This should be called after a 262 * successful hardware_init() and before the call to h1394_attach(). 263 */ 264 static void 265 hci1394_soft_state_phase2_init(hci1394_state_t *soft_state) 266 { 267 ASSERT(soft_state != NULL); 268 269 /* 270 * Setup our initial driver state. This requires the HW iblock 271 * cookie so this must be setup in phase2_init() 272 */ 273 soft_state->drvinfo.di_drvstate.ds_state = HCI1394_INITIAL; 274 mutex_init(&soft_state->drvinfo.di_drvstate.ds_mutex, NULL, 275 MUTEX_DRIVER, soft_state->drvinfo.di_iblock_cookie); 276 277 /* 278 * halinfo.acc_attr tells the services layer what our buffer access 279 * attributes are. drvinfo.di_buf_attr it initialized in pci_init so 280 * this must be setup in phase2_init() 281 */ 282 soft_state->halinfo.acc_attr = soft_state->drvinfo.di_buf_attr; 283 284 /* 285 * halinfo.hw_interrupt tells the services layer what our 286 * iblock_cookie is. drvinfo.di_iblock_cookie is setup in isr_init so 287 * this must be setup in phase2_init() 288 */ 289 soft_state->halinfo.hw_interrupt = soft_state->drvinfo.di_iblock_cookie; 290 291 /* 292 * Read in our node capabilities. Since we are calling into csr 293 * we must have first called hardware_init(). Therefore, this must 294 * be in phase2_init(). 295 */ 296 hci1394_csr_node_capabilities(soft_state->csr, 297 &soft_state->halinfo.node_capabilities); 298 299 /* 300 * Read in our bus capabilities. Since we are calling into ohci 301 * we must have first called hardware_init(). Therefore, this must 302 * be in phase2_init(). 303 */ 304 hci1394_ohci_bus_capabilities(soft_state->ohci, 305 &soft_state->halinfo.bus_capabilities); 306 307 /* 308 * Setup our async command overhead. When a target driver or the ARREQ 309 * engine allocates a command, the services layer will tack on space 310 * for itself and the HAL so we do not have to manage memory for every 311 * command. hal_overhead is how much memory the hal requires to track 312 * an async command. Since we are calling into async we must have first 313 * called hardware_init(). Therefore, this must be in phase2_init(). 314 */ 315 soft_state->halinfo.hal_overhead = hci1394_async_cmd_overhead(); 316 } 317 318 319 /* 320 * hci1394_hardware_init() 321 * Initialize the adapter hardware. This should be called during 322 * the initial attach(). 323 */ 324 static int 325 hci1394_hardware_init(hci1394_state_t *soft_state) 326 { 327 int status; 328 329 330 ASSERT(soft_state != NULL); 331 332 /* Initialize PCI config registers */ 333 status = hci1394_pci_init(soft_state); 334 if (status != DDI_SUCCESS) { 335 return (DDI_FAILURE); 336 } 337 338 /* Initialize the OpenHCI Hardware */ 339 status = hci1394_ohci_init(soft_state, &soft_state->drvinfo, 340 &soft_state->ohci); 341 if (status != DDI_SUCCESS) { 342 hci1394_pci_fini(soft_state); 343 return (DDI_FAILURE); 344 } 345 346 /* Initialize SW based CSR registers */ 347 hci1394_csr_init(&soft_state->drvinfo, soft_state->ohci, 348 &soft_state->csr); 349 350 /* Initialize the Asynchronous Q's */ 351 status = hci1394_async_init(&soft_state->drvinfo, soft_state->ohci, 352 soft_state->csr, &soft_state->async); 353 if (status != DDI_SUCCESS) { 354 hci1394_csr_fini(&soft_state->csr); 355 hci1394_ohci_fini(&soft_state->ohci); 356 hci1394_pci_fini(soft_state); 357 return (DDI_FAILURE); 358 } 359 360 /* Initialize the Isochronous logic */ 361 hci1394_isoch_init(&soft_state->drvinfo, soft_state->ohci, 362 &soft_state->isoch); 363 364 /* Initialize any Vendor Specific Registers */ 365 status = hci1394_vendor_init(&soft_state->drvinfo, soft_state->ohci, 366 &soft_state->vendor_info, &soft_state->vendor); 367 if (status != DDI_SUCCESS) { 368 hci1394_isoch_fini(&soft_state->isoch); 369 hci1394_async_fini(&soft_state->async); 370 hci1394_csr_fini(&soft_state->csr); 371 hci1394_ohci_fini(&soft_state->ohci); 372 hci1394_pci_fini(soft_state); 373 return (DDI_FAILURE); 374 } 375 376 return (DDI_SUCCESS); 377 } 378 379 380 /* 381 * hci1394_hardware_resume() 382 * Resume the adapter HW. This routine will be called during resume after 383 * a successful system suspend. All memory should be in the state it was 384 * before the suspend. All we have to do is re-setup the HW. 385 */ 386 static int 387 hci1394_hardware_resume(hci1394_state_t *soft_state) 388 { 389 int status; 390 391 392 ASSERT(soft_state != NULL); 393 394 /* re-enable global byte swap (if we using it) */ 395 hci1394_pci_resume(soft_state); 396 397 /* Re-init the OpenHCI HW */ 398 status = hci1394_ohci_resume(soft_state->ohci); 399 if (status != DDI_SUCCESS) { 400 return (DDI_FAILURE); 401 } 402 403 /* re-setup our SW based CSR registers */ 404 hci1394_csr_resume(soft_state->csr); 405 406 /* Re-setup the Async Q's */ 407 status = hci1394_async_resume(soft_state->async); 408 if (status != DDI_SUCCESS) { 409 return (DDI_FAILURE); 410 } 411 412 /* Re-setup any Vendor Specific Registers */ 413 status = hci1394_vendor_resume(soft_state->vendor); 414 if (status != DDI_SUCCESS) { 415 return (DDI_FAILURE); 416 } 417 418 return (DDI_SUCCESS); 419 } 420 421 422 /* 423 * hci1394_pci_init() 424 * Map in PCI config space and initialize PCI config space registers. 425 */ 426 static int 427 hci1394_pci_init(hci1394_state_t *soft_state) 428 { 429 int status; 430 #ifndef _LITTLE_ENDIAN 431 uint32_t global_swap; 432 #endif 433 434 435 ASSERT(soft_state != NULL); 436 437 /* Setup PCI configuration space */ 438 status = pci_config_setup(soft_state->drvinfo.di_dip, 439 &soft_state->pci_config); 440 if (status != DDI_SUCCESS) { 441 return (DDI_FAILURE); 442 } 443 444 445 #ifdef _LITTLE_ENDIAN 446 /* Start of little endian specific code */ 447 soft_state->drvinfo.di_reg_attr.devacc_attr_version = 448 DDI_DEVICE_ATTR_V0; 449 soft_state->drvinfo.di_reg_attr.devacc_attr_endian_flags = 450 DDI_STRUCTURE_LE_ACC; 451 soft_state->drvinfo.di_reg_attr.devacc_attr_dataorder = 452 DDI_STRICTORDER_ACC; 453 soft_state->drvinfo.di_buf_attr.devacc_attr_version = 454 DDI_DEVICE_ATTR_V0; 455 soft_state->drvinfo.di_buf_attr.devacc_attr_endian_flags = 456 DDI_STRUCTURE_LE_ACC; 457 soft_state->drvinfo.di_buf_attr.devacc_attr_dataorder = 458 DDI_STRICTORDER_ACC; 459 soft_state->swap_data = B_TRUE; 460 /* End of little endian specific code */ 461 #else 462 /* Start of big endian specific code */ 463 /* If PCI_Global_Swap bit is not set, try to set it */ 464 global_swap = pci_config_get32(soft_state->pci_config, 465 OHCI_PCI_HCI_CONTROL_REG); 466 467 /* Lets see if the global byte swap feature is supported */ 468 if ((global_swap & OHCI_PCI_GLOBAL_SWAP) == 0) { 469 global_swap = global_swap | OHCI_PCI_GLOBAL_SWAP; 470 pci_config_put32(soft_state->pci_config, 471 OHCI_PCI_HCI_CONTROL_REG, global_swap); 472 } 473 474 global_swap = pci_config_get32(soft_state->pci_config, 475 OHCI_PCI_HCI_CONTROL_REG); 476 477 /* If PCI_Global_Swap bit is not set, it is unsupported */ 478 if ((global_swap & OHCI_PCI_GLOBAL_SWAP) == 0) { 479 soft_state->drvinfo.di_reg_attr.devacc_attr_version = 480 DDI_DEVICE_ATTR_V0; 481 soft_state->drvinfo.di_reg_attr.devacc_attr_endian_flags = 482 DDI_STRUCTURE_LE_ACC; 483 soft_state->drvinfo.di_reg_attr.devacc_attr_dataorder = 484 DDI_STRICTORDER_ACC; 485 soft_state->drvinfo.di_buf_attr.devacc_attr_version = 486 DDI_DEVICE_ATTR_V0; 487 soft_state->drvinfo.di_buf_attr.devacc_attr_endian_flags = 488 DDI_STRUCTURE_LE_ACC; 489 soft_state->drvinfo.di_buf_attr.devacc_attr_dataorder = 490 DDI_STRICTORDER_ACC; 491 soft_state->swap_data = B_TRUE; 492 /* 493 * global byte swap is supported. This should be the case 494 * for almost all of the adapters. 495 */ 496 } else { 497 soft_state->drvinfo.di_reg_attr.devacc_attr_version = 498 DDI_DEVICE_ATTR_V0; 499 soft_state->drvinfo.di_reg_attr.devacc_attr_endian_flags = 500 DDI_STRUCTURE_BE_ACC; 501 soft_state->drvinfo.di_reg_attr.devacc_attr_dataorder = 502 DDI_STRICTORDER_ACC; 503 soft_state->drvinfo.di_buf_attr.devacc_attr_version = 504 DDI_DEVICE_ATTR_V0; 505 soft_state->drvinfo.di_buf_attr.devacc_attr_endian_flags = 506 DDI_STRUCTURE_BE_ACC; 507 soft_state->drvinfo.di_buf_attr.devacc_attr_dataorder = 508 DDI_STRICTORDER_ACC; 509 soft_state->swap_data = B_FALSE; 510 } 511 /* End of big endian specific code */ 512 #endif 513 514 /* read in vendor Information */ 515 soft_state->vendor_info.vendor_id = 516 (uint_t)pci_config_get16(soft_state->pci_config, PCI_CONF_VENID); 517 soft_state->vendor_info.device_id = 518 (uint_t)pci_config_get16(soft_state->pci_config, PCI_CONF_DEVID); 519 soft_state->vendor_info.revision_id = 520 (uint_t)pci_config_get8(soft_state->pci_config, PCI_CONF_REVID); 521 522 return (DDI_SUCCESS); 523 } 524 525 526 /* 527 * hci1394_pci_resume() 528 * Re-Initialize PCI config space registers during a resume. 529 */ 530 /* ARGSUSED */ 531 static void 532 hci1394_pci_resume(hci1394_state_t *soft_state) 533 { 534 #ifndef _LITTLE_ENDIAN 535 uint32_t global_swap; 536 #endif 537 538 539 ASSERT(soft_state != NULL); 540 541 #ifdef _LITTLE_ENDIAN 542 /* Start of little endian specific code */ 543 /* nothing to do here yet. Maybe later?? */ 544 /* End of little endian specific code */ 545 #else 546 /* Start of big endian specific code */ 547 /* If PCI_Global_Swap bit is not set, try to set it */ 548 global_swap = pci_config_get32(soft_state->pci_config, 549 OHCI_PCI_HCI_CONTROL_REG); 550 /* Try and set GlobalByteSwap */ 551 if ((global_swap & OHCI_PCI_GLOBAL_SWAP) == 0) { 552 global_swap = global_swap | OHCI_PCI_GLOBAL_SWAP; 553 pci_config_put32(soft_state->pci_config, 554 OHCI_PCI_HCI_CONTROL_REG, global_swap); 555 } 556 /* End of big endian specific code */ 557 #endif 558 } 559 560 561 /* 562 * hci1394_resmap_get() 563 * Look for adapter property "reserved-addresses". This property is used to 564 * reserve 1394 address space so that it will not randomly be given to a 565 * target driver during a 1394 address space alloc. Some protocols hard 566 * code addresses which make us do this. The target driver must specifically 567 * ask for these addresses. This routine should be called before the 568 * call to h1394_attach(). 569 */ 570 static int 571 hci1394_resmap_get(hci1394_state_t *soft_state) 572 { 573 h1394_addr_map_t *resv_map; 574 int resv_num; 575 int status; 576 int reslen; 577 uint32_t *resptr; 578 int rescnt; 579 int mapcnt; 580 581 582 ASSERT(soft_state != NULL); 583 584 /* 585 * See if the "reserved-addresses" property is defined. The format 586 * should be: 587 * 588 * reserved-addresses= 0x0000ffff,0xf0000B00,0x200, 589 * 0x0000ffff,0xf0000D00,0x200, 590 * 0x0000ffff,0xf0000234,0x4; 591 * You can have multiple reserved addresses. Each reserved address 592 * takes up 3 integers. 593 * MSWofAddr,LSWofAddr,ByteCount 594 */ 595 status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, 596 soft_state->drvinfo.di_dip, DDI_PROP_DONTPASS, "reserved-addresses", 597 (int **)&resptr, (uint_t *)&reslen); 598 if (status != DDI_PROP_SUCCESS) { 599 /* the property is not defined, 0 reserved addresses */ 600 soft_state->halinfo.resv_map_num_entries = 0; 601 soft_state->halinfo.resv_map = NULL; 602 return (DDI_SUCCESS); 603 } else if ((reslen < 3) || ((reslen % 3) != 0)) { 604 /* 605 * the property is defined but the correct number of integers 606 * is not present. 607 */ 608 resv_num = 0; 609 resv_map = NULL; 610 cmn_err(CE_NOTE, "!%s(%d): Invalid reserved-addresses property." 611 " Property ignored", ddi_node_name( 612 soft_state->drvinfo.di_dip), ddi_get_instance( 613 soft_state->drvinfo.di_dip)); 614 } else { 615 /* the property is defined. Alloc space to copy data into */ 616 resv_num = reslen / 3; 617 resv_map = kmem_alloc((sizeof (h1394_addr_map_t) * (resv_num)), 618 KM_SLEEP); 619 620 /* read in the address, length, and set the type to reserved */ 621 rescnt = 0; 622 mapcnt = 0; 623 while (rescnt < reslen) { 624 resv_map[mapcnt].address = 625 (uint64_t)resptr[rescnt] << 32; 626 rescnt++; 627 resv_map[mapcnt].address |= (uint64_t)resptr[rescnt]; 628 rescnt++; 629 resv_map[mapcnt].length = (uint64_t)resptr[rescnt]; 630 rescnt++; 631 resv_map[mapcnt].addr_type = H1394_ADDR_RESERVED; 632 mapcnt++; 633 } 634 } 635 636 ddi_prop_free(resptr); 637 638 /* 639 * copy the number of reserved address ranges and a pointer to the map 640 * into halinfo so we can tell the services layer about them in 641 * h1394_attach() 642 */ 643 soft_state->halinfo.resv_map_num_entries = resv_num; 644 soft_state->halinfo.resv_map = resv_map; 645 646 return (DDI_SUCCESS); 647 } 648 649 650 /* 651 * hci1394_resmap_free() 652 * Free up the space alloced in hci1394_resmap_get(). This routine should 653 * be called after h1394_attach(). The HAL does not need this information 654 * and the services layer only uses it for a calculation during attach and 655 * should not refer to the pointer after it returns from h1394_attach(). 656 */ 657 static void 658 hci1394_resmap_free(hci1394_state_t *soft_state) 659 { 660 ASSERT(soft_state != NULL); 661 662 /* 663 * if we have one or more reserved map entries, free up the space that 664 * was allocated to store them 665 */ 666 if (soft_state->halinfo.resv_map_num_entries > 0) { 667 ASSERT(soft_state->halinfo.resv_map != NULL); 668 kmem_free(soft_state->halinfo.resv_map, 669 (sizeof (h1394_addr_map_t) * 670 soft_state->halinfo.resv_map_num_entries)); 671 } 672 } 673 674 675 /* 676 * hci1394_statebit_set() 677 * Set bit "statebit" in "state" 678 */ 679 static void 680 hci1394_statebit_set(uint64_t *state, uint_t statebit) 681 { 682 ASSERT(state != NULL); 683 ASSERT(statebit < 64); 684 *state |= (uint64_t)0x1 << statebit; 685 } 686 687 688 /* 689 * hci1394_statebit_tst() 690 * Return status of bit "statebit". Is it set or not? 691 */ 692 static boolean_t 693 hci1394_statebit_tst(uint64_t state, uint_t statebit) 694 { 695 uint64_t bitset; 696 int status; 697 698 699 ASSERT(statebit < 64); 700 bitset = state & ((uint64_t)0x1 << statebit); 701 if (bitset == 0) { 702 status = B_FALSE; 703 } else { 704 status = B_TRUE; 705 } 706 return (status); 707 } 708 709 710 /* 711 * hci1394_cleanup() 712 * Cleanup after a failed attach 713 */ 714 static void 715 hci1394_cleanup(hci1394_state_t *soft_state, uint64_t attach_state) 716 { 717 int status; 718 719 720 ASSERT(soft_state != NULL); 721 722 status = hci1394_statebit_tst(attach_state, STATE_STARTUP); 723 if (status == B_TRUE) { 724 /* Don't allow the HW to generate any more interrupts */ 725 hci1394_ohci_intr_master_disable(soft_state->ohci); 726 727 /* don't accept anymore commands from services layer */ 728 (void) hci1394_state_set(&soft_state->drvinfo, 729 HCI1394_SHUTDOWN); 730 731 /* Reset the chip */ 732 (void) hci1394_ohci_soft_reset(soft_state->ohci); 733 734 /* Flush out async DMA Q's (cancels pendingQ timeouts too) */ 735 hci1394_async_flush(soft_state->async); 736 } 737 738 status = hci1394_statebit_tst(attach_state, STATE_ISR_HANDLER); 739 if (status == B_TRUE) { 740 hci1394_isr_handler_fini(soft_state); 741 } 742 743 status = hci1394_statebit_tst(attach_state, STATE_H1394_ATTACH); 744 if (status == B_TRUE) { 745 (void) h1394_detach(&soft_state->drvinfo.di_sl_private, 746 DDI_DETACH); 747 } 748 749 status = hci1394_statebit_tst(attach_state, STATE_HW_INIT); 750 if (status == B_TRUE) { 751 hci1394_detach_hardware(soft_state); 752 } 753 754 status = hci1394_statebit_tst(attach_state, STATE_MINOR_NODE); 755 if (status == B_TRUE) { 756 ddi_remove_minor_node(soft_state->drvinfo.di_dip, "devctl"); 757 } 758 759 status = hci1394_statebit_tst(attach_state, STATE_ISR_INIT); 760 if (status == B_TRUE) { 761 hci1394_isr_fini(soft_state); 762 } 763 764 status = hci1394_statebit_tst(attach_state, STATE_PHASE2); 765 if (status == B_TRUE) { 766 hci1394_soft_state_fini(soft_state); 767 } 768 769 status = hci1394_statebit_tst(attach_state, STATE_ZALLOC); 770 if (status == B_TRUE) { 771 ddi_soft_state_free(hci1394_statep, 772 soft_state->drvinfo.di_instance); 773 } 774 } 775