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