cregit-Linux how code gets into the kernel

Release 4.7 drivers/pci/hotplug/shpchp_core.c

/*
 * Standard 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/types.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include "shpchp.h"

/* Global variables */

bool shpchp_debug;

bool shpchp_poll_mode;

int shpchp_poll_time;


#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	"Standard Hot Plug PCI Controller Driver"


MODULE_AUTHOR(DRIVER_AUTHOR);

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

module_param(shpchp_debug, bool, 0644);
module_param(shpchp_poll_mode, bool, 0644);
module_param(shpchp_poll_time, int, 0644);
MODULE_PARM_DESC(shpchp_debug, "Debugging mode enabled or not");
MODULE_PARM_DESC(shpchp_poll_mode, "Using polling mechanism for hot-plug events or not");
MODULE_PARM_DESC(shpchp_poll_time, "Polling mechanism frequency, in seconds");


#define SHPC_MODULE_NAME "shpchp"

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 struct hotplug_slot_ops shpchp_hotplug_slot_ops = {
	.set_attention_status =	set_attention_status,
	.enable_slot =		enable_slot,
	.disable_slot =		disable_slot,
	.get_power_status =	get_power_status,
	.get_attention_status =	get_attention_status,
	.get_latch_status =	get_latch_status,
	.get_adapter_status =	get_adapter_status,
};

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

static void release_slot(struct hotplug_slot *hotplug_slot) { struct slot *slot = hotplug_slot->private; ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", __func__, slot_name(slot)); kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot); kfree(slot); }

Contributors

PersonTokensPropCommitsCommitProp
rolf eike beerrolf eike beer4680.70%120.00%
taku izumitaku izumi610.53%240.00%
alex chiangalex chiang47.02%120.00%
harvey harrisonharvey harrison11.75%120.00%
Total57100.00%5100.00%


static int init_slots(struct controller *ctrl) { struct slot *slot; struct hotplug_slot *hotplug_slot; struct hotplug_slot_info *info; char name[SLOT_NAME_SIZE]; int retval; int i; for (i = 0; i < ctrl->num_slots; i++) { slot = kzalloc(sizeof(*slot), GFP_KERNEL); if (!slot) { retval = -ENOMEM; goto error; } hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); if (!hotplug_slot) { retval = -ENOMEM; goto error_slot; } slot->hotplug_slot = hotplug_slot; info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { retval = -ENOMEM; goto error_hpslot; } hotplug_slot->info = info; slot->hp_slot = i; slot->ctrl = ctrl; slot->bus = ctrl->pci_dev->subordinate->number; slot->device = ctrl->slot_device_offset + i; slot->hpc_ops = ctrl->hpc_ops; slot->number = ctrl->first_slot + (ctrl->slot_num_inc * i); slot->wq = alloc_workqueue("shpchp-%d", 0, 0, slot->number); if (!slot->wq) { retval = -ENOMEM; goto error_info; } mutex_init(&slot->lock); INIT_DELAYED_WORK(&slot->work, shpchp_queue_pushbutton_work); /* register this slot with the hotplug pci core */ hotplug_slot->private = slot; hotplug_slot->release = &release_slot; snprintf(name, SLOT_NAME_SIZE, "%d", slot->number); hotplug_slot->ops = &shpchp_hotplug_slot_ops; ctrl_dbg(ctrl, "Registering domain:bus:dev=%04x:%02x:%02x hp_slot=%x sun=%x slot_device_offset=%x\n", pci_domain_nr(ctrl->pci_dev->subordinate), slot->bus, slot->device, slot->hp_slot, slot->number, ctrl->slot_device_offset); retval = pci_hp_register(slot->hotplug_slot, ctrl->pci_dev->subordinate, slot->device, name); if (retval) { ctrl_err(ctrl, "pci_hp_register failed with error %d\n", retval); goto error_slotwq; } get_power_status(hotplug_slot, &info->power_status); get_attention_status(hotplug_slot, &info->attention_status); get_latch_status(hotplug_slot, &info->latch_status); get_adapter_status(hotplug_slot, &info->adapter_status); list_add(&slot->slot_list, &ctrl->slot_list); } return 0; error_slotwq: destroy_workqueue(slot->wq); error_info: kfree(info); error_hpslot: kfree(hotplug_slot); error_slot: kfree(slot); error: return retval; }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy15533.62%14.55%
kenji kaneshigekenji kaneshige10923.64%836.36%
alex chiangalex chiang7215.62%418.18%
rolf eike beerrolf eike beer429.11%14.55%
bjorn helgaasbjorn helgaas398.46%14.55%
julia lawalljulia lawall214.56%14.55%
taku izumitaku izumi153.25%29.09%
kees cookkees cook51.08%14.55%
kristen carlson accardikristen carlson accardi10.22%14.55%
david howellsdavid howells10.22%14.55%
ryan desfossesryan desfosses10.22%14.55%
Total461100.00%22100.00%


