cregit-Linux how code gets into the kernel

Release 4.7 drivers/pci/hotplug/pciehp_core.c

/*
 * PCI Express Hot Plug Controller Driver
 *
 * Copyright (C) 1995,2001 Compaq Computer Corporation
 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
 * Copyright (C) 2001 IBM Corp.
 * Copyright (C) 2003-2004 Intel Corporation
 *
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 * NON INFRINGEMENT.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
 *
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/pci.h>
#include "pciehp.h"
#include <linux/interrupt.h>
#include <linux/time.h>

/* Global variables */

bool pciehp_debug;

bool pciehp_poll_mode;

int pciehp_poll_time;

static bool pciehp_force;


#define DRIVER_VERSION	"0.4"

#define DRIVER_AUTHOR	"Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"

#define DRIVER_DESC	"PCI Express Hot Plug Controller Driver"


MODULE_AUTHOR(DRIVER_AUTHOR);

MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

module_param(pciehp_debug, bool, 0644);
module_param(pciehp_poll_mode, bool, 0644);
module_param(pciehp_poll_time, int, 0644);
module_param(pciehp_force, bool, 0644);
MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if OSHP is missing");


#define PCIE_MODULE_NAME "pciehp"

static int set_attention_status(struct hotplug_slot *slot, u8 value);
static int enable_slot(struct hotplug_slot *slot);
static int disable_slot(struct hotplug_slot *slot);
static int get_power_status(struct hotplug_slot *slot, u8 *value);
static int get_attention_status(struct hotplug_slot *slot, u8 *value);
static int get_latch_status(struct hotplug_slot *slot, u8 *value);
static int get_adapter_status(struct hotplug_slot *slot, u8 *value);
static int reset_slot(struct hotplug_slot *slot, int probe);

/**
 * release_slot - free up the memory used by a slot
 * @hotplug_slot: slot to free
 */

static void release_slot(struct hotplug_slot *hotplug_slot) { kfree(hotplug_slot->ops); kfree(hotplug_slot->info); kfree(hotplug_slot); }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy2376.67%150.00%
kenji kaneshigekenji kaneshige723.33%150.00%
Total30100.00%2100.00%


static int init_slot(struct controller *ctrl) { struct slot *slot = ctrl->slot; struct hotplug_slot *hotplug = NULL; struct hotplug_slot_info *info = NULL; struct hotplug_slot_ops *ops = NULL; char name[SLOT_NAME_SIZE]; int retval = -ENOMEM; hotplug = kzalloc(sizeof(*hotplug), GFP_KERNEL); if (!hotplug) goto out; info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) goto out; /* Setup hotplug slot ops */ ops = kzalloc(sizeof(*ops), GFP_KERNEL); if (!ops) goto out; ops->enable_slot = enable_slot; ops->disable_slot = disable_slot; ops->get_power_status = get_power_status; ops->get_adapter_status = get_adapter_status; ops->reset_slot = reset_slot; if (MRL_SENS(ctrl)) ops->get_latch_status = get_latch_status; if (ATTN_LED(ctrl)) { ops->get_attention_status = get_attention_status; ops->set_attention_status = set_attention_status; } /* register this slot with the hotplug pci core */ hotplug->info = info; hotplug->private = slot; hotplug->release = &release_slot; hotplug->ops = ops; slot->hotplug_slot = hotplug; snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl)); retval = pci_hp_register(hotplug, ctrl->pcie->port->subordinate, 0, name); if (retval) ctrl_err(ctrl, "pci_hp_register failed: error %d\n", retval); out: if (retval) { kfree(ops); kfree(info); kfree(hotplug); } return retval; }

Contributors

PersonTokensPropCommitsCommitProp
kenji kaneshigekenji kaneshige14350.18%838.10%
dely sydely sy7325.61%29.52%
alex chiangalex chiang269.12%419.05%
rolf eike beerrolf eike beer207.02%29.52%
jesper juhljesper juhl113.86%14.76%
alex williamsonalex williamson62.11%14.76%
taku izumitaku izumi31.05%14.76%
eric sesterhenneric sesterhenn20.70%14.76%
bjorn helgaasbjorn helgaas10.35%14.76%
Total285100.00%21100.00%


static void cleanup_slot(struct controller *ctrl) { pci_hp_deregister(ctrl->slot->hotplug_slot); }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy1575.00%133.33%
kenji kaneshigekenji kaneshige525.00%266.67%
Total20100.00%3100.00%

