diff options
author | Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> | 2009-10-05 04:41:37 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-11-04 12:01:44 -0500 |
commit | 586f1d6688c68a6c7fa4e6a00fa3968b16daef75 (patch) | |
tree | 08777d2d739a940dac83df927389323f56569ee2 /drivers/pci/hotplug | |
parent | 3c3a1b1759616e6603027108f8abcbec54271e62 (diff) |
PCI: pciehp: create files only for existing capabilities
Current pciehp driver creates 'attention' and 'latch' files even if
the controller doesn't support them. In this case, the contents of
those files are meaningless and unpredictable. Those files should be
created only if the controller has the corresponding capabilities.
Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r-- | drivers/pci/hotplug/pciehp_core.c | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index bc234719b1df..77feafd39e29 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -72,18 +72,6 @@ static int get_adapter_status (struct hotplug_slot *slot, u8 *value); | |||
72 | static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | 72 | static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); |
73 | static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | 73 | static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); |
74 | 74 | ||
75 | static struct hotplug_slot_ops pciehp_hotplug_slot_ops = { | ||
76 | .set_attention_status = set_attention_status, | ||
77 | .enable_slot = enable_slot, | ||
78 | .disable_slot = disable_slot, | ||
79 | .get_power_status = get_power_status, | ||
80 | .get_attention_status = get_attention_status, | ||
81 | .get_latch_status = get_latch_status, | ||
82 | .get_adapter_status = get_adapter_status, | ||
83 | .get_max_bus_speed = get_max_bus_speed, | ||
84 | .get_cur_bus_speed = get_cur_bus_speed, | ||
85 | }; | ||
86 | |||
87 | /** | 75 | /** |
88 | * release_slot - free up the memory used by a slot | 76 | * release_slot - free up the memory used by a slot |
89 | * @hotplug_slot: slot to free | 77 | * @hotplug_slot: slot to free |
@@ -95,6 +83,7 @@ static void release_slot(struct hotplug_slot *hotplug_slot) | |||
95 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 83 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
96 | __func__, hotplug_slot_name(hotplug_slot)); | 84 | __func__, hotplug_slot_name(hotplug_slot)); |
97 | 85 | ||
86 | kfree(hotplug_slot->ops); | ||
98 | kfree(hotplug_slot->info); | 87 | kfree(hotplug_slot->info); |
99 | kfree(hotplug_slot); | 88 | kfree(hotplug_slot); |
100 | } | 89 | } |
@@ -104,6 +93,7 @@ static int init_slot(struct controller *ctrl) | |||
104 | struct slot *slot = ctrl->slot; | 93 | struct slot *slot = ctrl->slot; |
105 | struct hotplug_slot *hotplug = NULL; | 94 | struct hotplug_slot *hotplug = NULL; |
106 | struct hotplug_slot_info *info = NULL; | 95 | struct hotplug_slot_info *info = NULL; |
96 | struct hotplug_slot_ops *ops = NULL; | ||
107 | char name[SLOT_NAME_SIZE]; | 97 | char name[SLOT_NAME_SIZE]; |
108 | int retval = -ENOMEM; | 98 | int retval = -ENOMEM; |
109 | 99 | ||
@@ -115,11 +105,28 @@ static int init_slot(struct controller *ctrl) | |||
115 | if (!info) | 105 | if (!info) |
116 | goto out; | 106 | goto out; |
117 | 107 | ||
108 | /* Setup hotplug slot ops */ | ||
109 | ops = kzalloc(sizeof(*ops), GFP_KERNEL); | ||
110 | if (!ops) | ||
111 | goto out; | ||
112 | ops->enable_slot = enable_slot; | ||
113 | ops->disable_slot = disable_slot; | ||
114 | ops->get_power_status = get_power_status; | ||
115 | ops->get_adapter_status = get_adapter_status; | ||
116 | ops->get_max_bus_speed = get_max_bus_speed; | ||
117 | ops->get_cur_bus_speed = get_cur_bus_speed; | ||
118 | if (MRL_SENS(ctrl)) | ||
119 | ops->get_latch_status = get_latch_status; | ||
120 | if (ATTN_LED(ctrl)) { | ||
121 | ops->get_attention_status = get_attention_status; | ||
122 | ops->set_attention_status = set_attention_status; | ||
123 | } | ||
124 | |||
118 | /* register this slot with the hotplug pci core */ | 125 | /* register this slot with the hotplug pci core */ |
119 | hotplug->info = info; | 126 | hotplug->info = info; |
120 | hotplug->private = slot; | 127 | hotplug->private = slot; |
121 | hotplug->release = &release_slot; | 128 | hotplug->release = &release_slot; |
122 | hotplug->ops = &pciehp_hotplug_slot_ops; | 129 | hotplug->ops = ops; |
123 | slot->hotplug_slot = hotplug; | 130 | slot->hotplug_slot = hotplug; |
124 | snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl)); | 131 | snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl)); |
125 | 132 | ||
@@ -139,6 +146,7 @@ static int init_slot(struct controller *ctrl) | |||
139 | get_adapter_status(hotplug, &info->adapter_status); | 146 | get_adapter_status(hotplug, &info->adapter_status); |
140 | out: | 147 | out: |
141 | if (retval) { | 148 | if (retval) { |
149 | kfree(ops); | ||
142 | kfree(info); | 150 | kfree(info); |
143 | kfree(hotplug); | 151 | kfree(hotplug); |
144 | } | 152 | } |
@@ -161,9 +169,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) | |||
161 | __func__, slot_name(slot)); | 169 | __func__, slot_name(slot)); |
162 | 170 | ||
163 | hotplug_slot->info->attention_status = status; | 171 | hotplug_slot->info->attention_status = status; |
164 | 172 | pciehp_set_attention_status(slot, status); | |
165 | if (ATTN_LED(slot->ctrl)) | ||
166 | pciehp_set_attention_status(slot, status); | ||
167 | 173 | ||
168 | return 0; | 174 | return 0; |
169 | } | 175 | } |