aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Haverkamp <markh@osdl.org>2006-08-03 11:03:30 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-08-19 16:35:11 -0400
commit8c867b257d159ca04602d7087fa29f846785f9ea (patch)
tree4c95fc920744556d718b8d63371a6b525524cfbe
parent90ee346651524eb275405d410f5d3bb6765a2d93 (diff)
[SCSI] aacraid: Reset adapter in recovery timeout
Received from Mark Salyzyn If the adapter is in blinkled (Firmware Assert) when error recovery timeout actions have been triggered, perform an adapter warm reset and restart the initialization. Signed-off-by: Mark Haverkamp <markh@osdl.org> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/aacraid/aachba.c39
-rw-r--r--drivers/scsi/aacraid/aacraid.h4
-rw-r--r--drivers/scsi/aacraid/commctrl.c2
-rw-r--r--drivers/scsi/aacraid/commsup.c258
-rw-r--r--drivers/scsi/aacraid/linit.c14
5 files changed, 296 insertions, 21 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 699351c15cc9..37c55ddce214 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -175,7 +175,7 @@ MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size.
175 * 175 *
176 * Query config status, and commit the configuration if needed. 176 * Query config status, and commit the configuration if needed.
177 */ 177 */
178int aac_get_config_status(struct aac_dev *dev) 178int aac_get_config_status(struct aac_dev *dev, int commit_flag)
179{ 179{
180 int status = 0; 180 int status = 0;
181 struct fib * fibptr; 181 struct fib * fibptr;
@@ -219,7 +219,7 @@ int aac_get_config_status(struct aac_dev *dev)
219 aac_fib_complete(fibptr); 219 aac_fib_complete(fibptr);
220 /* Send a CT_COMMIT_CONFIG to enable discovery of devices */ 220 /* Send a CT_COMMIT_CONFIG to enable discovery of devices */
221 if (status >= 0) { 221 if (status >= 0) {
222 if (commit == 1) { 222 if ((commit == 1) || commit_flag) {
223 struct aac_commit_config * dinfo; 223 struct aac_commit_config * dinfo;
224 aac_fib_init(fibptr); 224 aac_fib_init(fibptr);
225 dinfo = (struct aac_commit_config *) fib_data(fibptr); 225 dinfo = (struct aac_commit_config *) fib_data(fibptr);
@@ -784,8 +784,9 @@ int aac_get_adapter_info(struct aac_dev* dev)
784 dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount); 784 dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount);
785 } 785 }
786 786
787 tmp = le32_to_cpu(dev->adapter_info.kernelrev); 787 if (!dev->in_reset) {
788 printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d] %.*s\n", 788 tmp = le32_to_cpu(dev->adapter_info.kernelrev);
789 printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d] %.*s\n",
789 dev->name, 790 dev->name,
790 dev->id, 791 dev->id,
791 tmp>>24, 792 tmp>>24,
@@ -794,20 +795,21 @@ int aac_get_adapter_info(struct aac_dev* dev)
794 le32_to_cpu(dev->adapter_info.kernelbuild), 795 le32_to_cpu(dev->adapter_info.kernelbuild),
795 (int)sizeof(dev->supplement_adapter_info.BuildDate), 796 (int)sizeof(dev->supplement_adapter_info.BuildDate),
796 dev->supplement_adapter_info.BuildDate); 797 dev->supplement_adapter_info.BuildDate);
797 tmp = le32_to_cpu(dev->adapter_info.monitorrev); 798 tmp = le32_to_cpu(dev->adapter_info.monitorrev);
798 printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n", 799 printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n",
799 dev->name, dev->id, 800 dev->name, dev->id,
800 tmp>>24,(tmp>>16)&0xff,tmp&0xff, 801 tmp>>24,(tmp>>16)&0xff,tmp&0xff,
801 le32_to_cpu(dev->adapter_info.monitorbuild)); 802 le32_to_cpu(dev->adapter_info.monitorbuild));
802 tmp = le32_to_cpu(dev->adapter_info.biosrev); 803 tmp = le32_to_cpu(dev->adapter_info.biosrev);
803 printk(KERN_INFO "%s%d: bios %d.%d-%d[%d]\n", 804 printk(KERN_INFO "%s%d: bios %d.%d-%d[%d]\n",
804 dev->name, dev->id, 805 dev->name, dev->id,
805 tmp>>24,(tmp>>16)&0xff,tmp&0xff, 806 tmp>>24,(tmp>>16)&0xff,tmp&0xff,
806 le32_to_cpu(dev->adapter_info.biosbuild)); 807 le32_to_cpu(dev->adapter_info.biosbuild));
807 if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0) 808 if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0)
808 printk(KERN_INFO "%s%d: serial %x\n", 809 printk(KERN_INFO "%s%d: serial %x\n",
809 dev->name, dev->id, 810 dev->name, dev->id,
810 le32_to_cpu(dev->adapter_info.serial[0])); 811 le32_to_cpu(dev->adapter_info.serial[0]));
812 }
811 813
812 dev->nondasd_support = 0; 814 dev->nondasd_support = 0;
813 dev->raid_scsi_mode = 0; 815 dev->raid_scsi_mode = 0;
@@ -1417,6 +1419,9 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
1417 return SCSI_MLQUEUE_DEVICE_BUSY; 1419 return SCSI_MLQUEUE_DEVICE_BUSY;
1418 1420
1419 aac = (struct aac_dev *)scsicmd->device->host->hostdata; 1421 aac = (struct aac_dev *)scsicmd->device->host->hostdata;
1422 if (aac->in_reset)
1423 return SCSI_MLQUEUE_HOST_BUSY;
1424
1420 /* 1425 /*
1421 * Allocate and initialize a Fib 1426 * Allocate and initialize a Fib
1422 */ 1427 */
@@ -1504,6 +1509,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
1504 case INQUIRY: 1509 case INQUIRY:
1505 case READ_CAPACITY: 1510 case READ_CAPACITY:
1506 case TEST_UNIT_READY: 1511 case TEST_UNIT_READY:
1512 if (dev->in_reset)
1513 return -1;
1507 spin_unlock_irq(host->host_lock); 1514 spin_unlock_irq(host->host_lock);
1508 aac_probe_container(dev, cid); 1515 aac_probe_container(dev, cid);
1509 if ((fsa_dev_ptr[cid].valid & 1) == 0) 1516 if ((fsa_dev_ptr[cid].valid & 1) == 0)
@@ -1529,6 +1536,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
1529 } 1536 }
1530 } else { /* check for physical non-dasd devices */ 1537 } else { /* check for physical non-dasd devices */
1531 if(dev->nondasd_support == 1){ 1538 if(dev->nondasd_support == 1){
1539 if (dev->in_reset)
1540 return -1;
1532 return aac_send_srb_fib(scsicmd); 1541 return aac_send_srb_fib(scsicmd);
1533 } else { 1542 } else {
1534 scsicmd->result = DID_NO_CONNECT << 16; 1543 scsicmd->result = DID_NO_CONNECT << 16;
@@ -1584,6 +1593,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
1584 scsicmd->scsi_done(scsicmd); 1593 scsicmd->scsi_done(scsicmd);
1585 return 0; 1594 return 0;
1586 } 1595 }
1596 if (dev->in_reset)
1597 return -1;
1587 setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); 1598 setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type);
1588 inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ 1599 inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */
1589 aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); 1600 aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
@@ -1739,6 +1750,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
1739 case READ_10: 1750 case READ_10:
1740 case READ_12: 1751 case READ_12:
1741 case READ_16: 1752 case READ_16:
1753 if (dev->in_reset)
1754 return -1;
1742 /* 1755 /*
1743 * Hack to keep track of ordinal number of the device that 1756 * Hack to keep track of ordinal number of the device that
1744 * corresponds to a container. Needed to convert 1757 * corresponds to a container. Needed to convert
@@ -1757,6 +1770,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
1757 case WRITE_10: 1770 case WRITE_10:
1758 case WRITE_12: 1771 case WRITE_12:
1759 case WRITE_16: 1772 case WRITE_16:
1773 if (dev->in_reset)
1774 return -1;
1760 return aac_write(scsicmd, cid); 1775 return aac_write(scsicmd, cid);
1761 1776
1762 case SYNCHRONIZE_CACHE: 1777 case SYNCHRONIZE_CACHE:
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 05f80982efa5..8924c183d9c3 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1029,6 +1029,7 @@ struct aac_dev
1029 init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4) 1029 init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4)
1030 u8 raw_io_64; 1030 u8 raw_io_64;
1031 u8 printf_enabled; 1031 u8 printf_enabled;
1032 u8 in_reset;
1032}; 1033};
1033 1034
1034#define aac_adapter_interrupt(dev) \ 1035#define aac_adapter_interrupt(dev) \
@@ -1789,7 +1790,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum);
1789int aac_fib_complete(struct fib * context); 1790int aac_fib_complete(struct fib * context);
1790#define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data) 1791#define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data)
1791struct aac_dev *aac_init_adapter(struct aac_dev *dev); 1792struct aac_dev *aac_init_adapter(struct aac_dev *dev);
1792int aac_get_config_status(struct aac_dev *dev); 1793int aac_get_config_status(struct aac_dev *dev, int commit_flag);
1793int aac_get_containers(struct aac_dev *dev); 1794int aac_get_containers(struct aac_dev *dev);
1794int aac_scsi_cmd(struct scsi_cmnd *cmd); 1795int aac_scsi_cmd(struct scsi_cmnd *cmd);
1795int aac_dev_ioctl(struct aac_dev *dev, int cmd, void __user *arg); 1796int aac_dev_ioctl(struct aac_dev *dev, int cmd, void __user *arg);
@@ -1800,6 +1801,7 @@ int aac_sa_init(struct aac_dev *dev);
1800unsigned int aac_response_normal(struct aac_queue * q); 1801unsigned int aac_response_normal(struct aac_queue * q);
1801unsigned int aac_command_normal(struct aac_queue * q); 1802unsigned int aac_command_normal(struct aac_queue * q);
1802unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index); 1803unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index);
1804int aac_check_health(struct aac_dev * dev);
1803int aac_command_thread(void *data); 1805int aac_command_thread(void *data);
1804int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx); 1806int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx);
1805int aac_fib_adapter_complete(struct fib * fibptr, unsigned short size); 1807int aac_fib_adapter_complete(struct fib * fibptr, unsigned short size);
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index 14d7aa9b7df3..da1d3a9212f8 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -298,7 +298,7 @@ return_fib:
298 spin_unlock_irqrestore(&dev->fib_lock, flags); 298 spin_unlock_irqrestore(&dev->fib_lock, flags);
299 /* If someone killed the AIF aacraid thread, restart it */ 299 /* If someone killed the AIF aacraid thread, restart it */
300 status = !dev->aif_thread; 300 status = !dev->aif_thread;
301 if (status && dev->queues && dev->fsa_dev) { 301 if (status && !dev->in_reset && dev->queues && dev->fsa_dev) {
302 /* Be paranoid, be very paranoid! */ 302 /* Be paranoid, be very paranoid! */
303 kthread_stop(dev->thread); 303 kthread_stop(dev->thread);
304 ssleep(1); 304 ssleep(1);
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index c67da1321133..53add53be0bd 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -40,8 +40,10 @@
40#include <linux/blkdev.h> 40#include <linux/blkdev.h>
41#include <linux/delay.h> 41#include <linux/delay.h>
42#include <linux/kthread.h> 42#include <linux/kthread.h>
43#include <scsi/scsi.h>
43#include <scsi/scsi_host.h> 44#include <scsi/scsi_host.h>
44#include <scsi/scsi_device.h> 45#include <scsi/scsi_device.h>
46#include <scsi/scsi_cmnd.h>
45#include <asm/semaphore.h> 47#include <asm/semaphore.h>
46 48
47#include "aacraid.h" 49#include "aacraid.h"
@@ -1054,6 +1056,262 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
1054 1056
1055} 1057}
1056 1058
1059static int _aac_reset_adapter(struct aac_dev *aac)
1060{
1061 int index, quirks;
1062 u32 ret;
1063 int retval;
1064 struct Scsi_Host *host;
1065 struct scsi_device *dev;
1066 struct scsi_cmnd *command;
1067 struct scsi_cmnd *command_list;
1068
1069 /*
1070 * Assumptions:
1071 * - host is locked.
1072 * - in_reset is asserted, so no new i/o is getting to the
1073 * card.
1074 * - The card is dead.
1075 */
1076 host = aac->scsi_host_ptr;
1077 scsi_block_requests(host);
1078 aac_adapter_disable_int(aac);
1079 spin_unlock_irq(host->host_lock);
1080 kthread_stop(aac->thread);
1081
1082 /*
1083 * If a positive health, means in a known DEAD PANIC
1084 * state and the adapter could be reset to `try again'.
1085 */
1086 retval = aac_adapter_check_health(aac);
1087 if (retval == 0)
1088 retval = aac_adapter_sync_cmd(aac, IOP_RESET_ALWAYS,
1089 0, 0, 0, 0, 0, 0, &ret, NULL, NULL, NULL, NULL);
1090 if (retval)
1091 retval = aac_adapter_sync_cmd(aac, IOP_RESET,
1092 0, 0, 0, 0, 0, 0, &ret, NULL, NULL, NULL, NULL);
1093
1094 if (retval)
1095 goto out;
1096 if (ret != 0x00000001) {
1097 retval = -ENODEV;
1098 goto out;
1099 }
1100
1101 index = aac->cardtype;
1102
1103 /*
1104 * Re-initialize the adapter, first free resources, then carefully
1105 * apply the initialization sequence to come back again. Only risk
1106 * is a change in Firmware dropping cache, it is assumed the caller
1107 * will ensure that i/o is queisced and the card is flushed in that
1108 * case.
1109 */
1110 aac_fib_map_free(aac);
1111 aac->hw_fib_va = NULL;
1112 aac->hw_fib_pa = 0;
1113 pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys);
1114 aac->comm_addr = NULL;
1115 aac->comm_phys = 0;
1116 kfree(aac->queues);
1117 aac->queues = NULL;
1118 free_irq(aac->pdev->irq, aac);
1119 kfree(aac->fsa_dev);
1120 aac->fsa_dev = NULL;
1121 if (aac_get_driver_ident(index)->quirks & AAC_QUIRK_31BIT) {
1122 if (((retval = pci_set_dma_mask(aac->pdev, DMA_32BIT_MASK))) ||
1123 ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_32BIT_MASK))))
1124 goto out;
1125 } else {
1126 if (((retval = pci_set_dma_mask(aac->pdev, 0x7FFFFFFFULL))) ||
1127 ((retval = pci_set_consistent_dma_mask(aac->pdev, 0x7FFFFFFFULL))))
1128 goto out;
1129 }
1130 if ((retval = (*(aac_get_driver_ident(index)->init))(aac)))
1131 goto out;
1132 if (aac_get_driver_ident(index)->quirks & AAC_QUIRK_31BIT)
1133 if ((retval = pci_set_dma_mask(aac->pdev, DMA_32BIT_MASK)))
1134 goto out;
1135 aac->thread = kthread_run(aac_command_thread, aac, aac->name);
1136 if (IS_ERR(aac->thread)) {
1137 retval = PTR_ERR(aac->thread);
1138 goto out;
1139 }
1140 (void)aac_get_adapter_info(aac);
1141 quirks = aac_get_driver_ident(index)->quirks;
1142 if ((quirks & AAC_QUIRK_34SG) && (host->sg_tablesize > 34)) {
1143 host->sg_tablesize = 34;
1144 host->max_sectors = (host->sg_tablesize * 8) + 112;
1145 }
1146 if ((quirks & AAC_QUIRK_17SG) && (host->sg_tablesize > 17)) {
1147 host->sg_tablesize = 17;
1148 host->max_sectors = (host->sg_tablesize * 8) + 112;
1149 }
1150 aac_get_config_status(aac, 1);
1151 aac_get_containers(aac);
1152 /*
1153 * This is where the assumption that the Adapter is quiesced
1154 * is important.
1155 */
1156 command_list = NULL;
1157 __shost_for_each_device(dev, host) {
1158 unsigned long flags;
1159 spin_lock_irqsave(&dev->list_lock, flags);
1160 list_for_each_entry(command, &dev->cmd_list, list)
1161 if (command->SCp.phase == AAC_OWNER_FIRMWARE) {
1162 command->SCp.buffer = (struct scatterlist *)command_list;
1163 command_list = command;
1164 }
1165 spin_unlock_irqrestore(&dev->list_lock, flags);
1166 }
1167 while ((command = command_list)) {
1168 command_list = (struct scsi_cmnd *)command->SCp.buffer;
1169 command->SCp.buffer = NULL;
1170 command->result = DID_OK << 16
1171 | COMMAND_COMPLETE << 8
1172 | SAM_STAT_TASK_SET_FULL;
1173 command->SCp.phase = AAC_OWNER_ERROR_HANDLER;
1174 command->scsi_done(command);
1175 }
1176 retval = 0;
1177
1178out:
1179 aac->in_reset = 0;
1180 scsi_unblock_requests(host);
1181 spin_lock_irq(host->host_lock);
1182 return retval;
1183}
1184
1185int aac_check_health(struct aac_dev * aac)
1186{
1187 int BlinkLED;
1188 unsigned long time_now, flagv = 0;
1189 struct list_head * entry;
1190 struct Scsi_Host * host;
1191
1192 /* Extending the scope of fib_lock slightly to protect aac->in_reset */
1193 if (spin_trylock_irqsave(&aac->fib_lock, flagv) == 0)
1194 return 0;
1195
1196 if (aac->in_reset || !(BlinkLED = aac_adapter_check_health(aac))) {
1197 spin_unlock_irqrestore(&aac->fib_lock, flagv);
1198 return 0; /* OK */
1199 }
1200
1201 aac->in_reset = 1;
1202
1203 /* Fake up an AIF:
1204 * aac_aifcmd.command = AifCmdEventNotify = 1
1205 * aac_aifcmd.seqnum = 0xFFFFFFFF
1206 * aac_aifcmd.data[0] = AifEnExpEvent = 23
1207 * aac_aifcmd.data[1] = AifExeFirmwarePanic = 3
1208 * aac.aifcmd.data[2] = AifHighPriority = 3
1209 * aac.aifcmd.data[3] = BlinkLED
1210 */
1211
1212 time_now = jiffies/HZ;
1213 entry = aac->fib_list.next;
1214
1215 /*
1216 * For each Context that is on the
1217 * fibctxList, make a copy of the
1218 * fib, and then set the event to wake up the
1219 * thread that is waiting for it.
1220 */
1221 while (entry != &aac->fib_list) {
1222 /*
1223 * Extract the fibctx
1224 */
1225 struct aac_fib_context *fibctx = list_entry(entry, struct aac_fib_context, next);
1226 struct hw_fib * hw_fib;
1227 struct fib * fib;
1228 /*
1229 * Check if the queue is getting
1230 * backlogged
1231 */
1232 if (fibctx->count > 20) {
1233 /*
1234 * It's *not* jiffies folks,
1235 * but jiffies / HZ, so do not
1236 * panic ...
1237 */
1238 u32 time_last = fibctx->jiffies;
1239 /*
1240 * Has it been > 2 minutes
1241 * since the last read off
1242 * the queue?
1243 */
1244 if ((time_now - time_last) > aif_timeout) {
1245 entry = entry->next;
1246 aac_close_fib_context(aac, fibctx);
1247 continue;
1248 }
1249 }
1250 /*
1251 * Warning: no sleep allowed while
1252 * holding spinlock
1253 */
1254 hw_fib = kmalloc(sizeof(struct hw_fib), GFP_ATOMIC);
1255 fib = kmalloc(sizeof(struct fib), GFP_ATOMIC);
1256 if (fib && hw_fib) {
1257 struct aac_aifcmd * aif;
1258
1259 memset(hw_fib, 0, sizeof(struct hw_fib));
1260 memset(fib, 0, sizeof(struct fib));
1261 fib->hw_fib = hw_fib;
1262 fib->dev = aac;
1263 aac_fib_init(fib);
1264 fib->type = FSAFS_NTC_FIB_CONTEXT;
1265 fib->size = sizeof (struct fib);
1266 fib->data = hw_fib->data;
1267 aif = (struct aac_aifcmd *)hw_fib->data;
1268 aif->command = cpu_to_le32(AifCmdEventNotify);
1269 aif->seqnum = cpu_to_le32(0xFFFFFFFF);
1270 aif->data[0] = cpu_to_le32(AifEnExpEvent);
1271 aif->data[1] = cpu_to_le32(AifExeFirmwarePanic);
1272 aif->data[2] = cpu_to_le32(AifHighPriority);
1273 aif->data[3] = cpu_to_le32(BlinkLED);
1274
1275 /*
1276 * Put the FIB onto the
1277 * fibctx's fibs
1278 */
1279 list_add_tail(&fib->fiblink, &fibctx->fib_list);
1280 fibctx->count++;
1281 /*
1282 * Set the event to wake up the
1283 * thread that will waiting.
1284 */
1285 up(&fibctx->wait_sem);
1286 } else {
1287 printk(KERN_WARNING "aifd: didn't allocate NewFib.\n");
1288 kfree(fib);
1289 kfree(hw_fib);
1290 }
1291 entry = entry->next;
1292 }
1293
1294 spin_unlock_irqrestore(&aac->fib_lock, flagv);
1295
1296 if (BlinkLED < 0) {
1297 printk(KERN_ERR "%s: Host adapter dead %d\n", aac->name, BlinkLED);
1298 goto out;
1299 }
1300
1301 printk(KERN_ERR "%s: Host adapter BLINK LED 0x%x\n", aac->name, BlinkLED);
1302
1303 host = aac->scsi_host_ptr;
1304 spin_lock_irqsave(host->host_lock, flagv);
1305 BlinkLED = _aac_reset_adapter(aac);
1306 spin_unlock_irqrestore(host->host_lock, flagv);
1307 return BlinkLED;
1308
1309out:
1310 aac->in_reset = 0;
1311 return BlinkLED;
1312}
1313
1314
1057/** 1315/**
1058 * aac_command_thread - command processing thread 1316 * aac_command_thread - command processing thread
1059 * @dev: Adapter to monitor 1317 * @dev: Adapter to monitor
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 9d8b550a91cb..d67058f80816 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -454,17 +454,17 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
454 printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n", 454 printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n",
455 AAC_DRIVERNAME); 455 AAC_DRIVERNAME);
456 aac = (struct aac_dev *)host->hostdata; 456 aac = (struct aac_dev *)host->hostdata;
457 if (aac_adapter_check_health(aac)) { 457
458 printk(KERN_ERR "%s: Host adapter appears dead\n", 458 if ((count = aac_check_health(aac)))
459 AAC_DRIVERNAME); 459 return count;
460 return -ENODEV;
461 }
462 /* 460 /*
463 * Wait for all commands to complete to this specific 461 * Wait for all commands to complete to this specific
464 * target (block maximum 60 seconds). 462 * target (block maximum 60 seconds).
465 */ 463 */
466 for (count = 60; count; --count) { 464 for (count = 60; count; --count) {
467 int active = 0; 465 int active = aac->in_reset;
466
467 if (active == 0)
468 __shost_for_each_device(dev, host) { 468 __shost_for_each_device(dev, host) {
469 spin_lock_irqsave(&dev->list_lock, flags); 469 spin_lock_irqsave(&dev->list_lock, flags);
470 list_for_each_entry(command, &dev->cmd_list, list) { 470 list_for_each_entry(command, &dev->cmd_list, list) {
@@ -933,7 +933,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
933 else 933 else
934 shost->max_channel = 0; 934 shost->max_channel = 0;
935 935
936 aac_get_config_status(aac); 936 aac_get_config_status(aac, 0);
937 aac_get_containers(aac); 937 aac_get_containers(aac);
938 list_add(&aac->entry, insert); 938 list_add(&aac->entry, insert);
939 939