/* * set_attention_status - Turns the Amber LED for a slot on, off or blink */
static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) { struct slot *slot = hotplug_slot->private; pciehp_set_attention_status(slot, status); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy2781.82%125.00%
bjorn helgaasbjorn helgaas39.09%125.00%
rolf eike beerrolf eike beer26.06%125.00%
kenji kaneshigekenji kaneshige13.03%125.00%
Total33100.00%4100.00%


static int enable_slot(struct hotplug_slot *hotplug_slot) { struct slot *slot = hotplug_slot->private; return pciehp_sysfs_enable_slot(slot); }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy2388.46%133.33%
rolf eike beerrolf eike beer27.69%133.33%
kenji kaneshigekenji kaneshige13.85%133.33%
Total26100.00%3100.00%


static int disable_slot(struct hotplug_slot *hotplug_slot) { struct slot *slot = hotplug_slot->private; return pciehp_sysfs_disable_slot(slot); }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy2388.46%133.33%
rolf eike beerrolf eike beer27.69%133.33%
kenji kaneshigekenji kaneshige13.85%133.33%
Total26100.00%3100.00%


static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) { struct slot *slot = hotplug_slot->private; pciehp_get_power_status(slot, value); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy2882.35%125.00%
bjorn helgaasbjorn helgaas38.82%125.00%
rolf eike beerrolf eike beer25.88%125.00%
kenji kaneshigekenji kaneshige12.94%125.00%
Total34100.00%4100.00%


static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) { struct slot *slot = hotplug_slot->private; pciehp_get_attention_status(slot, value); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy2882.35%125.00%
bjorn helgaasbjorn helgaas38.82%125.00%
rolf eike beerrolf eike beer25.88%125.00%
kenji kaneshigekenji kaneshige12.94%125.00%
Total34100.00%4100.00%


static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) { struct slot *slot = hotplug_slot->private; pciehp_get_latch_status(slot, value); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy2882.35%125.00%
bjorn helgaasbjorn helgaas38.82%125.00%
rolf eike beerrolf eike beer25.88%125.00%
kenji kaneshigekenji kaneshige12.94%125.00%
Total34100.00%4100.00%


static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) { struct slot *slot = hotplug_slot->private; pciehp_get_adapter_status(slot, value); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy2882.35%125.00%
bjorn helgaasbjorn helgaas38.82%125.00%
rolf eike beerrolf eike beer25.88%125.00%
kenji kaneshigekenji kaneshige12.94%125.00%
Total34100.00%4100.00%


static int reset_slot(struct hotplug_slot *hotplug_slot, int probe) { struct slot *slot = hotplug_slot->private; return pciehp_reset_slot(slot, probe); }

Contributors

PersonTokensPropCommitsCommitProp
alex williamsonalex williamson31100.00%1100.00%
Total31100.00%1100.00%


static int pciehp_probe(struct pcie_device *dev) { int rc; struct controller *ctrl; struct slot *slot; u8 occupied, poweron; /* If this is not a "hotplug" service, we have no business here. */ if (dev->service != PCIE_PORT_SERVICE_HP) return -ENODEV; if (!dev->port->subordinate) { /* Can happen if we run out of bus numbers during probe */ dev_err(&dev->device, "Hotplug bridge without secondary bus, ignoring\n"); return -ENODEV; } ctrl = pcie_init(dev); if (!ctrl) { dev_err(&dev->device, "Controller initialization failed\n"); return -ENODEV; } set_service_data(dev, ctrl); /* Setup the slot information structures */ rc = init_slot(ctrl); if (rc) { if (rc == -EBUSY) ctrl_warn(ctrl, "Slot already registered by another hotplug driver\n"); else ctrl_err(ctrl, "Slot initialization failed (%d)\n", rc); goto err_out_release_ctlr; } /* Enable events after we have setup the data structures */ rc = pcie_init_notification(ctrl); if (rc) { ctrl_err(ctrl, "Notification initialization failed (%d)\n", rc); goto err_out_free_ctrl_slot; } /* Check if slot is occupied */ slot = ctrl->slot; pciehp_get_adapter_status(slot, &occupied); pciehp_get_power_status(slot, &poweron); if (occupied && pciehp_force) { mutex_lock(&slot->hotplug_lock); pciehp_enable_slot(slot); mutex_unlock(&slot->hotplug_lock); } /* If empty slot's power status is on, turn power off */ if (!occupied && poweron && POWER_CTRL(ctrl)) pciehp_power_off_slot(slot); return 0; err_out_free_ctrl_slot: cleanup_slot(ctrl); err_out_release_ctlr: pciehp_release_ctrl(ctrl); return -ENODEV; }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy9536.40%28.33%
kenji kaneshigekenji kaneshige4818.39%1041.67%
eric w. biedermaneric w. biederman228.43%14.17%
andreas noeverandreas noever228.43%14.17%
rajat jainrajat jain186.90%14.17%
rafael j. wysockirafael j. wysocki166.13%28.33%
alex chiangalex chiang124.60%14.17%
taku izumitaku izumi103.83%28.33%
mark lordmark lord62.30%14.17%
bjorn helgaasbjorn helgaas62.30%14.17%
tom l. nguyentom l. nguyen51.92%14.17%
ryan desfossesryan desfosses10.38%14.17%
Total261100.00%24100.00%


static void pciehp_remove(struct pcie_device *dev) { struct controller *ctrl = get_service_data(dev); cleanup_slot(ctrl); pciehp_release_ctrl(ctrl); }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy1858.06%120.00%
kenji kaneshigekenji kaneshige1341.94%480.00%
Total31100.00%5100.00%

#ifdef CONFIG_PM
static int pciehp_suspend(struct pcie_device *dev) { return 0; }

Contributors

PersonTokensPropCommitsCommitProp
tom l. nguyentom l. nguyen14100.00%1100.00%
Total14100.00%1100.00%


static int pciehp_resume(struct pcie_device *dev) { struct controller *ctrl; struct slot *slot; u8 status; ctrl = get_service_data(dev); /* reinitialize the chipset's event detection logic */ pcie_enable_notification(ctrl); slot = ctrl->slot; /* Check if slot is occupied */ pciehp_get_adapter_status(slot, &status); mutex_lock(&slot->hotplug_lock); if (status) pciehp_enable_slot(slot); else pciehp_disable_slot(slot); mutex_unlock(&slot->hotplug_lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
mark lordmark lord3237.21%112.50%
rajat jainrajat jain1618.60%112.50%
oliver neukumoliver neukum1517.44%112.50%
tom l. nguyentom l. nguyen1416.28%112.50%
kenji kaneshigekenji kaneshige910.47%450.00%
Total86100.00%8100.00%

#endif /* PM */ static struct pcie_port_service_driver hpdriver_portdrv = { .name = PCIE_MODULE_NAME, .port_type = PCIE_ANY_PORT, .service = PCIE_PORT_SERVICE_HP, .probe = pciehp_probe, .remove = pciehp_remove, #ifdef CONFIG_PM .suspend = pciehp_suspend, .resume = pciehp_resume, #endif /* PM */ };
static int __init pcied_init(void) { int retval = 0; retval = pcie_port_service_register(&hpdriver_portdrv); dbg("pcie_port_service_register = %d\n", retval); info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); if (retval) dbg("Failure to register service\n"); return retval; }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy3775.51%133.33%
tom l. nguyentom l. nguyen1122.45%133.33%
taku izumitaku izumi12.04%133.33%
Total49100.00%3100.00%


static void __exit pcied_cleanup(void) { dbg("unload_pciehpd()\n"); pcie_port_service_unregister(&hpdriver_portdrv); info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy2278.57%133.33%
kenji kaneshigekenji kaneshige310.71%133.33%
tejun heotejun heo310.71%133.33%
Total28100.00%3100.00%

module_init(pcied_init); module_exit(pcied_cleanup);

Overall Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy67949.85%46.67%
kenji kaneshigekenji kaneshige23517.25%2033.33%
tom l. nguyentom l. nguyen765.58%11.67%
alex williamsonalex williamson503.67%11.67%
rolf eike beerrolf eike beer463.38%46.67%
alex chiangalex chiang382.79%46.67%
mark lordmark lord382.79%23.33%
rajat jainrajat jain342.50%11.67%
rafael j. wysockirafael j. wysocki231.69%58.33%
eric w. biedermaneric w. biederman221.62%11.67%
andreas noeverandreas noever221.62%11.67%
bjorn helgaasbjorn helgaas221.62%23.33%
rajesh shahrajesh shah171.25%11.67%
oliver neukumoliver neukum151.10%11.67%
taku izumitaku izumi141.03%23.33%
jesper juhljesper juhl110.81%11.67%
rusty russellrusty russell60.44%23.33%
tejun heotejun heo60.44%23.33%
kristen carlson accardikristen carlson accardi40.29%23.33%
eric sesterhenneric sesterhenn20.15%11.67%
ryan desfossesryan desfosses10.07%11.67%
stephen hemmingerstephen hemminger10.07%11.67%
Total1362100.00%60100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}