2  * CompactPCI Hot Plug Driver
 
   4  * Copyright (C) 2002,2005 SOMA Networks, Inc.
 
   5  * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
 
   6  * Copyright (C) 2001 IBM Corp.
 
  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.
 
  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
 
  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.
 
  25  * Send feedback to <scottm@somanetworks.com>
 
  28 #include <linux/module.h>
 
  29 #include <linux/kernel.h>
 
  30 #include <linux/slab.h>
 
  31 #include <linux/pci.h>
 
  32 #include <linux/pci_hotplug.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 <linux/kthread.h>
 
  39 #include "cpci_hotplug.h"
 
  41 #define DRIVER_AUTHOR   "Scott Murray <scottm@somanetworks.com>"
 
  42 #define DRIVER_DESC     "CompactPCI Hot Plug Core"
 
  44 #define MY_NAME "cpci_hotplug"
 
  46 #define dbg(format, arg...)                                     \
 
  49                         printk (KERN_DEBUG "%s: " format "\n",  \
 
  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)
 
  57 static DECLARE_RWSEM(list_rwsem);
 
  58 static LIST_HEAD(slot_list);
 
  60 static atomic_t extracting;
 
  62 static struct cpci_hp_controller *controller;
 
  63 static struct task_struct *cpci_thread;
 
  64 static int thread_finished;
 
  66 static int enable_slot(struct hotplug_slot *slot);
 
  67 static int disable_slot(struct hotplug_slot *slot);
 
  68 static int set_attention_status(struct hotplug_slot *slot, u8 value);
 
  69 static int get_power_status(struct hotplug_slot *slot, u8 * value);
 
  70 static int get_attention_status(struct hotplug_slot *slot, u8 * value);
 
  71 static int get_adapter_status(struct hotplug_slot *slot, u8 * value);
 
  72 static int get_latch_status(struct hotplug_slot *slot, u8 * value);
 
  74 static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
 
  76         .enable_slot = enable_slot,
 
  77         .disable_slot = disable_slot,
 
  78         .set_attention_status = set_attention_status,
 
  79         .get_power_status = get_power_status,
 
  80         .get_attention_status = get_attention_status,
 
  81         .get_adapter_status = get_adapter_status,
 
  82         .get_latch_status = get_latch_status,
 
  86 update_latch_status(struct hotplug_slot *hotplug_slot, u8 value)
 
  88         struct hotplug_slot_info info;
 
  90         memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
 
  91         info.latch_status = value;
 
  92         return pci_hp_change_slot_info(hotplug_slot, &info);
 
  96 update_adapter_status(struct hotplug_slot *hotplug_slot, u8 value)
 
  98         struct hotplug_slot_info info;
 
 100         memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
 
 101         info.adapter_status = value;
 
 102         return pci_hp_change_slot_info(hotplug_slot, &info);
 
 106 enable_slot(struct hotplug_slot *hotplug_slot)
 
 108         struct slot *slot = hotplug_slot->private;
 
 111         dbg("%s - physical_slot = %s", __func__, slot_name(slot));
 
 113         if (controller->ops->set_power)
 
 114                 retval = controller->ops->set_power(slot, 1);
 
 119 disable_slot(struct hotplug_slot *hotplug_slot)
 
 121         struct slot *slot = hotplug_slot->private;
 
 124         dbg("%s - physical_slot = %s", __func__, slot_name(slot));
 
 126         down_write(&list_rwsem);
 
 128         /* Unconfigure device */
 
 129         dbg("%s - unconfiguring slot %s", __func__, slot_name(slot));
 
 130         if ((retval = cpci_unconfigure_slot(slot))) {
 
 131                 err("%s - could not unconfigure slot %s",
 
 132                     __func__, slot_name(slot));
 
 135         dbg("%s - finished unconfiguring slot %s", __func__, slot_name(slot));
 
 137         /* Clear EXT (by setting it) */
 
 138         if (cpci_clear_ext(slot)) {
 
 139                 err("%s - could not clear EXT for slot %s",
 
 140                     __func__, slot_name(slot));
 
 146         if (controller->ops->set_power)
 
 147                 if ((retval = controller->ops->set_power(slot, 0)))
 
 150         if (update_adapter_status(slot->hotplug_slot, 0))
 
 151                 warn("failure to update adapter file");
 
 153         if (slot->extracting) {
 
 154                 slot->extracting = 0;
 
 155                 atomic_dec(&extracting);
 
 158         up_write(&list_rwsem);
 
 163 cpci_get_power_status(struct slot *slot)
 
 167         if (controller->ops->get_power)
 
 168                 power = controller->ops->get_power(slot);
 
 173 get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
 
 175         struct slot *slot = hotplug_slot->private;
 
 177         *value = cpci_get_power_status(slot);
 
 182 get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
 
 184         struct slot *slot = hotplug_slot->private;
 
 186         *value = cpci_get_attention_status(slot);
 
 191 set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
 
 193         return cpci_set_attention_status(hotplug_slot->private, status);
 
 197 get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value)
 
 199         *value = hotplug_slot->info->adapter_status;
 
 204 get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
 
 206         *value = hotplug_slot->info->latch_status;
 
 210 static void release_slot(struct hotplug_slot *hotplug_slot)
 
 212         struct slot *slot = hotplug_slot->private;
 
 214         kfree(slot->hotplug_slot->info);
 
 215         kfree(slot->hotplug_slot);
 
 217                 pci_dev_put(slot->dev);
 
 221 #define SLOT_NAME_SIZE  6
 
 224 cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
 
 227         struct hotplug_slot *hotplug_slot;
 
 228         struct hotplug_slot_info *info;
 
 229         char name[SLOT_NAME_SIZE];
 
 230         int status = -ENOMEM;
 
 233         if (!(controller && bus))
 
 237          * Create a structure for each slot, and register that slot
 
 238          * with the pci_hotplug subsystem.
 
 240         for (i = first; i <= last; ++i) {
 
 241                 slot = kzalloc(sizeof (struct slot), GFP_KERNEL);
 
 246                         kzalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
 
 249                 slot->hotplug_slot = hotplug_slot;
 
 251                 info = kzalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL);
 
 254                 hotplug_slot->info = info;
 
 258                 slot->devfn = PCI_DEVFN(i, 0);
 
 260                 snprintf(name, SLOT_NAME_SIZE, "%02x:%02x", bus->number, i);
 
 262                 hotplug_slot->private = slot;
 
 263                 hotplug_slot->release = &release_slot;
 
 264                 hotplug_slot->ops = &cpci_hotplug_slot_ops;
 
 267                  * Initialize the slot info structure with some known
 
 270                 dbg("initializing slot %s", name);
 
 271                 info->power_status = cpci_get_power_status(slot);
 
 272                 info->attention_status = cpci_get_attention_status(slot);
 
 274                 dbg("registering slot %s", name);
 
 275                 status = pci_hp_register(slot->hotplug_slot, bus, i, name);
 
 277                         err("pci_hp_register failed with error %d", status);
 
 280                 dbg("slot registered with name: %s", slot_name(slot));
 
 282                 /* Add slot to our internal list */
 
 283                 down_write(&list_rwsem);
 
 284                 list_add(&slot->slot_list, &slot_list);
 
 286                 up_write(&list_rwsem);
 
 300 cpci_hp_unregister_bus(struct pci_bus *bus)
 
 306         down_write(&list_rwsem);
 
 308                 up_write(&list_rwsem);
 
 311         list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) {
 
 312                 if (slot->bus == bus) {
 
 313                         list_del(&slot->slot_list);
 
 316                         dbg("deregistering slot %s", slot_name(slot));
 
 317                         status = pci_hp_deregister(slot->hotplug_slot);
 
 319                                 err("pci_hp_deregister failed with error %d",
 
 325         up_write(&list_rwsem);
 
 329 /* This is the interrupt mode interrupt handler */
 
 331 cpci_hp_intr(int irq, void *data)
 
 333         dbg("entered cpci_hp_intr");
 
 335         /* Check to see if it was our interrupt */
 
 336         if ((controller->irq_flags & IRQF_SHARED) &&
 
 337             !controller->ops->check_irq(controller->dev_id)) {
 
 338                 dbg("exited cpci_hp_intr, not our interrupt");
 
 342         /* Disable ENUM interrupt */
 
 343         controller->ops->disable_irq();
 
 345         /* Trigger processing by the event thread */
 
 346         wake_up_process(cpci_thread);
 
 351  * According to PICMG 2.1 R2.0, section 6.3.2, upon
 
 352  * initialization, the system driver shall clear the
 
 353  * INS bits of the cold-inserted devices.
 
 356 init_slots(int clear_ins)
 
 361         dbg("%s - enter", __func__);
 
 362         down_read(&list_rwsem);
 
 364                 up_read(&list_rwsem);
 
 367         list_for_each_entry(slot, &slot_list, slot_list) {
 
 368                 dbg("%s - looking at slot %s", __func__, slot_name(slot));
 
 369                 if (clear_ins && cpci_check_and_clear_ins(slot))
 
 370                         dbg("%s - cleared INS for slot %s",
 
 371                             __func__, slot_name(slot));
 
 372                 dev = pci_get_slot(slot->bus, PCI_DEVFN(slot->number, 0));
 
 374                         if (update_adapter_status(slot->hotplug_slot, 1))
 
 375                                 warn("failure to update adapter file");
 
 376                         if (update_latch_status(slot->hotplug_slot, 1))
 
 377                                 warn("failure to update latch file");
 
 381         up_read(&list_rwsem);
 
 382         dbg("%s - exit", __func__);
 
 394         down_read(&list_rwsem);
 
 396                 up_read(&list_rwsem);
 
 397                 err("no slots registered, shutting down");
 
 400         extracted = inserted = 0;
 
 401         list_for_each_entry(slot, &slot_list, slot_list) {
 
 402                 dbg("%s - looking at slot %s", __func__, slot_name(slot));
 
 403                 if (cpci_check_and_clear_ins(slot)) {
 
 405                          * Some broken hardware (e.g. PLX 9054AB) asserts
 
 409                                 warn("slot %s already inserted",
 
 415                         /* Process insertion */
 
 416                         dbg("%s - slot %s inserted", __func__, slot_name(slot));
 
 419                         hs_csr = cpci_get_hs_csr(slot);
 
 420                         dbg("%s - slot %s HS_CSR (1) = %04x",
 
 421                             __func__, slot_name(slot), hs_csr);
 
 423                         /* Configure device */
 
 424                         dbg("%s - configuring slot %s",
 
 425                             __func__, slot_name(slot));
 
 426                         if (cpci_configure_slot(slot)) {
 
 427                                 err("%s - could not configure slot %s",
 
 428                                     __func__, slot_name(slot));
 
 431                         dbg("%s - finished configuring slot %s",
 
 432                             __func__, slot_name(slot));
 
 435                         hs_csr = cpci_get_hs_csr(slot);
 
 436                         dbg("%s - slot %s HS_CSR (2) = %04x",
 
 437                             __func__, slot_name(slot), hs_csr);
 
 439                         if (update_latch_status(slot->hotplug_slot, 1))
 
 440                                 warn("failure to update latch file");
 
 442                         if (update_adapter_status(slot->hotplug_slot, 1))
 
 443                                 warn("failure to update adapter file");
 
 448                         hs_csr = cpci_get_hs_csr(slot);
 
 449                         dbg("%s - slot %s HS_CSR (3) = %04x",
 
 450                             __func__, slot_name(slot), hs_csr);
 
 453                 } else if (cpci_check_ext(slot)) {
 
 454                         /* Process extraction request */
 
 455                         dbg("%s - slot %s extracted",
 
 456                             __func__, slot_name(slot));
 
 459                         hs_csr = cpci_get_hs_csr(slot);
 
 460                         dbg("%s - slot %s HS_CSR = %04x",
 
 461                             __func__, slot_name(slot), hs_csr);
 
 463                         if (!slot->extracting) {
 
 464                                 if (update_latch_status(slot->hotplug_slot, 0)) {
 
 465                                         warn("failure to update latch file");
 
 467                                 slot->extracting = 1;
 
 468                                 atomic_inc(&extracting);
 
 471                 } else if (slot->extracting) {
 
 472                         hs_csr = cpci_get_hs_csr(slot);
 
 473                         if (hs_csr == 0xffff) {
 
 475                                  * Hmmm, we're likely hosed at this point, should we
 
 476                                  * bother trying to tell the driver or not?
 
 478                                 err("card in slot %s was improperly removed",
 
 480                                 if (update_adapter_status(slot->hotplug_slot, 0))
 
 481                                         warn("failure to update adapter file");
 
 482                                 slot->extracting = 0;
 
 483                                 atomic_dec(&extracting);
 
 487         up_read(&list_rwsem);
 
 488         dbg("inserted=%d, extracted=%d, extracting=%d",
 
 489             inserted, extracted, atomic_read(&extracting));
 
 490         if (inserted || extracted)
 
 492         else if (!atomic_read(&extracting)) {
 
 493                 err("cannot find ENUM# source, shutting down");
 
 499 /* This is the interrupt mode worker thread body */
 
 501 event_thread(void *data)
 
 505         dbg("%s - event thread started", __func__);
 
 507                 dbg("event thread sleeping");
 
 508                 set_current_state(TASK_INTERRUPTIBLE);
 
 510                 if (kthread_should_stop())
 
 515                                 /* Give userspace a chance to handle extraction */
 
 518                                 dbg("%s - error checking slots", __func__);
 
 522                 } while (atomic_read(&extracting) && !kthread_should_stop());
 
 523                 if (kthread_should_stop())
 
 526                 /* Re-enable ENUM# interrupt */
 
 527                 dbg("%s - re-enabling irq", __func__);
 
 528                 controller->ops->enable_irq();
 
 534 /* This is the polling mode worker thread body */
 
 536 poll_thread(void *data)
 
 541                 if (kthread_should_stop() || signal_pending(current))
 
 543                 if (controller->ops->query_enum()) {
 
 547                                         /* Give userspace a chance to handle extraction */
 
 550                                         dbg("%s - error checking slots", __func__);
 
 554                         } while (atomic_read(&extracting) && !kthread_should_stop());
 
 563 cpci_start_thread(void)
 
 566                 cpci_thread = kthread_run(event_thread, NULL, "cpci_hp_eventd");
 
 568                 cpci_thread = kthread_run(poll_thread, NULL, "cpci_hp_polld");
 
 569         if (IS_ERR(cpci_thread)) {
 
 570                 err("Can't start up our thread");
 
 571                 return PTR_ERR(cpci_thread);
 
 578 cpci_stop_thread(void)
 
 580         kthread_stop(cpci_thread);
 
 585 cpci_hp_register_controller(struct cpci_hp_controller *new_controller)
 
 591         if (!(new_controller && new_controller->ops))
 
 593         if (new_controller->irq) {
 
 594                 if (!(new_controller->ops->enable_irq &&
 
 595                      new_controller->ops->disable_irq))
 
 597                 if (request_irq(new_controller->irq,
 
 599                                new_controller->irq_flags,
 
 601                                new_controller->dev_id)) {
 
 602                         err("Can't get irq %d for the hotplug cPCI controller",
 
 603                             new_controller->irq);
 
 606                 dbg("%s - acquired controller irq %d",
 
 607                     __func__, new_controller->irq);
 
 610                 controller = new_controller;
 
 621          * Unregister all of our slots with the pci_hotplug subsystem,
 
 622          * and free up all memory that we had allocated.
 
 624         down_write(&list_rwsem);
 
 627         list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) {
 
 628                 list_del(&slot->slot_list);
 
 629                 pci_hp_deregister(slot->hotplug_slot);
 
 632         up_write(&list_rwsem);
 
 637 cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller)
 
 642                 if (!thread_finished)
 
 645                         free_irq(controller->irq, controller->dev_id);
 
 656         static int first = 1;
 
 659         dbg("%s - enter", __func__);
 
 663         down_read(&list_rwsem);
 
 664         if (list_empty(&slot_list)) {
 
 665                 up_read(&list_rwsem);
 
 668         up_read(&list_rwsem);
 
 670         status = init_slots(first);
 
 676         status = cpci_start_thread();
 
 679         dbg("%s - thread started", __func__);
 
 681         if (controller->irq) {
 
 682                 /* Start enum interrupt processing */
 
 683                 dbg("%s - enabling irq", __func__);
 
 684                 controller->ops->enable_irq();
 
 686         dbg("%s - exit", __func__);
 
 695         if (controller->irq) {
 
 696                 /* Stop enum interrupt processing */
 
 697                 dbg("%s - disabling irq", __func__);
 
 698                 controller->ops->disable_irq();
 
 705 cpci_hotplug_init(int debug)
 
 712 cpci_hotplug_exit(void)
 
 715          * Clean everything up.
 
 718         cpci_hp_unregister_controller(controller);
 
 721 EXPORT_SYMBOL_GPL(cpci_hp_register_controller);
 
 722 EXPORT_SYMBOL_GPL(cpci_hp_unregister_controller);
 
 723 EXPORT_SYMBOL_GPL(cpci_hp_register_bus);
 
 724 EXPORT_SYMBOL_GPL(cpci_hp_unregister_bus);
 
 725 EXPORT_SYMBOL_GPL(cpci_hp_start);
 
 726 EXPORT_SYMBOL_GPL(cpci_hp_stop);