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 slot *slot) 199 { 200 kfree(slot->hotplug_slot->info); 201 kfree(slot->hotplug_slot); 202 pci_dev_put(slot->dev); 203 kfree(slot); 204 } 205 206 #define SLOT_NAME_SIZE 6 207 208 int 209 cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) 210 { 211 struct slot *slot; 212 struct hotplug_slot *hotplug_slot; 213 struct hotplug_slot_info *info; 214 char name[SLOT_NAME_SIZE]; 215 int status; 216 int i; 217 218 if (!(controller && bus)) 219 return -ENODEV; 220 221 /* 222 * Create a structure for each slot, and register that slot 223 * with the pci_hotplug subsystem. 224 */ 225 for (i = first; i <= last; ++i) { 226 slot = kzalloc(sizeof(struct slot), GFP_KERNEL); 227 if (!slot) { 228 status = -ENOMEM; 229 goto error; 230 } 231 232 hotplug_slot = 233 kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); 234 if (!hotplug_slot) { 235 status = -ENOMEM; 236 goto error_slot; 237 } 238 slot->hotplug_slot = hotplug_slot; 239 240 info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); 241 if (!info) { 242 status = -ENOMEM; 243 goto error_hpslot; 244 } 245 hotplug_slot->info = info; 246 247 slot->bus = bus; 248 slot->number = i; 249 slot->devfn = PCI_DEVFN(i, 0); 250 251 snprintf(name, SLOT_NAME_SIZE, "%02x:%02x", bus->number, i); 252 253 hotplug_slot->private = slot; 254 hotplug_slot->ops = &cpci_hotplug_slot_ops; 255 256 /* 257 * Initialize the slot info structure with some known 258 * good values. 259 */ 260 dbg("initializing slot %s", name); 261 info->power_status = cpci_get_power_status(slot); 262 info->attention_status = cpci_get_attention_status(slot); 263 264 dbg("registering slot %s", name); 265 status = pci_hp_register(slot->hotplug_slot, bus, i, name); 266 if (status) { 267 err("pci_hp_register failed with error %d", status); 268 goto error_info; 269 } 270 dbg("slot registered with name: %s", slot_name(slot)); 271 272 /* Add slot to our internal list */ 273 down_write(&list_rwsem); 274 list_add(&slot->slot_list, &slot_list); 275 slots++; 276 up_write(&list_rwsem); 277 } 278 return 0; 279 error_info: 280 kfree(info); 281 error_hpslot: 282 kfree(hotplug_slot); 283 error_slot: 284 kfree(slot); 285 error: 286 return status; 287 } 288 EXPORT_SYMBOL_GPL(cpci_hp_register_bus); 289 290 int 291 cpci_hp_unregister_bus(struct pci_bus *bus) 292 { 293 struct slot *slot; 294 struct slot *tmp; 295 int status = 0; 296 297 down_write(&list_rwsem); 298 if (!slots) { 299 up_write(&list_rwsem); 300 return -1; 301 } 302 list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) { 303 if (slot->bus == bus) { 304 list_del(&slot->slot_list); 305 slots--; 306 307 dbg("deregistering slot %s", slot_name(slot)); 308 pci_hp_deregister(slot->hotplug_slot); 309 release_slot(slot); 310 } 311 } 312 up_write(&list_rwsem); 313 return status; 314 } 315 EXPORT_SYMBOL_GPL(cpci_hp_unregister_bus); 316 317 /* This is the interrupt mode interrupt handler */ 318 static irqreturn_t 319 cpci_hp_intr(int irq, void *data) 320 { 321 dbg("entered cpci_hp_intr"); 322 323 /* Check to see if it was our interrupt */ 324 if ((controller->irq_flags & IRQF_SHARED) && 325 !controller->ops->check_irq(controller->dev_id)) { 326 dbg("exited cpci_hp_intr, not our interrupt"); 327 return IRQ_NONE; 328 } 329 330 /* Disable ENUM interrupt */ 331 controller->ops->disable_irq(); 332 333 /* Trigger processing by the event thread */ 334 wake_up_process(cpci_thread); 335 return IRQ_HANDLED; 336 } 337 338 /* 339 * According to PICMG 2.1 R2.0, section 6.3.2, upon 340 * initialization, the system driver shall clear the 341 * INS bits of the cold-inserted devices. 342 */ 343 static int 344 init_slots(int clear_ins) 345 { 346 struct slot *slot; 347 struct pci_dev *dev; 348 349 dbg("%s - enter", __func__); 350 down_read(&list_rwsem); 351 if (!slots) { 352 up_read(&list_rwsem); 353 return -1; 354 } 355 list_for_each_entry(slot, &slot_list, slot_list) { 356 dbg("%s - looking at slot %s", __func__, slot_name(slot)); 357 if (clear_ins && cpci_check_and_clear_ins(slot)) 358 dbg("%s - cleared INS for slot %s", 359 __func__, slot_name(slot)); 360 dev = pci_get_slot(slot->bus, PCI_DEVFN(slot->number, 0)); 361 if (dev) { 362 if (update_adapter_status(slot->hotplug_slot, 1)) 363 warn("failure to update adapter file"); 364 if (update_latch_status(slot->hotplug_slot, 1)) 365 warn("failure to update latch file"); 366 slot->dev = dev; 367 } 368 } 369 up_read(&list_rwsem); 370 dbg("%s - exit", __func__); 371 return 0; 372 } 373 374 static int 375 check_slots(void) 376 { 377 struct slot *slot; 378 int extracted; 379 int inserted; 380 u16 hs_csr; 381 382 down_read(&list_rwsem); 383 if (!slots) { 384 up_read(&list_rwsem); 385 err("no slots registered, shutting down"); 386 return -1; 387 } 388 extracted = inserted = 0; 389 list_for_each_entry(slot, &slot_list, slot_list) { 390 dbg("%s - looking at slot %s", __func__, slot_name(slot)); 391 if (cpci_check_and_clear_ins(slot)) { 392 /* 393 * Some broken hardware (e.g. PLX 9054AB) asserts 394 * ENUM# twice... 395 */ 396 if (slot->dev) { 397 warn("slot %s already inserted", 398 slot_name(slot)); 399 inserted++; 400 continue; 401 } 402 403 /* Process insertion */ 404 dbg("%s - slot %s inserted", __func__, slot_name(slot)); 405 406 /* GSM, debug */ 407 hs_csr = cpci_get_hs_csr(slot); 408 dbg("%s - slot %s HS_CSR (1) = %04x", 409 __func__, slot_name(slot), hs_csr); 410 411 /* Configure device */ 412 dbg("%s - configuring slot %s", 413 __func__, slot_name(slot)); 414 if (cpci_configure_slot(slot)) { 415 err("%s - could not configure slot %s", 416 __func__, slot_name(slot)); 417 continue; 418 } 419 dbg("%s - finished configuring slot %s", 420 __func__, slot_name(slot)); 421 422 /* GSM, debug */ 423 hs_csr = cpci_get_hs_csr(slot); 424 dbg("%s - slot %s HS_CSR (2) = %04x", 425 __func__, slot_name(slot), hs_csr); 426 427 if (update_latch_status(slot->hotplug_slot, 1)) 428 warn("failure to update latch file"); 429 430 if (update_adapter_status(slot->hotplug_slot, 1)) 431 warn("failure to update adapter file"); 432 433 cpci_led_off(slot); 434 435 /* GSM, debug */ 436 hs_csr = cpci_get_hs_csr(slot); 437 dbg("%s - slot %s HS_CSR (3) = %04x", 438 __func__, slot_name(slot), hs_csr); 439 440 inserted++; 441 } else if (cpci_check_ext(slot)) { 442 /* Process extraction request */ 443 dbg("%s - slot %s extracted", 444 __func__, slot_name(slot)); 445 446 /* GSM, debug */ 447 hs_csr = cpci_get_hs_csr(slot); 448 dbg("%s - slot %s HS_CSR = %04x", 449 __func__, slot_name(slot), hs_csr); 450 451 if (!slot->extracting) { 452 if (update_latch_status(slot->hotplug_slot, 0)) 453 warn("failure to update latch file"); 454 455 slot->extracting = 1; 456 atomic_inc(&extracting); 457 } 458 extracted++; 459 } else if (slot->extracting) { 460 hs_csr = cpci_get_hs_csr(slot); 461 if (hs_csr == 0xffff) { 462 /* 463 * Hmmm, we're likely hosed at this point, should we 464 * bother trying to tell the driver or not? 465 */ 466 err("card in slot %s was improperly removed", 467 slot_name(slot)); 468 if (update_adapter_status(slot->hotplug_slot, 0)) 469 warn("failure to update adapter file"); 470 slot->extracting = 0; 471 atomic_dec(&extracting); 472 } 473 } 474 } 475 up_read(&list_rwsem); 476 dbg("inserted=%d, extracted=%d, extracting=%d", 477 inserted, extracted, atomic_read(&extracting)); 478 if (inserted || extracted) 479 return extracted; 480 else if (!atomic_read(&extracting)) { 481 err("cannot find ENUM# source, shutting down"); 482 return -1; 483 } 484 return 0; 485 } 486 487 /* This is the interrupt mode worker thread body */ 488 static int 489 event_thread(void *data) 490 { 491 int rc; 492 493 dbg("%s - event thread started", __func__); 494 while (1) { 495 dbg("event thread sleeping"); 496 set_current_state(TASK_INTERRUPTIBLE); 497 schedule(); 498 if (kthread_should_stop()) 499 break; 500 do { 501 rc = check_slots(); 502 if (rc > 0) { 503 /* Give userspace a chance to handle extraction */ 504 msleep(500); 505 } else if (rc < 0) { 506 dbg("%s - error checking slots", __func__); 507 thread_finished = 1; 508 goto out; 509 } 510 } while (atomic_read(&extracting) && !kthread_should_stop()); 511 if (kthread_should_stop()) 512 break; 513 514 /* Re-enable ENUM# interrupt */ 515 dbg("%s - re-enabling irq", __func__); 516 controller->ops->enable_irq(); 517 } 518 out: 519 return 0; 520 } 521 522 /* This is the polling mode worker thread body */ 523 static int 524 poll_thread(void *data) 525 { 526 int rc; 527 528 while (1) { 529 if (kthread_should_stop() || signal_pending(current)) 530 break; 531 if (controller->ops->query_enum()) { 532 do { 533 rc = check_slots(); 534 if (rc > 0) { 535 /* Give userspace a chance to handle extraction */ 536 msleep(500); 537 } else if (rc < 0) { 538 dbg("%s - error checking slots", __func__); 539 thread_finished = 1; 540 goto out; 541 } 542 } while (atomic_read(&extracting) && !kthread_should_stop()); 543 } 544 msleep(100); 545 } 546 out: 547 return 0; 548 } 549 550 static int 551 cpci_start_thread(void) 552 { 553 if (controller->irq) 554 cpci_thread = kthread_run(event_thread, NULL, "cpci_hp_eventd"); 555 else 556 cpci_thread = kthread_run(poll_thread, NULL, "cpci_hp_polld"); 557 if (IS_ERR(cpci_thread)) { 558 err("Can't start up our thread"); 559 return PTR_ERR(cpci_thread); 560 } 561 thread_finished = 0; 562 return 0; 563 } 564 565 static void 566 cpci_stop_thread(void) 567 { 568 kthread_stop(cpci_thread); 569 thread_finished = 1; 570 } 571 572 int 573 cpci_hp_register_controller(struct cpci_hp_controller *new_controller) 574 { 575 int status = 0; 576 577 if (controller) 578 return -1; 579 if (!(new_controller && new_controller->ops)) 580 return -EINVAL; 581 if (new_controller->irq) { 582 if (!(new_controller->ops->enable_irq && 583 new_controller->ops->disable_irq)) 584 status = -EINVAL; 585 if (request_irq(new_controller->irq, 586 cpci_hp_intr, 587 new_controller->irq_flags, 588 MY_NAME, 589 new_controller->dev_id)) { 590 err("Can't get irq %d for the hotplug cPCI controller", 591 new_controller->irq); 592 status = -ENODEV; 593 } 594 dbg("%s - acquired controller irq %d", 595 __func__, new_controller->irq); 596 } 597 if (!status) 598 controller = new_controller; 599 return status; 600 } 601 EXPORT_SYMBOL_GPL(cpci_hp_register_controller); 602 603 static void 604 cleanup_slots(void) 605 { 606 struct slot *slot; 607 struct slot *tmp; 608 609 /* 610 * Unregister all of our slots with the pci_hotplug subsystem, 611 * and free up all memory that we had allocated. 612 */ 613 down_write(&list_rwsem); 614 if (!slots) 615 goto cleanup_null; 616 list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) { 617 list_del(&slot->slot_list); 618 pci_hp_deregister(slot->hotplug_slot); 619 release_slot(slot); 620 } 621 cleanup_null: 622 up_write(&list_rwsem); 623 return; 624 } 625 626 int 627 cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller) 628 { 629 int status = 0; 630 631 if (controller) { 632 if (!thread_finished) 633 cpci_stop_thread(); 634 if (controller->irq) 635 free_irq(controller->irq, controller->dev_id); 636 controller = NULL; 637 cleanup_slots(); 638 } else 639 status = -ENODEV; 640 return status; 641 } 642 EXPORT_SYMBOL_GPL(cpci_hp_unregister_controller); 643 644 int 645 cpci_hp_start(void) 646 { 647 static int first = 1; 648 int status; 649 650 dbg("%s - enter", __func__); 651 if (!controller) 652 return -ENODEV; 653 654 down_read(&list_rwsem); 655 if (list_empty(&slot_list)) { 656 up_read(&list_rwsem); 657 return -ENODEV; 658 } 659 up_read(&list_rwsem); 660 661 status = init_slots(first); 662 if (first) 663 first = 0; 664 if (status) 665 return status; 666 667 status = cpci_start_thread(); 668 if (status) 669 return status; 670 dbg("%s - thread started", __func__); 671 672 if (controller->irq) { 673 /* Start enum interrupt processing */ 674 dbg("%s - enabling irq", __func__); 675 controller->ops->enable_irq(); 676 } 677 dbg("%s - exit", __func__); 678 return 0; 679 } 680 EXPORT_SYMBOL_GPL(cpci_hp_start); 681 682 int 683 cpci_hp_stop(void) 684 { 685 if (!controller) 686 return -ENODEV; 687 if (controller->irq) { 688 /* Stop enum interrupt processing */ 689 dbg("%s - disabling irq", __func__); 690 controller->ops->disable_irq(); 691 } 692 cpci_stop_thread(); 693 return 0; 694 } 695 EXPORT_SYMBOL_GPL(cpci_hp_stop); 696 697 int __init 698 cpci_hotplug_init(int debug) 699 { 700 cpci_debug = debug; 701 return 0; 702 } 703