aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorMark Haverkamp <markh@linux-foundation.org>2007-03-15 13:26:05 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-03-20 11:54:11 -0400
commit8418852d11f0bbaeebeedd4243560d8fdc85410d (patch)
tree83a6d2c4841c41bdc8a627c3e248deb1cc730210 /drivers/scsi
parentb22f687dd28a7a8886b918294b4d558ef175c07d (diff)
[SCSI] aacraid: add restart adapter platform function
Received from Mark Salyzyn, This patch updates the adapter restart function to deal with some adapters that have specific IOP reset needs. Since the code for restarting the adapter was in two places, changed over to utilizing a platform function in one place. Signed-off-by: Mark Haverkamp <markh@linux-foundation.org> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/aacraid/aacraid.h4
-rw-r--r--drivers/scsi/aacraid/commsup.c13
-rw-r--r--drivers/scsi/aacraid/rx.c39
3 files changed, 31 insertions, 25 deletions
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 39ecd0d22eb0..7e25c0bbd644 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -497,6 +497,7 @@ struct adapter_ops
497 void (*adapter_enable_int)(struct aac_dev *dev); 497 void (*adapter_enable_int)(struct aac_dev *dev);
498 int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4); 498 int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4);
499 int (*adapter_check_health)(struct aac_dev *dev); 499 int (*adapter_check_health)(struct aac_dev *dev);
500 int (*adapter_restart)(struct aac_dev *dev, int bled);
500 /* Transport operations */ 501 /* Transport operations */
501 int (*adapter_ioremap)(struct aac_dev * dev, u32 size); 502 int (*adapter_ioremap)(struct aac_dev * dev, u32 size);
502 irqreturn_t (*adapter_intr)(int irq, void *dev_id); 503 irqreturn_t (*adapter_intr)(int irq, void *dev_id);
@@ -1060,6 +1061,9 @@ struct aac_dev
1060#define aac_adapter_check_health(dev) \ 1061#define aac_adapter_check_health(dev) \
1061 (dev)->a_ops.adapter_check_health(dev) 1062 (dev)->a_ops.adapter_check_health(dev)
1062 1063
1064#define aac_adapter_restart(dev,bled) \
1065 (dev)->a_ops.adapter_restart(dev,bled)
1066
1063#define aac_adapter_ioremap(dev, size) \ 1067#define aac_adapter_ioremap(dev, size) \
1064 (dev)->a_ops.adapter_ioremap(dev, size) 1068 (dev)->a_ops.adapter_ioremap(dev, size)
1065 1069
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 1b97f60652ba..55bf6f395e92 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1035,7 +1035,6 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
1035static int _aac_reset_adapter(struct aac_dev *aac) 1035static int _aac_reset_adapter(struct aac_dev *aac)
1036{ 1036{
1037 int index, quirks; 1037 int index, quirks;
1038 u32 ret;
1039 int retval; 1038 int retval;
1040 struct Scsi_Host *host; 1039 struct Scsi_Host *host;
1041 struct scsi_device *dev; 1040 struct scsi_device *dev;
@@ -1059,20 +1058,10 @@ static int _aac_reset_adapter(struct aac_dev *aac)
1059 * If a positive health, means in a known DEAD PANIC 1058 * If a positive health, means in a known DEAD PANIC
1060 * state and the adapter could be reset to `try again'. 1059 * state and the adapter could be reset to `try again'.
1061 */ 1060 */
1062 retval = aac_adapter_check_health(aac); 1061 retval = aac_adapter_restart(aac, aac_adapter_check_health(aac));
1063 if (retval == 0)
1064 retval = aac_adapter_sync_cmd(aac, IOP_RESET_ALWAYS,
1065 0, 0, 0, 0, 0, 0, &ret, NULL, NULL, NULL, NULL);
1066 if (retval)
1067 retval = aac_adapter_sync_cmd(aac, IOP_RESET,
1068 0, 0, 0, 0, 0, 0, &ret, NULL, NULL, NULL, NULL);
1069 1062
1070 if (retval) 1063 if (retval)
1071 goto out; 1064 goto out;
1072 if (ret != 0x00000001) {
1073 retval = -ENODEV;
1074 goto out;
1075 }
1076 1065
1077 /* 1066 /*
1078 * Loop through the fibs, close the synchronous FIBS 1067 * Loop through the fibs, close the synchronous FIBS
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index d242e2611d67..00e3cba9d8ef 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -460,22 +460,31 @@ static int aac_rx_ioremap(struct aac_dev * dev, u32 size)
460 return 0; 460 return 0;
461} 461}
462 462
463static int aac_rx_restart_adapter(struct aac_dev *dev) 463static int aac_rx_restart_adapter(struct aac_dev *dev, int bled)
464{ 464{
465 u32 var; 465 u32 var;
466 466
467 printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", 467 if (bled)
468 dev->name, dev->id); 468 printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
469 469 dev->name, dev->id, bled);
470 if (aac_rx_check_health(dev) <= 0) 470 else
471 return 1; 471 bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
472 if (rx_sync_cmd(dev, IOP_RESET, 0, 0, 0, 0, 0, 0, 472 0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL);
473 &var, NULL, NULL, NULL, NULL)) 473 if (bled)
474 return 1; 474 bled = aac_adapter_sync_cmd(dev, IOP_RESET,
475 0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL);
476
477 if (bled)
478 return -EINVAL;
479 if (var == 0x3803000F) { /* USE_OTHER_METHOD */
480 rx_writel(dev, MUnit.reserved2, 3);
481 msleep(5000); /* Delay 5 seconds */
482 var = 0x00000001;
483 }
475 if (var != 0x00000001) 484 if (var != 0x00000001)
476 return 1; 485 return -EINVAL;
477 if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) 486 if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC)
478 return 1; 487 return -ENODEV;
479 return 0; 488 return 0;
480} 489}
481 490
@@ -532,9 +541,12 @@ int _aac_rx_init(struct aac_dev *dev)
532 * Check to see if the board panic'd while booting. 541 * Check to see if the board panic'd while booting.
533 */ 542 */
534 status = rx_readl(dev, MUnit.OMRx[0]); 543 status = rx_readl(dev, MUnit.OMRx[0]);
535 if (status & KERNEL_PANIC) 544 if (status & KERNEL_PANIC) {
536 if (aac_rx_restart_adapter(dev)) 545 if ((status = aac_rx_check_health(dev)) <= 0)
537 goto error_iounmap; 546 goto error_iounmap;
547 if (aac_rx_restart_adapter(dev, status))
548 goto error_iounmap;
549 }
538 /* 550 /*
539 * Check to see if the board failed any self tests. 551 * Check to see if the board failed any self tests.
540 */ 552 */
@@ -572,6 +584,7 @@ int _aac_rx_init(struct aac_dev *dev)
572 dev->a_ops.adapter_notify = aac_rx_notify_adapter; 584 dev->a_ops.adapter_notify = aac_rx_notify_adapter;
573 dev->a_ops.adapter_sync_cmd = rx_sync_cmd; 585 dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
574 dev->a_ops.adapter_check_health = aac_rx_check_health; 586 dev->a_ops.adapter_check_health = aac_rx_check_health;
587 dev->a_ops.adapter_restart = aac_rx_restart_adapter;
575 588
576 /* 589 /*
577 * First clear out all interrupts. Then enable the one's that we 590 * First clear out all interrupts. Then enable the one's that we