aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornickcheng(鄭守謙 <nick.cheng@areca.com.tw>2007-06-14 23:43:32 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-06-17 15:49:01 -0400
commita1f6e0211b71a6c3ff401ad1d345ab024d0c6f01 (patch)
tree779c34c385f962a5d68429b90d22a2b7c7b43f6f
parent727eead62e22cf0a9498cf34e075c08269402978 (diff)
[SCSI] areca: improve driver stability and compatibility
Description: 1. Implement PCI-Express error recovery function and AER capability, especially thanks to Yanmin Zhang's openhanded help about AER 2. Implement the selection of ARCMSR_MAX_XFER_SECTORS_B=4096 if firmware version is latter than 1.42 3. Add arcmsr_done4_abort_postqueue in arcmsr_iop_reset function to improve the stability as hot-unplug/plug 4. Modify the ISR, arcmsr_interrupt routine, to prevent the inconsistency with sg_mod driver if application directly calls the arcmsr driver w/o passing through scsi midlayer Signed-off-by: Nick Cheng <nick.cheng@areca.com.tw> [jejb: unused variable removal] Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/arcmsr/arcmsr.h4
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c456
2 files changed, 425 insertions, 35 deletions
diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
index aff96db9ccf6..f0b8bf4534f0 100644
--- a/drivers/scsi/arcmsr/arcmsr.h
+++ b/drivers/scsi/arcmsr/arcmsr.h
@@ -48,9 +48,10 @@ struct class_device_attribute;
48 48
49#define ARCMSR_MAX_OUTSTANDING_CMD 256 49#define ARCMSR_MAX_OUTSTANDING_CMD 256
50#define ARCMSR_MAX_FREECCB_NUM 288 50#define ARCMSR_MAX_FREECCB_NUM 288
51#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.13" 51#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.14"
52#define ARCMSR_SCSI_INITIATOR_ID 255 52#define ARCMSR_SCSI_INITIATOR_ID 255
53#define ARCMSR_MAX_XFER_SECTORS 512 53#define ARCMSR_MAX_XFER_SECTORS 512
54#define ARCMSR_MAX_XFER_SECTORS_B 4096
54#define ARCMSR_MAX_TARGETID 17 55#define ARCMSR_MAX_TARGETID 17
55#define ARCMSR_MAX_TARGETLUN 8 56#define ARCMSR_MAX_TARGETLUN 8
56#define ARCMSR_MAX_CMD_PERLUN ARCMSR_MAX_OUTSTANDING_CMD 57#define ARCMSR_MAX_CMD_PERLUN ARCMSR_MAX_OUTSTANDING_CMD
@@ -469,4 +470,3 @@ extern void arcmsr_post_Qbuffer(struct AdapterControlBlock *acb);
469extern struct class_device_attribute *arcmsr_host_attrs[]; 470extern struct class_device_attribute *arcmsr_host_attrs[];
470extern int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *acb); 471extern int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *acb);
471void arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb); 472void arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb);
472
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 672df79d7e39..0ddfc21e9f7d 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -57,6 +57,7 @@
57#include <linux/dma-mapping.h> 57#include <linux/dma-mapping.h>
58#include <linux/timer.h> 58#include <linux/timer.h>
59#include <linux/pci.h> 59#include <linux/pci.h>
60#include <linux/aer.h>
60#include <asm/dma.h> 61#include <asm/dma.h>
61#include <asm/io.h> 62#include <asm/io.h>
62#include <asm/system.h> 63#include <asm/system.h>
@@ -71,7 +72,7 @@
71#include "arcmsr.h" 72#include "arcmsr.h"
72 73
73MODULE_AUTHOR("Erich Chen <erich@areca.com.tw>"); 74MODULE_AUTHOR("Erich Chen <erich@areca.com.tw>");
74MODULE_DESCRIPTION("ARECA (ARC11xx/12xx) SATA RAID HOST Adapter"); 75MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/13xx/16xx) SATA/SAS RAID HOST Adapter");
75MODULE_LICENSE("Dual BSD/GPL"); 76MODULE_LICENSE("Dual BSD/GPL");
76MODULE_VERSION(ARCMSR_DRIVER_VERSION); 77MODULE_VERSION(ARCMSR_DRIVER_VERSION);
77 78
@@ -93,7 +94,9 @@ static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb);
93static uint8_t arcmsr_wait_msgint_ready(struct AdapterControlBlock *acb); 94static uint8_t arcmsr_wait_msgint_ready(struct AdapterControlBlock *acb);
94static const char *arcmsr_info(struct Scsi_Host *); 95static const char *arcmsr_info(struct Scsi_Host *);
95static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb); 96static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
96 97static pci_ers_result_t arcmsr_pci_error_detected(struct pci_dev *pdev,
98 pci_channel_state_t state);
99static pci_ers_result_t arcmsr_pci_slot_reset(struct pci_dev *pdev);
97static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth) 100static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth)
98{ 101{
99 if (queue_depth > ARCMSR_MAX_CMD_PERLUN) 102 if (queue_depth > ARCMSR_MAX_CMD_PERLUN)
@@ -104,7 +107,8 @@ static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_de
104 107
105static struct scsi_host_template arcmsr_scsi_host_template = { 108static struct scsi_host_template arcmsr_scsi_host_template = {
106 .module = THIS_MODULE, 109 .module = THIS_MODULE,
107 .name = "ARCMSR ARECA SATA RAID HOST Adapter" ARCMSR_DRIVER_VERSION, 110 .name = "ARCMSR ARECA SATA/SAS RAID HOST Adapter"
111 ARCMSR_DRIVER_VERSION,
108 .info = arcmsr_info, 112 .info = arcmsr_info,
109 .queuecommand = arcmsr_queue_command, 113 .queuecommand = arcmsr_queue_command,
110 .eh_abort_handler = arcmsr_abort, 114 .eh_abort_handler = arcmsr_abort,
@@ -119,6 +123,10 @@ static struct scsi_host_template arcmsr_scsi_host_template = {
119 .use_clustering = ENABLE_CLUSTERING, 123 .use_clustering = ENABLE_CLUSTERING,
120 .shost_attrs = arcmsr_host_attrs, 124 .shost_attrs = arcmsr_host_attrs,
121}; 125};
126static struct pci_error_handlers arcmsr_pci_error_handlers = {
127 .error_detected = arcmsr_pci_error_detected,
128 .slot_reset = arcmsr_pci_slot_reset,
129};
122 130
123static struct pci_device_id arcmsr_device_id_table[] = { 131static struct pci_device_id arcmsr_device_id_table[] = {
124 {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)}, 132 {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)},
@@ -144,7 +152,8 @@ static struct pci_driver arcmsr_pci_driver = {
144 .id_table = arcmsr_device_id_table, 152 .id_table = arcmsr_device_id_table,
145 .probe = arcmsr_probe, 153 .probe = arcmsr_probe,
146 .remove = arcmsr_remove, 154 .remove = arcmsr_remove,
147 .shutdown = arcmsr_shutdown 155 .shutdown = arcmsr_shutdown,
156 .err_handler = &arcmsr_pci_error_handlers,
148}; 157};
149 158
150static irqreturn_t arcmsr_do_interrupt(int irq, void *dev_id) 159static irqreturn_t arcmsr_do_interrupt(int irq, void *dev_id)
@@ -328,6 +337,8 @@ static int arcmsr_probe(struct pci_dev *pdev,
328 337
329 arcmsr_iop_init(acb); 338 arcmsr_iop_init(acb);
330 pci_set_drvdata(pdev, host); 339 pci_set_drvdata(pdev, host);
340 if (strncmp(acb->firm_version, "V1.42", 5) >= 0)
341 host->max_sectors= ARCMSR_MAX_XFER_SECTORS_B;
331 342
332 error = scsi_add_host(host, &pdev->dev); 343 error = scsi_add_host(host, &pdev->dev);
333 if (error) 344 if (error)
@@ -338,6 +349,7 @@ static int arcmsr_probe(struct pci_dev *pdev,
338 goto out_free_sysfs; 349 goto out_free_sysfs;
339 350
340 scsi_scan_host(host); 351 scsi_scan_host(host);
352 pci_enable_pcie_error_reporting(pdev);
341 return 0; 353 return 0;
342 out_free_sysfs: 354 out_free_sysfs:
343 out_free_irq: 355 out_free_irq:
@@ -488,7 +500,7 @@ static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb,
488 500
489static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb) 501static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb)
490{ 502{
491 struct MessageUnit __iomem *reg=acb->pmu; 503 struct MessageUnit __iomem *reg = acb->pmu;
492 504
493 writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, &reg->inbound_msgaddr0); 505 writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, &reg->inbound_msgaddr0);
494 if (arcmsr_wait_msgint_ready(acb)) 506 if (arcmsr_wait_msgint_ready(acb))
@@ -718,7 +730,7 @@ static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb)
718 int id, lun; 730 int id, lun;
719 /* 731 /*
720 **************************************************************** 732 ****************************************************************
721 ** areca cdb command done 733 ** areca cdb command done
722 **************************************************************** 734 ****************************************************************
723 */ 735 */
724 while (1) { 736 while (1) {
@@ -729,20 +741,20 @@ static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb)
729 (flag_ccb << 5)); 741 (flag_ccb << 5));
730 if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) { 742 if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) {
731 if (ccb->startdone == ARCMSR_CCB_ABORTED) { 743 if (ccb->startdone == ARCMSR_CCB_ABORTED) {
732 struct scsi_cmnd *abortcmd=ccb->pcmd; 744 struct scsi_cmnd *abortcmd = ccb->pcmd;
733 if (abortcmd) { 745 if (abortcmd) {
734 abortcmd->result |= DID_ABORT >> 16; 746 abortcmd->result |= DID_ABORT >> 16;
735 arcmsr_ccb_complete(ccb, 1); 747 arcmsr_ccb_complete(ccb, 1);
736 printk(KERN_NOTICE 748 printk(KERN_NOTICE
737 "arcmsr%d: ccb='0x%p' isr got aborted command \n" 749 "arcmsr%d: ccb ='0x%p' isr got aborted command \n"
738 , acb->host->host_no, ccb); 750 , acb->host->host_no, ccb);
739 } 751 }
740 continue; 752 continue;
741 } 753 }
742 printk(KERN_NOTICE 754 printk(KERN_NOTICE
743 "arcmsr%d: isr get an illegal ccb command done acb='0x%p'" 755 "arcmsr%d: isr get an illegal ccb command done acb = '0x%p'"
744 "ccb='0x%p' ccbacb='0x%p' startdone = 0x%x" 756 "ccb = '0x%p' ccbacb = '0x%p' startdone = 0x%x"
745 " ccboutstandingcount=%d \n" 757 " ccboutstandingcount = %d \n"
746 , acb->host->host_no 758 , acb->host->host_no
747 , acb 759 , acb
748 , ccb 760 , ccb
@@ -762,7 +774,7 @@ static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb)
762 switch(ccb->arcmsr_cdb.DeviceStatus) { 774 switch(ccb->arcmsr_cdb.DeviceStatus) {
763 case ARCMSR_DEV_SELECT_TIMEOUT: { 775 case ARCMSR_DEV_SELECT_TIMEOUT: {
764 acb->devstate[id][lun] = ARECA_RAID_GONE; 776 acb->devstate[id][lun] = ARECA_RAID_GONE;
765 ccb->pcmd->result = DID_TIME_OUT << 16; 777 ccb->pcmd->result = DID_NO_CONNECT << 16;
766 arcmsr_ccb_complete(ccb, 1); 778 arcmsr_ccb_complete(ccb, 1);
767 } 779 }
768 break; 780 break;
@@ -781,8 +793,8 @@ static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb)
781 break; 793 break;
782 default: 794 default:
783 printk(KERN_NOTICE 795 printk(KERN_NOTICE
784 "arcmsr%d: scsi id=%d lun=%d" 796 "arcmsr%d: scsi id = %d lun = %d"
785 " isr get command error done," 797 " isr get command error done, "
786 "but got unknown DeviceStatus = 0x%x \n" 798 "but got unknown DeviceStatus = 0x%x \n"
787 , acb->host->host_no 799 , acb->host->host_no
788 , id 800 , id
@@ -1062,7 +1074,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
1062 inqdata[1] = 0; 1074 inqdata[1] = 0;
1063 /* rem media bit & Dev Type Modifier */ 1075 /* rem media bit & Dev Type Modifier */
1064 inqdata[2] = 0; 1076 inqdata[2] = 0;
1065 /* ISO,ECMA,& ANSI versions */ 1077 /* ISO, ECMA, & ANSI versions */
1066 inqdata[4] = 31; 1078 inqdata[4] = 31;
1067 /* length of additional data */ 1079 /* length of additional data */
1068 strncpy(&inqdata[8], "Areca ", 8); 1080 strncpy(&inqdata[8], "Areca ", 8);
@@ -1112,7 +1124,7 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd,
1112 , acb->host->host_no); 1124 , acb->host->host_no);
1113 return SCSI_MLQUEUE_HOST_BUSY; 1125 return SCSI_MLQUEUE_HOST_BUSY;
1114 } 1126 }
1115 if(target == 16) { 1127 if (target == 16) {
1116 /* virtual device for iop message transfer */ 1128 /* virtual device for iop message transfer */
1117 arcmsr_handle_virtual_command(acb, cmd); 1129 arcmsr_handle_virtual_command(acb, cmd);
1118 return 0; 1130 return 0;
@@ -1125,7 +1137,7 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd,
1125 printk(KERN_NOTICE 1137 printk(KERN_NOTICE
1126 "arcmsr%d: block 'read/write'" 1138 "arcmsr%d: block 'read/write'"
1127 "command with gone raid volume" 1139 "command with gone raid volume"
1128 " Cmd=%2x, TargetId=%d, Lun=%d \n" 1140 " Cmd = %2x, TargetId = %d, Lun = %d \n"
1129 , acb->host->host_no 1141 , acb->host->host_no
1130 , cmd->cmnd[0] 1142 , cmd->cmnd[0]
1131 , target, lun); 1143 , target, lun);
@@ -1216,7 +1228,7 @@ static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb,
1216 if ((ccb->startdone == ARCMSR_CCB_ABORTED) || 1228 if ((ccb->startdone == ARCMSR_CCB_ABORTED) ||
1217 (ccb == poll_ccb)) { 1229 (ccb == poll_ccb)) {
1218 printk(KERN_NOTICE 1230 printk(KERN_NOTICE
1219 "arcmsr%d: scsi id=%d lun=%d ccb='0x%p'" 1231 "arcmsr%d: scsi id = %d lun = %d ccb = '0x%p'"
1220 " poll command abort successfully \n" 1232 " poll command abort successfully \n"
1221 , acb->host->host_no 1233 , acb->host->host_no
1222 , ccb->pcmd->device->id 1234 , ccb->pcmd->device->id
@@ -1229,8 +1241,8 @@ static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb,
1229 } 1241 }
1230 printk(KERN_NOTICE 1242 printk(KERN_NOTICE
1231 "arcmsr%d: polling get an illegal ccb" 1243 "arcmsr%d: polling get an illegal ccb"
1232 " command done ccb='0x%p'" 1244 " command done ccb ='0x%p'"
1233 "ccboutstandingcount=%d \n" 1245 "ccboutstandingcount = %d \n"
1234 , acb->host->host_no 1246 , acb->host->host_no
1235 , ccb 1247 , ccb
1236 , atomic_read(&acb->ccboutstandingcount)); 1248 , atomic_read(&acb->ccboutstandingcount));
@@ -1247,7 +1259,7 @@ static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb,
1247 switch(ccb->arcmsr_cdb.DeviceStatus) { 1259 switch(ccb->arcmsr_cdb.DeviceStatus) {
1248 case ARCMSR_DEV_SELECT_TIMEOUT: { 1260 case ARCMSR_DEV_SELECT_TIMEOUT: {
1249 acb->devstate[id][lun] = ARECA_RAID_GONE; 1261 acb->devstate[id][lun] = ARECA_RAID_GONE;
1250 ccb->pcmd->result = DID_TIME_OUT << 16; 1262 ccb->pcmd->result = DID_NO_CONNECT << 16;
1251 arcmsr_ccb_complete(ccb, 1); 1263 arcmsr_ccb_complete(ccb, 1);
1252 } 1264 }
1253 break; 1265 break;
@@ -1266,7 +1278,7 @@ static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb,
1266 break; 1278 break;
1267 default: 1279 default:
1268 printk(KERN_NOTICE 1280 printk(KERN_NOTICE
1269 "arcmsr%d: scsi id=%d lun=%d" 1281 "arcmsr%d: scsi id = %d lun = %d"
1270 " polling and getting command error done" 1282 " polling and getting command error done"
1271 "but got unknown DeviceStatus = 0x%x \n" 1283 "but got unknown DeviceStatus = 0x%x \n"
1272 , acb->host->host_no 1284 , acb->host->host_no
@@ -1281,6 +1293,94 @@ static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb,
1281 } 1293 }
1282 } 1294 }
1283} 1295}
1296static void arcmsr_done4_abort_postqueue(struct AdapterControlBlock *acb)
1297{
1298 int i = 0, found = 0;
1299 int id, lun;
1300 uint32_t flag_ccb, outbound_intstatus;
1301 struct MessageUnit __iomem *reg = acb->pmu;
1302 struct CommandControlBlock *ccb;
1303 /*clear and abort all outbound posted Q*/
1304
1305 while (((flag_ccb = readl(&reg->outbound_queueport)) != 0xFFFFFFFF) &&
1306(i++ < 256)){
1307 ccb = (struct CommandControlBlock *)(acb->vir2phy_offset +
1308(flag_ccb << 5));
1309 if (ccb){
1310 if ((ccb->acb != acb)||(ccb->startdone != \
1311ARCMSR_CCB_START)){
1312 printk(KERN_NOTICE "arcmsr%d: polling get \
1313an illegal ccb" "command done ccb = '0x%p'""ccboutstandingcount = %d \n",
1314 acb->host->host_no, ccb,
1315 atomic_read(&acb->ccboutstandingcount));
1316 continue;
1317 }
1318
1319 id = ccb->pcmd->device->id;
1320 lun = ccb->pcmd->device->lun;
1321 if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)){
1322 if (acb->devstate[id][lun] == ARECA_RAID_GONE)
1323 acb->devstate[id][lun] = ARECA_RAID_GOOD;
1324 ccb->pcmd->result = DID_OK << 16;
1325 arcmsr_ccb_complete(ccb, 1);
1326 }
1327 else {
1328 switch(ccb->arcmsr_cdb.DeviceStatus) {
1329 case ARCMSR_DEV_SELECT_TIMEOUT: {
1330 acb->devstate[id][lun] = ARECA_RAID_GONE;
1331 ccb->pcmd->result = DID_NO_CONNECT << 16;
1332 arcmsr_ccb_complete(ccb, 1);
1333 }
1334 break;
1335
1336 case ARCMSR_DEV_ABORTED:
1337
1338 case ARCMSR_DEV_INIT_FAIL: {
1339 acb->devstate[id][lun] =
1340 ARECA_RAID_GONE;
1341 ccb->pcmd->result =
1342 DID_BAD_TARGET << 16;
1343 arcmsr_ccb_complete(ccb, 1);
1344 }
1345 break;
1346
1347 case ARCMSR_DEV_CHECK_CONDITION: {
1348 acb->devstate[id][lun] =
1349 ARECA_RAID_GOOD;
1350 arcmsr_report_sense_info(ccb);
1351 arcmsr_ccb_complete(ccb, 1);
1352 }
1353 break;
1354
1355 default:
1356 printk(KERN_NOTICE
1357 "arcmsr%d: scsi id = %d \
1358 lun = %d""polling and \
1359 getting command error \
1360 done""but got unknown \
1361 DeviceStatus = 0x%x \n",
1362 acb->host->host_no, id,
1363 lun, ccb->arcmsr_cdb.DeviceStatus);
1364 acb->devstate[id][lun] =
1365 ARECA_RAID_GONE;
1366 ccb->pcmd->result =
1367 DID_BAD_TARGET << 16;
1368 arcmsr_ccb_complete(ccb, 1);
1369 break;
1370 }
1371 }
1372 found = 1;
1373 }
1374 }
1375 if (found){
1376 outbound_intstatus = readl(&reg->outbound_intstatus) & \
1377 acb->outbound_int_enable;
1378 writel(outbound_intstatus, &reg->outbound_intstatus);
1379 /*clear interrupt*/
1380 }
1381 return;
1382}
1383
1284 1384
1285static void arcmsr_iop_init(struct AdapterControlBlock *acb) 1385static void arcmsr_iop_init(struct AdapterControlBlock *acb)
1286{ 1386{
@@ -1314,7 +1414,6 @@ static void arcmsr_iop_init(struct AdapterControlBlock *acb)
1314 1414
1315static void arcmsr_iop_reset(struct AdapterControlBlock *acb) 1415static void arcmsr_iop_reset(struct AdapterControlBlock *acb)
1316{ 1416{
1317 struct MessageUnit __iomem *reg = acb->pmu;
1318 struct CommandControlBlock *ccb; 1417 struct CommandControlBlock *ccb;
1319 uint32_t intmask_org; 1418 uint32_t intmask_org;
1320 int i = 0; 1419 int i = 0;
@@ -1327,21 +1426,17 @@ static void arcmsr_iop_reset(struct AdapterControlBlock *acb)
1327 /* disable all outbound interrupt */ 1426 /* disable all outbound interrupt */
1328 intmask_org = arcmsr_disable_outbound_ints(acb); 1427 intmask_org = arcmsr_disable_outbound_ints(acb);
1329 /* clear all outbound posted Q */ 1428 /* clear all outbound posted Q */
1330 for (i = 0; i < ARCMSR_MAX_OUTSTANDING_CMD; i++) 1429 arcmsr_done4_abort_postqueue(acb);
1331 readl(&reg->outbound_queueport);
1332 for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { 1430 for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
1333 ccb = acb->pccb_pool[i]; 1431 ccb = acb->pccb_pool[i];
1334 if ((ccb->startdone == ARCMSR_CCB_START) || 1432 if (ccb->startdone == ARCMSR_CCB_START) {
1335 (ccb->startdone == ARCMSR_CCB_ABORTED)) {
1336 ccb->startdone = ARCMSR_CCB_ABORTED; 1433 ccb->startdone = ARCMSR_CCB_ABORTED;
1337 ccb->pcmd->result = DID_ABORT << 16;
1338 arcmsr_ccb_complete(ccb, 1);
1339 } 1434 }
1340 } 1435 }
1341 /* enable all outbound interrupt */ 1436 /* enable all outbound interrupt */
1342 arcmsr_enable_outbound_ints(acb, intmask_org); 1437 arcmsr_enable_outbound_ints(acb, intmask_org);
1343 } 1438 }
1344 atomic_set(&acb->ccboutstandingcount, 0); 1439
1345} 1440}
1346 1441
1347static int arcmsr_bus_reset(struct scsi_cmnd *cmd) 1442static int arcmsr_bus_reset(struct scsi_cmnd *cmd)
@@ -1387,10 +1482,9 @@ static int arcmsr_abort(struct scsi_cmnd *cmd)
1387 int i = 0; 1482 int i = 0;
1388 1483
1389 printk(KERN_NOTICE 1484 printk(KERN_NOTICE
1390 "arcmsr%d: abort device command of scsi id=%d lun=%d \n", 1485 "arcmsr%d: abort device command of scsi id = %d lun = %d \n",
1391 acb->host->host_no, cmd->device->id, cmd->device->lun); 1486 acb->host->host_no, cmd->device->id, cmd->device->lun);
1392 acb->num_aborts++; 1487 acb->num_aborts++;
1393
1394 /* 1488 /*
1395 ************************************************ 1489 ************************************************
1396 ** the all interrupt service routine is locked 1490 ** the all interrupt service routine is locked
@@ -1445,10 +1539,306 @@ static const char *arcmsr_info(struct Scsi_Host *host)
1445 type = "X-TYPE"; 1539 type = "X-TYPE";
1446 break; 1540 break;
1447 } 1541 }
1448 sprintf(buf, "Areca %s Host Adapter RAID Controller%s\n %s", 1542 sprintf(buf, "Areca %s Host Adapter RAID Controller%s\n %s",
1449 type, raid6 ? "( RAID6 capable)" : "", 1543 type, raid6 ? "( RAID6 capable)" : "",
1450 ARCMSR_DRIVER_VERSION); 1544 ARCMSR_DRIVER_VERSION);
1451 return buf; 1545 return buf;
1452} 1546}
1453 1547
1548static pci_ers_result_t arcmsr_pci_slot_reset(struct pci_dev *pdev)
1549{
1550 struct Scsi_Host *host;
1551 struct AdapterControlBlock *acb;
1552 uint8_t bus, dev_fun;
1553 int error;
1554
1555 error = pci_enable_device(pdev);
1556 if (error)
1557 return PCI_ERS_RESULT_DISCONNECT;
1558 pci_set_master(pdev);
1559
1560 host = scsi_host_alloc(&arcmsr_scsi_host_template, sizeof \
1561(struct AdapterControlBlock));
1562 if (!host)
1563 return PCI_ERS_RESULT_DISCONNECT;
1564 acb = (struct AdapterControlBlock *)host->hostdata;
1565 memset(acb, 0, sizeof (struct AdapterControlBlock));
1566
1567 error = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
1568 if (error) {
1569 error = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
1570 if (error) {
1571 printk(KERN_WARNING
1572 "scsi%d: No suitable DMA mask available\n",
1573 host->host_no);
1574 return PCI_ERS_RESULT_DISCONNECT;
1575 }
1576 }
1577 bus = pdev->bus->number;
1578 dev_fun = pdev->devfn;
1579 acb = (struct AdapterControlBlock *) host->hostdata;
1580 memset(acb, 0, sizeof(struct AdapterControlBlock));
1581 acb->pdev = pdev;
1582 acb->host = host;
1583 host->max_sectors = ARCMSR_MAX_XFER_SECTORS;
1584 host->max_lun = ARCMSR_MAX_TARGETLUN;
1585 host->max_id = ARCMSR_MAX_TARGETID;/*16:8*/
1586 host->max_cmd_len = 16; /*this is issue of 64bit LBA, over 2T byte*/
1587 host->sg_tablesize = ARCMSR_MAX_SG_ENTRIES;
1588 host->can_queue = ARCMSR_MAX_FREECCB_NUM; /* max simultaneous cmds */
1589 host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN;
1590 host->this_id = ARCMSR_SCSI_INITIATOR_ID;
1591 host->unique_id = (bus << 8) | dev_fun;
1592 host->irq = pdev->irq;
1593 error = pci_request_regions(pdev, "arcmsr");
1594 if (error)
1595 return PCI_ERS_RESULT_DISCONNECT;
1596
1597 acb->pmu = ioremap(pci_resource_start(pdev, 0),
1598 pci_resource_len(pdev, 0));
1599 if (!acb->pmu) {
1600 printk(KERN_NOTICE "arcmsr%d: memory"
1601 " mapping region fail \n", acb->host->host_no);
1602 return PCI_ERS_RESULT_DISCONNECT;
1603 }
1604 acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
1605 ACB_F_MESSAGE_RQBUFFER_CLEARED |
1606 ACB_F_MESSAGE_WQBUFFER_READED);
1607 acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER;
1608 INIT_LIST_HEAD(&acb->ccb_free_list);
1609
1610 error = arcmsr_alloc_ccb_pool(acb);
1611 if (error)
1612 return PCI_ERS_RESULT_DISCONNECT;
1613
1614 error = request_irq(pdev->irq, arcmsr_do_interrupt,
1615 IRQF_DISABLED | IRQF_SHARED, "arcmsr", acb);
1616 if (error)
1617 return PCI_ERS_RESULT_DISCONNECT;
1618
1619 arcmsr_iop_init(acb);
1620 if (strncmp(acb->firm_version, "V1.42", 5) >= 0)
1621 host->max_sectors = ARCMSR_MAX_XFER_SECTORS_B;
1622
1623 pci_set_drvdata(pdev, host);
1624
1625 error = scsi_add_host(host, &pdev->dev);
1626 if (error)
1627 return PCI_ERS_RESULT_DISCONNECT;
1628
1629 error = arcmsr_alloc_sysfs_attr(acb);
1630 if (error)
1631 return PCI_ERS_RESULT_DISCONNECT;
1632
1633 scsi_scan_host(host);
1634 return PCI_ERS_RESULT_RECOVERED;
1635}
1636
1637static void arcmsr_pci_ers_need_reset_forepart(struct pci_dev *pdev)
1638{
1639 struct Scsi_Host *host = pci_get_drvdata(pdev);
1640 struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata;
1641 struct MessageUnit __iomem *reg = acb->pmu;
1642 struct CommandControlBlock *ccb;
1643 /*clear and abort all outbound posted Q*/
1644 int i = 0, found = 0;
1645 int id, lun;
1646 uint32_t flag_ccb, outbound_intstatus;
1647
1648 while (((flag_ccb = readl(&reg->outbound_queueport)) != 0xFFFFFFFF) &&
1649 (i++ < 256)){
1650 ccb = (struct CommandControlBlock *)(acb->vir2phy_offset
1651 + (flag_ccb << 5));
1652 if (ccb){
1653 if ((ccb->acb != acb)||(ccb->startdone !=
1654 ARCMSR_CCB_START)){
1655 printk(KERN_NOTICE "arcmsr%d: polling \
1656 get an illegal ccb"" command done ccb = '0x%p'"
1657 "ccboutstandingcount = %d \n",
1658 acb->host->host_no, ccb,
1659 atomic_read(&acb->ccboutstandingcount));
1660 continue;
1661 }
1662
1663 id = ccb->pcmd->device->id;
1664 lun = ccb->pcmd->device->lun;
1665 if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) {
1666 if (acb->devstate[id][lun] ==
1667 ARECA_RAID_GONE)
1668 acb->devstate[id][lun] =
1669 ARECA_RAID_GOOD;
1670 ccb->pcmd->result = DID_OK << 16;
1671 arcmsr_ccb_complete(ccb, 1);
1672 }
1673 else {
1674 switch(ccb->arcmsr_cdb.DeviceStatus) {
1675 case ARCMSR_DEV_SELECT_TIMEOUT: {
1676 acb->devstate[id][lun] =
1677 ARECA_RAID_GONE;
1678 ccb->pcmd->result =
1679 DID_NO_CONNECT << 16;
1680 arcmsr_ccb_complete(ccb, 1);
1681 }
1682 break;
1683
1684 case ARCMSR_DEV_ABORTED:
1685
1686 case ARCMSR_DEV_INIT_FAIL: {
1687 acb->devstate[id][lun] =
1688 ARECA_RAID_GONE;
1689 ccb->pcmd->result =
1690 DID_BAD_TARGET << 16;
1691 arcmsr_ccb_complete(ccb, 1);
1692 }
1693 break;
1694
1695 case ARCMSR_DEV_CHECK_CONDITION: {
1696 acb->devstate[id][lun] =
1697 ARECA_RAID_GOOD;
1698 arcmsr_report_sense_info(ccb);
1699 arcmsr_ccb_complete(ccb, 1);
1700 }
1701 break;
1702
1703 default:
1704 printk(KERN_NOTICE
1705 "arcmsr%d: scsi \
1706 id = %d lun = %d"
1707 " polling and \
1708 getting command \
1709 error done"
1710 "but got unknown \
1711 DeviceStatus = 0x%x \n"
1712 , acb->host->host_no,
1713 id, lun,
1714 ccb->arcmsr_cdb.DeviceStatus);
1715 acb->devstate[id][lun] =
1716 ARECA_RAID_GONE;
1717 ccb->pcmd->result =
1718 DID_BAD_TARGET << 16;
1719 arcmsr_ccb_complete(ccb, 1);
1720 break;
1721 }
1722 }
1723 found = 1;
1724 }
1725 }
1726 if (found){
1727 outbound_intstatus = readl(&reg->outbound_intstatus) &
1728 acb->outbound_int_enable;
1729 writel(outbound_intstatus, &reg->outbound_intstatus);
1730 /*clear interrupt*/
1731 }
1732 return;
1733}
1734
1454 1735
1736static void arcmsr_pci_ers_disconnect_forepart(struct pci_dev *pdev)
1737{
1738 struct Scsi_Host *host = pci_get_drvdata(pdev);
1739 struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata;
1740 struct MessageUnit __iomem *reg = acb->pmu;
1741 struct CommandControlBlock *ccb;
1742 /*clear and abort all outbound posted Q*/
1743 int i = 0, found = 0;
1744 int id, lun;
1745 uint32_t flag_ccb, outbound_intstatus;
1746
1747 while (((flag_ccb = readl(&reg->outbound_queueport)) != 0xFFFFFFFF) &&
1748 (i++ < 256)){
1749 ccb = (struct CommandControlBlock *)(acb->vir2phy_offset +
1750 (flag_ccb << 5));
1751 if (ccb){
1752 if ((ccb->acb != acb)||(ccb->startdone !=
1753 ARCMSR_CCB_START)){
1754 printk(KERN_NOTICE
1755 "arcmsr%d: polling get an illegal ccb"
1756 " command done ccb = '0x%p'"
1757 "ccboutstandingcount = %d \n",
1758 acb->host->host_no, ccb,
1759 atomic_read(&acb->ccboutstandingcount));
1760 continue;
1761 }
1762
1763 id = ccb->pcmd->device->id;
1764 lun = ccb->pcmd->device->lun;
1765 if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) {
1766 if (acb->devstate[id][lun] == ARECA_RAID_GONE)
1767 acb->devstate[id][lun] = ARECA_RAID_GOOD;
1768 ccb->pcmd->result = DID_OK << 16;
1769 arcmsr_ccb_complete(ccb, 1);
1770 }
1771 else {
1772 switch(ccb->arcmsr_cdb.DeviceStatus) {
1773 case ARCMSR_DEV_SELECT_TIMEOUT: {
1774 acb->devstate[id][lun] =
1775 ARECA_RAID_GONE;
1776 ccb->pcmd->result =
1777 DID_NO_CONNECT << 16;
1778 arcmsr_ccb_complete(ccb, 1);
1779 }
1780 break;
1781
1782 case ARCMSR_DEV_ABORTED:
1783
1784 case ARCMSR_DEV_INIT_FAIL: {
1785 acb->devstate[id][lun] =
1786 ARECA_RAID_GONE;
1787 ccb->pcmd->result =
1788 DID_BAD_TARGET << 16;
1789 arcmsr_ccb_complete(ccb, 1);
1790 }
1791 break;
1792
1793 case ARCMSR_DEV_CHECK_CONDITION: {
1794 acb->devstate[id][lun] =
1795 ARECA_RAID_GOOD;
1796 arcmsr_report_sense_info(ccb);
1797 arcmsr_ccb_complete(ccb, 1);
1798 }
1799 break;
1800
1801 default:
1802 printk(KERN_NOTICE "arcmsr%d: \
1803 scsi id = %d lun = %d"
1804 " polling and \
1805 getting command error done"
1806 "but got unknown \
1807 DeviceStatus = 0x%x \n"
1808 , acb->host->host_no,
1809 id, lun, ccb->arcmsr_cdb.DeviceStatus);
1810 acb->devstate[id][lun] =
1811 ARECA_RAID_GONE;
1812 ccb->pcmd->result =
1813 DID_BAD_TARGET << 16;
1814 arcmsr_ccb_complete(ccb, 1);
1815 break;
1816 }
1817 }
1818 found = 1;
1819 }
1820 }
1821 if (found){
1822 outbound_intstatus = readl(&reg->outbound_intstatus) &
1823 acb->outbound_int_enable;
1824 writel(outbound_intstatus, &reg->outbound_intstatus);
1825 /*clear interrupt*/
1826 }
1827 return;
1828}
1829
1830static pci_ers_result_t arcmsr_pci_error_detected(struct pci_dev *pdev,
1831 pci_channel_state_t state)
1832{
1833 switch (state) {
1834 case pci_channel_io_frozen:
1835 arcmsr_pci_ers_need_reset_forepart(pdev);
1836 return PCI_ERS_RESULT_NEED_RESET;
1837 case pci_channel_io_perm_failure:
1838 arcmsr_pci_ers_disconnect_forepart(pdev);
1839 return PCI_ERS_RESULT_DISCONNECT;
1840 break;
1841 default:
1842 return PCI_ERS_RESULT_NEED_RESET;
1843 }
1844}