void cleanup_slots(struct controller *ctrl) { struct slot *slot, *next; list_for_each_entry_safe(slot, next, &ctrl->slot_list, slot_list) { list_del(&slot->slot_list); cancel_delayed_work(&slot->work); destroy_workqueue(slot->wq); pci_hp_deregister(slot->hotplug_slot); } }

Contributors

PersonTokensPropCommitsCommitProp
kenji kaneshigekenji kaneshige2745.00%228.57%
dely sydely sy1931.67%114.29%
geliang tanggeliang tang711.67%114.29%
bjorn helgaasbjorn helgaas46.67%114.29%
rolf eike beerrolf eike beer35.00%228.57%
Total60100.00%7100.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 = get_slot(hotplug_slot); ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", __func__, slot_name(slot)); hotplug_slot->info->attention_status = status; slot->hpc_ops->set_attention_status(slot, status); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy5182.26%120.00%
taku izumitaku izumi69.68%240.00%
alex chiangalex chiang46.45%120.00%
harvey harrisonharvey harrison11.61%120.00%
Total62100.00%5100.00%


static int enable_slot(struct hotplug_slot *hotplug_slot) { struct slot *slot = get_slot(hotplug_slot); ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", __func__, slot_name(slot)); return shpchp_sysfs_enable_slot(slot); }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy3172.09%116.67%
taku izumitaku izumi613.95%233.33%
alex chiangalex chiang49.30%116.67%
harvey harrisonharvey harrison12.33%116.67%
kenji kaneshigekenji kaneshige12.33%116.67%
Total43100.00%6100.00%


static int disable_slot(struct hotplug_slot *hotplug_slot) { struct slot *slot = get_slot(hotplug_slot); ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", __func__, slot_name(slot)); return shpchp_sysfs_disable_slot(slot); }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy3172.09%116.67%
taku izumitaku izumi613.95%233.33%
alex chiangalex chiang49.30%116.67%
kenji kaneshigekenji kaneshige12.33%116.67%
harvey harrisonharvey harrison12.33%116.67%
Total43100.00%6100.00%


static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) { struct slot *slot = get_slot(hotplug_slot); int retval; ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", __func__, slot_name(slot)); retval = slot->hpc_ops->get_power_status(slot, value); if (retval < 0) *value = hotplug_slot->info->power_status; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy6485.33%120.00%
taku izumitaku izumi68.00%240.00%
alex chiangalex chiang45.33%120.00%
harvey harrisonharvey harrison11.33%120.00%
Total75100.00%5100.00%


static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) { struct slot *slot = get_slot(hotplug_slot); int retval; ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", __func__, slot_name(slot)); retval = slot->hpc_ops->get_attention_status(slot, value); if (retval < 0) *value = hotplug_slot->info->attention_status; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy6485.33%120.00%
taku izumitaku izumi68.00%240.00%
alex chiangalex chiang45.33%120.00%
harvey harrisonharvey harrison11.33%120.00%
Total75100.00%5100.00%


static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) { struct slot *slot = get_slot(hotplug_slot); int retval; ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", __func__, slot_name(slot)); retval = slot->hpc_ops->get_latch_status(slot, value); if (retval < 0) *value = hotplug_slot->info->latch_status; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy6485.33%120.00%
taku izumitaku izumi68.00%240.00%
alex chiangalex chiang45.33%120.00%
harvey harrisonharvey harrison11.33%120.00%
Total75100.00%5100.00%


static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) { struct slot *slot = get_slot(hotplug_slot); int retval; ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", __func__, slot_name(slot)); retval = slot->hpc_ops->get_adapter_status(slot, value); if (retval < 0) *value = hotplug_slot->info->adapter_status; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy6384.00%116.67%
taku izumitaku izumi68.00%233.33%
alex chiangalex chiang45.33%116.67%
kenji kaneshigekenji kaneshige11.33%116.67%
harvey harrisonharvey harrison11.33%116.67%
Total75100.00%6100.00%


static int is_shpc_capable(struct pci_dev *dev) { if (dev->vendor == PCI_VENDOR_ID_AMD && dev->device == PCI_DEVICE_ID_AMD_GOLAM_7450) return 1; if (!pci_find_capability(dev, PCI_CAP_ID_SHPC)) return 0; if (get_hp_hw_control_from_firmware(dev)) return 0; return 1; }

Contributors

PersonTokensPropCommitsCommitProp
rajesh shahrajesh shah4175.93%133.33%
kenji kaneshigekenji kaneshige1222.22%133.33%
bjorn helgaasbjorn helgaas11.85%133.33%
Total54100.00%3100.00%


static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int rc; struct controller *ctrl; if (!is_shpc_capable(pdev)) return -ENODEV; ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); if (!ctrl) { dev_err(&pdev->dev, "%s: Out of memory\n", __func__); goto err_out_none; } INIT_LIST_HEAD(&ctrl->slot_list); rc = shpc_init(ctrl, pdev); if (rc) { ctrl_dbg(ctrl, "Controller initialization failed\n"); goto err_out_free_ctrl; } pci_set_drvdata(pdev, ctrl); /* Setup the slot information structures */ rc = init_slots(ctrl); if (rc) { ctrl_err(ctrl, "Slot initialization failed\n"); goto err_out_release_ctlr; } rc = shpchp_create_ctrl_files(ctrl); if (rc) goto err_cleanup_slots; return 0; err_cleanup_slots: cleanup_slots(ctrl); err_out_release_ctlr: ctrl->hpc_ops->release_ctlr(ctrl); err_out_free_ctrl: kfree(ctrl); err_out_none: return -ENODEV; }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy12970.11%111.11%
greg kroah-hartmangreg kroah-hartman168.70%111.11%
kenji kaneshigekenji kaneshige137.07%333.33%
taku izumitaku izumi137.07%222.22%
rajesh shahrajesh shah126.52%111.11%
harvey harrisonharvey harrison10.54%111.11%
Total184100.00%9100.00%


