aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/shpchp_pci.c
diff options
context:
space:
mode:
authorrajesh.shah@intel.com <rajesh.shah@intel.com>2005-10-13 15:05:40 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-10-28 18:37:00 -0400
commit70b6091946ab486c4dab8abeb4a3fc2bf7d3e7fe (patch)
treeb61b3262529be1b03cabac951bac5cf764e2daf2 /drivers/pci/hotplug/shpchp_pci.c
parent1410dc1cef1e2f5e90c1fcb97041f42e0eee35b4 (diff)
[PATCH] shpchp: dont save PCI config for hotplug slots/devices
This patch eliminates saving the PCI config header for devices in hotplug capable slots. We now use the PCI core to get the specific parts of the config header as required. Signed-off-by: Rajesh Shah <rajesh.shah@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci/hotplug/shpchp_pci.c')
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c314
1 files changed, 0 insertions, 314 deletions
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index 6209972313f3..f51a97d7611f 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -166,317 +166,3 @@ int shpchp_unconfigure_device(struct pci_func* func)
166 return rc; 166 return rc;
167} 167}
168 168
169/* More PCI configuration routines; this time centered around hotplug controller */
170
171
172/*
173 * shpchp_save_config
174 *
175 * Reads configuration for all slots in a PCI bus and saves info.
176 *
177 * Note: For non-hot plug busses, the slot # saved is the device #
178 *
179 * returns 0 if success
180 */
181int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num)
182{
183 int rc;
184 u8 class_code;
185 u8 header_type;
186 u32 ID;
187 u8 secondary_bus;
188 struct pci_func *new_slot;
189 int sub_bus;
190 int FirstSupported;
191 int LastSupported;
192 int max_functions;
193 int function;
194 u8 DevError;
195 int device = 0;
196 int cloop = 0;
197 int stop_it;
198 int index;
199 int is_hot_plug = num_ctlr_slots || first_device_num;
200 struct pci_bus lpci_bus, *pci_bus;
201
202 dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__,
203 num_ctlr_slots, first_device_num);
204
205 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
206 pci_bus = &lpci_bus;
207
208 dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__,
209 num_ctlr_slots, first_device_num);
210
211 /* Decide which slots are supported */
212 if (is_hot_plug) {
213 /*********************************
214 * is_hot_plug is the slot mask
215 *********************************/
216 FirstSupported = first_device_num;
217 LastSupported = FirstSupported + num_ctlr_slots - 1;
218 } else {
219 FirstSupported = 0;
220 LastSupported = 0x1F;
221 }
222
223 dbg("FirstSupported = %d, LastSupported = %d\n", FirstSupported,
224 LastSupported);
225
226 /* Save PCI configuration space for all devices in supported slots */
227 pci_bus->number = busnumber;
228 for (device = FirstSupported; device <= LastSupported; device++) {
229 ID = 0xFFFFFFFF;
230 rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0),
231 PCI_VENDOR_ID, &ID);
232
233 if (ID != 0xFFFFFFFF) { /* device in slot */
234 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
235 0x0B, &class_code);
236 if (rc)
237 return rc;
238
239 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
240 PCI_HEADER_TYPE, &header_type);
241 if (rc)
242 return rc;
243
244 dbg("class_code = %x, header_type = %x\n", class_code, header_type);
245
246 /* If multi-function device, set max_functions to 8 */
247 if (header_type & 0x80)
248 max_functions = 8;
249 else
250 max_functions = 1;
251
252 function = 0;
253
254 do {
255 DevError = 0;
256
257 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* P-P Bridge */
258 /* Recurse the subordinate bus
259 * get the subordinate bus number
260 */
261 rc = pci_bus_read_config_byte(pci_bus,
262 PCI_DEVFN(device, function),
263 PCI_SECONDARY_BUS, &secondary_bus);
264 if (rc) {
265 return rc;
266 } else {
267 sub_bus = (int) secondary_bus;
268
269 /* Save secondary bus cfg spc with this recursive call. */
270 rc = shpchp_save_config(ctrl, sub_bus, 0, 0);
271 if (rc)
272 return rc;
273 }
274 }
275
276 index = 0;
277 new_slot = shpchp_slot_find(busnumber, device, index++);
278
279 dbg("new_slot = %p\n", new_slot);
280
281 while (new_slot && (new_slot->function != (u8) function)) {
282 new_slot = shpchp_slot_find(busnumber, device, index++);
283 dbg("new_slot = %p\n", new_slot);
284 }
285 if (!new_slot) {
286 /* Setup slot structure. */
287 new_slot = shpchp_slot_create(busnumber);
288 dbg("new_slot = %p\n", new_slot);
289
290 if (new_slot == NULL)
291 return(1);
292 }
293
294 new_slot->bus = (u8) busnumber;
295 new_slot->device = (u8) device;
296 new_slot->function = (u8) function;
297 new_slot->is_a_board = 1;
298 new_slot->switch_save = 0x10;
299 new_slot->pwr_save = 1;
300 /* In case of unsupported board */
301 new_slot->status = DevError;
302 new_slot->pci_dev = pci_find_slot(new_slot->bus,
303 (new_slot->device << 3) | new_slot->function);
304 dbg("new_slot->pci_dev = %p\n", new_slot->pci_dev);
305
306 for (cloop = 0; cloop < 0x20; cloop++) {
307 rc = pci_bus_read_config_dword(pci_bus,
308 PCI_DEVFN(device, function),
309 cloop << 2,
310 (u32 *) &(new_slot->config_space [cloop]));
311 /* dbg("new_slot->config_space[%x] = %x\n",
312 cloop, new_slot->config_space[cloop]); */
313 if (rc)
314 return rc;
315 }
316
317 function++;
318
319 stop_it = 0;
320
321 /* this loop skips to the next present function
322 * reading in Class Code and Header type.
323 */
324
325 while ((function < max_functions)&&(!stop_it)) {
326 rc = pci_bus_read_config_dword(pci_bus,
327 PCI_DEVFN(device, function),
328 PCI_VENDOR_ID, &ID);
329
330 if (ID == 0xFFFFFFFF) { /* nothing there. */
331 function++;
332 dbg("Nothing there\n");
333 } else { /* Something there */
334 rc = pci_bus_read_config_byte(pci_bus,
335 PCI_DEVFN(device, function),
336 0x0B, &class_code);
337 if (rc)
338 return rc;
339
340 rc = pci_bus_read_config_byte(pci_bus,
341 PCI_DEVFN(device, function),
342 PCI_HEADER_TYPE, &header_type);
343 if (rc)
344 return rc;
345
346 dbg("class_code = %x, header_type = %x\n",
347 class_code, header_type);
348 stop_it++;
349 }
350 }
351
352 } while (function < max_functions);
353 /* End of IF (device in slot?) */
354 } else if (is_hot_plug) {
355 /* Setup slot structure with entry for empty slot */
356 new_slot = shpchp_slot_create(busnumber);
357
358 if (new_slot == NULL) {
359 return(1);
360 }
361 dbg("new_slot = %p\n", new_slot);
362
363 new_slot->bus = (u8) busnumber;
364 new_slot->device = (u8) device;
365 new_slot->function = 0;
366 new_slot->is_a_board = 0;
367 new_slot->presence_save = 0;
368 new_slot->switch_save = 0;
369 }
370 } /* End of FOR loop */
371
372 return(0);
373}
374
375
376/*
377 * shpchp_save_slot_config
378 *
379 * Saves configuration info for all PCI devices in a given slot
380 * including subordinate busses.
381 *
382 * returns 0 if success
383 */
384int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot)
385{
386 int rc;
387 u8 class_code;
388 u8 header_type;
389 u32 ID;
390 u8 secondary_bus;
391 int sub_bus;
392 int max_functions;
393 int function;
394 int cloop = 0;
395 int stop_it;
396 struct pci_bus lpci_bus, *pci_bus;
397 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
398 pci_bus = &lpci_bus;
399 pci_bus->number = new_slot->bus;
400
401 ID = 0xFFFFFFFF;
402
403 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, 0),
404 PCI_VENDOR_ID, &ID);
405
406 if (ID != 0xFFFFFFFF) { /* device in slot */
407 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
408 0x0B, &class_code);
409
410 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
411 PCI_HEADER_TYPE, &header_type);
412
413 if (header_type & 0x80) /* Multi-function device */
414 max_functions = 8;
415 else
416 max_functions = 1;
417
418 function = 0;
419
420 do {
421 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
422 /* Recurse the subordinate bus */
423 pci_bus_read_config_byte(pci_bus,
424 PCI_DEVFN(new_slot->device, function),
425 PCI_SECONDARY_BUS, &secondary_bus);
426
427 sub_bus = (int) secondary_bus;
428
429 /* Save the config headers for the secondary bus. */
430 rc = shpchp_save_config(ctrl, sub_bus, 0, 0);
431
432 if (rc)
433 return rc;
434
435 } /* End of IF */
436
437 new_slot->status = 0;
438
439 for (cloop = 0; cloop < 0x20; cloop++) {
440 pci_bus_read_config_dword(pci_bus,
441 PCI_DEVFN(new_slot->device, function),
442 cloop << 2,
443 (u32 *) &(new_slot->config_space [cloop]));
444 }
445
446 function++;
447
448 stop_it = 0;
449
450 /* this loop skips to the next present function
451 * reading in the Class Code and the Header type.
452 */
453
454 while ((function < max_functions) && (!stop_it)) {
455 pci_bus_read_config_dword(pci_bus,
456 PCI_DEVFN(new_slot->device, function),
457 PCI_VENDOR_ID, &ID);
458
459 if (ID == 0xFFFFFFFF) { /* nothing there. */
460 function++;
461 } else { /* Something there */
462 pci_bus_read_config_byte(pci_bus,
463 PCI_DEVFN(new_slot->device, function),
464 0x0B, &class_code);
465
466 pci_bus_read_config_byte(pci_bus,
467 PCI_DEVFN(new_slot->device, function),
468 PCI_HEADER_TYPE, &header_type);
469
470 stop_it++;
471 }
472 }
473
474 } while (function < max_functions);
475 } /* End of IF (device in slot?) */
476 else {
477 return 2;
478 }
479
480 return 0;
481}
482