diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2007-12-06 09:52:45 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-12-10 21:42:23 -0500 |
commit | 0d416f2a9eb31823f824ac067be7771fd93bffa3 (patch) | |
tree | fcc77273849f177c041477d7fb93c2da446b6053 | |
parent | 3f1786328a1c5f6240d96ca6359246c4bded7ec3 (diff) |
[POWERPC] iSeries: Consoldiate PCI IO error check
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r-- | arch/powerpc/platforms/iseries/pci.c | 105 |
1 files changed, 26 insertions, 79 deletions
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index 8e2ac3d0c81..105b23d3360 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c | |||
@@ -342,7 +342,7 @@ static int check_return_code(char *type, struct device_node *dn, | |||
342 | */ | 342 | */ |
343 | static inline struct device_node *xlate_iomm_address( | 343 | static inline struct device_node *xlate_iomm_address( |
344 | const volatile void __iomem *addr, | 344 | const volatile void __iomem *addr, |
345 | u64 *dsaptr, u64 *bar_offset) | 345 | u64 *dsaptr, u64 *bar_offset, const char *func) |
346 | { | 346 | { |
347 | unsigned long orig_addr; | 347 | unsigned long orig_addr; |
348 | unsigned long base_addr; | 348 | unsigned long base_addr; |
@@ -350,8 +350,20 @@ static inline struct device_node *xlate_iomm_address( | |||
350 | struct device_node *dn; | 350 | struct device_node *dn; |
351 | 351 | ||
352 | orig_addr = (unsigned long __force)addr; | 352 | orig_addr = (unsigned long __force)addr; |
353 | if ((orig_addr < BASE_IO_MEMORY) || (orig_addr >= max_io_memory)) | 353 | if ((orig_addr < BASE_IO_MEMORY) || (orig_addr >= max_io_memory)) { |
354 | static unsigned long last_jiffies; | ||
355 | static int num_printed; | ||
356 | |||
357 | if ((jiffies - last_jiffies) > 60 * HZ) { | ||
358 | last_jiffies = jiffies; | ||
359 | num_printed = 0; | ||
360 | } | ||
361 | if (num_printed++ < 10) | ||
362 | printk(KERN_ERR | ||
363 | "iSeries_%s: invalid access at IO address %p\n", | ||
364 | func, addr); | ||
354 | return NULL; | 365 | return NULL; |
366 | } | ||
355 | base_addr = orig_addr - BASE_IO_MEMORY; | 367 | base_addr = orig_addr - BASE_IO_MEMORY; |
356 | ind = base_addr / IOMM_TABLE_ENTRY_SIZE; | 368 | ind = base_addr / IOMM_TABLE_ENTRY_SIZE; |
357 | dn = iomm_table[ind]; | 369 | dn = iomm_table[ind]; |
@@ -377,21 +389,10 @@ static u8 iSeries_read_byte(const volatile void __iomem *addr) | |||
377 | int retry = 0; | 389 | int retry = 0; |
378 | struct HvCallPci_LoadReturn ret; | 390 | struct HvCallPci_LoadReturn ret; |
379 | struct device_node *dn = | 391 | struct device_node *dn = |
380 | xlate_iomm_address(addr, &dsa, &bar_offset); | 392 | xlate_iomm_address(addr, &dsa, &bar_offset, "read_byte"); |
381 | |||
382 | if (dn == NULL) { | ||
383 | static unsigned long last_jiffies; | ||
384 | static int num_printed; | ||
385 | 393 | ||
386 | if ((jiffies - last_jiffies) > 60 * HZ) { | 394 | if (dn == NULL) |
387 | last_jiffies = jiffies; | ||
388 | num_printed = 0; | ||
389 | } | ||
390 | if (num_printed++ < 10) | ||
391 | printk(KERN_ERR "iSeries_read_byte: invalid access at IO address %p\n", | ||
392 | addr); | ||
393 | return 0xff; | 395 | return 0xff; |
394 | } | ||
395 | do { | 396 | do { |
396 | HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, bar_offset, 0); | 397 | HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, bar_offset, 0); |
397 | } while (check_return_code("RDB", dn, &retry, ret.rc) != 0); | 398 | } while (check_return_code("RDB", dn, &retry, ret.rc) != 0); |
@@ -406,21 +407,10 @@ static u16 iSeries_read_word(const volatile void __iomem *addr) | |||
406 | int retry = 0; | 407 | int retry = 0; |
407 | struct HvCallPci_LoadReturn ret; | 408 | struct HvCallPci_LoadReturn ret; |
408 | struct device_node *dn = | 409 | struct device_node *dn = |
409 | xlate_iomm_address(addr, &dsa, &bar_offset); | 410 | xlate_iomm_address(addr, &dsa, &bar_offset, "read_word"); |
410 | |||
411 | if (dn == NULL) { | ||
412 | static unsigned long last_jiffies; | ||
413 | static int num_printed; | ||
414 | 411 | ||
415 | if ((jiffies - last_jiffies) > 60 * HZ) { | 412 | if (dn == NULL) |
416 | last_jiffies = jiffies; | ||
417 | num_printed = 0; | ||
418 | } | ||
419 | if (num_printed++ < 10) | ||
420 | printk(KERN_ERR "iSeries_read_word: invalid access at IO address %p\n", | ||
421 | addr); | ||
422 | return 0xffff; | 413 | return 0xffff; |
423 | } | ||
424 | do { | 414 | do { |
425 | HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa, | 415 | HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa, |
426 | bar_offset, 0); | 416 | bar_offset, 0); |
@@ -436,21 +426,10 @@ static u32 iSeries_read_long(const volatile void __iomem *addr) | |||
436 | int retry = 0; | 426 | int retry = 0; |
437 | struct HvCallPci_LoadReturn ret; | 427 | struct HvCallPci_LoadReturn ret; |
438 | struct device_node *dn = | 428 | struct device_node *dn = |
439 | xlate_iomm_address(addr, &dsa, &bar_offset); | 429 | xlate_iomm_address(addr, &dsa, &bar_offset, "read_long"); |
440 | |||
441 | if (dn == NULL) { | ||
442 | static unsigned long last_jiffies; | ||
443 | static int num_printed; | ||
444 | 430 | ||
445 | if ((jiffies - last_jiffies) > 60 * HZ) { | 431 | if (dn == NULL) |
446 | last_jiffies = jiffies; | ||
447 | num_printed = 0; | ||
448 | } | ||
449 | if (num_printed++ < 10) | ||
450 | printk(KERN_ERR "iSeries_read_long: invalid access at IO address %p\n", | ||
451 | addr); | ||
452 | return 0xffffffff; | 432 | return 0xffffffff; |
453 | } | ||
454 | do { | 433 | do { |
455 | HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa, | 434 | HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa, |
456 | bar_offset, 0); | 435 | bar_offset, 0); |
@@ -470,20 +449,10 @@ static void iSeries_write_byte(u8 data, volatile void __iomem *addr) | |||
470 | int retry = 0; | 449 | int retry = 0; |
471 | u64 rc; | 450 | u64 rc; |
472 | struct device_node *dn = | 451 | struct device_node *dn = |
473 | xlate_iomm_address(addr, &dsa, &bar_offset); | 452 | xlate_iomm_address(addr, &dsa, &bar_offset, "write_byte"); |
474 | 453 | ||
475 | if (dn == NULL) { | 454 | if (dn == NULL) |
476 | static unsigned long last_jiffies; | ||
477 | static int num_printed; | ||
478 | |||
479 | if ((jiffies - last_jiffies) > 60 * HZ) { | ||
480 | last_jiffies = jiffies; | ||
481 | num_printed = 0; | ||
482 | } | ||
483 | if (num_printed++ < 10) | ||
484 | printk(KERN_ERR "iSeries_write_byte: invalid access at IO address %p\n", addr); | ||
485 | return; | 455 | return; |
486 | } | ||
487 | do { | 456 | do { |
488 | rc = HvCall4(HvCallPciBarStore8, dsa, bar_offset, data, 0); | 457 | rc = HvCall4(HvCallPciBarStore8, dsa, bar_offset, data, 0); |
489 | } while (check_return_code("WWB", dn, &retry, rc) != 0); | 458 | } while (check_return_code("WWB", dn, &retry, rc) != 0); |
@@ -496,21 +465,10 @@ static void iSeries_write_word(u16 data, volatile void __iomem *addr) | |||
496 | int retry = 0; | 465 | int retry = 0; |
497 | u64 rc; | 466 | u64 rc; |
498 | struct device_node *dn = | 467 | struct device_node *dn = |
499 | xlate_iomm_address(addr, &dsa, &bar_offset); | 468 | xlate_iomm_address(addr, &dsa, &bar_offset, "write_word"); |
500 | |||
501 | if (dn == NULL) { | ||
502 | static unsigned long last_jiffies; | ||
503 | static int num_printed; | ||
504 | 469 | ||
505 | if ((jiffies - last_jiffies) > 60 * HZ) { | 470 | if (dn == NULL) |
506 | last_jiffies = jiffies; | ||
507 | num_printed = 0; | ||
508 | } | ||
509 | if (num_printed++ < 10) | ||
510 | printk(KERN_ERR "iSeries_write_word: invalid access at IO address %p\n", | ||
511 | addr); | ||
512 | return; | 471 | return; |
513 | } | ||
514 | do { | 472 | do { |
515 | rc = HvCall4(HvCallPciBarStore16, dsa, bar_offset, data, 0); | 473 | rc = HvCall4(HvCallPciBarStore16, dsa, bar_offset, data, 0); |
516 | } while (check_return_code("WWW", dn, &retry, rc) != 0); | 474 | } while (check_return_code("WWW", dn, &retry, rc) != 0); |
@@ -523,21 +481,10 @@ static void iSeries_write_long(u32 data, volatile void __iomem *addr) | |||
523 | int retry = 0; | 481 | int retry = 0; |
524 | u64 rc; | 482 | u64 rc; |
525 | struct device_node *dn = | 483 | struct device_node *dn = |
526 | xlate_iomm_address(addr, &dsa, &bar_offset); | 484 | xlate_iomm_address(addr, &dsa, &bar_offset, "write_long"); |
527 | 485 | ||
528 | if (dn == NULL) { | 486 | if (dn == NULL) |
529 | static unsigned long last_jiffies; | ||
530 | static int num_printed; | ||
531 | |||
532 | if ((jiffies - last_jiffies) > 60 * HZ) { | ||
533 | last_jiffies = jiffies; | ||
534 | num_printed = 0; | ||
535 | } | ||
536 | if (num_printed++ < 10) | ||
537 | printk(KERN_ERR "iSeries_write_long: invalid access at IO address %p\n", | ||
538 | addr); | ||
539 | return; | 487 | return; |
540 | } | ||
541 | do { | 488 | do { |
542 | rc = HvCall4(HvCallPciBarStore32, dsa, bar_offset, data, 0); | 489 | rc = HvCall4(HvCallPciBarStore32, dsa, bar_offset, data, 0); |
543 | } while (check_return_code("WWL", dn, &retry, rc) != 0); | 490 | } while (check_return_code("WWL", dn, &retry, rc) != 0); |