static void shpc_remove(struct pci_dev *dev) { struct controller *ctrl = pci_get_drvdata(dev); shpchp_remove_ctrl_files(ctrl); ctrl->hpc_ops->release_ctlr(ctrl); kfree(ctrl); }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy2152.50%125.00%
kenji kaneshigekenji kaneshige1435.00%250.00%
rajesh shahrajesh shah512.50%125.00%
Total40100.00%4100.00%

static struct pci_device_id shpcd_pci_tbl[] = { {PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0)}, { /* end: all zeroes */ } }; MODULE_DEVICE_TABLE(pci, shpcd_pci_tbl); static struct pci_driver shpc_driver = { .name = SHPC_MODULE_NAME, .id_table = shpcd_pci_tbl, .probe = shpc_probe, .remove = shpc_remove, };
static int __init shpcd_init(void) { int retval; retval = pci_register_driver(&shpc_driver); dbg("%s: pci_register_driver = %d\n", __func__, retval); info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); return retval; }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy3792.50%133.33%
greg kroah-hartmangreg kroah-hartman25.00%133.33%
harvey harrisonharvey harrison12.50%133.33%
Total40100.00%3100.00%


static void __exit shpcd_cleanup(void) { dbg("unload_shpchpd()\n"); pci_unregister_driver(&shpc_driver); info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); }

Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy28100.00%1100.00%
Total28100.00%1100.00%

module_init(shpcd_init); module_exit(shpcd_cleanup);

Overall Contributors

PersonTokensPropCommitsCommitProp
dely sydely sy103561.39%12.44%
kenji kaneshigekenji kaneshige19211.39%1331.71%
alex chiangalex chiang1046.17%49.76%
rolf eike beerrolf eike beer1046.17%49.76%
taku izumitaku izumi764.51%24.88%
rajesh shahrajesh shah583.44%24.88%
bjorn helgaasbjorn helgaas442.61%24.88%
julia lawalljulia lawall211.25%12.44%
greg kroah-hartmangreg kroah-hartman181.07%24.88%
harvey harrisonharvey harrison100.59%12.44%
geliang tanggeliang tang70.42%12.44%
kees cookkees cook50.30%12.44%
rusty russellrusty russell50.30%24.88%
tejun heotejun heo30.18%12.44%
kristen carlson accardikristen carlson accardi20.12%24.88%
ryan desfossesryan desfosses10.06%12.44%
david howellsdavid howells10.06%12.44%
Total1686100.00%41100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}