aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/linit.c
diff options
context:
space:
mode:
authorSalyzyn, Mark <mark_salyzyn@adaptec.com>2007-06-12 09:33:54 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-06-17 16:00:47 -0400
commit29c976844d0bef07d97babc8db60fa6c46788133 (patch)
tree9543cef49748d0fe7ac08a5a1780c213e0fc37bd /drivers/scsi/aacraid/linit.c
parent1a655040c24ebf3954ad5cf8848391cb420b1ffb (diff)
[SCSI] aacraid: add user initiated reset
Add the ability for an application to issue a hardware reset to the adapter via sysfs. Typical uses include restarting the adapter after it has been flashed. Bumped revision number for the driver and added a feature to periodically check the adapter's health (check_interval), update the adapter's concept of time (update_interval) and block checking/resetting of the adapter (check_reset). Signed-off-by: Mark Salyzyn <aacraid@adaptec.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/aacraid/linit.c')
-rw-r--r--drivers/scsi/aacraid/linit.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 6f92d077679f..f8c2aaf72aff 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -39,10 +39,8 @@
39#include <linux/pci.h> 39#include <linux/pci.h>
40#include <linux/slab.h> 40#include <linux/slab.h>
41#include <linux/spinlock.h> 41#include <linux/spinlock.h>
42#include <linux/dma-mapping.h>
43#include <linux/syscalls.h> 42#include <linux/syscalls.h>
44#include <linux/delay.h> 43#include <linux/delay.h>
45#include <linux/smp_lock.h>
46#include <linux/kthread.h> 44#include <linux/kthread.h>
47#include <asm/semaphore.h> 45#include <asm/semaphore.h>
48 46
@@ -581,6 +579,14 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
581 ssleep(1); 579 ssleep(1);
582 } 580 }
583 printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME); 581 printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME);
582 /*
583 * This adapter needs a blind reset, only do so for Adapters that
584 * support a register, instead of a commanded, reset.
585 */
586 if ((aac->supplement_adapter_info.SupportedOptions2 &
587 le32_to_cpu(AAC_OPTION_MU_RESET|AAC_OPTION_IGNORE_RESET)) ==
588 le32_to_cpu(AAC_OPTION_MU_RESET))
589 aac_reset_adapter(aac, 2); /* Bypass wait for command quiesce */
584 return SUCCESS; /* Cause an immediate retry of the command with a ten second delay after successful tur */ 590 return SUCCESS; /* Cause an immediate retry of the command with a ten second delay after successful tur */
585} 591}
586 592
@@ -788,6 +794,31 @@ static ssize_t aac_show_max_id(struct class_device *class_dev, char *buf)
788 class_to_shost(class_dev)->max_id); 794 class_to_shost(class_dev)->max_id);
789} 795}
790 796
797static ssize_t aac_store_reset_adapter(struct class_device *class_dev,
798 const char *buf, size_t count)
799{
800 int retval = -EACCES;
801
802 if (!capable(CAP_SYS_ADMIN))
803 return retval;
804 retval = aac_reset_adapter((struct aac_dev*)class_to_shost(class_dev)->hostdata, buf[0] == '!');
805 if (retval >= 0)
806 retval = count;
807 return retval;
808}
809
810static ssize_t aac_show_reset_adapter(struct class_device *class_dev,
811 char *buf)
812{
813 struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
814 int len, tmp;
815
816 tmp = aac_adapter_check_health(dev);
817 if ((tmp == 0) && dev->in_reset)
818 tmp = -EBUSY;
819 len = snprintf(buf, PAGE_SIZE, "0x%x", tmp);
820 return len;
821}
791 822
792static struct class_device_attribute aac_model = { 823static struct class_device_attribute aac_model = {
793 .attr = { 824 .attr = {
@@ -845,6 +876,14 @@ static struct class_device_attribute aac_max_id = {
845 }, 876 },
846 .show = aac_show_max_id, 877 .show = aac_show_max_id,
847}; 878};
879static struct class_device_attribute aac_reset = {
880 .attr = {
881 .name = "reset_host",
882 .mode = S_IWUSR|S_IRUGO,
883 },
884 .store = aac_store_reset_adapter,
885 .show = aac_show_reset_adapter,
886};
848 887
849static struct class_device_attribute *aac_attrs[] = { 888static struct class_device_attribute *aac_attrs[] = {
850 &aac_model, 889 &aac_model,
@@ -855,6 +894,7 @@ static struct class_device_attribute *aac_attrs[] = {
855 &aac_serial_number, 894 &aac_serial_number,
856 &aac_max_channel, 895 &aac_max_channel,
857 &aac_max_id, 896 &aac_max_id,
897 &aac_reset,
858 NULL 898 NULL
859}; 899};
860 900
@@ -1118,7 +1158,7 @@ static int __init aac_init(void)
1118{ 1158{
1119 int error; 1159 int error;
1120 1160
1121 printk(KERN_INFO "Adaptec %s driver (%s)\n", 1161 printk(KERN_INFO "Adaptec %s driver %s\n",
1122 AAC_DRIVERNAME, aac_driver_version); 1162 AAC_DRIVERNAME, aac_driver_version);
1123 1163
1124 error = pci_register_driver(&aac_pci_driver); 1164 error = pci_register_driver(&aac_pci_driver);