#include <linux/config.h>
#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
int pciehp_debug;
int pciehp_poll_mode;
int pciehp_poll_time;
-struct controller *pciehp_ctrl_list; /* = NULL */
+struct controller *pciehp_ctrl_list;
struct pci_func *pciehp_slot_list[256];
#define DRIVER_VERSION "0.4"
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-MODULE_PARM(pciehp_debug, "i");
-MODULE_PARM(pciehp_poll_mode, "i");
-MODULE_PARM(pciehp_poll_time, "i");
+module_param(pciehp_debug, bool, 644);
+module_param(pciehp_poll_mode, bool, 644);
+module_param(pciehp_poll_time, int, 644);
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");
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 hardware_test (struct hotplug_slot *slot, u32 value);
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);
.set_attention_status = set_attention_status,
.enable_slot = enable_slot,
.disable_slot = disable_slot,
- .hardware_test = hardware_test,
.get_power_status = get_power_status,
.get_attention_status = get_attention_status,
.get_latch_status = get_latch_status,
u8 number_of_slots;
u8 slot_device;
u32 slot_number;
- int result;
+ int result = -ENOMEM;
dbg("%s\n",__FUNCTION__);
slot_number = ctrl->first_slot;
while (number_of_slots) {
- new_slot = (struct slot *) kmalloc(sizeof(struct slot), GFP_KERNEL);
+ new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL);
if (!new_slot)
- return -ENOMEM;
+ goto error;
memset(new_slot, 0, sizeof(struct slot));
- new_slot->hotplug_slot = kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL);
- if (!new_slot->hotplug_slot) {
- kfree (new_slot);
- return -ENOMEM;
- }
- memset(new_slot->hotplug_slot, 0, sizeof (struct hotplug_slot));
-
- new_slot->hotplug_slot->info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
- if (!new_slot->hotplug_slot->info) {
- kfree (new_slot->hotplug_slot);
- kfree (new_slot);
- return -ENOMEM;
- }
- memset(new_slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info));
- new_slot->hotplug_slot->name = kmalloc (SLOT_NAME_SIZE, GFP_KERNEL);
- if (!new_slot->hotplug_slot->name) {
- kfree (new_slot->hotplug_slot->info);
- kfree (new_slot->hotplug_slot);
- kfree (new_slot);
- return -ENOMEM;
- }
+ new_slot->hotplug_slot =
+ kmalloc(sizeof(*(new_slot->hotplug_slot)),
+ GFP_KERNEL);
+ if (!new_slot->hotplug_slot)
+ goto error_slot;
+ memset(new_slot->hotplug_slot, 0, sizeof(struct hotplug_slot));
+
+ new_slot->hotplug_slot->info =
+ kmalloc(sizeof(*(new_slot->hotplug_slot->info)),
+ GFP_KERNEL);
+ if (!new_slot->hotplug_slot->info)
+ goto error_hpslot;
+ memset(new_slot->hotplug_slot->info, 0,
+ sizeof(struct hotplug_slot_info));
+ new_slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE,
+ GFP_KERNEL);
+ if (!new_slot->hotplug_slot->name)
+ goto error_info;
- new_slot->magic = SLOT_MAGIC;
new_slot->ctrl = ctrl;
new_slot->bus = ctrl->slot_bus;
new_slot->device = slot_device;
result = pci_hp_register (new_slot->hotplug_slot);
if (result) {
err ("pci_hp_register failed with error %d\n", result);
- kfree (new_slot->hotplug_slot->info);
- kfree (new_slot->hotplug_slot->name);
- kfree (new_slot->hotplug_slot);
- kfree (new_slot);
- return result;
+ goto error_name;
}
new_slot->next = ctrl->slot;
slot_number += ctrl->slot_num_inc;
}
- return(0);
+ return 0;
+
+error_name:
+ kfree(new_slot->hotplug_slot->name);
+error_info:
+ kfree(new_slot->hotplug_slot->info);
+error_hpslot:
+ kfree(new_slot->hotplug_slot);
+error_slot:
+ kfree(new_slot);
+error:
+ return result;
}
/*
* 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)
+static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
{
- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+ struct slot *slot = hotplug_slot->private;
- if (slot == NULL)
- return -ENODEV;
-
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
hotplug_slot->info->attention_status = status;
}
-static int enable_slot (struct hotplug_slot *hotplug_slot)
+static int enable_slot(struct hotplug_slot *hotplug_slot)
{
- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-
- if (slot == NULL)
- return -ENODEV;
+ struct slot *slot = hotplug_slot->private;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
}
-static int disable_slot (struct hotplug_slot *hotplug_slot)
+static int disable_slot(struct hotplug_slot *hotplug_slot)
{
- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-
- if (slot == NULL)
- return -ENODEV;
+ struct slot *slot = hotplug_slot->private;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
return pciehp_disable_slot(slot);
}
-
-static int hardware_test (struct hotplug_slot *hotplug_slot, u32 value)
+static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
{
- return 0;
-}
-
-
-static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
-{
- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+ struct slot *slot = hotplug_slot->private;
int retval;
-
- if (slot == NULL)
- return -ENODEV;
-
+
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
retval = slot->hpc_ops->get_power_status(slot, value);
return 0;
}
-static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
+static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
{
- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+ struct slot *slot = hotplug_slot->private;
int retval;
-
- if (slot == NULL)
- return -ENODEV;
-
+
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
retval = slot->hpc_ops->get_attention_status(slot, value);
return 0;
}
-static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
+static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
{
- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+ struct slot *slot = hotplug_slot->private;
int retval;
-
- if (slot == NULL)
- return -ENODEV;
-
+
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
retval = slot->hpc_ops->get_latch_status(slot, value);
return 0;
}
-static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
+static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
{
- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+ struct slot *slot = hotplug_slot->private;
int retval;
-
- if (slot == NULL)
- return -ENODEV;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
retval = slot->hpc_ops->get_adapter_status(slot, value);
-
if (retval < 0)
*value = hotplug_slot->info->adapter_status;
return 0;
}
-static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
+static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
{
- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+ struct slot *slot = hotplug_slot->private;
int retval;
-
- if (slot == NULL)
- return -ENODEV;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
return 0;
}
-static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
+static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
{
- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+ struct slot *slot = hotplug_slot->private;
int retval;
-
- if (slot == NULL)
- return -ENODEV;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
int num_ctlr_slots; /* number of slots supported by this HPC */
u8 value;
- ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
+ ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL);
if (!ctrl) {
err("%s : out of memory\n", __FUNCTION__);
goto err_out_none;
pci_set_drvdata(pdev, ctrl);
- ctrl->pci_bus = kmalloc (sizeof (*ctrl->pci_bus), GFP_KERNEL);
+ ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL);
if (!ctrl->pci_bus) {
err("%s: out of memory\n", __FUNCTION__);
rc = -ENOMEM;
return retval;
}
+static inline void __exit
+free_pciehp_res(struct pci_resource *res)
+{
+ struct pci_resource *tres;
+
+ while (res) {
+ tres = res;
+ res = res->next;
+ kfree(tres);
+ }
+}
-static void unload_pciehpd(void)
+static void __exit unload_pciehpd(void)
{
struct pci_func *next;
struct pci_func *TempSlot;
int loop;
struct controller *ctrl;
struct controller *tctrl;
- struct pci_resource *res;
- struct pci_resource *tres;
ctrl = pciehp_ctrl_list;
while (ctrl) {
cleanup_slots(ctrl);
- res = ctrl->io_head;
- while (res) {
- tres = res;
- res = res->next;
- kfree(tres);
- }
-
- res = ctrl->mem_head;
- while (res) {
- tres = res;
- res = res->next;
- kfree(tres);
- }
-
- res = ctrl->p_mem_head;
- while (res) {
- tres = res;
- res = res->next;
- kfree(tres);
- }
-
- res = ctrl->bus_head;
- while (res) {
- tres = res;
- res = res->next;
- kfree(tres);
- }
+ free_pciehp_res(ctrl->io_head);
+ free_pciehp_res(ctrl->mem_head);
+ free_pciehp_res(ctrl->p_mem_head);
+ free_pciehp_res(ctrl->bus_head);
kfree (ctrl->pci_bus);
for (loop = 0; loop < 256; loop++) {
next = pciehp_slot_list[loop];
while (next != NULL) {
- res = next->io_head;
- while (res) {
- tres = res;
- res = res->next;
- kfree(tres);
- }
-
- res = next->mem_head;
- while (res) {
- tres = res;
- res = res->next;
- kfree(tres);
- }
-
- res = next->p_mem_head;
- while (res) {
- tres = res;
- res = res->next;
- kfree(tres);
- }
-
- res = next->bus_head;
- while (res) {
- tres = res;
- res = res->next;
- kfree(tres);
- }
+ free_pciehp_res(next->io_head);
+ free_pciehp_res(next->mem_head);
+ free_pciehp_res(next->p_mem_head);
+ free_pciehp_res(next->bus_head);
TempSlot = next;
next = next->next;
info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
}
-
module_init(pcied_init);
module_exit(pcied_cleanup);
-
-