1 /* 2 * CompactPCI Hot Plug Driver 3 * 4 * Copyright (C) 2002,2005 SOMA Networks, Inc. 5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) 6 * Copyright (C) 2001 IBM Corp. 7 * 8 * All rights reserved. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or (at 13 * your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, but 16 * WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 18 * NON INFRINGEMENT. See the GNU General Public License for more 19 * details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24 * 25 * Send feedback to <scottm@somanetworks.com> 26 */ 27 28 #include <linux/config.h> 29 #include <linux/module.h> 30 #include <linux/kernel.h> 31 #include <linux/slab.h> 32 #include <linux/pci.h> 33 #include <linux/init.h> 34 #include <linux/interrupt.h> 35 #include <linux/smp_lock.h> 36 #include <asm/atomic.h> 37 #include <linux/delay.h> 38 #include "pci_hotplug.h" 39 #include "cpci_hotplug.h" 40 41 #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>" 42 #define DRIVER_DESC "CompactPCI Hot Plug Core" 43 44 #define MY_NAME "cpci_hotplug" 45 46 #define dbg(format, arg...) \ 47 do { \ 48 if (cpci_debug) \ 49 printk (KERN_DEBUG "%s: " format "\n", \ 50 MY_NAME , ## arg); \ 51 } while (0) 52 #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) 53 #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) 54 #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) 55 56 /* local variables */ 57 static DECLARE_RWSEM(list_rwsem); 58 static LIST_HEAD(slot_list); 59 static int slots; 60 static atomic_t extracting; 61 int cpci_debug; 62 static struct cpci_hp_controller *controller; 63 static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ 64 static struct semaphore thread_exit; /* guard ensure thread has exited before calling it quits */ 65 static int thread_finished = 1; 66 67 static int enable_slot(struct hotplug_slot *slot); 68 static int disable_slot(struct hotplug_slot *slot); 69 static int set_attention_status(struct hotplug_slot *slot, u8 value); 70 static int get_power_status(struct hotplug_slot *slot, u8 * value); 71 static int get_attention_status(struct hotplug_slot *slot, u8 * value); 72 static int get_adapter_status(struct hotplug_slot *slot, u8 * value); 73 static int get_latch_status(struct hotplug_slot *slot, u8 * value); 74 75 static struct hotplug_slot_ops cpci_hotplug_slot_ops = { 76 .owner = THIS_MODULE, 77 .enable_slot = enable_slot, 78 .disable_slot = disable_slot, 79 .set_attention_status = set_attention_status, 80 .get_power_status = get_power_status, 81 .get_attention_status = get_attention_status, 82 .get_adapter_status = get_adapter_status, 83 .get_latch_status = get_latch_status, 84 }; 85 86 static int 87 update_latch_status(struct hotplug_slot *hotplug_slot, u8 value) 88 { 89 struct hotplug_slot_info info; 90 91 memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info)); 92 info.latch_status = value; 93 return pci_hp_change_slot_info(hotplug_slot, &info); 94 } 95 96 static int 97 update_adapter_status(struct hotplug_slot *hotplug_slot, u8 value) 98 { 99 struct hotplug_slot_info info; 100 101 memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info)); 102 info.adapter_status = value; 103 return pci_hp_change_slot_info(hotplug_slot, &info); 104 } 105 106 static int 107 enable_slot(struct hotplug_slot *hotplug_slot) 108 { 109 struct slot *slot = hotplug_slot->private; 110 int retval = 0; 111 112 dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name); 113 114 if (controller->ops->set_power) 115 retval = controller->ops->set_power(slot, 1); 116 return retval; 117 } 118 119 static int 120 disable_slot(struct hotplug_slot *hotplug_slot) 121 { 122 struct slot *slot = hotplug_slot->private; 123 int retval = 0; 124 125 dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name); 126 127 down_write(&list_rwsem); 128 129 /* Unconfigure device */ 130 dbg("%s - unconfiguring slot %s", 131 __FUNCTION__, slot->hotplug_slot->name); 132 if ((retval = cpci_unconfigure_slot(slot))) { 133 err("%s - could not unconfigure slot %s", 134 __FUNCTION__, slot->hotplug_slot->name); 135 goto disable_error; 136 } 137 dbg("%s - finished unconfiguring slot %s", 138 __FUNCTION__, slot->hotplug_slot->name); 139 140 /* Clear EXT (by setting it) */ 141 if (cpci_clear_ext(slot)) { 142 err("%s - could not clear EXT for slot %s", 143 __FUNCTION__, slot->hotplug_slot->name); 144 retval = -ENODEV; 145 goto disable_error; 146 } 147 cpci_led_on(slot); 148 149 if (controller->ops->set_power) 150 if ((retval = controller->ops->set_power(slot, 0))) 151 goto disable_error; 152 153 if (update_adapter_status(slot->hotplug_slot, 0)) 154 warn("failure to update adapter file"); 155 156 if (slot->extracting) { 157 slot->extracting = 0; 158 atomic_dec(&extracting); 159 } 160 disable_error: 161 up_write(&list_rwsem); 162 return retval; 163 } 164 165 static u8 166 cpci_get_power_status(struct slot *slot) 167 { 168 u8 power = 1; 169 170 if (controller->ops->get_power) 171 power = controller->ops->get_power(slot); 172 return power; 173 } 174 175 static int 176 get_power_status(struct hotplug_slot *hotplug_slot, u8 * value) 177 { 178 struct slot *slot = hotplug_slot->private; 179 180 *value = cpci_get_power_status(slot); 181 return 0; 182 } 183 184 static int 185 get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value) 186 { 187 struct slot *slot = hotplug_slot->private; 188 189 *value = cpci_get_attention_status(slot); 190 return 0; 191 } 192 193 static int 194 set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) 195 { 196 return cpci_set_attention_status(hotplug_slot->private, status); 197 } 198 199 static int 200 get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value) 201 { 202 *value = hotplug_slot->info->adapter_status; 203 return 0; 204 } 205 206 static int 207 get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value) 208 { 209 *value = hotplug_slot->info->latch_status; 210 return 0; 211 } 212 213 static void release_slot(struct hotplug_slot *hotplug_slot) 214 { 215 struct slot *slot = hotplug_slot->private; 216 217 kfree(slot->hotplug_slot->info); 218 kfree(slot->hotplug_slot->name); 219 kfree(slot->hotplug_slot); 220 if (slot->dev) 221 pci_dev_put(slot->dev); 222 kfree(slot); 223 } 224 225 #define SLOT_NAME_SIZE 6 226 static void 227 make_slot_name(struct slot *slot) 228 { 229 snprintf(slot->hotplug_slot->name, 230 SLOT_NAME_SIZE, "%02x:%02x", slot->bus->number, slot->number); 231 } 232 233 int 234 cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) 235 { 236 struct slot *slot; 237 struct hotplug_slot *hotplug_slot; 238 struct hotplug_slot_info *info; 239 char *name; 240 int status = -ENOMEM; 241 int i; 242 243 if (!(controller && bus)) 244 return -ENODEV; 245 246 /* 247 * Create a structure for each slot, and register that slot 248 * with the pci_hotplug subsystem. 249 */ 250 for (i = first; i <= last; ++i) { 251 slot = kzalloc(sizeof (struct slot), GFP_KERNEL); 252 if (!slot) 253 goto error; 254 255 hotplug_slot = 256 kzalloc(sizeof (struct hotplug_slot), GFP_KERNEL); 257 if (!hotplug_slot) 258 goto error_slot; 259 slot->hotplug_slot = hotplug_slot; 260 261 info = kzalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL); 262 if (!info) 263 goto error_hpslot; 264 hotplug_slot->info = info; 265 266 name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); 267 if (!name) 268 goto error_info; 269 hotplug_slot->name = name; 270 271 slot->bus = bus; 272 slot->number = i; 273 slot->devfn = PCI_DEVFN(i, 0); 274 275 hotplug_slot->private = slot; 276 hotplug_slot->release = &release_slot; 277 make_slot_name(slot); 278 hotplug_slot->ops = &cpci_hotplug_slot_ops; 279 280 /* 281 * Initialize the slot info structure with some known 282 * good values. 283 */ 284 dbg("initializing slot %s", slot->hotplug_slot->name); 285 info->power_status = cpci_get_power_status(slot); 286 info->attention_status = cpci_get_attention_status(slot); 287 288 dbg("registering slot %s", slot->hotplug_slot->name); 289 status = pci_hp_register(slot->hotplug_slot); 290 if (status) { 291 err("pci_hp_register failed with error %d", status); 292 goto error_name; 293 } 294 295 /* Add slot to our internal list */ 296 down_write(&list_rwsem); 297 list_add(&slot->slot_list, &slot_list); 298 slots++; 299 up_write(&list_rwsem); 300 } 301 return 0; 302 error_name: 303 kfree(name); 304 error_info: 305 kfree(info); 306 error_hpslot: 307 kfree(hotplug_slot); 308 error_slot: 309 kfree(slot); 310 error: 311 return status; 312 } 313 314 int 315 cpci_hp_unregister_bus(struct pci_bus *bus) 316 { 317 struct slot *slot; 318 struct slot *tmp; 319 int status = 0; 320 321 down_write(&list_rwsem); 322 if (!slots) { 323 up_write(&list_rwsem); 324 return -1; 325 } 326 list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) { 327 if (slot->bus == bus) { 328 list_del(&slot->slot_list); 329 slots--; 330 331 dbg("deregistering slot %s", slot->hotplug_slot->name); 332 status = pci_hp_deregister(slot->hotplug_slot); 333 if (status) { 334 err("pci_hp_deregister failed with error %d", 335 status); 336 break; 337 } 338 } 339 } 340 up_write(&list_rwsem); 341 return status; 342 } 343 344 /* This is the interrupt mode interrupt handler */ 345 static irqreturn_t 346 cpci_hp_intr(int irq, void *data, struct pt_regs *regs) 347 { 348 dbg("entered cpci_hp_intr"); 349 350 /* Check to see if it was our interrupt */ 351 if ((controller->irq_flags & SA_SHIRQ) && 352 !controller->ops->check_irq(controller->dev_id)) { 353 dbg("exited cpci_hp_intr, not our interrupt"); 354 return IRQ_NONE; 355 } 356 357 /* Disable ENUM interrupt */ 358 controller->ops->disable_irq(); 359 360 /* Trigger processing by the event thread */ 361 dbg("Signal event_semaphore"); 362 up(&event_semaphore); 363 dbg("exited cpci_hp_intr"); 364 return IRQ_HANDLED; 365 } 366 367 /* 368 * According to PICMG 2.1 R2.0, section 6.3.2, upon 369 * initialization, the system driver shall clear the 370 * INS bits of the cold-inserted devices. 371 */ 372 static int 373 init_slots(int clear_ins) 374 { 375 struct slot *slot; 376 struct pci_dev* dev; 377 378 dbg("%s - enter", __FUNCTION__); 379 down_read(&list_rwsem); 380 if (!slots) { 381 up_read(&list_rwsem); 382 return -1; 383 } 384 list_for_each_entry(slot, &slot_list, slot_list) { 385 dbg("%s - looking at slot %s", 386 __FUNCTION__, slot->hotplug_slot->name); 387 if (clear_ins && cpci_check_and_clear_ins(slot)) 388 dbg("%s - cleared INS for slot %s", 389 __FUNCTION__, slot->hotplug_slot->name); 390 dev = pci_get_slot(slot->bus, PCI_DEVFN(slot->number, 0)); 391 if (dev) { 392 if (update_adapter_status(slot->hotplug_slot, 1)) 393 warn("failure to update adapter file"); 394 if (update_latch_status(slot->hotplug_slot, 1)) 395 warn("failure to update latch file"); 396 slot->dev = dev; 397 } 398 } 399 up_read(&list_rwsem); 400 dbg("%s - exit", __FUNCTION__); 401 return 0; 402 } 403 404 static int 405 check_slots(void) 406 { 407 struct slot *slot; 408 int extracted; 409 int inserted; 410 u16 hs_csr; 411 412 down_read(&list_rwsem); 413 if (!slots) { 414 up_read(&list_rwsem); 415 err("no slots registered, shutting down"); 416 return -1; 417 } 418 extracted = inserted = 0; 419 list_for_each_entry(slot, &slot_list, slot_list) { 420 dbg("%s - looking at slot %s", 421 __FUNCTION__, slot->hotplug_slot->name); 422 if (cpci_check_and_clear_ins(slot)) { 423 /* 424 * Some broken hardware (e.g. PLX 9054AB) asserts 425 * ENUM# twice... 426 */ 427 if (slot->dev) { 428 warn("slot %s already inserted", 429 slot->hotplug_slot->name); 430 inserted++; 431 continue; 432 } 433 434 /* Process insertion */ 435 dbg("%s - slot %s inserted", 436 __FUNCTION__, slot->hotplug_slot->name); 437 438 /* GSM, debug */ 439 hs_csr = cpci_get_hs_csr(slot); 440 dbg("%s - slot %s HS_CSR (1) = %04x", 441 __FUNCTION__, slot->hotplug_slot->name, hs_csr); 442 443 /* Configure device */ 444 dbg("%s - configuring slot %s", 445 __FUNCTION__, slot->hotplug_slot->name); 446 if (cpci_configure_slot(slot)) { 447 err("%s - could not configure slot %s", 448 __FUNCTION__, slot->hotplug_slot->name); 449 continue; 450 } 451 dbg("%s - finished configuring slot %s", 452 __FUNCTION__, slot->hotplug_slot->name); 453 454 /* GSM, debug */ 455 hs_csr = cpci_get_hs_csr(slot); 456 dbg("%s - slot %s HS_CSR (2) = %04x", 457 __FUNCTION__, slot->hotplug_slot->name, hs_csr); 458 459 if (update_latch_status(slot->hotplug_slot, 1)) 460 warn("failure to update latch file"); 461 462 if (update_adapter_status(slot->hotplug_slot, 1)) 463 warn("failure to update adapter file"); 464 465 cpci_led_off(slot); 466 467 /* GSM, debug */ 468 hs_csr = cpci_get_hs_csr(slot); 469 dbg("%s - slot %s HS_CSR (3) = %04x", 470 __FUNCTION__, slot->hotplug_slot->name, hs_csr); 471 472 inserted++; 473 } else if (cpci_check_ext(slot)) { 474 /* Process extraction request */ 475 dbg("%s - slot %s extracted", 476 __FUNCTION__, slot->hotplug_slot->name); 477 478 /* GSM, debug */ 479 hs_csr = cpci_get_hs_csr(slot); 480 dbg("%s - slot %s HS_CSR = %04x", 481 __FUNCTION__, slot->hotplug_slot->name, hs_csr); 482 483 if (!slot->extracting) { 484 if (update_latch_status(slot->hotplug_slot, 0)) { 485 warn("failure to update latch file"); 486 } 487 slot->extracting = 1; 488 atomic_inc(&extracting); 489 } 490 extracted++; 491 } else if (slot->extracting) { 492 hs_csr = cpci_get_hs_csr(slot); 493 if (hs_csr == 0xffff) { 494 /* 495 * Hmmm, we're likely hosed at this point, should we 496 * bother trying to tell the driver or not? 497 */ 498 err("card in slot %s was improperly removed", 499 slot->hotplug_slot->name); 500 if (update_adapter_status(slot->hotplug_slot, 0)) 501 warn("failure to update adapter file"); 502 slot->extracting = 0; 503 atomic_dec(&extracting); 504 } 505 } 506 } 507 up_read(&list_rwsem); 508 dbg("inserted=%d, extracted=%d, extracting=%d", 509 inserted, extracted, atomic_read(&extracting)); 510 if (inserted || extracted) 511 return extracted; 512 else if (!atomic_read(&extracting)) { 513 err("cannot find ENUM# source, shutting down"); 514 return -1; 515 } 516 return 0; 517 } 518 519 /* This is the interrupt mode worker thread body */ 520 static int 521 event_thread(void *data) 522 { 523 int rc; 524 525 lock_kernel(); 526 daemonize("cpci_hp_eventd"); 527 unlock_kernel(); 528 529 dbg("%s - event thread started", __FUNCTION__); 530 while (1) { 531 dbg("event thread sleeping"); 532 down_interruptible(&event_semaphore); 533 dbg("event thread woken, thread_finished = %d", 534 thread_finished); 535 if (thread_finished || signal_pending(current)) 536 break; 537 do { 538 rc = check_slots(); 539 if (rc > 0) { 540 /* Give userspace a chance to handle extraction */ 541 msleep(500); 542 } else if (rc < 0) { 543 dbg("%s - error checking slots", __FUNCTION__); 544 thread_finished = 1; 545 break; 546 } 547 } while (atomic_read(&extracting) && !thread_finished); 548 if (thread_finished) 549 break; 550 551 /* Re-enable ENUM# interrupt */ 552 dbg("%s - re-enabling irq", __FUNCTION__); 553 controller->ops->enable_irq(); 554 } 555 dbg("%s - event thread signals exit", __FUNCTION__); 556 up(&thread_exit); 557 return 0; 558 } 559 560 /* This is the polling mode worker thread body */ 561 static int 562 poll_thread(void *data) 563 { 564 int rc; 565 566 lock_kernel(); 567 daemonize("cpci_hp_polld"); 568 unlock_kernel(); 569 570 while (1) { 571 if (thread_finished || signal_pending(current)) 572 break; 573 if (controller->ops->query_enum()) { 574 do { 575 rc = check_slots(); 576 if (rc > 0) { 577 /* Give userspace a chance to handle extraction */ 578 msleep(500); 579 } else if (rc < 0) { 580 dbg("%s - error checking slots", __FUNCTION__); 581 thread_finished = 1; 582 break; 583 } 584 } while (atomic_read(&extracting) && !thread_finished); 585 } 586 msleep(100); 587 } 588 dbg("poll thread signals exit"); 589 up(&thread_exit); 590 return 0; 591 } 592 593 static int 594 cpci_start_thread(void) 595 { 596 int pid; 597 598 /* initialize our semaphores */ 599 init_MUTEX_LOCKED(&event_semaphore); 600 init_MUTEX_LOCKED(&thread_exit); 601 thread_finished = 0; 602 603 if (controller->irq) 604 pid = kernel_thread(event_thread, NULL, 0); 605 else 606 pid = kernel_thread(poll_thread, NULL, 0); 607 if (pid < 0) { 608 err("Can't start up our thread"); 609 return -1; 610 } 611 dbg("Our thread pid = %d", pid); 612 return 0; 613 } 614 615 static void 616 cpci_stop_thread(void) 617 { 618 thread_finished = 1; 619 dbg("thread finish command given"); 620 if (controller->irq) 621 up(&event_semaphore); 622 dbg("wait for thread to exit"); 623 down(&thread_exit); 624 } 625 626 int 627 cpci_hp_register_controller(struct cpci_hp_controller *new_controller) 628 { 629 int status = 0; 630 631 if (controller) 632 return -1; 633 if (!(new_controller && new_controller->ops)) 634 return -EINVAL; 635 if (new_controller->irq) { 636 if (!(new_controller->ops->enable_irq && 637 new_controller->ops->disable_irq)) 638 status = -EINVAL; 639 if (request_irq(new_controller->irq, 640 cpci_hp_intr, 641 new_controller->irq_flags, 642 MY_NAME, 643 new_controller->dev_id)) { 644 err("Can't get irq %d for the hotplug cPCI controller", 645 new_controller->irq); 646 status = -ENODEV; 647 } 648 dbg("%s - acquired controller irq %d", 649 __FUNCTION__, new_controller->irq); 650 } 651 if (!status) 652 controller = new_controller; 653 return status; 654 } 655 656 static void 657 cleanup_slots(void) 658 { 659 struct slot *slot; 660 struct slot *tmp; 661 662 /* 663 * Unregister all of our slots with the pci_hotplug subsystem, 664 * and free up all memory that we had allocated. 665 */ 666 down_write(&list_rwsem); 667 if (!slots) 668 goto cleanup_null; 669 list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) { 670 list_del(&slot->slot_list); 671 pci_hp_deregister(slot->hotplug_slot); 672 } 673 cleanup_null: 674 up_write(&list_rwsem); 675 return; 676 } 677 678 int 679 cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller) 680 { 681 int status = 0; 682 683 if (controller) { 684 if (!thread_finished) 685 cpci_stop_thread(); 686 if (controller->irq) 687 free_irq(controller->irq, controller->dev_id); 688 controller = NULL; 689 cleanup_slots(); 690 } else 691 status = -ENODEV; 692 return status; 693 } 694 695 int 696 cpci_hp_start(void) 697 { 698 static int first = 1; 699 int status; 700 701 dbg("%s - enter", __FUNCTION__); 702 if (!controller) 703 return -ENODEV; 704 705 down_read(&list_rwsem); 706 if (list_empty(&slot_list)) { 707 up_read(&list_rwsem); 708 return -ENODEV; 709 } 710 up_read(&list_rwsem); 711 712 status = init_slots(first); 713 if (first) 714 first = 0; 715 if (status) 716 return status; 717 718 status = cpci_start_thread(); 719 if (status) 720 return status; 721 dbg("%s - thread started", __FUNCTION__); 722 723 if (controller->irq) { 724 /* Start enum interrupt processing */ 725 dbg("%s - enabling irq", __FUNCTION__); 726 controller->ops->enable_irq(); 727 } 728 dbg("%s - exit", __FUNCTION__); 729 return 0; 730 } 731 732 int 733 cpci_hp_stop(void) 734 { 735 if (!controller) 736 return -ENODEV; 737 if (controller->irq) { 738 /* Stop enum interrupt processing */ 739 dbg("%s - disabling irq", __FUNCTION__); 740 controller->ops->disable_irq(); 741 } 742 cpci_stop_thread(); 743 return 0; 744 } 745 746 int __init 747 cpci_hotplug_init(int debug) 748 { 749 cpci_debug = debug; 750 return 0; 751 } 752 753 void __exit 754 cpci_hotplug_exit(void) 755 { 756 /* 757 * Clean everything up. 758 */ 759 cpci_hp_stop(); 760 cpci_hp_unregister_controller(controller); 761 } 762 763 EXPORT_SYMBOL_GPL(cpci_hp_register_controller); 764 EXPORT_SYMBOL_GPL(cpci_hp_unregister_controller); 765 EXPORT_SYMBOL_GPL(cpci_hp_register_bus); 766 EXPORT_SYMBOL_GPL(cpci_hp_unregister_bus); 767 EXPORT_SYMBOL_GPL(cpci_hp_start); 768 EXPORT_SYMBOL_GPL(cpci_hp_stop); 769