aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_scsih.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c1055
1 files changed, 646 insertions, 409 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index be171ed682e..c5ff26a2a51 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,