aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-08-25 14:25:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-08-25 14:25:10 -0400
commita56cb4ecbdb66a504601dfacc31cd0cf91c97e7f (patch)
tree748f6fcef042122249d6df8816b4463bb532972a
parentb9b50363e6c60d471fe2e71e48d434aad58b3749 (diff)
parentebca4f1bce1eb7b91a63c515db66316db9391221 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: PCI: fix reference leak in pci_get_dev_by_id() PCI: shpchp: Rename duplicate slot name N as N-1, N-2, N-M... PCI: pciehp: Rename duplicate slot name N as N-1, N-2, N-M...
-rw-r--r--drivers/pci/hotplug/pciehp.h1
-rw-r--r--drivers/pci/hotplug/pciehp_core.c21
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c11
-rw-r--r--drivers/pci/hotplug/shpchp_core.c34
-rw-r--r--drivers/pci/search.c2
5 files changed, 32 insertions, 37 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index e3a1e7e7dba2..9e6cec67e1cc 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -43,7 +43,6 @@ extern int pciehp_poll_mode;
43extern int pciehp_poll_time; 43extern int pciehp_poll_time;
44extern int pciehp_debug; 44extern int pciehp_debug;
45extern int pciehp_force; 45extern int pciehp_force;
46extern int pciehp_slot_with_bus;
47extern struct workqueue_struct *pciehp_wq; 46extern struct workqueue_struct *pciehp_wq;
48 47
49#define dbg(format, arg...) \ 48#define dbg(format, arg...) \
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 3677495c4f91..4fd5355bc3b5 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -41,7 +41,6 @@ int pciehp_debug;
41int pciehp_poll_mode; 41int pciehp_poll_mode;
42int pciehp_poll_time; 42int pciehp_poll_time;
43int pciehp_force; 43int pciehp_force;
44int pciehp_slot_with_bus;
45struct workqueue_struct *pciehp_wq; 44struct workqueue_struct *pciehp_wq;
46 45
47#define DRIVER_VERSION "0.4" 46#define DRIVER_VERSION "0.4"
@@ -56,12 +55,10 @@ module_param(pciehp_debug, bool, 0644);
56module_param(pciehp_poll_mode, bool, 0644); 55module_param(pciehp_poll_mode, bool, 0644);
57module_param(pciehp_poll_time, int, 0644); 56module_param(pciehp_poll_time, int, 0644);
58module_param(pciehp_force, bool, 0644); 57module_param(pciehp_force, bool, 0644);
59module_param(pciehp_slot_with_bus, bool, 0644);
60MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not"); 58MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
61MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); 59MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
62MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); 60MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
63MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing"); 61MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing");
64MODULE_PARM_DESC(pciehp_slot_with_bus, "Use bus number in the slot name");
65 62
66#define PCIE_MODULE_NAME "pciehp" 63#define PCIE_MODULE_NAME "pciehp"
67 64
@@ -194,6 +191,7 @@ static int init_slots(struct controller *ctrl)
194 struct slot *slot; 191 struct slot *slot;
195 struct hotplug_slot *hotplug_slot; 192 struct hotplug_slot *hotplug_slot;
196 struct hotplug_slot_info *info; 193 struct hotplug_slot_info *info;
194 int len, dup = 1;
197 int retval = -ENOMEM; 195 int retval = -ENOMEM;
198 196
199 list_for_each_entry(slot, &ctrl->slot_list, slot_list) { 197 list_for_each_entry(slot, &ctrl->slot_list, slot_list) {
@@ -220,15 +218,24 @@ static int init_slots(struct controller *ctrl)
220 dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x " 218 dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x "
221 "slot_device_offset=%x\n", slot->bus, slot->device, 219 "slot_device_offset=%x\n", slot->bus, slot->device,
222 slot->hp_slot, slot->number, ctrl->slot_device_offset); 220 slot->hp_slot, slot->number, ctrl->slot_device_offset);
221duplicate_name:
223 retval = pci_hp_register(hotplug_slot, 222 retval = pci_hp_register(hotplug_slot,
224 ctrl->pci_dev->subordinate, 223 ctrl->pci_dev->subordinate,
225 slot->device); 224 slot->device);
226 if (retval) { 225 if (retval) {
226 /*
227 * If slot N already exists, we'll try to create
228 * slot N-1, N-2 ... N-M, until we overflow.
229 */
230 if (retval == -EEXIST) {
231 len = snprintf(slot->name, SLOT_NAME_SIZE,
232 "%d-%d", slot->number, dup++);
233 if (len < SLOT_NAME_SIZE)
234 goto duplicate_name;
235 else
236 err("duplicate slot name overflow\n");
237 }
227 err("pci_hp_register failed with error %d\n", retval); 238 err("pci_hp_register failed with error %d\n", retval);
228 if (retval == -EEXIST)
229 err("Failed to register slot because of name "
230 "collision. Try \'pciehp_slot_with_bus\' "
231 "module option.\n");
232 goto error_info; 239 goto error_info;
233 } 240 }
234 /* create additional sysfs entries */ 241 /* create additional sysfs entries */
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index ad27e9e225a6..ab31f5ba665d 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -1030,15 +1030,6 @@ static void pcie_shutdown_notification(struct controller *ctrl)
1030 pciehp_free_irq(ctrl); 1030 pciehp_free_irq(ctrl);
1031} 1031}
1032 1032
1033static void make_slot_name(struct slot *slot)
1034{
1035 if (pciehp_slot_with_bus)
1036 snprintf(slot->name, SLOT_NAME_SIZE, "%04d_%04d",
1037 slot->bus, slot->number);
1038 else
1039 snprintf(slot->name, SLOT_NAME_SIZE, "%d", slot->number);
1040}
1041
1042static int pcie_init_slot(struct controller *ctrl) 1033static int pcie_init_slot(struct controller *ctrl)
1043{ 1034{
1044 struct slot *slot; 1035 struct slot *slot;
@@ -1053,7 +1044,7 @@ static int pcie_init_slot(struct controller *ctrl)
1053 slot->device = ctrl->slot_device_offset + slot->hp_slot; 1044 slot->device = ctrl->slot_device_offset + slot->hp_slot;
1054 slot->hpc_ops = ctrl->hpc_ops; 1045 slot->hpc_ops = ctrl->hpc_ops;
1055 slot->number = ctrl->first_slot; 1046 slot->number = ctrl->first_slot;
1056 make_slot_name(slot); 1047 snprintf(slot->name, SLOT_NAME_SIZE, "%d", slot->number);
1057 mutex_init(&slot->lock); 1048 mutex_init(&slot->lock);
1058 INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work); 1049 INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work);
1059 list_add(&slot->slot_list, &ctrl->slot_list); 1050 list_add(&slot->slot_list, &ctrl->slot_list);
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index a8cbd039b85b..cc38615395f1 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -39,7 +39,6 @@
39int shpchp_debug; 39int shpchp_debug;
40int shpchp_poll_mode; 40int shpchp_poll_mode;
41int shpchp_poll_time; 41int shpchp_poll_time;
42static int shpchp_slot_with_bus;
43struct workqueue_struct *shpchp_wq; 42struct workqueue_struct *shpchp_wq;
44 43
45#define DRIVER_VERSION "0.4" 44#define DRIVER_VERSION "0.4"
@@ -53,11 +52,9 @@ MODULE_LICENSE("GPL");
53module_param(shpchp_debug, bool, 0644); 52module_param(shpchp_debug, bool, 0644);
54module_param(shpchp_poll_mode, bool, 0644); 53module_param(shpchp_poll_mode, bool, 0644);
55module_param(shpchp_poll_time, int, 0644); 54module_param(shpchp_poll_time, int, 0644);
56module_param(shpchp_slot_with_bus, bool, 0644);
57MODULE_PARM_DESC(shpchp_debug, "Debugging mode enabled or not"); 55MODULE_PARM_DESC(shpchp_debug, "Debugging mode enabled or not");
58MODULE_PARM_DESC(shpchp_poll_mode, "Using polling mechanism for hot-plug events or not"); 56MODULE_PARM_DESC(shpchp_poll_mode, "Using polling mechanism for hot-plug events or not");
59MODULE_PARM_DESC(shpchp_poll_time, "Polling mechanism frequency, in seconds"); 57MODULE_PARM_DESC(shpchp_poll_time, "Polling mechanism frequency, in seconds");
60MODULE_PARM_DESC(shpchp_slot_with_bus, "Use bus number in the slot name");
61 58
62#define SHPC_MODULE_NAME "shpchp" 59#define SHPC_MODULE_NAME "shpchp"
63 60
@@ -99,23 +96,13 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
99 kfree(slot); 96 kfree(slot);
100} 97}
101 98
102static void make_slot_name(struct slot *slot)
103{
104 if (shpchp_slot_with_bus)
105 snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%04d_%04d",
106 slot->bus, slot->number);
107 else
108 snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%d",
109 slot->number);
110}
111
112static int init_slots(struct controller *ctrl) 99static int init_slots(struct controller *ctrl)
113{ 100{
114 struct slot *slot; 101 struct slot *slot;
115 struct hotplug_slot *hotplug_slot; 102 struct hotplug_slot *hotplug_slot;
116 struct hotplug_slot_info *info; 103 struct hotplug_slot_info *info;
117 int retval = -ENOMEM; 104 int retval = -ENOMEM;
118 int i; 105 int i, len, dup = 1;
119 106
120 for (i = 0; i < ctrl->num_slots; i++) { 107 for (i = 0; i < ctrl->num_slots; i++) {
121 slot = kzalloc(sizeof(*slot), GFP_KERNEL); 108 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
@@ -146,7 +133,7 @@ static int init_slots(struct controller *ctrl)
146 /* register this slot with the hotplug pci core */ 133 /* register this slot with the hotplug pci core */
147 hotplug_slot->private = slot; 134 hotplug_slot->private = slot;
148 hotplug_slot->release = &release_slot; 135 hotplug_slot->release = &release_slot;
149 make_slot_name(slot); 136 snprintf(slot->name, SLOT_NAME_SIZE, "%d", slot->number);
150 hotplug_slot->ops = &shpchp_hotplug_slot_ops; 137 hotplug_slot->ops = &shpchp_hotplug_slot_ops;
151 138
152 get_power_status(hotplug_slot, &info->power_status); 139 get_power_status(hotplug_slot, &info->power_status);
@@ -157,14 +144,23 @@ static int init_slots(struct controller *ctrl)
157 dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x " 144 dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x "
158 "slot_device_offset=%x\n", slot->bus, slot->device, 145 "slot_device_offset=%x\n", slot->bus, slot->device,
159 slot->hp_slot, slot->number, ctrl->slot_device_offset); 146 slot->hp_slot, slot->number, ctrl->slot_device_offset);
147duplicate_name:
160 retval = pci_hp_register(slot->hotplug_slot, 148 retval = pci_hp_register(slot->hotplug_slot,
161 ctrl->pci_dev->subordinate, slot->device); 149 ctrl->pci_dev->subordinate, slot->device);
162 if (retval) { 150 if (retval) {
151 /*
152 * If slot N already exists, we'll try to create
153 * slot N-1, N-2 ... N-M, until we overflow.
154 */
155 if (retval == -EEXIST) {
156 len = snprintf(slot->name, SLOT_NAME_SIZE,
157 "%d-%d", slot->number, dup++);
158 if (len < SLOT_NAME_SIZE)
159 goto duplicate_name;
160 else
161 err("duplicate slot name overflow\n");
162 }
163 err("pci_hp_register failed with error %d\n", retval); 163 err("pci_hp_register failed with error %d\n", retval);
164 if (retval == -EEXIST)
165 err("Failed to register slot because of name "
166 "collision. Try \'shpchp_slot_with_bus\' "
167 "module option.\n");
168 goto error_info; 164 goto error_info;
169 } 165 }
170 166
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index 217814fef4ef..3b3b5f178797 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -280,6 +280,8 @@ static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id,
280 match_pci_dev_by_id); 280 match_pci_dev_by_id);
281 if (dev) 281 if (dev)
282 pdev = to_pci_dev(dev); 282 pdev = to_pci_dev(dev);
283 if (from)
284 pci_dev_put(from);
283 return pdev; 285 return pdev;
284} 286}
285 287