aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r--drivers/scsi/mpt2sas/Kconfig2
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2.h2
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h2
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_history.txt2
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_init.h2
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_ioc.h2
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_tool.h2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c90
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h36
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_config.c8
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c46
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.h2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_debug.h2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c1055
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_transport.c89
15 files changed, 852 insertions, 490 deletions
diff --git a/drivers/scsi/mpt2sas/Kconfig b/drivers/scsi/mpt2sas/Kconfig
index ba8e128de238..bbb7e4bf30a3 100644
--- a/drivers/scsi/mpt2sas/Kconfig
+++ b/drivers/scsi/mpt2sas/Kconfig
@@ -2,7 +2,7 @@
2# Kernel configuration file for the MPT2SAS 2# Kernel configuration file for the MPT2SAS
3# 3#
4# This code is based on drivers/scsi/mpt2sas/Kconfig 4# This code is based on drivers/scsi/mpt2sas/Kconfig
5# Copyright (C) 2007-2009 LSI Corporation 5# Copyright (C) 2007-2010 LSI Corporation
6# (mailto:DL-MPTFusionLinux@lsi.com) 6# (mailto:DL-MPTFusionLinux@lsi.com)
7 7
8# This program is free software; you can redistribute it and/or 8# This program is free software; you can redistribute it and/or
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2.h b/drivers/scsi/mpt2sas/mpi/mpi2.h
index 9958d847a88d..dada0a13223f 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2009 LSI Corporation. 2 * Copyright (c) 2000-2010 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2.h 5 * Name: mpi2.h
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
index cf0ac9f40c97..d4e9d6f8452e 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2009 LSI Corporation. 2 * Copyright (c) 2000-2010 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2_cnfg.h 5 * Name: mpi2_cnfg.h
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_history.txt b/drivers/scsi/mpt2sas/mpi/mpi2_history.txt
index c4adf76b49d9..bd6c92b5fae5 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_history.txt
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_history.txt
@@ -2,7 +2,7 @@
2 Fusion-MPT MPI 2.0 Header File Change History 2 Fusion-MPT MPI 2.0 Header File Change History
3 ============================== 3 ==============================
4 4
5 Copyright (c) 2000-2009 LSI Corporation. 5 Copyright (c) 2000-2010 LSI Corporation.
6 6
7 --------------------------------------- 7 ---------------------------------------
8 Header Set Release Version: 02.00.14 8 Header Set Release Version: 02.00.14
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_init.h b/drivers/scsi/mpt2sas/mpi/mpi2_init.h
index 6541945e97c3..220bf65a9216 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_init.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_init.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2009 LSI Corporation. 2 * Copyright (c) 2000-2010 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2_init.h 5 * Name: mpi2_init.h
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
index 754938422f6a..f18f114922ba 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2009 LSI Corporation. 2 * Copyright (c) 2000-2010 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2_ioc.h 5 * Name: mpi2_ioc.h
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
index 73fcdbf92632..686b09b81219 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2009 LSI Corporation. 2 * Copyright (c) 2000-2010 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2_tool.h 5 * Name: mpi2_tool.h
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 88e6eebc3159..b830d61684dd 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -3,7 +3,7 @@
3 * for access to MPT (Message Passing Technology) firmware. 3 * for access to MPT (Message Passing Technology) firmware.
4 * 4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c 5 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c
6 * Copyright (C) 2007-2009 LSI Corporation 6 * Copyright (C) 2007-2010 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com) 7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
@@ -58,6 +58,7 @@
58#include <linux/sort.h> 58#include <linux/sort.h>
59#include <linux/io.h> 59#include <linux/io.h>
60#include <linux/time.h> 60#include <linux/time.h>
61#include <linux/aer.h>
61 62
62#include "mpt2sas_base.h" 63#include "mpt2sas_base.h"
63 64
@@ -285,6 +286,9 @@ _base_sas_ioc_info(struct MPT2SAS_ADAPTER *ioc, MPI2DefaultReply_t *mpi_reply,
285 request_hdr->Function == MPI2_FUNCTION_EVENT_NOTIFICATION) 286 request_hdr->Function == MPI2_FUNCTION_EVENT_NOTIFICATION)
286 return; 287 return;
287 288
289 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
290 return;
291
288 switch (ioc_status) { 292 switch (ioc_status) {
289 293
290/**************************************************************************** 294/****************************************************************************
@@ -517,8 +521,18 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc,
517 desc = "IR Operation Status"; 521 desc = "IR Operation Status";
518 break; 522 break;
519 case MPI2_EVENT_SAS_DISCOVERY: 523 case MPI2_EVENT_SAS_DISCOVERY:
520 desc = "Discovery"; 524 {
521 break; 525 Mpi2EventDataSasDiscovery_t *event_data =
526 (Mpi2EventDataSasDiscovery_t *)mpi_reply->EventData;
527 printk(MPT2SAS_INFO_FMT "Discovery: (%s)", ioc->name,
528 (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ?
529 "start" : "stop");
530 if (event_data->DiscoveryStatus)
531 printk("discovery_status(0x%08x)",
532 le32_to_cpu(event_data->DiscoveryStatus));
533 printk("\n");
534 return;
535 }
522 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: 536 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
523 desc = "SAS Broadcast Primitive"; 537 desc = "SAS Broadcast Primitive";
524 break; 538 break;
@@ -1243,6 +1257,9 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1243 goto out_fail; 1257 goto out_fail;
1244 } 1258 }
1245 1259
1260 /* AER (Advanced Error Reporting) hooks */
1261 pci_enable_pcie_error_reporting(pdev);
1262
1246 pci_set_master(pdev); 1263 pci_set_master(pdev);
1247 1264
1248 if (_base_config_dma_addressing(ioc, pdev) != 0) { 1265 if (_base_config_dma_addressing(ioc, pdev) != 0) {
@@ -1253,7 +1270,7 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1253 } 1270 }
1254 1271
1255 for (i = 0, memap_sz = 0, pio_sz = 0 ; i < DEVICE_COUNT_RESOURCE; i++) { 1272 for (i = 0, memap_sz = 0, pio_sz = 0 ; i < DEVICE_COUNT_RESOURCE; i++) {
1256 if (pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO) { 1273 if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
1257 if (pio_sz) 1274 if (pio_sz)
1258 continue; 1275 continue;
1259 pio_chip = (u64)pci_resource_start(pdev, i); 1276 pio_chip = (u64)pci_resource_start(pdev, i);
@@ -1261,15 +1278,18 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1261 } else { 1278 } else {
1262 if (memap_sz) 1279 if (memap_sz)
1263 continue; 1280 continue;
1264 ioc->chip_phys = pci_resource_start(pdev, i); 1281 /* verify memory resource is valid before using */
1265 chip_phys = (u64)ioc->chip_phys; 1282 if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) {
1266 memap_sz = pci_resource_len(pdev, i); 1283 ioc->chip_phys = pci_resource_start(pdev, i);
1267 ioc->chip = ioremap(ioc->chip_phys, memap_sz); 1284 chip_phys = (u64)ioc->chip_phys;
1268 if (ioc->chip == NULL) { 1285 memap_sz = pci_resource_len(pdev, i);
1269 printk(MPT2SAS_ERR_FMT "unable to map adapter " 1286 ioc->chip = ioremap(ioc->chip_phys, memap_sz);
1270 "memory!\n", ioc->name); 1287 if (ioc->chip == NULL) {
1271 r = -EINVAL; 1288 printk(MPT2SAS_ERR_FMT "unable to map "
1272 goto out_fail; 1289 "adapter memory!\n", ioc->name);
1290 r = -EINVAL;
1291 goto out_fail;
1292 }
1273 } 1293 }
1274 } 1294 }
1275 } 1295 }
@@ -1295,6 +1315,7 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1295 ioc->chip_phys = 0; 1315 ioc->chip_phys = 0;
1296 ioc->pci_irq = -1; 1316 ioc->pci_irq = -1;
1297 pci_release_selected_regions(ioc->pdev, ioc->bars); 1317 pci_release_selected_regions(ioc->pdev, ioc->bars);
1318 pci_disable_pcie_error_reporting(pdev);
1298 pci_disable_device(pdev); 1319 pci_disable_device(pdev);
1299 return r; 1320 return r;
1300} 1321}
@@ -1898,7 +1919,10 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
1898 ioc->config_page, ioc->config_page_dma); 1919 ioc->config_page, ioc->config_page_dma);
1899 } 1920 }
1900 1921
1901 kfree(ioc->scsi_lookup); 1922 if (ioc->scsi_lookup) {
1923 free_pages((ulong)ioc->scsi_lookup, ioc->scsi_lookup_pages);
1924 ioc->scsi_lookup = NULL;
1925 }
1902 kfree(ioc->hpr_lookup); 1926 kfree(ioc->hpr_lookup);
1903 kfree(ioc->internal_lookup); 1927 kfree(ioc->internal_lookup);
1904} 1928}
@@ -2110,11 +2134,13 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2110 ioc->name, (unsigned long long) ioc->request_dma)); 2134 ioc->name, (unsigned long long) ioc->request_dma));
2111 total_sz += sz; 2135 total_sz += sz;
2112 2136
2113 ioc->scsi_lookup = kcalloc(ioc->scsiio_depth, 2137 sz = ioc->scsiio_depth * sizeof(struct request_tracker);
2114 sizeof(struct request_tracker), GFP_KERNEL); 2138 ioc->scsi_lookup_pages = get_order(sz);
2139 ioc->scsi_lookup = (struct request_tracker *)__get_free_pages(
2140 GFP_KERNEL, ioc->scsi_lookup_pages);
2115 if (!ioc->scsi_lookup) { 2141 if (!ioc->scsi_lookup) {
2116 printk(MPT2SAS_ERR_FMT "scsi_lookup: kcalloc failed\n", 2142 printk(MPT2SAS_ERR_FMT "scsi_lookup: get_free_pages failed, "
2117 ioc->name); 2143 "sz(%d)\n", ioc->name, (int)sz);
2118 goto out; 2144 goto out;
2119 } 2145 }
2120 2146
@@ -3006,8 +3032,8 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3006 * since epoch ~ midnight January 1, 1970. 3032 * since epoch ~ midnight January 1, 1970.
3007 */ 3033 */
3008 do_gettimeofday(&current_time); 3034 do_gettimeofday(&current_time);
3009 mpi_request.TimeStamp = (current_time.tv_sec * 1000) + 3035 mpi_request.TimeStamp = cpu_to_le64((u64)current_time.tv_sec * 1000 +
3010 (current_time.tv_usec >> 3); 3036 (current_time.tv_usec / 1000));
3011 3037
3012 if (ioc->logging_level & MPT_DEBUG_INIT) { 3038 if (ioc->logging_level & MPT_DEBUG_INIT) {
3013 u32 *mfp; 3039 u32 *mfp;
@@ -3179,7 +3205,7 @@ _base_event_notification(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3179 mpi_request->VP_ID = 0; 3205 mpi_request->VP_ID = 0;
3180 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) 3206 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
3181 mpi_request->EventMasks[i] = 3207 mpi_request->EventMasks[i] =
3182 le32_to_cpu(ioc->event_masks[i]); 3208 cpu_to_le32(ioc->event_masks[i]);
3183 mpt2sas_base_put_smid_default(ioc, smid); 3209 mpt2sas_base_put_smid_default(ioc, smid);
3184 init_completion(&ioc->base_cmds.done); 3210 init_completion(&ioc->base_cmds.done);
3185 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ); 3211 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ);
@@ -3516,7 +3542,9 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc)
3516 __func__)); 3542 __func__));
3517 3543
3518 _base_mask_interrupts(ioc); 3544 _base_mask_interrupts(ioc);
3545 ioc->shost_recovery = 1;
3519 _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); 3546 _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
3547 ioc->shost_recovery = 0;
3520 if (ioc->pci_irq) { 3548 if (ioc->pci_irq) {
3521 synchronize_irq(pdev->irq); 3549 synchronize_irq(pdev->irq);
3522 free_irq(ioc->pci_irq, ioc); 3550 free_irq(ioc->pci_irq, ioc);
@@ -3527,6 +3555,7 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc)
3527 ioc->pci_irq = -1; 3555 ioc->pci_irq = -1;
3528 ioc->chip_phys = 0; 3556 ioc->chip_phys = 0;
3529 pci_release_selected_regions(ioc->pdev, ioc->bars); 3557 pci_release_selected_regions(ioc->pdev, ioc->bars);
3558 pci_disable_pcie_error_reporting(pdev);
3530 pci_disable_device(pdev); 3559 pci_disable_device(pdev);
3531 return; 3560 return;
3532} 3561}
@@ -3560,8 +3589,10 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3560 3589
3561 ioc->pfacts = kcalloc(ioc->facts.NumberOfPorts, 3590 ioc->pfacts = kcalloc(ioc->facts.NumberOfPorts,
3562 sizeof(Mpi2PortFactsReply_t), GFP_KERNEL); 3591 sizeof(Mpi2PortFactsReply_t), GFP_KERNEL);
3563 if (!ioc->pfacts) 3592 if (!ioc->pfacts) {
3593 r = -ENOMEM;
3564 goto out_free_resources; 3594 goto out_free_resources;
3595 }
3565 3596
3566 for (i = 0 ; i < ioc->facts.NumberOfPorts; i++) { 3597 for (i = 0 ; i < ioc->facts.NumberOfPorts; i++) {
3567 r = _base_get_port_facts(ioc, i, CAN_SLEEP); 3598 r = _base_get_port_facts(ioc, i, CAN_SLEEP);
@@ -3607,6 +3638,15 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3607 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; 3638 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
3608 mutex_init(&ioc->ctl_cmds.mutex); 3639 mutex_init(&ioc->ctl_cmds.mutex);
3609 3640
3641 if (!ioc->base_cmds.reply || !ioc->transport_cmds.reply ||
3642 !ioc->scsih_cmds.reply || !ioc->tm_cmds.reply ||
3643 !ioc->config_cmds.reply || !ioc->ctl_cmds.reply) {
3644 r = -ENOMEM;
3645 goto out_free_resources;
3646 }
3647
3648 init_completion(&ioc->shost_recovery_done);
3649
3610 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) 3650 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
3611 ioc->event_masks[i] = -1; 3651 ioc->event_masks[i] = -1;
3612 3652
@@ -3639,6 +3679,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3639 pci_set_drvdata(ioc->pdev, NULL); 3679 pci_set_drvdata(ioc->pdev, NULL);
3640 kfree(ioc->tm_cmds.reply); 3680 kfree(ioc->tm_cmds.reply);
3641 kfree(ioc->transport_cmds.reply); 3681 kfree(ioc->transport_cmds.reply);
3682 kfree(ioc->scsih_cmds.reply);
3642 kfree(ioc->config_cmds.reply); 3683 kfree(ioc->config_cmds.reply);
3643 kfree(ioc->base_cmds.reply); 3684 kfree(ioc->base_cmds.reply);
3644 kfree(ioc->ctl_cmds.reply); 3685 kfree(ioc->ctl_cmds.reply);
@@ -3646,6 +3687,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3646 ioc->ctl_cmds.reply = NULL; 3687 ioc->ctl_cmds.reply = NULL;
3647 ioc->base_cmds.reply = NULL; 3688 ioc->base_cmds.reply = NULL;
3648 ioc->tm_cmds.reply = NULL; 3689 ioc->tm_cmds.reply = NULL;
3690 ioc->scsih_cmds.reply = NULL;
3649 ioc->transport_cmds.reply = NULL; 3691 ioc->transport_cmds.reply = NULL;
3650 ioc->config_cmds.reply = NULL; 3692 ioc->config_cmds.reply = NULL;
3651 ioc->pfacts = NULL; 3693 ioc->pfacts = NULL;
@@ -3675,6 +3717,7 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
3675 kfree(ioc->base_cmds.reply); 3717 kfree(ioc->base_cmds.reply);
3676 kfree(ioc->tm_cmds.reply); 3718 kfree(ioc->tm_cmds.reply);
3677 kfree(ioc->transport_cmds.reply); 3719 kfree(ioc->transport_cmds.reply);
3720 kfree(ioc->scsih_cmds.reply);
3678 kfree(ioc->config_cmds.reply); 3721 kfree(ioc->config_cmds.reply);
3679} 3722}
3680 3723
@@ -3811,9 +3854,8 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
3811 3854
3812 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 3855 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
3813 ioc->shost_recovery = 0; 3856 ioc->shost_recovery = 0;
3857 complete(&ioc->shost_recovery_done);
3814 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); 3858 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
3815 3859
3816 if (!r)
3817 _base_reset_handler(ioc, MPT2_IOC_RUNNING);
3818 return r; 3860 return r;
3819} 3861}
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index e18b0544c38f..b4afe431ac1e 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -3,7 +3,7 @@
3 * for access to MPT (Message Passing Technology) firmware. 3 * for access to MPT (Message Passing Technology) firmware.
4 * 4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_base.h 5 * This code is based on drivers/scsi/mpt2sas/mpt2_base.h
6 * Copyright (C) 2007-2009 LSI Corporation 6 * Copyright (C) 2007-2010 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com) 7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
@@ -69,11 +69,11 @@
69#define MPT2SAS_DRIVER_NAME "mpt2sas" 69#define MPT2SAS_DRIVER_NAME "mpt2sas"
70#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" 70#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>"
71#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" 71#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver"
72#define MPT2SAS_DRIVER_VERSION "04.100.01.00" 72#define MPT2SAS_DRIVER_VERSION "05.100.00.02"
73#define MPT2SAS_MAJOR_VERSION 04 73#define MPT2SAS_MAJOR_VERSION 05
74#define MPT2SAS_MINOR_VERSION 100 74#define MPT2SAS_MINOR_VERSION 100
75#define MPT2SAS_BUILD_VERSION 01 75#define MPT2SAS_BUILD_VERSION 00
76#define MPT2SAS_RELEASE_VERSION 00 76#define MPT2SAS_RELEASE_VERSION 02
77 77
78/* 78/*
79 * Set MPT2SAS_SG_DEPTH value based on user input. 79 * Set MPT2SAS_SG_DEPTH value based on user input.
@@ -119,7 +119,6 @@
119#define MPT2_IOC_PRE_RESET 1 /* prior to host reset */ 119#define MPT2_IOC_PRE_RESET 1 /* prior to host reset */
120#define MPT2_IOC_AFTER_RESET 2 /* just after host reset */ 120#define MPT2_IOC_AFTER_RESET 2 /* just after host reset */
121#define MPT2_IOC_DONE_RESET 3 /* links re-initialized */ 121#define MPT2_IOC_DONE_RESET 3 /* links re-initialized */
122#define MPT2_IOC_RUNNING 4 /* shost running */
123 122
124/* 123/*
125 * logging format 124 * logging format
@@ -260,16 +259,6 @@ struct _internal_cmd {
260 u16 smid; 259 u16 smid;
261}; 260};
262 261
263/*
264 * SAS Topology Structures
265 */
266
267#define MPTSAS_STATE_TR_SEND 0x0001
268#define MPTSAS_STATE_TR_COMPLETE 0x0002
269#define MPTSAS_STATE_CNTRL_SEND 0x0004
270#define MPTSAS_STATE_CNTRL_COMPLETE 0x0008
271
272#define MPT2SAS_REQ_SAS_CNTRL 0x0010
273 262
274/** 263/**
275 * struct _sas_device - attached device information 264 * struct _sas_device - attached device information
@@ -307,7 +296,6 @@ struct _sas_device {
307 u16 slot; 296 u16 slot;
308 u8 hidden_raid_component; 297 u8 hidden_raid_component;
309 u8 responding; 298 u8 responding;
310 u16 state;
311}; 299};
312 300
313/** 301/**
@@ -378,6 +366,7 @@ struct _sas_port {
378 * @phy_id: unique phy id 366 * @phy_id: unique phy id
379 * @handle: device handle for this phy 367 * @handle: device handle for this phy
380 * @attached_handle: device handle for attached device 368 * @attached_handle: device handle for attached device
369 * @phy_belongs_to_port: port has been created for this phy
381 */ 370 */
382struct _sas_phy { 371struct _sas_phy {
383 struct list_head port_siblings; 372 struct list_head port_siblings;
@@ -387,6 +376,7 @@ struct _sas_phy {
387 u8 phy_id; 376 u8 phy_id;
388 u16 handle; 377 u16 handle;
389 u16 attached_handle; 378 u16 attached_handle;
379 u8 phy_belongs_to_port;
390}; 380};
391 381
392/** 382/**
@@ -603,7 +593,6 @@ struct MPT2SAS_ADAPTER {
603 /* fw event handler */ 593 /* fw event handler */
604 char firmware_event_name[20]; 594 char firmware_event_name[20];
605 struct workqueue_struct *firmware_event_thread; 595 struct workqueue_struct *firmware_event_thread;
606 u8 fw_events_off;
607 spinlock_t fw_event_lock; 596 spinlock_t fw_event_lock;
608 struct list_head fw_event_list; 597 struct list_head fw_event_list;
609 598
@@ -611,6 +600,7 @@ struct MPT2SAS_ADAPTER {
611 int aen_event_read_flag; 600 int aen_event_read_flag;
612 u8 broadcast_aen_busy; 601 u8 broadcast_aen_busy;
613 u8 shost_recovery; 602 u8 shost_recovery;
603 struct completion shost_recovery_done;
614 spinlock_t ioc_reset_in_progress_lock; 604 spinlock_t ioc_reset_in_progress_lock;
615 u8 ioc_link_reset_in_progress; 605 u8 ioc_link_reset_in_progress;
616 u8 ignore_loginfos; 606 u8 ignore_loginfos;
@@ -688,7 +678,8 @@ struct MPT2SAS_ADAPTER {
688 dma_addr_t request_dma; 678 dma_addr_t request_dma;
689 u32 request_dma_sz; 679 u32 request_dma_sz;
690 struct request_tracker *scsi_lookup; 680 struct request_tracker *scsi_lookup;
691 spinlock_t scsi_lookup_lock; 681 ulong scsi_lookup_pages;
682 spinlock_t scsi_lookup_lock;
692 struct list_head free_list; 683 struct list_head free_list;
693 int pending_io_count; 684 int pending_io_count;
694 wait_queue_head_t reset_wq; 685 wait_queue_head_t reset_wq;
@@ -700,7 +691,7 @@ struct MPT2SAS_ADAPTER {
700 u16 max_sges_in_chain_message; 691 u16 max_sges_in_chain_message;
701 u16 chains_needed_per_io; 692 u16 chains_needed_per_io;
702 u16 chain_offset_value_for_main_message; 693 u16 chain_offset_value_for_main_message;
703 u16 chain_depth; 694 u32 chain_depth;
704 695
705 /* hi-priority queue */ 696 /* hi-priority queue */
706 u16 hi_priority_smid; 697 u16 hi_priority_smid;
@@ -814,8 +805,9 @@ void mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc);
814/* scsih shared API */ 805/* scsih shared API */
815u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, 806u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
816 u32 reply); 807 u32 reply);
817void mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun, 808int mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle,
818 u8 type, u16 smid_task, ulong timeout); 809 uint channel, uint id, uint lun, u8 type, u16 smid_task,
810 ulong timeout, struct scsi_cmnd *scmd);
819void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); 811void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
820void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); 812void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
821struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, 813struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc,
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c
index cf44b355bc97..e762dd3e2fcb 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_config.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_config.c
@@ -2,7 +2,7 @@
2 * This module provides common API for accessing firmware configuration pages 2 * This module provides common API for accessing firmware configuration pages
3 * 3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c 4 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c
5 * Copyright (C) 2007-2009 LSI Corporation 5 * Copyright (C) 2007-2010 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com) 6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
@@ -1390,12 +1390,12 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
1390 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) 1390 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
1391 goto out; 1391 goto out;
1392 for (i = 0; i < config_page->NumElements; i++) { 1392 for (i = 0; i < config_page->NumElements; i++) {
1393 if ((config_page->ConfigElement[i].ElementFlags & 1393 if ((le16_to_cpu(config_page->ConfigElement[i].ElementFlags) &
1394 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE) != 1394 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE) !=
1395 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT) 1395 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT)
1396 continue; 1396 continue;
1397 if (config_page->ConfigElement[i].PhysDiskDevHandle == 1397 if (le16_to_cpu(config_page->ConfigElement[i].
1398 pd_handle) { 1398 PhysDiskDevHandle) == pd_handle) {
1399 *volume_handle = le16_to_cpu(config_page-> 1399 *volume_handle = le16_to_cpu(config_page->
1400 ConfigElement[i].VolDevHandle); 1400 ConfigElement[i].VolDevHandle);
1401 r = 0; 1401 r = 0;
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index fa9bf83819d5..d88e9756d8f5 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -3,7 +3,7 @@
3 * controllers 3 * controllers
4 * 4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.c 5 * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.c
6 * Copyright (C) 2007-2009 LSI Corporation 6 * Copyright (C) 2007-2010 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com) 7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
@@ -533,7 +533,7 @@ _ctl_set_task_mid(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command *karg,
533 if (!found) { 533 if (!found) {
534 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 534 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
535 "handle(0x%04x), lun(%d), no active mid!!\n", ioc->name, 535 "handle(0x%04x), lun(%d), no active mid!!\n", ioc->name,
536 desc, tm_request->DevHandle, lun)); 536 desc, le16_to_cpu(tm_request->DevHandle), lun));
537 tm_reply = ioc->ctl_cmds.reply; 537 tm_reply = ioc->ctl_cmds.reply;
538 tm_reply->DevHandle = tm_request->DevHandle; 538 tm_reply->DevHandle = tm_request->DevHandle;
539 tm_reply->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; 539 tm_reply->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
@@ -551,7 +551,8 @@ _ctl_set_task_mid(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command *karg,
551 551
552 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 552 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
553 "handle(0x%04x), lun(%d), task_mid(%d)\n", ioc->name, 553 "handle(0x%04x), lun(%d), task_mid(%d)\n", ioc->name,
554 desc, tm_request->DevHandle, lun, tm_request->TaskMID)); 554 desc, le16_to_cpu(tm_request->DevHandle), lun,
555 le16_to_cpu(tm_request->TaskMID)));
555 return 0; 556 return 0;
556} 557}
557 558
@@ -647,9 +648,9 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
647 648
648 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || 649 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
649 mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) { 650 mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
650 if (!mpi_request->FunctionDependent1 || 651 if (!le16_to_cpu(mpi_request->FunctionDependent1) ||
651 mpi_request->FunctionDependent1 > 652 le16_to_cpu(mpi_request->FunctionDependent1) >
652 cpu_to_le16(ioc->facts.MaxDevHandle)) { 653 ioc->facts.MaxDevHandle) {
653 ret = -EINVAL; 654 ret = -EINVAL;
654 mpt2sas_base_free_smid(ioc, smid); 655 mpt2sas_base_free_smid(ioc, smid);
655 goto out; 656 goto out;
@@ -743,8 +744,11 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
743 mpt2sas_base_get_sense_buffer_dma(ioc, smid); 744 mpt2sas_base_get_sense_buffer_dma(ioc, smid);
744 priv_sense = mpt2sas_base_get_sense_buffer(ioc, smid); 745 priv_sense = mpt2sas_base_get_sense_buffer(ioc, smid);
745 memset(priv_sense, 0, SCSI_SENSE_BUFFERSIZE); 746 memset(priv_sense, 0, SCSI_SENSE_BUFFERSIZE);
746 mpt2sas_base_put_smid_scsi_io(ioc, smid, 747 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)
747 le16_to_cpu(mpi_request->FunctionDependent1)); 748 mpt2sas_base_put_smid_scsi_io(ioc, smid,
749 le16_to_cpu(mpi_request->FunctionDependent1));
750 else
751 mpt2sas_base_put_smid_default(ioc, smid);
748 break; 752 break;
749 } 753 }
750 case MPI2_FUNCTION_SCSI_TASK_MGMT: 754 case MPI2_FUNCTION_SCSI_TASK_MGMT:
@@ -752,6 +756,10 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
752 Mpi2SCSITaskManagementRequest_t *tm_request = 756 Mpi2SCSITaskManagementRequest_t *tm_request =
753 (Mpi2SCSITaskManagementRequest_t *)mpi_request; 757 (Mpi2SCSITaskManagementRequest_t *)mpi_request;
754 758
759 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "TASK_MGMT: "
760 "handle(0x%04x), task_type(0x%02x)\n", ioc->name,
761 le16_to_cpu(tm_request->DevHandle), tm_request->TaskType));
762
755 if (tm_request->TaskType == 763 if (tm_request->TaskType ==
756 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK || 764 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK ||
757 tm_request->TaskType == 765 tm_request->TaskType ==
@@ -762,7 +770,6 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
762 } 770 }
763 } 771 }
764 772
765 mutex_lock(&ioc->tm_cmds.mutex);
766 mpt2sas_scsih_set_tm_flag(ioc, le16_to_cpu( 773 mpt2sas_scsih_set_tm_flag(ioc, le16_to_cpu(
767 tm_request->DevHandle)); 774 tm_request->DevHandle));
768 mpt2sas_base_put_smid_hi_priority(ioc, smid); 775 mpt2sas_base_put_smid_hi_priority(ioc, smid);
@@ -818,7 +825,6 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
818 if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) { 825 if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
819 Mpi2SCSITaskManagementRequest_t *tm_request = 826 Mpi2SCSITaskManagementRequest_t *tm_request =
820 (Mpi2SCSITaskManagementRequest_t *)mpi_request; 827 (Mpi2SCSITaskManagementRequest_t *)mpi_request;
821 mutex_unlock(&ioc->tm_cmds.mutex);
822 mpt2sas_scsih_clear_tm_flag(ioc, le16_to_cpu( 828 mpt2sas_scsih_clear_tm_flag(ioc, le16_to_cpu(
823 tm_request->DevHandle)); 829 tm_request->DevHandle));
824 } else if ((mpi_request->Function == MPI2_FUNCTION_SMP_PASSTHROUGH || 830 } else if ((mpi_request->Function == MPI2_FUNCTION_SMP_PASSTHROUGH ||
@@ -897,14 +903,13 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
897 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 903 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
898 printk(MPT2SAS_INFO_FMT "issue target reset: handle " 904 printk(MPT2SAS_INFO_FMT "issue target reset: handle "
899 "= (0x%04x)\n", ioc->name, 905 "= (0x%04x)\n", ioc->name,
900 mpi_request->FunctionDependent1); 906 le16_to_cpu(mpi_request->FunctionDependent1));
901 mpt2sas_halt_firmware(ioc); 907 mpt2sas_halt_firmware(ioc);
902 mutex_lock(&ioc->tm_cmds.mutex);
903 mpt2sas_scsih_issue_tm(ioc, 908 mpt2sas_scsih_issue_tm(ioc,
904 mpi_request->FunctionDependent1, 0, 909 le16_to_cpu(mpi_request->FunctionDependent1), 0, 0,
905 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 10); 910 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 10,
911 NULL);
906 ioc->tm_cmds.status = MPT2_CMD_NOT_USED; 912 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
907 mutex_unlock(&ioc->tm_cmds.mutex);
908 } else 913 } else
909 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, 914 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
910 FORCE_BIG_HAMMER); 915 FORCE_BIG_HAMMER);
@@ -1373,7 +1378,8 @@ _ctl_diag_register_2(struct MPT2SAS_ADAPTER *ioc,
1373 1378
1374 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: diag_buffer(0x%p), " 1379 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: diag_buffer(0x%p), "
1375 "dma(0x%llx), sz(%d)\n", ioc->name, __func__, request_data, 1380 "dma(0x%llx), sz(%d)\n", ioc->name, __func__, request_data,
1376 (unsigned long long)request_data_dma, mpi_request->BufferLength)); 1381 (unsigned long long)request_data_dma,
1382 le32_to_cpu(mpi_request->BufferLength)));
1377 1383
1378 for (i = 0; i < MPT2_PRODUCT_SPECIFIC_DWORDS; i++) 1384 for (i = 0; i < MPT2_PRODUCT_SPECIFIC_DWORDS; i++)
1379 mpi_request->ProductSpecific[i] = 1385 mpi_request->ProductSpecific[i] =
@@ -2334,8 +2340,8 @@ _ctl_version_nvdata_persistent_show(struct device *cdev,
2334 struct Scsi_Host *shost = class_to_shost(cdev); 2340 struct Scsi_Host *shost = class_to_shost(cdev);
2335 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); 2341 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2336 2342
2337 return snprintf(buf, PAGE_SIZE, "%02xh\n", 2343 return snprintf(buf, PAGE_SIZE, "%08xh\n",
2338 le16_to_cpu(ioc->iounit_pg0.NvdataVersionPersistent.Word)); 2344 le32_to_cpu(ioc->iounit_pg0.NvdataVersionPersistent.Word));
2339} 2345}
2340static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO, 2346static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
2341 _ctl_version_nvdata_persistent_show, NULL); 2347 _ctl_version_nvdata_persistent_show, NULL);
@@ -2354,8 +2360,8 @@ _ctl_version_nvdata_default_show(struct device *cdev,
2354 struct Scsi_Host *shost = class_to_shost(cdev); 2360 struct Scsi_Host *shost = class_to_shost(cdev);
2355 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); 2361 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2356 2362
2357 return snprintf(buf, PAGE_SIZE, "%02xh\n", 2363 return snprintf(buf, PAGE_SIZE, "%08xh\n",
2358 le16_to_cpu(ioc->iounit_pg0.NvdataVersionDefault.Word)); 2364 le32_to_cpu(ioc->iounit_pg0.NvdataVersionDefault.Word));
2359} 2365}
2360static DEVICE_ATTR(version_nvdata_default, S_IRUGO, 2366static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
2361 _ctl_version_nvdata_default_show, NULL); 2367 _ctl_version_nvdata_default_show, NULL);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.h b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
index 8a5eeb1a5c84..69916e46e04f 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
@@ -3,7 +3,7 @@
3 * controllers 3 * controllers
4 * 4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.h 5 * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.h
6 * Copyright (C) 2007-2009 LSI Corporation 6 * Copyright (C) 2007-2010 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com) 7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
diff --git a/drivers/scsi/mpt2sas/mpt2sas_debug.h b/drivers/scsi/mpt2sas/mpt2sas_debug.h
index 5308a25cb307..3dcddfeb6f4c 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_debug.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_debug.h
@@ -2,7 +2,7 @@
2 * Logging Support for MPT (Message Passing Technology) based controllers 2 * Logging Support for MPT (Message Passing Technology) based controllers
3 * 3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_debug.c 4 * This code is based on drivers/scsi/mpt2sas/mpt2_debug.c
5 * Copyright (C) 2007-2009 LSI Corporation 5 * Copyright (C) 2007-2010 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com) 6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index be171ed682e0..c5ff26a2a51d 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -2,7 +2,7 @@
2 * Scsi Host Layer for MPT (Message Passing Technology) based controllers 2 * Scsi Host Layer for MPT (Message Passing Technology) based controllers
3 * 3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_scsih.c 4 * This code is based on drivers/scsi/mpt2sas/mpt2_scsih.c
5 * Copyright (C) 2007-2009 LSI Corporation 5 * Copyright (C) 2007-2010 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com) 6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
@@ -52,6 +52,7 @@
52#include <linux/delay.h> 52#include <linux/delay.h>
53#include <linux/pci.h> 53#include <linux/pci.h>
54#include <linux/interrupt.h> 54#include <linux/interrupt.h>
55#include <linux/aer.h>
55#include <linux/raid_class.h> 56#include <linux/raid_class.h>
56#include <linux/slab.h> 57#include <linux/slab.h>
57 58
@@ -109,14 +110,16 @@ struct sense_info {
109}; 110};
110 111
111 112
113#define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF)
114
112/** 115/**
113 * struct fw_event_work - firmware event struct 116 * struct fw_event_work - firmware event struct
114 * @list: link list framework 117 * @list: link list framework
115 * @work: work object (ioc->fault_reset_work_q) 118 * @work: work object (ioc->fault_reset_work_q)
119 * @cancel_pending_work: flag set during reset handling
116 * @ioc: per adapter object 120 * @ioc: per adapter object
117 * @VF_ID: virtual function id 121 * @VF_ID: virtual function id
118 * @VP_ID: virtual port id 122 * @VP_ID: virtual port id
119 * @host_reset_handling: handling events during host reset
120 * @ignore: flag meaning this event has been marked to ignore 123 * @ignore: flag meaning this event has been marked to ignore
121 * @event: firmware event MPI2_EVENT_XXX defined in mpt2_ioc.h 124 * @event: firmware event MPI2_EVENT_XXX defined in mpt2_ioc.h
122 * @event_data: reply event data payload follows 125 * @event_data: reply event data payload follows
@@ -125,11 +128,11 @@ struct sense_info {
125 */ 128 */
126struct fw_event_work { 129struct fw_event_work {
127 struct list_head list; 130 struct list_head list;
128 struct work_struct work; 131 u8 cancel_pending_work;
132 struct delayed_work delayed_work;
129 struct MPT2SAS_ADAPTER *ioc; 133 struct MPT2SAS_ADAPTER *ioc;
130 u8 VF_ID; 134 u8 VF_ID;
131 u8 VP_ID; 135 u8 VP_ID;
132 u8 host_reset_handling;
133 u8 ignore; 136 u8 ignore;
134 u16 event; 137 u16 event;
135 void *event_data; 138 void *event_data;
@@ -482,27 +485,17 @@ struct _sas_device *
482mpt2sas_scsih_sas_device_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc, 485mpt2sas_scsih_sas_device_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
483 u64 sas_address) 486 u64 sas_address)
484{ 487{
485 struct _sas_device *sas_device, *r; 488 struct _sas_device *sas_device;
486 489
487 r = NULL; 490 list_for_each_entry(sas_device, &ioc->sas_device_list, list)
488 /* check the sas_device_init_list */ 491 if (sas_device->sas_address == sas_address)
489 list_for_each_entry(sas_device, &ioc->sas_device_init_list, 492 return sas_device;
490 list) {
491 if (sas_device->sas_address != sas_address)
492 continue;
493 r = sas_device;
494 goto out;
495 }
496 493
497 /* then check the sas_device_list */ 494 list_for_each_entry(sas_device, &ioc->sas_device_init_list, list)
498 list_for_each_entry(sas_device, &ioc->sas_device_list, list) { 495 if (sas_device->sas_address == sas_address)
499 if (sas_device->sas_address != sas_address) 496 return sas_device;
500 continue; 497
501 r = sas_device; 498 return NULL;
502 goto out;
503 }
504 out:
505 return r;
506} 499}
507 500
508/** 501/**
@@ -517,28 +510,17 @@ mpt2sas_scsih_sas_device_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
517static struct _sas_device * 510static struct _sas_device *
518_scsih_sas_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle) 511_scsih_sas_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
519{ 512{
520 struct _sas_device *sas_device, *r; 513 struct _sas_device *sas_device;
521 514
522 r = NULL; 515 list_for_each_entry(sas_device, &ioc->sas_device_list, list)
523 if (ioc->wait_for_port_enable_to_complete) { 516 if (sas_device->handle == handle)
524 list_for_each_entry(sas_device, &ioc->sas_device_init_list, 517 return sas_device;
525 list) {
526 if (sas_device->handle != handle)
527 continue;
528 r = sas_device;
529 goto out;
530 }
531 } else {
532 list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
533 if (sas_device->handle != handle)
534 continue;
535 r = sas_device;
536 goto out;
537 }
538 }
539 518
540 out: 519 list_for_each_entry(sas_device, &ioc->sas_device_init_list, list)
541 return r; 520 if (sas_device->handle == handle)
521 return sas_device;
522
523 return NULL;
542} 524}
543 525
544/** 526/**
@@ -555,10 +537,15 @@ _scsih_sas_device_remove(struct MPT2SAS_ADAPTER *ioc,
555{ 537{
556 unsigned long flags; 538 unsigned long flags;
557 539
540 if (!sas_device)
541 return;
542
558 spin_lock_irqsave(&ioc->sas_device_lock, flags); 543 spin_lock_irqsave(&ioc->sas_device_lock, flags);
559 list_del(&sas_device->list); 544 if (mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
560 memset(sas_device, 0, sizeof(struct _sas_device)); 545 sas_device->sas_address)) {
561 kfree(sas_device); 546 list_del(&sas_device->list);
547 kfree(sas_device);
548 }
562 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 549 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
563} 550}
564 551
@@ -988,7 +975,7 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
988 u32 chain_offset; 975 u32 chain_offset;
989 u32 chain_length; 976 u32 chain_length;
990 u32 chain_flags; 977 u32 chain_flags;
991 u32 sges_left; 978 int sges_left;
992 u32 sges_in_segment; 979 u32 sges_in_segment;
993 u32 sgl_flags; 980 u32 sgl_flags;
994 u32 sgl_flags_last_element; 981 u32 sgl_flags_last_element;
@@ -1009,7 +996,7 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
1009 996
1010 sg_scmd = scsi_sglist(scmd); 997 sg_scmd = scsi_sglist(scmd);
1011 sges_left = scsi_dma_map(scmd); 998 sges_left = scsi_dma_map(scmd);
1012 if (!sges_left) { 999 if (sges_left < 0) {
1013 sdev_printk(KERN_ERR, scmd->device, "pci_map_sg" 1000 sdev_printk(KERN_ERR, scmd->device, "pci_map_sg"
1014 " failed: request for %d bytes!\n", scsi_bufflen(scmd)); 1001 " failed: request for %d bytes!\n", scsi_bufflen(scmd));
1015 return -ENOMEM; 1002 return -ENOMEM;
@@ -1395,7 +1382,7 @@ _scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc,
1395 } 1382 }
1396 1383
1397 flags = le16_to_cpu(sas_device_pg0.Flags); 1384 flags = le16_to_cpu(sas_device_pg0.Flags);
1398 device_info = le16_to_cpu(sas_device_pg0.DeviceInfo); 1385 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
1399 1386
1400 sdev_printk(KERN_INFO, sdev, 1387 sdev_printk(KERN_INFO, sdev,
1401 "atapi(%s), ncq(%s), asyn_notify(%s), smart(%s), fua(%s), " 1388 "atapi(%s), ncq(%s), asyn_notify(%s), smart(%s), fua(%s), "
@@ -1963,65 +1950,78 @@ mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle)
1963 } 1950 }
1964} 1951}
1965 1952
1953
1966/** 1954/**
1967 * mpt2sas_scsih_issue_tm - main routine for sending tm requests 1955 * mpt2sas_scsih_issue_tm - main routine for sending tm requests
1968 * @ioc: per adapter struct 1956 * @ioc: per adapter struct
1969 * @device_handle: device handle 1957 * @device_handle: device handle
1958 * @channel: the channel assigned by the OS
1959 * @id: the id assigned by the OS
1970 * @lun: lun number 1960 * @lun: lun number
1971 * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h) 1961 * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
1972 * @smid_task: smid assigned to the task 1962 * @smid_task: smid assigned to the task
1973 * @timeout: timeout in seconds 1963 * @timeout: timeout in seconds
1974 * Context: The calling function needs to acquire the tm_cmds.mutex 1964 * Context: user
1975 * 1965 *
1976 * A generic API for sending task management requests to firmware. 1966 * A generic API for sending task management requests to firmware.
1977 * 1967 *
1978 * The ioc->tm_cmds.status flag should be MPT2_CMD_NOT_USED before calling
1979 * this API.
1980 *
1981 * The callback index is set inside `ioc->tm_cb_idx`. 1968 * The callback index is set inside `ioc->tm_cb_idx`.
1982 * 1969 *
1983 * Return nothing. 1970 * Return SUCCESS or FAILED.
1984 */ 1971 */
1985void 1972int
1986mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun, 1973mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint channel,
1987 u8 type, u16 smid_task, ulong timeout) 1974 uint id, uint lun, u8 type, u16 smid_task, ulong timeout,
1975 struct scsi_cmnd *scmd)
1988{ 1976{
1989 Mpi2SCSITaskManagementRequest_t *mpi_request; 1977 Mpi2SCSITaskManagementRequest_t *mpi_request;
1990 Mpi2SCSITaskManagementReply_t *mpi_reply; 1978 Mpi2SCSITaskManagementReply_t *mpi_reply;
1991 u16 smid = 0; 1979 u16 smid = 0;
1992 u32 ioc_state; 1980 u32 ioc_state;
1993 unsigned long timeleft; 1981 unsigned long timeleft;
1982 struct scsi_cmnd *scmd_lookup;
1983 int rc;
1994 1984
1985 mutex_lock(&ioc->tm_cmds.mutex);
1995 if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED) { 1986 if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED) {
1996 printk(MPT2SAS_INFO_FMT "%s: tm_cmd busy!!!\n", 1987 printk(MPT2SAS_INFO_FMT "%s: tm_cmd busy!!!\n",
1997 __func__, ioc->name); 1988 __func__, ioc->name);
1998 return; 1989 rc = FAILED;
1990 goto err_out;
1999 } 1991 }
2000 1992
2001 if (ioc->shost_recovery) { 1993 if (ioc->shost_recovery || ioc->remove_host) {
2002 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 1994 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
2003 __func__, ioc->name); 1995 __func__, ioc->name);
2004 return; 1996 rc = FAILED;
1997 goto err_out;
2005 } 1998 }
2006 1999
2007 ioc_state = mpt2sas_base_get_iocstate(ioc, 0); 2000 ioc_state = mpt2sas_base_get_iocstate(ioc, 0);
2008 if (ioc_state & MPI2_DOORBELL_USED) { 2001 if (ioc_state & MPI2_DOORBELL_USED) {
2009 dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "unexpected doorbell " 2002 dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "unexpected doorbell "
2010 "active!\n", ioc->name)); 2003 "active!\n", ioc->name));
2011 goto issue_host_reset; 2004 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
2005 FORCE_BIG_HAMMER);
2006 rc = SUCCESS;
2007 goto err_out;
2012 } 2008 }
2013 2009
2014 if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { 2010 if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
2015 mpt2sas_base_fault_info(ioc, ioc_state & 2011 mpt2sas_base_fault_info(ioc, ioc_state &
2016 MPI2_DOORBELL_DATA_MASK); 2012 MPI2_DOORBELL_DATA_MASK);
2017 goto issue_host_reset; 2013 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
2014 FORCE_BIG_HAMMER);
2015 rc = SUCCESS;
2016 goto err_out;
2018 } 2017 }
2019 2018
2020 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_cb_idx); 2019 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_cb_idx);
2021 if (!smid) { 2020 if (!smid) {
2022 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 2021 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
2023 ioc->name, __func__); 2022 ioc->name, __func__);
2024 return; 2023 rc = FAILED;
2024 goto err_out;
2025 } 2025 }
2026 2026
2027 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "sending tm: handle(0x%04x)," 2027 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "sending tm: handle(0x%04x),"
@@ -2035,21 +2035,24 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
2035 mpi_request->DevHandle = cpu_to_le16(handle); 2035 mpi_request->DevHandle = cpu_to_le16(handle);
2036 mpi_request->TaskType = type; 2036 mpi_request->TaskType = type;
2037 mpi_request->TaskMID = cpu_to_le16(smid_task); 2037 mpi_request->TaskMID = cpu_to_le16(smid_task);
2038 mpi_request->VP_ID = 0; /* TODO */
2039 mpi_request->VF_ID = 0;
2040 int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN); 2038 int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
2041 mpt2sas_scsih_set_tm_flag(ioc, handle); 2039 mpt2sas_scsih_set_tm_flag(ioc, handle);
2042 init_completion(&ioc->tm_cmds.done); 2040 init_completion(&ioc->tm_cmds.done);
2043 mpt2sas_base_put_smid_hi_priority(ioc, smid); 2041 mpt2sas_base_put_smid_hi_priority(ioc, smid);
2044 timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ); 2042 timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ);
2045 mpt2sas_scsih_clear_tm_flag(ioc, handle);
2046 if (!(ioc->tm_cmds.status & MPT2_CMD_COMPLETE)) { 2043 if (!(ioc->tm_cmds.status & MPT2_CMD_COMPLETE)) {
2047 printk(MPT2SAS_ERR_FMT "%s: timeout\n", 2044 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
2048 ioc->name, __func__); 2045 ioc->name, __func__);
2049 _debug_dump_mf(mpi_request, 2046 _debug_dump_mf(mpi_request,
2050 sizeof(Mpi2SCSITaskManagementRequest_t)/4); 2047 sizeof(Mpi2SCSITaskManagementRequest_t)/4);
2051 if (!(ioc->tm_cmds.status & MPT2_CMD_RESET)) 2048 if (!(ioc->tm_cmds.status & MPT2_CMD_RESET)) {
2052 goto issue_host_reset; 2049 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
2050 FORCE_BIG_HAMMER);
2051 rc = SUCCESS;
2052 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
2053 mpt2sas_scsih_clear_tm_flag(ioc, handle);
2054 goto err_out;
2055 }
2053 } 2056 }
2054 2057
2055 if (ioc->tm_cmds.status & MPT2_CMD_REPLY_VALID) { 2058 if (ioc->tm_cmds.status & MPT2_CMD_REPLY_VALID) {
@@ -2059,12 +2062,57 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
2059 ioc->name, le16_to_cpu(mpi_reply->IOCStatus), 2062 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
2060 le32_to_cpu(mpi_reply->IOCLogInfo), 2063 le32_to_cpu(mpi_reply->IOCLogInfo),
2061 le32_to_cpu(mpi_reply->TerminationCount))); 2064 le32_to_cpu(mpi_reply->TerminationCount)));
2062 if (ioc->logging_level & MPT_DEBUG_TM) 2065 if (ioc->logging_level & MPT_DEBUG_TM) {
2063 _scsih_response_code(ioc, mpi_reply->ResponseCode); 2066 _scsih_response_code(ioc, mpi_reply->ResponseCode);
2067 if (mpi_reply->IOCStatus)
2068 _debug_dump_mf(mpi_request,
2069 sizeof(Mpi2SCSITaskManagementRequest_t)/4);
2070 }
2064 } 2071 }
2065 return; 2072
2066 issue_host_reset: 2073 /* sanity check:
2067 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, FORCE_BIG_HAMMER); 2074 * Check to see the commands were terminated.
2075 * This is only needed for eh callbacks, hence the scmd check.
2076 */
2077 rc = FAILED;
2078 if (scmd == NULL)
2079 goto bypass_sanity_checks;
2080 switch (type) {
2081 case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
2082 scmd_lookup = _scsih_scsi_lookup_get(ioc, smid_task);
2083 if (scmd_lookup && (scmd_lookup->serial_number ==
2084 scmd->serial_number))
2085 rc = FAILED;
2086 else
2087 rc = SUCCESS;
2088 break;
2089
2090 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
2091 if (_scsih_scsi_lookup_find_by_target(ioc, id, channel))
2092 rc = FAILED;
2093 else
2094 rc = SUCCESS;
2095 break;
2096
2097 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
2098 if (_scsih_scsi_lookup_find_by_lun(ioc, id, lun, channel))
2099 rc = FAILED;
2100 else
2101 rc = SUCCESS;
2102 break;
2103 }
2104
2105 bypass_sanity_checks:
2106
2107 mpt2sas_scsih_clear_tm_flag(ioc, handle);
2108 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
2109 mutex_unlock(&ioc->tm_cmds.mutex);
2110
2111 return rc;
2112
2113 err_out:
2114 mutex_unlock(&ioc->tm_cmds.mutex);
2115 return rc;
2068} 2116}
2069 2117
2070/** 2118/**
@@ -2081,7 +2129,6 @@ _scsih_abort(struct scsi_cmnd *scmd)
2081 u16 smid; 2129 u16 smid;
2082 u16 handle; 2130 u16 handle;
2083 int r; 2131 int r;
2084 struct scsi_cmnd *scmd_lookup;
2085 2132
2086 printk(MPT2SAS_INFO_FMT "attempting task abort! scmd(%p)\n", 2133 printk(MPT2SAS_INFO_FMT "attempting task abort! scmd(%p)\n",
2087 ioc->name, scmd); 2134 ioc->name, scmd);
@@ -2116,19 +2163,10 @@ _scsih_abort(struct scsi_cmnd *scmd)
2116 2163
2117 mpt2sas_halt_firmware(ioc); 2164 mpt2sas_halt_firmware(ioc);
2118 2165
2119 mutex_lock(&ioc->tm_cmds.mutex);
2120 handle = sas_device_priv_data->sas_target->handle; 2166 handle = sas_device_priv_data->sas_target->handle;
2121 mpt2sas_scsih_issue_tm(ioc, handle, sas_device_priv_data->lun, 2167 r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
2122 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30); 2168 scmd->device->id, scmd->device->lun,
2123 2169 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30, scmd);
2124 /* sanity check - see whether command actually completed */
2125 scmd_lookup = _scsih_scsi_lookup_get(ioc, smid);
2126 if (scmd_lookup && (scmd_lookup->serial_number == scmd->serial_number))
2127 r = FAILED;
2128 else
2129 r = SUCCESS;
2130 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
2131 mutex_unlock(&ioc->tm_cmds.mutex);
2132 2170
2133 out: 2171 out:
2134 printk(MPT2SAS_INFO_FMT "task abort: %s scmd(%p)\n", 2172 printk(MPT2SAS_INFO_FMT "task abort: %s scmd(%p)\n",
@@ -2185,22 +2223,9 @@ _scsih_dev_reset(struct scsi_cmnd *scmd)
2185 goto out; 2223 goto out;
2186 } 2224 }
2187 2225
2188 mutex_lock(&ioc->tm_cmds.mutex); 2226 r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
2189 mpt2sas_scsih_issue_tm(ioc, handle, 0, 2227 scmd->device->id, scmd->device->lun,
2190 MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, scmd->device->lun, 2228 MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30, scmd);
2191 30);
2192
2193 /*
2194 * sanity check see whether all commands to this device been
2195 * completed
2196 */
2197 if (_scsih_scsi_lookup_find_by_lun(ioc, scmd->device->id,
2198 scmd->device->lun, scmd->device->channel))
2199 r = FAILED;
2200 else
2201 r = SUCCESS;
2202 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
2203 mutex_unlock(&ioc->tm_cmds.mutex);
2204 2229
2205 out: 2230 out:
2206 printk(MPT2SAS_INFO_FMT "device reset: %s scmd(%p)\n", 2231 printk(MPT2SAS_INFO_FMT "device reset: %s scmd(%p)\n",
@@ -2257,21 +2282,9 @@ _scsih_target_reset(struct scsi_cmnd *scmd)
2257 goto out; 2282 goto out;
2258 } 2283 }
2259 2284
2260 mutex_lock(&ioc->tm_cmds.mutex); 2285 r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
2261 mpt2sas_scsih_issue_tm(ioc, handle, 0, 2286 scmd->device->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
2262 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30); 2287 30, scmd);
2263
2264 /*
2265 * sanity check see whether all commands to this target been
2266 * completed
2267 */
2268 if (_scsih_scsi_lookup_find_by_target(ioc, scmd->device->id,
2269 scmd->device->channel))
2270 r = FAILED;
2271 else
2272 r = SUCCESS;
2273 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
2274 mutex_unlock(&ioc->tm_cmds.mutex);
2275 2288
2276 out: 2289 out:
2277 printk(MPT2SAS_INFO_FMT "target reset: %s scmd(%p)\n", 2290 printk(MPT2SAS_INFO_FMT "target reset: %s scmd(%p)\n",
@@ -2325,8 +2338,9 @@ _scsih_fw_event_add(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
2325 2338
2326 spin_lock_irqsave(&ioc->fw_event_lock, flags); 2339 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2327 list_add_tail(&fw_event->list, &ioc->fw_event_list); 2340 list_add_tail(&fw_event->list, &ioc->fw_event_list);
2328 INIT_WORK(&fw_event->work, _firmware_event_work); 2341 INIT_DELAYED_WORK(&fw_event->delayed_work, _firmware_event_work);
2329 queue_work(ioc->firmware_event_thread, &fw_event->work); 2342 queue_delayed_work(ioc->firmware_event_thread,
2343 &fw_event->delayed_work, 0);
2330 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 2344 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2331} 2345}
2332 2346
@@ -2353,61 +2367,53 @@ _scsih_fw_event_free(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
2353 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 2367 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2354} 2368}
2355 2369
2370
2356/** 2371/**
2357 * _scsih_fw_event_add - requeue an event 2372 * _scsih_queue_rescan - queue a topology rescan from user context
2358 * @ioc: per adapter object 2373 * @ioc: per adapter object
2359 * @fw_event: object describing the event
2360 * Context: This function will acquire ioc->fw_event_lock.
2361 * 2374 *
2362 * Return nothing. 2375 * Return nothing.
2363 */ 2376 */
2364static void 2377static void
2365_scsih_fw_event_requeue(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work 2378_scsih_queue_rescan(struct MPT2SAS_ADAPTER *ioc)
2366 *fw_event, unsigned long delay)
2367{ 2379{
2368 unsigned long flags; 2380 struct fw_event_work *fw_event;
2369 if (ioc->firmware_event_thread == NULL)
2370 return;
2371 2381
2372 spin_lock_irqsave(&ioc->fw_event_lock, flags); 2382 if (ioc->wait_for_port_enable_to_complete)
2373 queue_work(ioc->firmware_event_thread, &fw_event->work); 2383 return;
2374 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 2384 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
2385 if (!fw_event)
2386 return;
2387 fw_event->event = MPT2SAS_RESCAN_AFTER_HOST_RESET;
2388 fw_event->ioc = ioc;
2389 _scsih_fw_event_add(ioc, fw_event);
2375} 2390}
2376 2391
2377/** 2392/**
2378 * _scsih_fw_event_off - turn flag off preventing event handling 2393 * _scsih_fw_event_cleanup_queue - cleanup event queue
2379 * @ioc: per adapter object 2394 * @ioc: per adapter object
2380 * 2395 *
2381 * Used to prevent handling of firmware events during adapter reset 2396 * Walk the firmware event queue, either killing timers, or waiting
2382 * driver unload. 2397 * for outstanding events to complete
2383 * 2398 *
2384 * Return nothing. 2399 * Return nothing.
2385 */ 2400 */
2386static void 2401static void
2387_scsih_fw_event_off(struct MPT2SAS_ADAPTER *ioc) 2402_scsih_fw_event_cleanup_queue(struct MPT2SAS_ADAPTER *ioc)
2388{ 2403{
2389 unsigned long flags; 2404 struct fw_event_work *fw_event, *next;
2390 2405
2391 spin_lock_irqsave(&ioc->fw_event_lock, flags); 2406 if (list_empty(&ioc->fw_event_list) ||
2392 ioc->fw_events_off = 1; 2407 !ioc->firmware_event_thread || in_interrupt())
2393 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 2408 return;
2394
2395}
2396
2397/**
2398 * _scsih_fw_event_on - turn flag on allowing firmware event handling
2399 * @ioc: per adapter object
2400 *
2401 * Returns nothing.
2402 */
2403static void
2404_scsih_fw_event_on(struct MPT2SAS_ADAPTER *ioc)
2405{
2406 unsigned long flags;
2407 2409
2408 spin_lock_irqsave(&ioc->fw_event_lock, flags); 2410 list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) {
2409 ioc->fw_events_off = 0; 2411 if (cancel_delayed_work(&fw_event->delayed_work)) {
2410 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 2412 _scsih_fw_event_free(ioc, fw_event);
2413 continue;
2414 }
2415 fw_event->cancel_pending_work = 1;
2416 }
2411} 2417}
2412 2418
2413/** 2419/**
@@ -2571,25 +2577,24 @@ static void
2571_scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) 2577_scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2572{ 2578{
2573 Mpi2SCSITaskManagementRequest_t *mpi_request; 2579 Mpi2SCSITaskManagementRequest_t *mpi_request;
2574 struct MPT2SAS_TARGET *sas_target_priv_data;
2575 u16 smid; 2580 u16 smid;
2576 struct _sas_device *sas_device; 2581 struct _sas_device *sas_device;
2577 unsigned long flags; 2582 unsigned long flags;
2578 struct _tr_list *delayed_tr; 2583 struct _tr_list *delayed_tr;
2579 2584
2580 if (ioc->shost_recovery) { 2585 if (ioc->shost_recovery || ioc->remove_host) {
2581 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 2586 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in "
2582 __func__, ioc->name); 2587 "progress!\n", __func__, ioc->name));
2583 return; 2588 return;
2584 } 2589 }
2585 2590
2586 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2591 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2587 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2592 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2588 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2593 if (sas_device && sas_device->hidden_raid_component) {
2589 2594 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2590 /* skip is hidden raid component */
2591 if (sas_device && sas_device->hidden_raid_component)
2592 return; 2595 return;
2596 }
2597 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2593 2598
2594 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); 2599 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
2595 if (!smid) { 2600 if (!smid) {
@@ -2598,36 +2603,16 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2598 return; 2603 return;
2599 INIT_LIST_HEAD(&delayed_tr->list); 2604 INIT_LIST_HEAD(&delayed_tr->list);
2600 delayed_tr->handle = handle; 2605 delayed_tr->handle = handle;
2601 delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL; 2606 list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list);
2602 list_add_tail(&delayed_tr->list,
2603 &ioc->delayed_tr_list);
2604 if (sas_device && sas_device->starget) {
2605 dewtprintk(ioc, starget_printk(KERN_INFO,
2606 sas_device->starget, "DELAYED:tr:handle(0x%04x), "
2607 "(open)\n", handle));
2608 } else {
2609 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2610 "DELAYED:tr:handle(0x%04x), (open)\n",
2611 ioc->name, handle));
2612 }
2613 return;
2614 }
2615
2616 if (sas_device) {
2617 sas_device->state |= MPTSAS_STATE_TR_SEND;
2618 sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
2619 if (sas_device->starget && sas_device->starget->hostdata) {
2620 sas_target_priv_data = sas_device->starget->hostdata;
2621 sas_target_priv_data->tm_busy = 1;
2622 dewtprintk(ioc, starget_printk(KERN_INFO,
2623 sas_device->starget, "tr:handle(0x%04x), (open)\n",
2624 handle));
2625 }
2626 } else {
2627 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT 2607 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2628 "tr:handle(0x%04x), (open)\n", ioc->name, handle)); 2608 "DELAYED:tr:handle(0x%04x), (open)\n",
2609 ioc->name, handle));
2610 return;
2629 } 2611 }
2630 2612
2613 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "tr_send:handle(0x%04x), "
2614 "(open), smid(%d), cb(%d)\n", ioc->name, handle, smid,
2615 ioc->tm_tr_cb_idx));
2631 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 2616 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2632 memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t)); 2617 memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
2633 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; 2618 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
@@ -2657,35 +2642,15 @@ static u8
2657_scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, 2642_scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
2658 u8 msix_index, u32 reply) 2643 u8 msix_index, u32 reply)
2659{ 2644{
2660 unsigned long flags;
2661 u16 handle;
2662 struct _sas_device *sas_device;
2663 Mpi2SasIoUnitControlReply_t *mpi_reply = 2645 Mpi2SasIoUnitControlReply_t *mpi_reply =
2664 mpt2sas_base_get_reply_virt_addr(ioc, reply); 2646 mpt2sas_base_get_reply_virt_addr(ioc, reply);
2665 2647
2666 handle = le16_to_cpu(mpi_reply->DevHandle); 2648 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2667 2649 "sc_complete:handle(0x%04x), (open) "
2668 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2650 "smid(%d), ioc_status(0x%04x), loginfo(0x%08x)\n",
2669 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2651 ioc->name, le16_to_cpu(mpi_reply->DevHandle), smid,
2670 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2652 le16_to_cpu(mpi_reply->IOCStatus),
2671 2653 le32_to_cpu(mpi_reply->IOCLogInfo)));
2672 if (sas_device) {
2673 sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
2674 if (sas_device->starget)
2675 dewtprintk(ioc, starget_printk(KERN_INFO,
2676 sas_device->starget,
2677 "sc_complete:handle(0x%04x), "
2678 "ioc_status(0x%04x), loginfo(0x%08x)\n",
2679 handle, le16_to_cpu(mpi_reply->IOCStatus),
2680 le32_to_cpu(mpi_reply->IOCLogInfo)));
2681 } else {
2682 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2683 "sc_complete:handle(0x%04x), "
2684 "ioc_status(0x%04x), loginfo(0x%08x)\n",
2685 ioc->name, handle, le16_to_cpu(mpi_reply->IOCStatus),
2686 le32_to_cpu(mpi_reply->IOCLogInfo)));
2687 }
2688
2689 return 1; 2654 return 1;
2690} 2655}
2691 2656
@@ -2709,87 +2674,63 @@ static u8
2709_scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 2674_scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2710 u32 reply) 2675 u32 reply)
2711{ 2676{
2712 unsigned long flags;
2713 u16 handle; 2677 u16 handle;
2714 struct _sas_device *sas_device; 2678 Mpi2SCSITaskManagementRequest_t *mpi_request_tm;
2715 Mpi2SCSITaskManagementReply_t *mpi_reply = 2679 Mpi2SCSITaskManagementReply_t *mpi_reply =
2716 mpt2sas_base_get_reply_virt_addr(ioc, reply); 2680 mpt2sas_base_get_reply_virt_addr(ioc, reply);
2717 Mpi2SasIoUnitControlRequest_t *mpi_request; 2681 Mpi2SasIoUnitControlRequest_t *mpi_request;
2718 u16 smid_sas_ctrl; 2682 u16 smid_sas_ctrl;
2719 struct MPT2SAS_TARGET *sas_target_priv_data;
2720 struct _tr_list *delayed_tr; 2683 struct _tr_list *delayed_tr;
2721 u8 rc;
2722 2684
2723 handle = le16_to_cpu(mpi_reply->DevHandle); 2685 if (ioc->shost_recovery || ioc->remove_host) {
2724 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2686 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in "
2725 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2687 "progress!\n", __func__, ioc->name));
2726 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2688 return 1;
2727
2728 if (sas_device) {
2729 sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
2730 if (sas_device->starget) {
2731 dewtprintk(ioc, starget_printk(KERN_INFO,
2732 sas_device->starget, "tr_complete:handle(0x%04x), "
2733 "(%s) ioc_status(0x%04x), loginfo(0x%08x), "
2734 "completed(%d)\n", sas_device->handle,
2735 (sas_device->state & MPT2SAS_REQ_SAS_CNTRL) ?
2736 "open" : "active",
2737 le16_to_cpu(mpi_reply->IOCStatus),
2738 le32_to_cpu(mpi_reply->IOCLogInfo),
2739 le32_to_cpu(mpi_reply->TerminationCount)));
2740 if (sas_device->starget->hostdata) {
2741 sas_target_priv_data =
2742 sas_device->starget->hostdata;
2743 sas_target_priv_data->tm_busy = 0;
2744 }
2745 }
2746 } else {
2747 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2748 "tr_complete:handle(0x%04x), (open) ioc_status(0x%04x), "
2749 "loginfo(0x%08x), completed(%d)\n", ioc->name,
2750 handle, le16_to_cpu(mpi_reply->IOCStatus),
2751 le32_to_cpu(mpi_reply->IOCLogInfo),
2752 le32_to_cpu(mpi_reply->TerminationCount)));
2753 } 2689 }
2754 2690
2755 if (!list_empty(&ioc->delayed_tr_list)) { 2691 mpi_request_tm = mpt2sas_base_get_msg_frame(ioc, smid);
2756 delayed_tr = list_entry(ioc->delayed_tr_list.next, 2692 handle = le16_to_cpu(mpi_request_tm->DevHandle);
2757 struct _tr_list, list); 2693 if (handle != le16_to_cpu(mpi_reply->DevHandle)) {
2758 mpt2sas_base_free_smid(ioc, smid); 2694 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "spurious interrupt: "
2759 if (delayed_tr->state & MPT2SAS_REQ_SAS_CNTRL) 2695 "handle(0x%04x:0x%04x), smid(%d)!!!\n", ioc->name, handle,
2760 _scsih_tm_tr_send(ioc, delayed_tr->handle); 2696 le16_to_cpu(mpi_reply->DevHandle), smid));
2761 list_del(&delayed_tr->list); 2697 return 0;
2762 kfree(delayed_tr);
2763 rc = 0; /* tells base_interrupt not to free mf */
2764 } else
2765 rc = 1;
2766
2767 if (sas_device && !(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
2768 return rc;
2769
2770 if (ioc->shost_recovery) {
2771 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
2772 __func__, ioc->name);
2773 return rc;
2774 } 2698 }
2775 2699
2700 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2701 "tr_complete:handle(0x%04x), (open) smid(%d), ioc_status(0x%04x), "
2702 "loginfo(0x%08x), completed(%d)\n", ioc->name,
2703 handle, smid, le16_to_cpu(mpi_reply->IOCStatus),
2704 le32_to_cpu(mpi_reply->IOCLogInfo),
2705 le32_to_cpu(mpi_reply->TerminationCount)));
2706
2776 smid_sas_ctrl = mpt2sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx); 2707 smid_sas_ctrl = mpt2sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx);
2777 if (!smid_sas_ctrl) { 2708 if (!smid_sas_ctrl) {
2778 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 2709 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
2779 ioc->name, __func__); 2710 ioc->name, __func__);
2780 return rc; 2711 return 1;
2781 } 2712 }
2782 2713
2783 if (sas_device) 2714 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sc_send:handle(0x%04x), "
2784 sas_device->state |= MPTSAS_STATE_CNTRL_SEND; 2715 "(open), smid(%d), cb(%d)\n", ioc->name, handle, smid_sas_ctrl,
2785 2716 ioc->tm_sas_control_cb_idx));
2786 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl); 2717 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl);
2787 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); 2718 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
2788 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 2719 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
2789 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; 2720 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
2790 mpi_request->DevHandle = mpi_reply->DevHandle; 2721 mpi_request->DevHandle = mpi_request_tm->DevHandle;
2791 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl); 2722 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl);
2792 return rc; 2723
2724 if (!list_empty(&ioc->delayed_tr_list)) {
2725 delayed_tr = list_entry(ioc->delayed_tr_list.next,
2726 struct _tr_list, list);
2727 mpt2sas_base_free_smid(ioc, smid);
2728 _scsih_tm_tr_send(ioc, delayed_tr->handle);
2729 list_del(&delayed_tr->list);
2730 kfree(delayed_tr);
2731 return 0; /* tells base_interrupt not to free mf */
2732 }
2733 return 1;
2793} 2734}
2794 2735
2795/** 2736/**
@@ -3021,25 +2962,32 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
3021 2962
3022 scmd->scsi_done = done; 2963 scmd->scsi_done = done;
3023 sas_device_priv_data = scmd->device->hostdata; 2964 sas_device_priv_data = scmd->device->hostdata;
3024 if (!sas_device_priv_data) { 2965 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
3025 scmd->result = DID_NO_CONNECT << 16; 2966 scmd->result = DID_NO_CONNECT << 16;
3026 scmd->scsi_done(scmd); 2967 scmd->scsi_done(scmd);
3027 return 0; 2968 return 0;
3028 } 2969 }
3029 2970
3030 sas_target_priv_data = sas_device_priv_data->sas_target; 2971 sas_target_priv_data = sas_device_priv_data->sas_target;
3031 if (!sas_target_priv_data || sas_target_priv_data->handle == 2972 /* invalid device handle */
3032 MPT2SAS_INVALID_DEVICE_HANDLE || sas_target_priv_data->deleted) { 2973 if (sas_target_priv_data->handle == MPT2SAS_INVALID_DEVICE_HANDLE) {
3033 scmd->result = DID_NO_CONNECT << 16; 2974 scmd->result = DID_NO_CONNECT << 16;
3034 scmd->scsi_done(scmd); 2975 scmd->scsi_done(scmd);
3035 return 0; 2976 return 0;
3036 } 2977 }
3037 2978
3038 /* see if we are busy with task managment stuff */ 2979 /* host recovery or link resets sent via IOCTLs */
3039 if (sas_device_priv_data->block || sas_target_priv_data->tm_busy) 2980 if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
3040 return SCSI_MLQUEUE_DEVICE_BUSY;
3041 else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
3042 return SCSI_MLQUEUE_HOST_BUSY; 2981 return SCSI_MLQUEUE_HOST_BUSY;
2982 /* device busy with task managment */
2983 else if (sas_device_priv_data->block || sas_target_priv_data->tm_busy)
2984 return SCSI_MLQUEUE_DEVICE_BUSY;
2985 /* device has been deleted */
2986 else if (sas_target_priv_data->deleted) {
2987 scmd->result = DID_NO_CONNECT << 16;
2988 scmd->scsi_done(scmd);
2989 return 0;
2990 }
3043 2991
3044 if (scmd->sc_data_direction == DMA_FROM_DEVICE) 2992 if (scmd->sc_data_direction == DMA_FROM_DEVICE)
3045 mpi_control = MPI2_SCSIIO_CONTROL_READ; 2993 mpi_control = MPI2_SCSIIO_CONTROL_READ;
@@ -3110,8 +3058,11 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
3110 } 3058 }
3111 } 3059 }
3112 3060
3113 mpt2sas_base_put_smid_scsi_io(ioc, smid, 3061 if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST))
3114 sas_device_priv_data->sas_target->handle); 3062 mpt2sas_base_put_smid_scsi_io(ioc, smid,
3063 sas_device_priv_data->sas_target->handle);
3064 else
3065 mpt2sas_base_put_smid_default(ioc, smid);
3115 return 0; 3066 return 0;
3116 3067
3117 out: 3068 out:
@@ -3301,8 +3252,8 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
3301 struct sense_info data; 3252 struct sense_info data;
3302 _scsih_normalize_sense(scmd->sense_buffer, &data); 3253 _scsih_normalize_sense(scmd->sense_buffer, &data);
3303 printk(MPT2SAS_WARN_FMT "\t[sense_key,asc,ascq]: " 3254 printk(MPT2SAS_WARN_FMT "\t[sense_key,asc,ascq]: "
3304 "[0x%02x,0x%02x,0x%02x]\n", ioc->name, data.skey, 3255 "[0x%02x,0x%02x,0x%02x], count(%d)\n", ioc->name, data.skey,
3305 data.asc, data.ascq); 3256 data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
3306 } 3257 }
3307 3258
3308 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) { 3259 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
@@ -3356,7 +3307,7 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3356 mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; 3307 mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
3357 mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS; 3308 mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS;
3358 mpi_request.SlotStatus = 3309 mpi_request.SlotStatus =
3359 MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT; 3310 cpu_to_le32(MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
3360 mpi_request.DevHandle = cpu_to_le16(handle); 3311 mpi_request.DevHandle = cpu_to_le16(handle);
3361 mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS; 3312 mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS;
3362 if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply, 3313 if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply,
@@ -4008,6 +3959,134 @@ _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
4008} 3959}
4009 3960
4010/** 3961/**
3962 * _scsih_check_access_status - check access flags
3963 * @ioc: per adapter object
3964 * @sas_address: sas address
3965 * @handle: sas device handle
3966 * @access_flags: errors returned during discovery of the device
3967 *
3968 * Return 0 for success, else failure
3969 */
3970static u8
3971_scsih_check_access_status(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
3972 u16 handle, u8 access_status)
3973{
3974 u8 rc = 1;
3975 char *desc = NULL;
3976
3977 switch (access_status) {
3978 case MPI2_SAS_DEVICE0_ASTATUS_NO_ERRORS:
3979 case MPI2_SAS_DEVICE0_ASTATUS_SATA_NEEDS_INITIALIZATION:
3980 rc = 0;
3981 break;
3982 case MPI2_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED:
3983 desc = "sata capability failed";
3984 break;
3985 case MPI2_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT:
3986 desc = "sata affiliation conflict";
3987 break;
3988 case MPI2_SAS_DEVICE0_ASTATUS_ROUTE_NOT_ADDRESSABLE:
3989 desc = "route not addressable";
3990 break;
3991 case MPI2_SAS_DEVICE0_ASTATUS_SMP_ERROR_NOT_ADDRESSABLE:
3992 desc = "smp error not addressable";
3993 break;
3994 case MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED:
3995 desc = "device blocked";
3996 break;
3997 case MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED:
3998 case MPI2_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN:
3999 case MPI2_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT:
4000 case MPI2_SAS_DEVICE0_ASTATUS_SIF_DIAG:
4001 case MPI2_SAS_DEVICE0_ASTATUS_SIF_IDENTIFICATION:
4002 case MPI2_SAS_DEVICE0_ASTATUS_SIF_CHECK_POWER:
4003 case MPI2_SAS_DEVICE0_ASTATUS_SIF_PIO_SN:
4004 case MPI2_SAS_DEVICE0_ASTATUS_SIF_MDMA_SN:
4005 case MPI2_SAS_DEVICE0_ASTATUS_SIF_UDMA_SN:
4006 case MPI2_SAS_DEVICE0_ASTATUS_SIF_ZONING_VIOLATION:
4007 case MPI2_SAS_DEVICE0_ASTATUS_SIF_NOT_ADDRESSABLE:
4008 case MPI2_SAS_DEVICE0_ASTATUS_SIF_MAX:
4009 desc = "sata initialization failed";
4010 break;
4011 default:
4012 desc = "unknown";
4013 break;
4014 }
4015
4016 if (!rc)
4017 return 0;
4018
4019 printk(MPT2SAS_ERR_FMT "discovery errors(%s): sas_address(0x%016llx), "
4020 "handle(0x%04x)\n", ioc->name, desc,
4021 (unsigned long long)sas_address, handle);
4022 return rc;
4023}
4024
4025static void
4026_scsih_check_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
4027{
4028 Mpi2ConfigReply_t mpi_reply;
4029 Mpi2SasDevicePage0_t sas_device_pg0;
4030 struct _sas_device *sas_device;
4031 u32 ioc_status;
4032 unsigned long flags;
4033 u64 sas_address;
4034 struct scsi_target *starget;
4035 struct MPT2SAS_TARGET *sas_target_priv_data;
4036 u32 device_info;
4037
4038 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
4039 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle)))
4040 return;
4041
4042 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
4043 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
4044 return;
4045
4046 /* check if this is end device */
4047 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
4048 if (!(_scsih_is_end_device(device_info)))
4049 return;
4050
4051 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4052 sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
4053 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
4054 sas_address);
4055
4056 if (!sas_device) {
4057 printk(MPT2SAS_ERR_FMT "device is not present "
4058 "handle(0x%04x), no sas_device!!!\n", ioc->name, handle);
4059 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4060 return;
4061 }
4062
4063 if (unlikely(sas_device->handle != handle)) {
4064 starget = sas_device->starget;
4065 sas_target_priv_data = starget->hostdata;
4066 starget_printk(KERN_INFO, starget, "handle changed from(0x%04x)"
4067 " to (0x%04x)!!!\n", sas_device->handle, handle);
4068 sas_target_priv_data->handle = handle;
4069 sas_device->handle = handle;
4070 }
4071 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4072
4073 /* check if device is present */
4074 if (!(le16_to_cpu(sas_device_pg0.Flags) &
4075 MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) {
4076 printk(MPT2SAS_ERR_FMT "device is not present "
4077 "handle(0x%04x), flags!!!\n", ioc->name, handle);
4078 return;
4079 }
4080
4081 /* check if there were any issues with discovery */
4082 if (_scsih_check_access_status(ioc, sas_address, handle,
4083 sas_device_pg0.AccessStatus))
4084 return;
4085 _scsih_ublock_io_device(ioc, handle);
4086
4087}
4088
4089/**
4011 * _scsih_add_device - creating sas device object 4090 * _scsih_add_device - creating sas device object
4012 * @ioc: per adapter object 4091 * @ioc: per adapter object
4013 * @handle: sas device handle 4092 * @handle: sas device handle
@@ -4045,6 +4124,8 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
4045 return -1; 4124 return -1;
4046 } 4125 }
4047 4126
4127 sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
4128
4048 /* check if device is present */ 4129 /* check if device is present */
4049 if (!(le16_to_cpu(sas_device_pg0.Flags) & 4130 if (!(le16_to_cpu(sas_device_pg0.Flags) &
4050 MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) { 4131 MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) {
@@ -4055,15 +4136,10 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
4055 return -1; 4136 return -1;
4056 } 4137 }
4057 4138
4058 /* check if there were any issus with discovery */ 4139 /* check if there were any issues with discovery */
4059 if (sas_device_pg0.AccessStatus == 4140 if (_scsih_check_access_status(ioc, sas_address, handle,
4060 MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED) { 4141 sas_device_pg0.AccessStatus))
4061 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
4062 ioc->name, __FILE__, __LINE__, __func__);
4063 printk(MPT2SAS_ERR_FMT "AccessStatus = 0x%02x\n",
4064 ioc->name, sas_device_pg0.AccessStatus);
4065 return -1; 4142 return -1;
4066 }
4067 4143
4068 /* check if this is end device */ 4144 /* check if this is end device */
4069 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); 4145 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
@@ -4073,17 +4149,14 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
4073 return -1; 4149 return -1;
4074 } 4150 }
4075 4151
4076 sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
4077 4152
4078 spin_lock_irqsave(&ioc->sas_device_lock, flags); 4153 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4079 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 4154 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
4080 sas_address); 4155 sas_address);
4081 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 4156 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4082 4157
4083 if (sas_device) { 4158 if (sas_device)
4084 _scsih_ublock_io_device(ioc, handle);
4085 return 0; 4159 return 0;
4086 }
4087 4160
4088 sas_device = kzalloc(sizeof(struct _sas_device), 4161 sas_device = kzalloc(sizeof(struct _sas_device),
4089 GFP_KERNEL); 4162 GFP_KERNEL);
@@ -4126,67 +4199,38 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
4126} 4199}
4127 4200
4128/** 4201/**
4129 * _scsih_remove_device - removing sas device object 4202 * _scsih_remove_pd_device - removing sas device pd object
4130 * @ioc: per adapter object 4203 * @ioc: per adapter object
4131 * @sas_device: the sas_device object 4204 * @sas_device_delete: the sas_device object
4132 * 4205 *
4206 * For hidden raid components, we do driver-fw handshake from
4207 * hotplug work threads.
4133 * Return nothing. 4208 * Return nothing.
4134 */ 4209 */
4135static void 4210static void
4136_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device 4211_scsih_remove_pd_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device
4137 *sas_device) 4212 sas_device)
4138{ 4213{
4139 struct MPT2SAS_TARGET *sas_target_priv_data;
4140 Mpi2SasIoUnitControlReply_t mpi_reply; 4214 Mpi2SasIoUnitControlReply_t mpi_reply;
4141 Mpi2SasIoUnitControlRequest_t mpi_request; 4215 Mpi2SasIoUnitControlRequest_t mpi_request;
4142 u16 device_handle, handle; 4216 u16 vol_handle, handle;
4143
4144 if (!sas_device)
4145 return;
4146 4217
4147 handle = sas_device->handle; 4218 handle = sas_device.handle;
4148 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle(0x%04x)," 4219 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle(0x%04x),"
4149 " sas_addr(0x%016llx)\n", ioc->name, __func__, handle, 4220 " sas_addr(0x%016llx)\n", ioc->name, __func__, handle,
4150 (unsigned long long) sas_device->sas_address)); 4221 (unsigned long long) sas_device.sas_address));
4151
4152 if (sas_device->starget && sas_device->starget->hostdata) {
4153 sas_target_priv_data = sas_device->starget->hostdata;
4154 sas_target_priv_data->deleted = 1;
4155 }
4156
4157 if (ioc->remove_host || ioc->shost_recovery || !handle)
4158 goto out;
4159 4222
4160 if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) { 4223 vol_handle = sas_device.volume_handle;
4161 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip " 4224 if (!vol_handle)
4162 "target_reset handle(0x%04x)\n", ioc->name, 4225 return;
4163 handle)); 4226 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset: "
4164 goto skip_tr; 4227 "handle(0x%04x)\n", ioc->name, vol_handle));
4165 } 4228 mpt2sas_scsih_issue_tm(ioc, vol_handle, 0, 0, 0,
4166 4229 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30, NULL);
4167 /* Target Reset to flush out all the outstanding IO */ 4230 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset "
4168 device_handle = (sas_device->hidden_raid_component) ? 4231 "done: handle(0x%04x)\n", ioc->name, vol_handle));
4169 sas_device->volume_handle : handle; 4232 if (ioc->shost_recovery)
4170 if (device_handle) { 4233 return;
4171 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset: "
4172 "handle(0x%04x)\n", ioc->name, device_handle));
4173 mutex_lock(&ioc->tm_cmds.mutex);
4174 mpt2sas_scsih_issue_tm(ioc, device_handle, 0,
4175 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 10);
4176 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
4177 mutex_unlock(&ioc->tm_cmds.mutex);
4178 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset "
4179 "done: handle(0x%04x)\n", ioc->name, device_handle));
4180 if (ioc->shost_recovery)
4181 goto out;
4182 }
4183 skip_tr:
4184
4185 if ((sas_device->state & MPTSAS_STATE_CNTRL_COMPLETE)) {
4186 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip "
4187 "sas_cntrl handle(0x%04x)\n", ioc->name, handle));
4188 goto out;
4189 }
4190 4234
4191 /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */ 4235 /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */
4192 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle" 4236 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle"
@@ -4194,34 +4238,68 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device
4194 memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); 4238 memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
4195 mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 4239 mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
4196 mpi_request.Operation = MPI2_SAS_OP_REMOVE_DEVICE; 4240 mpi_request.Operation = MPI2_SAS_OP_REMOVE_DEVICE;
4197 mpi_request.DevHandle = handle; 4241 mpi_request.DevHandle = cpu_to_le16(handle);
4198 mpi_request.VF_ID = 0; /* TODO */
4199 mpi_request.VP_ID = 0;
4200 if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, 4242 if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply,
4201 &mpi_request)) != 0) { 4243 &mpi_request)) != 0)
4202 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 4244 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
4203 ioc->name, __FILE__, __LINE__, __func__); 4245 ioc->name, __FILE__, __LINE__, __func__);
4204 }
4205 4246
4206 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: ioc_status" 4247 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: ioc_status"
4207 "(0x%04x), loginfo(0x%08x)\n", ioc->name, 4248 "(0x%04x), loginfo(0x%08x)\n", ioc->name,
4208 le16_to_cpu(mpi_reply.IOCStatus), 4249 le16_to_cpu(mpi_reply.IOCStatus),
4209 le32_to_cpu(mpi_reply.IOCLogInfo))); 4250 le32_to_cpu(mpi_reply.IOCLogInfo)));
4210 4251
4211 out: 4252 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit: handle(0x%04x),"
4253 " sas_addr(0x%016llx)\n", ioc->name, __func__, handle,
4254 (unsigned long long) sas_device.sas_address));
4255}
4212 4256
4213 _scsih_ublock_io_device(ioc, handle); 4257/**
4258 * _scsih_remove_device - removing sas device object
4259 * @ioc: per adapter object
4260 * @sas_device_delete: the sas_device object
4261 *
4262 * Return nothing.
4263 */
4264static void
4265_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc,
4266 struct _sas_device *sas_device)
4267{
4268 struct _sas_device sas_device_backup;
4269 struct MPT2SAS_TARGET *sas_target_priv_data;
4214 4270
4215 mpt2sas_transport_port_remove(ioc, sas_device->sas_address, 4271 if (!sas_device)
4216 sas_device->sas_address_parent); 4272 return;
4217 4273
4218 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" 4274 memcpy(&sas_device_backup, sas_device, sizeof(struct _sas_device));
4219 "(0x%016llx)\n", ioc->name, handle,
4220 (unsigned long long) sas_device->sas_address);
4221 _scsih_sas_device_remove(ioc, sas_device); 4275 _scsih_sas_device_remove(ioc, sas_device);
4222 4276
4223 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit: handle" 4277 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: "
4224 "(0x%04x)\n", ioc->name, __func__, handle)); 4278 "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
4279 sas_device_backup.handle, (unsigned long long)
4280 sas_device_backup.sas_address));
4281
4282 if (sas_device_backup.starget && sas_device_backup.starget->hostdata) {
4283 sas_target_priv_data = sas_device_backup.starget->hostdata;
4284 sas_target_priv_data->deleted = 1;
4285 }
4286
4287 if (sas_device_backup.hidden_raid_component)
4288 _scsih_remove_pd_device(ioc, sas_device_backup);
4289
4290 _scsih_ublock_io_device(ioc, sas_device_backup.handle);
4291
4292 mpt2sas_transport_port_remove(ioc, sas_device_backup.sas_address,
4293 sas_device_backup.sas_address_parent);
4294
4295 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr"
4296 "(0x%016llx)\n", ioc->name, sas_device_backup.handle,
4297 (unsigned long long) sas_device_backup.sas_address);
4298
4299 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit: "
4300 "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
4301 sas_device_backup.handle, (unsigned long long)
4302 sas_device_backup.sas_address));
4225} 4303}
4226 4304
4227#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4305#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
@@ -4331,7 +4409,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4331 _scsih_sas_topology_change_event_debug(ioc, event_data); 4409 _scsih_sas_topology_change_event_debug(ioc, event_data);
4332#endif 4410#endif
4333 4411
4334 if (ioc->shost_recovery) 4412 if (ioc->shost_recovery || ioc->remove_host)
4335 return; 4413 return;
4336 4414
4337 if (!ioc->sas_hba.num_phys) 4415 if (!ioc->sas_hba.num_phys)
@@ -4370,7 +4448,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4370 "expander event\n", ioc->name)); 4448 "expander event\n", ioc->name));
4371 return; 4449 return;
4372 } 4450 }
4373 if (ioc->shost_recovery) 4451 if (ioc->shost_recovery || ioc->remove_host)
4374 return; 4452 return;
4375 phy_number = event_data->StartPhyNum + i; 4453 phy_number = event_data->StartPhyNum + i;
4376 reason_code = event_data->PHY[i].PhyStatus & 4454 reason_code = event_data->PHY[i].PhyStatus &
@@ -4393,8 +4471,10 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4393 mpt2sas_transport_update_links(ioc, sas_address, 4471 mpt2sas_transport_update_links(ioc, sas_address,
4394 handle, phy_number, link_rate); 4472 handle, phy_number, link_rate);
4395 4473
4396 if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5) 4474 if (link_rate < MPI2_SAS_NEG_LINK_RATE_1_5)
4397 _scsih_ublock_io_device(ioc, handle); 4475 break;
4476
4477 _scsih_check_device(ioc, handle);
4398 break; 4478 break;
4399 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 4479 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
4400 4480
@@ -4520,10 +4600,10 @@ _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc,
4520 event_data); 4600 event_data);
4521#endif 4601#endif
4522 4602
4523 if (!(event_data->ReasonCode == 4603 if (event_data->ReasonCode !=
4524 MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET && 4604 MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
4525 event_data->ReasonCode == 4605 event_data->ReasonCode !=
4526 MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET)) 4606 MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET)
4527 return; 4607 return;
4528 4608
4529 spin_lock_irqsave(&ioc->sas_device_lock, flags); 4609 spin_lock_irqsave(&ioc->sas_device_lock, flags);
@@ -4630,7 +4710,6 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
4630 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 4710 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name,
4631 __func__)); 4711 __func__));
4632 4712
4633 mutex_lock(&ioc->tm_cmds.mutex);
4634 termination_count = 0; 4713 termination_count = 0;
4635 query_count = 0; 4714 query_count = 0;
4636 mpi_reply = ioc->tm_cmds.reply; 4715 mpi_reply = ioc->tm_cmds.reply;
@@ -4654,8 +4733,8 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
4654 lun = sas_device_priv_data->lun; 4733 lun = sas_device_priv_data->lun;
4655 query_count++; 4734 query_count++;
4656 4735
4657 mpt2sas_scsih_issue_tm(ioc, handle, lun, 4736 mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun,
4658 MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30); 4737 MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, NULL);
4659 ioc->tm_cmds.status = MPT2_CMD_NOT_USED; 4738 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
4660 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) 4739 ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
4661 & MPI2_IOCSTATUS_MASK; 4740 & MPI2_IOCSTATUS_MASK;
@@ -4666,13 +4745,11 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
4666 MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC)) 4745 MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
4667 continue; 4746 continue;
4668 4747
4669 mpt2sas_scsih_issue_tm(ioc, handle, lun, 4748 mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun,
4670 MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, 0, 30); 4749 MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, 0, 30, NULL);
4671 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
4672 termination_count += le32_to_cpu(mpi_reply->TerminationCount); 4750 termination_count += le32_to_cpu(mpi_reply->TerminationCount);
4673 } 4751 }
4674 ioc->broadcast_aen_busy = 0; 4752 ioc->broadcast_aen_busy = 0;
4675 mutex_unlock(&ioc->tm_cmds.mutex);
4676 4753
4677 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT 4754 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT
4678 "%s - exit, query_count = %d termination_count = %d\n", 4755 "%s - exit, query_count = %d termination_count = %d\n",
@@ -5442,6 +5519,26 @@ _scsih_task_set_full(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
5442} 5519}
5443 5520
5444/** 5521/**
5522 * _scsih_prep_device_scan - initialize parameters prior to device scan
5523 * @ioc: per adapter object
5524 *
5525 * Set the deleted flag prior to device scan. If the device is found during
5526 * the scan, then we clear the deleted flag.
5527 */
5528static void
5529_scsih_prep_device_scan(struct MPT2SAS_ADAPTER *ioc)
5530{
5531 struct MPT2SAS_DEVICE *sas_device_priv_data;
5532 struct scsi_device *sdev;
5533
5534 shost_for_each_device(sdev, ioc->shost) {
5535 sas_device_priv_data = sdev->hostdata;
5536 if (sas_device_priv_data && sas_device_priv_data->sas_target)
5537 sas_device_priv_data->sas_target->deleted = 1;
5538 }
5539}
5540
5541/**
5445 * _scsih_mark_responding_sas_device - mark a sas_devices as responding 5542 * _scsih_mark_responding_sas_device - mark a sas_devices as responding
5446 * @ioc: per adapter object 5543 * @ioc: per adapter object
5447 * @sas_address: sas address 5544 * @sas_address: sas address
@@ -5467,10 +5564,13 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
5467 if (sas_device->sas_address == sas_address && 5564 if (sas_device->sas_address == sas_address &&
5468 sas_device->slot == slot && sas_device->starget) { 5565 sas_device->slot == slot && sas_device->starget) {
5469 sas_device->responding = 1; 5566 sas_device->responding = 1;
5470 sas_device->state = 0;
5471 starget = sas_device->starget; 5567 starget = sas_device->starget;
5472 sas_target_priv_data = starget->hostdata; 5568 if (starget && starget->hostdata) {
5473 sas_target_priv_data->tm_busy = 0; 5569 sas_target_priv_data = starget->hostdata;
5570 sas_target_priv_data->tm_busy = 0;
5571 sas_target_priv_data->deleted = 0;
5572 } else
5573 sas_target_priv_data = NULL;
5474 starget_printk(KERN_INFO, sas_device->starget, 5574 starget_printk(KERN_INFO, sas_device->starget,
5475 "handle(0x%04x), sas_addr(0x%016llx), enclosure " 5575 "handle(0x%04x), sas_addr(0x%016llx), enclosure "
5476 "logical id(0x%016llx), slot(%d)\n", handle, 5576 "logical id(0x%016llx), slot(%d)\n", handle,
@@ -5483,7 +5583,8 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
5483 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", 5583 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
5484 sas_device->handle); 5584 sas_device->handle);
5485 sas_device->handle = handle; 5585 sas_device->handle = handle;
5486 sas_target_priv_data->handle = handle; 5586 if (sas_target_priv_data)
5587 sas_target_priv_data->handle = handle;
5487 goto out; 5588 goto out;
5488 } 5589 }
5489 } 5590 }
@@ -5558,6 +5659,12 @@ _scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid,
5558 spin_lock_irqsave(&ioc->raid_device_lock, flags); 5659 spin_lock_irqsave(&ioc->raid_device_lock, flags);
5559 list_for_each_entry(raid_device, &ioc->raid_device_list, list) { 5660 list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
5560 if (raid_device->wwid == wwid && raid_device->starget) { 5661 if (raid_device->wwid == wwid && raid_device->starget) {
5662 starget = raid_device->starget;
5663 if (starget && starget->hostdata) {
5664 sas_target_priv_data = starget->hostdata;
5665 sas_target_priv_data->deleted = 0;
5666 } else
5667 sas_target_priv_data = NULL;
5561 raid_device->responding = 1; 5668 raid_device->responding = 1;
5562 starget_printk(KERN_INFO, raid_device->starget, 5669 starget_printk(KERN_INFO, raid_device->starget,
5563 "handle(0x%04x), wwid(0x%016llx)\n", handle, 5670 "handle(0x%04x), wwid(0x%016llx)\n", handle,
@@ -5567,9 +5674,8 @@ _scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid,
5567 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", 5674 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
5568 raid_device->handle); 5675 raid_device->handle);
5569 raid_device->handle = handle; 5676 raid_device->handle = handle;
5570 starget = raid_device->starget; 5677 if (sas_target_priv_data)
5571 sas_target_priv_data = starget->hostdata; 5678 sas_target_priv_data->handle = handle;
5572 sas_target_priv_data->handle = handle;
5573 goto out; 5679 goto out;
5574 } 5680 }
5575 } 5681 }
@@ -5694,13 +5800,13 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc)
5694} 5800}
5695 5801
5696/** 5802/**
5697 * _scsih_remove_unresponding_devices - removing unresponding devices 5803 * _scsih_remove_unresponding_sas_devices - removing unresponding devices
5698 * @ioc: per adapter object 5804 * @ioc: per adapter object
5699 * 5805 *
5700 * Return nothing. 5806 * Return nothing.
5701 */ 5807 */
5702static void 5808static void
5703_scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc) 5809_scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
5704{ 5810{
5705 struct _sas_device *sas_device, *sas_device_next; 5811 struct _sas_device *sas_device, *sas_device_next;
5706 struct _sas_node *sas_expander; 5812 struct _sas_node *sas_expander;
@@ -5722,8 +5828,6 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
5722 (unsigned long long) 5828 (unsigned long long)
5723 sas_device->enclosure_logical_id, 5829 sas_device->enclosure_logical_id,
5724 sas_device->slot); 5830 sas_device->slot);
5725 /* invalidate the device handle */
5726 sas_device->handle = 0;
5727 _scsih_remove_device(ioc, sas_device); 5831 _scsih_remove_device(ioc, sas_device);
5728 } 5832 }
5729 5833
@@ -5774,32 +5878,33 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
5774 case MPT2_IOC_PRE_RESET: 5878 case MPT2_IOC_PRE_RESET:
5775 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 5879 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
5776 "MPT2_IOC_PRE_RESET\n", ioc->name, __func__)); 5880 "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
5777 _scsih_fw_event_off(ioc);
5778 break; 5881 break;
5779 case MPT2_IOC_AFTER_RESET: 5882 case MPT2_IOC_AFTER_RESET:
5780 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 5883 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
5781 "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__)); 5884 "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
5885 if (ioc->scsih_cmds.status & MPT2_CMD_PENDING) {
5886 ioc->scsih_cmds.status |= MPT2_CMD_RESET;
5887 mpt2sas_base_free_smid(ioc, ioc->scsih_cmds.smid);
5888 complete(&ioc->scsih_cmds.done);
5889 }
5782 if (ioc->tm_cmds.status & MPT2_CMD_PENDING) { 5890 if (ioc->tm_cmds.status & MPT2_CMD_PENDING) {
5783 ioc->tm_cmds.status |= MPT2_CMD_RESET; 5891 ioc->tm_cmds.status |= MPT2_CMD_RESET;
5784 mpt2sas_base_free_smid(ioc, ioc->tm_cmds.smid); 5892 mpt2sas_base_free_smid(ioc, ioc->tm_cmds.smid);
5785 complete(&ioc->tm_cmds.done); 5893 complete(&ioc->tm_cmds.done);
5786 } 5894 }
5787 _scsih_fw_event_on(ioc); 5895 _scsih_fw_event_cleanup_queue(ioc);
5788 _scsih_flush_running_cmds(ioc); 5896 _scsih_flush_running_cmds(ioc);
5897 _scsih_queue_rescan(ioc);
5789 break; 5898 break;
5790 case MPT2_IOC_DONE_RESET: 5899 case MPT2_IOC_DONE_RESET:
5791 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 5900 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
5792 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); 5901 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
5793 _scsih_sas_host_refresh(ioc); 5902 _scsih_sas_host_refresh(ioc);
5903 _scsih_prep_device_scan(ioc);
5794 _scsih_search_responding_sas_devices(ioc); 5904 _scsih_search_responding_sas_devices(ioc);
5795 _scsih_search_responding_raid_devices(ioc); 5905 _scsih_search_responding_raid_devices(ioc);
5796 _scsih_search_responding_expanders(ioc); 5906 _scsih_search_responding_expanders(ioc);
5797 break; 5907 break;
5798 case MPT2_IOC_RUNNING:
5799 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
5800 "MPT2_IOC_RUNNING\n", ioc->name, __func__));
5801 _scsih_remove_unresponding_devices(ioc);
5802 break;
5803 } 5908 }
5804} 5909}
5805 5910
@@ -5815,21 +5920,28 @@ static void
5815_firmware_event_work(struct work_struct *work) 5920_firmware_event_work(struct work_struct *work)
5816{ 5921{
5817 struct fw_event_work *fw_event = container_of(work, 5922 struct fw_event_work *fw_event = container_of(work,
5818 struct fw_event_work, work); 5923 struct fw_event_work, delayed_work.work);
5819 unsigned long flags; 5924 unsigned long flags;
5820 struct MPT2SAS_ADAPTER *ioc = fw_event->ioc; 5925 struct MPT2SAS_ADAPTER *ioc = fw_event->ioc;
5821 5926
5822 /* the queue is being flushed so ignore this event */ 5927 /* the queue is being flushed so ignore this event */
5823 spin_lock_irqsave(&ioc->fw_event_lock, flags); 5928 if (ioc->remove_host || fw_event->cancel_pending_work) {
5824 if (ioc->fw_events_off || ioc->remove_host) {
5825 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5826 _scsih_fw_event_free(ioc, fw_event); 5929 _scsih_fw_event_free(ioc, fw_event);
5827 return; 5930 return;
5828 } 5931 }
5829 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5830 5932
5831 if (ioc->shost_recovery) { 5933 if (fw_event->event == MPT2SAS_RESCAN_AFTER_HOST_RESET) {
5832 _scsih_fw_event_requeue(ioc, fw_event, 1000); 5934 _scsih_fw_event_free(ioc, fw_event);
5935 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
5936 if (ioc->shost_recovery) {
5937 init_completion(&ioc->shost_recovery_done);
5938 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
5939 flags);
5940 wait_for_completion(&ioc->shost_recovery_done);
5941 } else
5942 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
5943 flags);
5944 _scsih_remove_unresponding_sas_devices(ioc);
5833 return; 5945 return;
5834 } 5946 }
5835 5947
@@ -5891,16 +6003,12 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
5891{ 6003{
5892 struct fw_event_work *fw_event; 6004 struct fw_event_work *fw_event;
5893 Mpi2EventNotificationReply_t *mpi_reply; 6005 Mpi2EventNotificationReply_t *mpi_reply;
5894 unsigned long flags;
5895 u16 event; 6006 u16 event;
6007 u16 sz;
5896 6008
5897 /* events turned off due to host reset or driver unloading */ 6009 /* events turned off due to host reset or driver unloading */
5898 spin_lock_irqsave(&ioc->fw_event_lock, flags); 6010 if (ioc->remove_host)
5899 if (ioc->fw_events_off || ioc->remove_host) {
5900 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5901 return 1; 6011 return 1;
5902 }
5903 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5904 6012
5905 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 6013 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
5906 event = le16_to_cpu(mpi_reply->Event); 6014 event = le16_to_cpu(mpi_reply->Event);
@@ -5947,8 +6055,8 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
5947 ioc->name, __FILE__, __LINE__, __func__); 6055 ioc->name, __FILE__, __LINE__, __func__);
5948 return 1; 6056 return 1;
5949 } 6057 }
5950 fw_event->event_data = 6058 sz = le16_to_cpu(mpi_reply->EventDataLength) * 4;
5951 kzalloc(mpi_reply->EventDataLength*4, GFP_ATOMIC); 6059 fw_event->event_data = kzalloc(sz, GFP_ATOMIC);
5952 if (!fw_event->event_data) { 6060 if (!fw_event->event_data) {
5953 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 6061 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
5954 ioc->name, __FILE__, __LINE__, __func__); 6062 ioc->name, __FILE__, __LINE__, __func__);
@@ -5957,7 +6065,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
5957 } 6065 }
5958 6066
5959 memcpy(fw_event->event_data, mpi_reply->EventData, 6067 memcpy(fw_event->event_data, mpi_reply->EventData,
5960 mpi_reply->EventDataLength*4); 6068 sz);
5961 fw_event->ioc = ioc; 6069 fw_event->ioc = ioc;
5962 fw_event->VF_ID = mpi_reply->VF_ID; 6070 fw_event->VF_ID = mpi_reply->VF_ID;
5963 fw_event->VP_ID = mpi_reply->VP_ID; 6071 fw_event->VP_ID = mpi_reply->VP_ID;
@@ -6158,6 +6266,18 @@ _scsih_shutdown(struct pci_dev *pdev)
6158{ 6266{
6159 struct Scsi_Host *shost = pci_get_drvdata(pdev); 6267 struct Scsi_Host *shost = pci_get_drvdata(pdev);
6160 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); 6268 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
6269 struct workqueue_struct *wq;
6270 unsigned long flags;
6271
6272 ioc->remove_host = 1;
6273 _scsih_fw_event_cleanup_queue(ioc);
6274
6275 spin_lock_irqsave(&ioc->fw_event_lock, flags);
6276 wq = ioc->firmware_event_thread;
6277 ioc->firmware_event_thread = NULL;
6278 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
6279 if (wq)
6280 destroy_workqueue(wq);
6161 6281
6162 _scsih_ir_shutdown(ioc); 6282 _scsih_ir_shutdown(ioc);
6163 mpt2sas_base_detach(ioc); 6283 mpt2sas_base_detach(ioc);
@@ -6184,7 +6304,7 @@ _scsih_remove(struct pci_dev *pdev)
6184 unsigned long flags; 6304 unsigned long flags;
6185 6305
6186 ioc->remove_host = 1; 6306 ioc->remove_host = 1;
6187 _scsih_fw_event_off(ioc); 6307 _scsih_fw_event_cleanup_queue(ioc);
6188 6308
6189 spin_lock_irqsave(&ioc->fw_event_lock, flags); 6309 spin_lock_irqsave(&ioc->fw_event_lock, flags);
6190 wq = ioc->firmware_event_thread; 6310 wq = ioc->firmware_event_thread;
@@ -6557,6 +6677,122 @@ _scsih_resume(struct pci_dev *pdev)
6557} 6677}
6558#endif /* CONFIG_PM */ 6678#endif /* CONFIG_PM */
6559 6679
6680/**
6681 * _scsih_pci_error_detected - Called when a PCI error is detected.
6682 * @pdev: PCI device struct
6683 * @state: PCI channel state
6684 *
6685 * Description: Called when a PCI error is detected.
6686 *
6687 * Return value:
6688 * PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT
6689 */
6690static pci_ers_result_t
6691_scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
6692{
6693 struct Scsi_Host *shost = pci_get_drvdata(pdev);
6694 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
6695
6696 printk(MPT2SAS_INFO_FMT "PCI error: detected callback, state(%d)!!\n",
6697 ioc->name, state);
6698
6699 switch (state) {
6700 case pci_channel_io_normal:
6701 return PCI_ERS_RESULT_CAN_RECOVER;
6702 case pci_channel_io_frozen:
6703 scsi_block_requests(ioc->shost);
6704 mpt2sas_base_stop_watchdog(ioc);
6705 mpt2sas_base_free_resources(ioc);
6706 return PCI_ERS_RESULT_NEED_RESET;
6707 case pci_channel_io_perm_failure:
6708 _scsih_remove(pdev);
6709 return PCI_ERS_RESULT_DISCONNECT;
6710 }
6711 return PCI_ERS_RESULT_NEED_RESET;
6712}
6713
6714/**
6715 * _scsih_pci_slot_reset - Called when PCI slot has been reset.
6716 * @pdev: PCI device struct
6717 *
6718 * Description: This routine is called by the pci error recovery
6719 * code after the PCI slot has been reset, just before we
6720 * should resume normal operations.
6721 */
6722static pci_ers_result_t
6723_scsih_pci_slot_reset(struct pci_dev *pdev)
6724{
6725 struct Scsi_Host *shost = pci_get_drvdata(pdev);
6726 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
6727 int rc;
6728
6729 printk(MPT2SAS_INFO_FMT "PCI error: slot reset callback!!\n",
6730 ioc->name);
6731
6732 ioc->pdev = pdev;
6733 rc = mpt2sas_base_map_resources(ioc);
6734 if (rc)
6735 return PCI_ERS_RESULT_DISCONNECT;
6736
6737
6738 rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
6739 FORCE_BIG_HAMMER);
6740
6741 printk(MPT2SAS_WARN_FMT "hard reset: %s\n", ioc->name,
6742 (rc == 0) ? "success" : "failed");
6743
6744 if (!rc)
6745 return PCI_ERS_RESULT_RECOVERED;
6746 else
6747 return PCI_ERS_RESULT_DISCONNECT;
6748}
6749
6750/**
6751 * _scsih_pci_resume() - resume normal ops after PCI reset
6752 * @pdev: pointer to PCI device
6753 *
6754 * Called when the error recovery driver tells us that its
6755 * OK to resume normal operation. Use completion to allow
6756 * halted scsi ops to resume.
6757 */
6758static void
6759_scsih_pci_resume(struct pci_dev *pdev)
6760{
6761 struct Scsi_Host *shost = pci_get_drvdata(pdev);
6762 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
6763
6764 printk(MPT2SAS_INFO_FMT "PCI error: resume callback!!\n", ioc->name);
6765
6766 pci_cleanup_aer_uncorrect_error_status(pdev);
6767 mpt2sas_base_start_watchdog(ioc);
6768 scsi_unblock_requests(ioc->shost);
6769}
6770
6771/**
6772 * _scsih_pci_mmio_enabled - Enable MMIO and dump debug registers
6773 * @pdev: pointer to PCI device
6774 */
6775static pci_ers_result_t
6776_scsih_pci_mmio_enabled(struct pci_dev *pdev)
6777{
6778 struct Scsi_Host *shost = pci_get_drvdata(pdev);
6779 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
6780
6781 printk(MPT2SAS_INFO_FMT "PCI error: mmio enabled callback!!\n",
6782 ioc->name);
6783
6784 /* TODO - dump whatever for debugging purposes */
6785
6786 /* Request a slot reset. */
6787 return PCI_ERS_RESULT_NEED_RESET;
6788}
6789
6790static struct pci_error_handlers _scsih_err_handler = {
6791 .error_detected = _scsih_pci_error_detected,
6792 .mmio_enabled = _scsih_pci_mmio_enabled,
6793 .slot_reset = _scsih_pci_slot_reset,
6794 .resume = _scsih_pci_resume,
6795};
6560 6796
6561static struct pci_driver scsih_driver = { 6797static struct pci_driver scsih_driver = {
6562 .name = MPT2SAS_DRIVER_NAME, 6798 .name = MPT2SAS_DRIVER_NAME,
@@ -6564,6 +6800,7 @@ static struct pci_driver scsih_driver = {
6564 .probe = _scsih_probe, 6800 .probe = _scsih_probe,
6565 .remove = __devexit_p(_scsih_remove), 6801 .remove = __devexit_p(_scsih_remove),
6566 .shutdown = _scsih_shutdown, 6802 .shutdown = _scsih_shutdown,
6803 .err_handler = &_scsih_err_handler,
6567#ifdef CONFIG_PM 6804#ifdef CONFIG_PM
6568 .suspend = _scsih_suspend, 6805 .suspend = _scsih_suspend,
6569 .resume = _scsih_resume, 6806 .resume = _scsih_resume,
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index bd7ca2b49f81..2727c3b65104 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -2,7 +2,7 @@
2 * SAS Transport Layer for MPT (Message Passing Technology) based controllers 2 * SAS Transport Layer for MPT (Message Passing Technology) based controllers
3 * 3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_transport.c 4 * This code is based on drivers/scsi/mpt2sas/mpt2_transport.c
5 * Copyright (C) 2007-2009 LSI Corporation 5 * Copyright (C) 2007-2010 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com) 6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
@@ -465,6 +465,85 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
465 return rc; 465 return rc;
466} 466}
467 467
468
469/**
470 * _transport_delete_duplicate_port - (see below description)
471 * @ioc: per adapter object
472 * @sas_node: sas node object (either expander or sas host)
473 * @sas_address: sas address of device being added
474 * @phy_num: phy number
475 *
476 * This function is called when attempting to add a new port that is claiming
477 * the same phy resources already in use by another port. If we don't release
478 * the claimed phy resources, the sas transport layer will hang from the BUG
479 * in sas_port_add_phy.
480 *
481 * The reason we would hit this issue is becuase someone is changing the
482 * sas address of a device on the fly, meanwhile controller firmware sends
483 * EVENTs out of order when removing the previous instance of the device.
484 */
485static void
486_transport_delete_duplicate_port(struct MPT2SAS_ADAPTER *ioc,
487 struct _sas_node *sas_node, u64 sas_address, int phy_num)
488{
489 struct _sas_port *mpt2sas_port, *mpt2sas_port_duplicate;
490 struct _sas_phy *mpt2sas_phy;
491
492 printk(MPT2SAS_ERR_FMT "new device located at sas_addr(0x%016llx), "
493 "phy_id(%d)\n", ioc->name, (unsigned long long)sas_address,
494 phy_num);
495
496 mpt2sas_port_duplicate = NULL;
497 list_for_each_entry(mpt2sas_port, &sas_node->sas_port_list, port_list) {
498 dev_printk(KERN_ERR, &mpt2sas_port->port->dev,
499 "existing device at sas_addr(0x%016llx), num_phys(%d)\n",
500 (unsigned long long)
501 mpt2sas_port->remote_identify.sas_address,
502 mpt2sas_port->num_phys);
503 list_for_each_entry(mpt2sas_phy, &mpt2sas_port->phy_list,
504 port_siblings) {
505 dev_printk(KERN_ERR, &mpt2sas_phy->phy->dev,
506 "phy_number(%d)\n", mpt2sas_phy->phy_id);
507 if (mpt2sas_phy->phy_id == phy_num)
508 mpt2sas_port_duplicate = mpt2sas_port;
509 }
510 }
511
512 if (!mpt2sas_port_duplicate)
513 return;
514
515 dev_printk(KERN_ERR, &mpt2sas_port_duplicate->port->dev,
516 "deleting duplicate device at sas_addr(0x%016llx), phy(%d)!!!!\n",
517 (unsigned long long)
518 mpt2sas_port_duplicate->remote_identify.sas_address, phy_num);
519 ioc->logging_level |= MPT_DEBUG_TRANSPORT;
520 mpt2sas_transport_port_remove(ioc,
521 mpt2sas_port_duplicate->remote_identify.sas_address,
522 sas_node->sas_address);
523 ioc->logging_level &= ~MPT_DEBUG_TRANSPORT;
524}
525
526/**
527 * _transport_sanity_check - sanity check when adding a new port
528 * @ioc: per adapter object
529 * @sas_node: sas node object (either expander or sas host)
530 * @sas_address: sas address of device being added
531 *
532 * See the explanation above from _transport_delete_duplicate_port
533 */
534static void
535_transport_sanity_check(struct MPT2SAS_ADAPTER *ioc, struct _sas_node *sas_node,
536 u64 sas_address)
537{
538 int i;
539
540 for (i = 0; i < sas_node->num_phys; i++)
541 if (sas_node->phy[i].remote_identify.sas_address == sas_address)
542 if (sas_node->phy[i].phy_belongs_to_port)
543 _transport_delete_duplicate_port(ioc, sas_node,
544 sas_address, i);
545}
546
468/** 547/**
469 * mpt2sas_transport_port_add - insert port to the list 548 * mpt2sas_transport_port_add - insert port to the list
470 * @ioc: per adapter object 549 * @ioc: per adapter object
@@ -522,6 +601,9 @@ mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle,
522 goto out_fail; 601 goto out_fail;
523 } 602 }
524 603
604 _transport_sanity_check(ioc, sas_node,
605 mpt2sas_port->remote_identify.sas_address);
606
525 for (i = 0; i < sas_node->num_phys; i++) { 607 for (i = 0; i < sas_node->num_phys; i++) {
526 if (sas_node->phy[i].remote_identify.sas_address != 608 if (sas_node->phy[i].remote_identify.sas_address !=
527 mpt2sas_port->remote_identify.sas_address) 609 mpt2sas_port->remote_identify.sas_address)
@@ -553,6 +635,7 @@ mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle,
553 mpt2sas_port->remote_identify.sas_address, 635 mpt2sas_port->remote_identify.sas_address,
554 mpt2sas_phy->phy_id); 636 mpt2sas_phy->phy_id);
555 sas_port_add_phy(port, mpt2sas_phy->phy); 637 sas_port_add_phy(port, mpt2sas_phy->phy);
638 mpt2sas_phy->phy_belongs_to_port = 1;
556 } 639 }
557 640
558 mpt2sas_port->port = port; 641 mpt2sas_port->port = port;
@@ -651,6 +734,7 @@ mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
651 (unsigned long long) 734 (unsigned long long)
652 mpt2sas_port->remote_identify.sas_address, 735 mpt2sas_port->remote_identify.sas_address,
653 mpt2sas_phy->phy_id); 736 mpt2sas_phy->phy_id);
737 mpt2sas_phy->phy_belongs_to_port = 0;
654 sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy); 738 sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy);
655 list_del(&mpt2sas_phy->port_siblings); 739 list_del(&mpt2sas_phy->port_siblings);
656 } 740 }
@@ -1341,7 +1425,8 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1341 memcpy(req->sense, mpi_reply, sizeof(*mpi_reply)); 1425 memcpy(req->sense, mpi_reply, sizeof(*mpi_reply));
1342 req->sense_len = sizeof(*mpi_reply); 1426 req->sense_len = sizeof(*mpi_reply);
1343 req->resid_len = 0; 1427 req->resid_len = 0;
1344 rsp->resid_len -= mpi_reply->ResponseDataLength; 1428 rsp->resid_len -=
1429 le16_to_cpu(mpi_reply->ResponseDataLength);
1345 } else { 1430 } else {
1346 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT 1431 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT
1347 "%s - no reply\n", ioc->name, __func__)); 1432 "%s - no reply\n", ioc->name, __func__));