aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>2008-01-18 15:30:53 -0500
committerPaul Mackerras <paulus@samba.org>2008-01-25 06:52:51 -0500
commit972b1f040c8698ef2a44ad3f2b790039d5a8ac09 (patch)
tree8c29e730fda9e3b1a061b05ee36aa8a4e44d64ac
parentb4cb2941f855993410ca456ef998888434e86098 (diff)
[POWERPC] PS3: Add repository polling loop to work around timing bug
PS3: Add repository polling loop to work around timing bug On some firmware versions (e.g. 1.90), the storage device may not show up in the repository immediately after receiving the notification message. Add a small polling loop to make sure we don't miss it. Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com> Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/platforms/ps3/device-init.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
index 5695e00219e4..05c7c1c624dc 100644
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -489,6 +489,38 @@ static int ps3_register_repository_device(
489 return result; 489 return result;
490} 490}
491 491
492static void ps3_find_and_add_device(u64 bus_id, u64 dev_id)
493{
494 struct ps3_repository_device repo;
495 int res;
496 unsigned int retries;
497 unsigned long rem;
498
499 /*
500 * On some firmware versions (e.g. 1.90), the device may not show up
501 * in the repository immediately
502 */
503 for (retries = 0; retries < 10; retries++) {
504 res = ps3_repository_find_device_by_id(&repo, bus_id, dev_id);
505 if (!res)
506 goto found;
507
508 rem = msleep_interruptible(100);
509 if (rem)
510 break;
511 }
512 pr_warning("%s:%u: device %lu:%lu not found\n", __func__, __LINE__,
513 bus_id, dev_id);
514 return;
515
516found:
517 if (retries)
518 pr_debug("%s:%u: device %lu:%lu found after %u retries\n",
519 __func__, __LINE__, bus_id, dev_id, retries);
520
521 ps3_register_repository_device(&repo);
522 return;
523}
492 524
493#define PS3_NOTIFICATION_DEV_ID ULONG_MAX 525#define PS3_NOTIFICATION_DEV_ID ULONG_MAX
494#define PS3_NOTIFICATION_INTERRUPT_ID 0 526#define PS3_NOTIFICATION_INTERRUPT_ID 0
@@ -600,7 +632,6 @@ static struct task_struct *probe_task;
600static int ps3_probe_thread(void *data) 632static int ps3_probe_thread(void *data)
601{ 633{
602 struct ps3_notification_device dev; 634 struct ps3_notification_device dev;
603 struct ps3_repository_device repo;
604 int res; 635 int res;
605 unsigned int irq; 636 unsigned int irq;
606 u64 lpar; 637 u64 lpar;
@@ -682,18 +713,7 @@ static int ps3_probe_thread(void *data)
682 continue; 713 continue;
683 } 714 }
684 715
685 res = ps3_repository_find_device_by_id(&repo, dev.sbd.bus_id, 716 ps3_find_and_add_device(dev.sbd.bus_id, notify_event->dev_id);
686 notify_event->dev_id);
687 if (res) {
688 pr_warning("%s:%u: device %lu:%lu not found\n",
689 __func__, __LINE__, dev.sbd.bus_id,
690 notify_event->dev_id);
691 continue;
692 }
693
694 pr_debug("%s:%u: device %lu:%lu found\n", __func__, __LINE__,
695 dev.sbd.bus_id, notify_event->dev_id);
696 ps3_register_repository_device(&repo);
697 717
698 } while (!kthread_should_stop()); 718 } while (!kthread_should_stop());
699 719