1 /* 2 * CompactPCI Hot Plug Driver PCI functions 3 * 4 * Copyright (C) 2002 by SOMA Networks, Inc. 5 * 6 * All rights reserved. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or (at 11 * your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 16 * NON INFRINGEMENT. See the GNU General Public License for more 17 * details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 * 23 * Send feedback to <scottm@somanetworks.com> 24 */ 25 26 #include <linux/config.h> 27 #include <linux/module.h> 28 #include <linux/kernel.h> 29 #include <linux/pci.h> 30 #include <linux/proc_fs.h> 31 #include "../pci.h" 32 #include "pci_hotplug.h" 33 #include "cpci_hotplug.h" 34 35 #if !defined(MODULE) 36 #define MY_NAME "cpci_hotplug" 37 #else 38 #define MY_NAME THIS_MODULE->name 39 #endif 40 41 extern int cpci_debug; 42 43 #define dbg(format, arg...) \ 44 do { \ 45 if(cpci_debug) \ 46 printk (KERN_DEBUG "%s: " format "\n", \ 47 MY_NAME , ## arg); \ 48 } while(0) 49 #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) 50 #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) 51 #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) 52 53 #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) 54 55 56 u8 cpci_get_attention_status(struct slot* slot) 57 { 58 int hs_cap; 59 u16 hs_csr; 60 61 hs_cap = pci_bus_find_capability(slot->bus, 62 slot->devfn, 63 PCI_CAP_ID_CHSWP); 64 if(!hs_cap) { 65 return 0; 66 } 67 68 if(pci_bus_read_config_word(slot->bus, 69 slot->devfn, 70 hs_cap + 2, 71 &hs_csr)) { 72 return 0; 73 } 74 return hs_csr & 0x0008 ? 1 : 0; 75 } 76 77 int cpci_set_attention_status(struct slot* slot, int status) 78 { 79 int hs_cap; 80 u16 hs_csr; 81 82 hs_cap = pci_bus_find_capability(slot->bus, 83 slot->devfn, 84 PCI_CAP_ID_CHSWP); 85 if(!hs_cap) { 86 return 0; 87 } 88 89 if(pci_bus_read_config_word(slot->bus, 90 slot->devfn, 91 hs_cap + 2, 92 &hs_csr)) { 93 return 0; 94 } 95 if(status) { 96 hs_csr |= HS_CSR_LOO; 97 } else { 98 hs_csr &= ~HS_CSR_LOO; 99 } 100 if(pci_bus_write_config_word(slot->bus, 101 slot->devfn, 102 hs_cap + 2, 103 hs_csr)) { 104 return 0; 105 } 106 return 1; 107 } 108 109 u16 cpci_get_hs_csr(struct slot* slot) 110 { 111 int hs_cap; 112 u16 hs_csr; 113 114 hs_cap = pci_bus_find_capability(slot->bus, 115 slot->devfn, 116 PCI_CAP_ID_CHSWP); 117 if(!hs_cap) { 118 return 0xFFFF; 119 } 120 121 if(pci_bus_read_config_word(slot->bus, 122 slot->devfn, 123 hs_cap + 2, 124 &hs_csr)) { 125 return 0xFFFF; 126 } 127 return hs_csr; 128 } 129 130 #if 0 131 u16 cpci_set_hs_csr(struct slot* slot, u16 hs_csr) 132 { 133 int hs_cap; 134 u16 new_hs_csr; 135 136 hs_cap = pci_bus_find_capability(slot->bus, 137 slot->devfn, 138 PCI_CAP_ID_CHSWP); 139 if(!hs_cap) { 140 return 0xFFFF; 141 } 142 143 /* Write out the new value */ 144 if(pci_bus_write_config_word(slot->bus, 145 slot->devfn, 146 hs_cap + 2, 147 hs_csr)) { 148 return 0xFFFF; 149 } 150 151 /* Read back what we just wrote out */ 152 if(pci_bus_read_config_word(slot->bus, 153 slot->devfn, 154 hs_cap + 2, 155 &new_hs_csr)) { 156 return 0xFFFF; 157 } 158 return new_hs_csr; 159 } 160 #endif 161 162 int cpci_check_and_clear_ins(struct slot* slot) 163 { 164 int hs_cap; 165 u16 hs_csr; 166 int ins = 0; 167 168 hs_cap = pci_bus_find_capability(slot->bus, 169 slot->devfn, 170 PCI_CAP_ID_CHSWP); 171 if(!hs_cap) { 172 return 0; 173 } 174 if(pci_bus_read_config_word(slot->bus, 175 slot->devfn, 176 hs_cap + 2, 177 &hs_csr)) { 178 return 0; 179 } 180 if(hs_csr & HS_CSR_INS) { 181 /* Clear INS (by setting it) */ 182 if(pci_bus_write_config_word(slot->bus, 183 slot->devfn, 184 hs_cap + 2, 185 hs_csr)) { 186 ins = 0; 187 } 188 ins = 1; 189 } 190 return ins; 191 } 192 193 int cpci_check_ext(struct slot* slot) 194 { 195 int hs_cap; 196 u16 hs_csr; 197 int ext = 0; 198 199 hs_cap = pci_bus_find_capability(slot->bus, 200 slot->devfn, 201 PCI_CAP_ID_CHSWP); 202 if(!hs_cap) { 203 return 0; 204 } 205 if(pci_bus_read_config_word(slot->bus, 206 slot->devfn, 207 hs_cap + 2, 208 &hs_csr)) { 209 return 0; 210 } 211 if(hs_csr & HS_CSR_EXT) { 212 ext = 1; 213 } 214 return ext; 215 } 216 217 int cpci_clear_ext(struct slot* slot) 218 { 219 int hs_cap; 220 u16 hs_csr; 221 222 hs_cap = pci_bus_find_capability(slot->bus, 223 slot->devfn, 224 PCI_CAP_ID_CHSWP); 225 if(!hs_cap) { 226 return -ENODEV; 227 } 228 if(pci_bus_read_config_word(slot->bus, 229 slot->devfn, 230 hs_cap + 2, 231 &hs_csr)) { 232 return -ENODEV; 233 } 234 if(hs_csr & HS_CSR_EXT) { 235 /* Clear EXT (by setting it) */ 236 if(pci_bus_write_config_word(slot->bus, 237 slot->devfn, 238 hs_cap + 2, 239 hs_csr)) { 240 return -ENODEV; 241 } 242 } 243 return 0; 244 } 245 246 int cpci_led_on(struct slot* slot) 247 { 248 int hs_cap; 249 u16 hs_csr; 250 251 hs_cap = pci_bus_find_capability(slot->bus, 252 slot->devfn, 253 PCI_CAP_ID_CHSWP); 254 if(!hs_cap) { 255 return -ENODEV; 256 } 257 if(pci_bus_read_config_word(slot->bus, 258 slot->devfn, 259 hs_cap + 2, 260 &hs_csr)) { 261 return -ENODEV; 262 } 263 if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) { 264 /* Set LOO */ 265 hs_csr |= HS_CSR_LOO; 266 if(pci_bus_write_config_word(slot->bus, 267 slot->devfn, 268 hs_cap + 2, 269 hs_csr)) { 270 err("Could not set LOO for slot %s", 271 slot->hotplug_slot->name); 272 return -ENODEV; 273 } 274 } 275 return 0; 276 } 277 278 int cpci_led_off(struct slot* slot) 279 { 280 int hs_cap; 281 u16 hs_csr; 282 283 hs_cap = pci_bus_find_capability(slot->bus, 284 slot->devfn, 285 PCI_CAP_ID_CHSWP); 286 if(!hs_cap) { 287 return -ENODEV; 288 } 289 if(pci_bus_read_config_word(slot->bus, 290 slot->devfn, 291 hs_cap + 2, 292 &hs_csr)) { 293 return -ENODEV; 294 } 295 if(hs_csr & HS_CSR_LOO) { 296 /* Clear LOO */ 297 hs_csr &= ~HS_CSR_LOO; 298 if(pci_bus_write_config_word(slot->bus, 299 slot->devfn, 300 hs_cap + 2, 301 hs_csr)) { 302 err("Could not clear LOO for slot %s", 303 slot->hotplug_slot->name); 304 return -ENODEV; 305 } 306 } 307 return 0; 308 } 309 310 311 /* 312 * Device configuration functions 313 */ 314 315 static int cpci_configure_dev(struct pci_bus *bus, struct pci_dev *dev) 316 { 317 u8 irq_pin; 318 int r; 319 320 dbg("%s - enter", __FUNCTION__); 321 322 /* NOTE: device already setup from prior scan */ 323 324 /* FIXME: How would we know if we need to enable the expansion ROM? */ 325 pci_write_config_word(dev, PCI_ROM_ADDRESS, 0x00L); 326 327 /* Assign resources */ 328 dbg("assigning resources for %02x:%02x.%x", 329 dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); 330 for (r = 0; r < 6; r++) { 331 struct resource *res = dev->resource + r; 332 if(res->flags) 333 pci_assign_resource(dev, r); 334 } 335 dbg("finished assigning resources for %02x:%02x.%x", 336 dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); 337 338 /* Does this function have an interrupt at all? */ 339 dbg("checking for function interrupt"); 340 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin); 341 if(irq_pin) { 342 dbg("function uses interrupt pin %d", irq_pin); 343 } 344 345 /* 346 * Need to explicitly set irq field to 0 so that it'll get assigned 347 * by the pcibios platform dependent code called by pci_enable_device. 348 */ 349 dev->irq = 0; 350 351 dbg("enabling device"); 352 pci_enable_device(dev); /* XXX check return */ 353 dbg("now dev->irq = %d", dev->irq); 354 if(irq_pin && dev->irq) { 355 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 356 } 357 358 /* Can't use pci_insert_device at the moment, do it manually for now */ 359 pci_proc_attach_device(dev); 360 dbg("notifying drivers"); 361 //pci_announce_device_to_drivers(dev); 362 dbg("%s - exit", __FUNCTION__); 363 return 0; 364 } 365 366 static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev) 367 { 368 int rc; 369 struct pci_bus* child; 370 struct resource* r; 371 u8 max, n; 372 u16 command; 373 374 dbg("%s - enter", __FUNCTION__); 375 376 /* Do basic bridge initialization */ 377 rc = pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40); 378 if(rc) { 379 printk(KERN_ERR "%s - write of PCI_LATENCY_TIMER failed\n", __FUNCTION__); 380 } 381 rc = pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40); 382 if(rc) { 383 printk(KERN_ERR "%s - write of PCI_SEC_LATENCY_TIMER failed\n", __FUNCTION__); 384 } 385 rc = pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4); 386 if(rc) { 387 printk(KERN_ERR "%s - write of PCI_CACHE_LINE_SIZE failed\n", __FUNCTION__); 388 } 389 390 /* 391 * Set parent bridge's subordinate field so that configuration space 392 * access will work in pci_scan_bridge and friends. 393 */ 394 max = pci_max_busnr(); 395 bus->subordinate = max + 1; 396 pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, max + 1); 397 398 /* Scan behind bridge */ 399 n = pci_scan_bridge(bus, dev, max, 2); 400 child = pci_find_bus(0, max + 1); 401 if (!child) 402 return -ENODEV; 403 pci_proc_attach_bus(child); 404 405 /* 406 * Update parent bridge's subordinate field if there were more bridges 407 * behind the bridge that was scanned. 408 */ 409 if(n > max) { 410 bus->subordinate = n; 411 pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, n); 412 } 413 414 /* 415 * Update the bridge resources of the bridge to accommodate devices 416 * behind it. 417 */ 418 pci_bus_size_bridges(child); 419 pci_bus_assign_resources(child); 420 421 /* Enable resource mapping via command register */ 422 command = PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR; 423 r = child->resource[0]; 424 if(r && r->start) { 425 command |= PCI_COMMAND_IO; 426 } 427 r = child->resource[1]; 428 if(r && r->start) { 429 command |= PCI_COMMAND_MEMORY; 430 } 431 r = child->resource[2]; 432 if(r && r->start) { 433 command |= PCI_COMMAND_MEMORY; 434 } 435 rc = pci_write_config_word(dev, PCI_COMMAND, command); 436 if(rc) { 437 err("Error setting command register"); 438 return rc; 439 } 440 441 /* Set bridge control register */ 442 command = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA; 443 rc = pci_write_config_word(dev, PCI_BRIDGE_CONTROL, command); 444 if(rc) { 445 err("Error setting bridge control register"); 446 return rc; 447 } 448 dbg("%s - exit", __FUNCTION__); 449 return 0; 450 } 451 452 static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev, 453 struct pci_bus_wrapped *wrapped_bus) 454 { 455 int rc; 456 struct pci_dev *dev = wrapped_dev->dev; 457 struct pci_bus *bus = wrapped_bus->bus; 458 struct slot* slot; 459 460 dbg("%s - enter", __FUNCTION__); 461 462 /* 463 * We need to fix up the hotplug representation with the Linux 464 * representation. 465 */ 466 if(wrapped_dev->data) { 467 slot = (struct slot*) wrapped_dev->data; 468 slot->dev = dev; 469 } 470 471 /* If it's a bridge, scan behind it for devices */ 472 if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { 473 rc = cpci_configure_bridge(bus, dev); 474 if(rc) 475 return rc; 476 } 477 478 /* Actually configure device */ 479 if(dev) { 480 rc = cpci_configure_dev(bus, dev); 481 if(rc) 482 return rc; 483 } 484 dbg("%s - exit", __FUNCTION__); 485 return 0; 486 } 487 488 static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev, 489 struct pci_bus_wrapped *wrapped_bus) 490 { 491 struct pci_dev *dev = wrapped_dev->dev; 492 struct slot* slot; 493 494 dbg("%s - enter", __FUNCTION__); 495 if(!dev) 496 return -ENODEV; 497 498 /* Remove the Linux representation */ 499 if(pci_remove_device_safe(dev)) { 500 err("Could not remove device\n"); 501 return -1; 502 } 503 504 /* 505 * Now remove the hotplug representation. 506 */ 507 if(wrapped_dev->data) { 508 slot = (struct slot*) wrapped_dev->data; 509 slot->dev = NULL; 510 } else { 511 dbg("No hotplug representation for %02x:%02x.%x", 512 dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); 513 } 514 dbg("%s - exit", __FUNCTION__); 515 return 0; 516 } 517 518 static int unconfigure_visit_pci_bus_phase2(struct pci_bus_wrapped *wrapped_bus, 519 struct pci_dev_wrapped *wrapped_dev) 520 { 521 struct pci_bus *bus = wrapped_bus->bus; 522 struct pci_bus *parent = bus->self->bus; 523 524 dbg("%s - enter", __FUNCTION__); 525 526 /* The cleanup code for proc entries regarding buses should be in the kernel... */ 527 if(bus->procdir) 528 dbg("detach_pci_bus %s", bus->procdir->name); 529 pci_proc_detach_bus(bus); 530 531 /* The cleanup code should live in the kernel... */ 532 bus->self->subordinate = NULL; 533 534 /* unlink from parent bus */ 535 list_del(&bus->node); 536 537 /* Now, remove */ 538 if(bus) 539 kfree(bus); 540 541 /* Update parent's subordinate field */ 542 if(parent) { 543 u8 n = pci_bus_max_busnr(parent); 544 if(n < parent->subordinate) { 545 parent->subordinate = n; 546 pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, n); 547 } 548 } 549 dbg("%s - exit", __FUNCTION__); 550 return 0; 551 } 552 553 static struct pci_visit configure_functions = { 554 .visit_pci_dev = configure_visit_pci_dev, 555 }; 556 557 static struct pci_visit unconfigure_functions_phase2 = { 558 .post_visit_pci_bus = unconfigure_visit_pci_bus_phase2, 559 .post_visit_pci_dev = unconfigure_visit_pci_dev_phase2 560 }; 561 562 563 int cpci_configure_slot(struct slot* slot) 564 { 565 int rc = 0; 566 567 dbg("%s - enter", __FUNCTION__); 568 569 if(slot->dev == NULL) { 570 dbg("pci_dev null, finding %02x:%02x:%x", 571 slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn)); 572 slot->dev = pci_find_slot(slot->bus->number, slot->devfn); 573 } 574 575 /* Still NULL? Well then scan for it! */ 576 if(slot->dev == NULL) { 577 int n; 578 dbg("pci_dev still null"); 579 580 /* 581 * This will generate pci_dev structures for all functions, but 582 * we will only call this case when lookup fails. 583 */ 584 n = pci_scan_slot(slot->bus, slot->devfn); 585 dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n); 586 if(n > 0) 587 pci_bus_add_devices(slot->bus); 588 slot->dev = pci_find_slot(slot->bus->number, slot->devfn); 589 if(slot->dev == NULL) { 590 err("Could not find PCI device for slot %02x", slot->number); 591 return 0; 592 } 593 } 594 dbg("slot->dev = %p", slot->dev); 595 if(slot->dev) { 596 struct pci_dev *dev; 597 struct pci_dev_wrapped wrapped_dev; 598 struct pci_bus_wrapped wrapped_bus; 599 int i; 600 601 memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped)); 602 memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped)); 603 604 for (i = 0; i < 8; i++) { 605 dev = pci_find_slot(slot->bus->number, 606 PCI_DEVFN(PCI_SLOT(slot->dev->devfn), i)); 607 if(!dev) 608 continue; 609 wrapped_dev.dev = dev; 610 wrapped_bus.bus = slot->dev->bus; 611 if(i) 612 wrapped_dev.data = NULL; 613 else 614 wrapped_dev.data = (void*) slot; 615 rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus); 616 } 617 } 618 619 dbg("%s - exit, rc = %d", __FUNCTION__, rc); 620 return rc; 621 } 622 623 int cpci_unconfigure_slot(struct slot* slot) 624 { 625 int rc = 0; 626 int i; 627 struct pci_dev_wrapped wrapped_dev; 628 struct pci_bus_wrapped wrapped_bus; 629 struct pci_dev *dev; 630 631 dbg("%s - enter", __FUNCTION__); 632 633 if(!slot->dev) { 634 err("No device for slot %02x\n", slot->number); 635 return -ENODEV; 636 } 637 638 memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped)); 639 memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped)); 640 641 for (i = 0; i < 8; i++) { 642 dev = pci_find_slot(slot->bus->number, 643 PCI_DEVFN(PCI_SLOT(slot->devfn), i)); 644 if(dev) { 645 wrapped_dev.dev = dev; 646 wrapped_bus.bus = dev->bus; 647 if(i) 648 wrapped_dev.data = NULL; 649 else 650 wrapped_dev.data = (void*) slot; 651 dbg("%s - unconfigure phase 2", __FUNCTION__); 652 rc = pci_visit_dev(&unconfigure_functions_phase2, 653 &wrapped_dev, 654 &wrapped_bus); 655 if(rc) 656 break; 657 } 658 } 659 dbg("%s - exit, rc = %d", __FUNCTION__, rc); 660 return rc; 661 } 662