diff options
-rw-r--r-- | drivers/scsi/aacraid/aachba.c | 39 | ||||
-rw-r--r-- | drivers/scsi/aacraid/aacraid.h | 4 | ||||
-rw-r--r-- | drivers/scsi/aacraid/commctrl.c | 2 | ||||
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 258 | ||||
-rw-r--r-- | drivers/scsi/aacraid/linit.c | 14 |
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 | */ |
178 | int aac_get_config_status(struct aac_dev *dev) | 178 | int 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); | |||
1789 | int aac_fib_complete(struct fib * context); | 1790 | int 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) |
1791 | struct aac_dev *aac_init_adapter(struct aac_dev *dev); | 1792 | struct aac_dev *aac_init_adapter(struct aac_dev *dev); |
1792 | int aac_get_config_status(struct aac_dev *dev); | 1793 | int aac_get_config_status(struct aac_dev *dev, int commit_flag); |
1793 | int aac_get_containers(struct aac_dev *dev); | 1794 | int aac_get_containers(struct aac_dev *dev); |
1794 | int aac_scsi_cmd(struct scsi_cmnd *cmd); | 1795 | int aac_scsi_cmd(struct scsi_cmnd *cmd); |
1795 | int aac_dev_ioctl(struct aac_dev *dev, int cmd, void __user *arg); | 1796 | int aac_dev_ioctl(struct aac_dev *dev, int cmd, void __user *arg); |
@@ -1800,6 +1801,7 @@ int aac_sa_init(struct aac_dev *dev); | |||
1800 | unsigned int aac_response_normal(struct aac_queue * q); | 1801 | unsigned int aac_response_normal(struct aac_queue * q); |
1801 | unsigned int aac_command_normal(struct aac_queue * q); | 1802 | unsigned int aac_command_normal(struct aac_queue * q); |
1802 | unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index); | 1803 | unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index); |
1804 | int aac_check_health(struct aac_dev * dev); | ||
1803 | int aac_command_thread(void *data); | 1805 | int aac_command_thread(void *data); |
1804 | int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx); | 1806 | int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx); |
1805 | int aac_fib_adapter_complete(struct fib * fibptr, unsigned short size); | 1807 | int 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 | ||
1059 | static 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 | |||
1178 | out: | ||
1179 | aac->in_reset = 0; | ||
1180 | scsi_unblock_requests(host); | ||
1181 | spin_lock_irq(host->host_lock); | ||
1182 | return retval; | ||
1183 | } | ||
1184 | |||
1185 | int 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 | |||
1309 | out: | ||
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 | ||