aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_scsih.c
diff options
context:
space:
mode:
authorEric Moore <eric.moore@lsi.com>2009-05-18 15:00:45 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-05-23 16:44:17 -0400
commit993e0da7b767c0a7c1fd0079b16f3d28e6f25a48 (patch)
tree1e64897334fdeb48b71778c0eddbb929c04eb4c1 /drivers/scsi/mpt2sas/mpt2sas_scsih.c
parent3c621b3ee1432e7a2aca4a3b670b1d05f19ecf9c (diff)
[SCSI] mpt2sas: LUN Reset Support
Adding new eh_target_reset_handler for target reset. Change the eh_device_reset_handler so its sending MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, instead of MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET. Add new function _scsih_scsi_lookup_find_by_lun as a sanity check to insure I_T_L commands are completed upon completing lun reset. Signed-off-by: Eric Moore <eric.moore@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c111
1 files changed, 109 insertions, 2 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 5394f6196416..f45837630b24 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -884,6 +884,41 @@ _scsih_scsi_lookup_find_by_target(struct MPT2SAS_ADAPTER *ioc, int id,
884} 884}
885 885
886/** 886/**
887 * _scsih_scsi_lookup_find_by_lun - search for matching channel:id:lun
888 * @ioc: per adapter object
889 * @id: target id
890 * @lun: lun number
891 * @channel: channel
892 * Context: This function will acquire ioc->scsi_lookup_lock.
893 *
894 * This will search for a matching channel:id:lun in the scsi_lookup array,
895 * returning 1 if found.
896 */
897static u8
898_scsih_scsi_lookup_find_by_lun(struct MPT2SAS_ADAPTER *ioc, int id,
899 unsigned int lun, int channel)
900{
901 u8 found;
902 unsigned long flags;
903 int i;
904
905 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
906 found = 0;
907 for (i = 0 ; i < ioc->request_depth; i++) {
908 if (ioc->scsi_lookup[i].scmd &&
909 (ioc->scsi_lookup[i].scmd->device->id == id &&
910 ioc->scsi_lookup[i].scmd->device->channel == channel &&
911 ioc->scsi_lookup[i].scmd->device->lun == lun)) {
912 found = 1;
913 goto out;
914 }
915 }
916 out:
917 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
918 return found;
919}
920
921/**
887 * _scsih_get_chain_buffer_dma - obtain block of chains (dma address) 922 * _scsih_get_chain_buffer_dma - obtain block of chains (dma address)
888 * @ioc: per adapter object 923 * @ioc: per adapter object
889 * @smid: system request message index 924 * @smid: system request message index
@@ -1889,7 +1924,6 @@ scsih_abort(struct scsi_cmnd *scmd)
1889 return r; 1924 return r;
1890} 1925}
1891 1926
1892
1893/** 1927/**
1894 * scsih_dev_reset - eh threads main device reset routine 1928 * scsih_dev_reset - eh threads main device reset routine
1895 * @sdev: scsi device struct 1929 * @sdev: scsi device struct
@@ -1906,7 +1940,7 @@ scsih_dev_reset(struct scsi_cmnd *scmd)
1906 u16 handle; 1940 u16 handle;
1907 int r; 1941 int r;
1908 1942
1909 printk(MPT2SAS_INFO_FMT "attempting target reset! scmd(%p)\n", 1943 printk(MPT2SAS_INFO_FMT "attempting device reset! scmd(%p)\n",
1910 ioc->name, scmd); 1944 ioc->name, scmd);
1911 scsi_print_command(scmd); 1945 scsi_print_command(scmd);
1912 1946
@@ -1941,6 +1975,78 @@ scsih_dev_reset(struct scsi_cmnd *scmd)
1941 1975
1942 mutex_lock(&ioc->tm_cmds.mutex); 1976 mutex_lock(&ioc->tm_cmds.mutex);
1943 mpt2sas_scsih_issue_tm(ioc, handle, 0, 1977 mpt2sas_scsih_issue_tm(ioc, handle, 0,
1978 MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, scmd->device->lun,
1979 30);
1980
1981 /*
1982 * sanity check see whether all commands to this device been
1983 * completed
1984 */
1985 if (_scsih_scsi_lookup_find_by_lun(ioc, scmd->device->id,
1986 scmd->device->lun, scmd->device->channel))
1987 r = FAILED;
1988 else
1989 r = SUCCESS;
1990 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
1991 mutex_unlock(&ioc->tm_cmds.mutex);
1992
1993 out:
1994 printk(MPT2SAS_INFO_FMT "device reset: %s scmd(%p)\n",
1995 ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
1996 return r;
1997}
1998
1999/**
2000 * scsih_target_reset - eh threads main target reset routine
2001 * @sdev: scsi device struct
2002 *
2003 * Returns SUCCESS if command aborted else FAILED
2004 */
2005static int
2006scsih_target_reset(struct scsi_cmnd *scmd)
2007{
2008 struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
2009 struct MPT2SAS_DEVICE *sas_device_priv_data;
2010 struct _sas_device *sas_device;
2011 unsigned long flags;
2012 u16 handle;
2013 int r;
2014
2015 printk(MPT2SAS_INFO_FMT "attempting target reset! scmd(%p)\n",
2016 ioc->name, scmd);
2017 scsi_print_command(scmd);
2018
2019 sas_device_priv_data = scmd->device->hostdata;
2020 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
2021 printk(MPT2SAS_INFO_FMT "target been deleted! scmd(%p)\n",
2022 ioc->name, scmd);
2023 scmd->result = DID_NO_CONNECT << 16;
2024 scmd->scsi_done(scmd);
2025 r = SUCCESS;
2026 goto out;
2027 }
2028
2029 /* for hidden raid components obtain the volume_handle */
2030 handle = 0;
2031 if (sas_device_priv_data->sas_target->flags &
2032 MPT_TARGET_FLAGS_RAID_COMPONENT) {
2033 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2034 sas_device = _scsih_sas_device_find_by_handle(ioc,
2035 sas_device_priv_data->sas_target->handle);
2036 if (sas_device)
2037 handle = sas_device->volume_handle;
2038 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2039 } else
2040 handle = sas_device_priv_data->sas_target->handle;
2041
2042 if (!handle) {
2043 scmd->result = DID_RESET << 16;
2044 r = FAILED;
2045 goto out;
2046 }
2047
2048 mutex_lock(&ioc->tm_cmds.mutex);
2049 mpt2sas_scsih_issue_tm(ioc, handle, 0,
1944 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30); 2050 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30);
1945 2051
1946 /* 2052 /*
@@ -5255,6 +5361,7 @@ static struct scsi_host_template scsih_driver_template = {
5255 .change_queue_type = scsih_change_queue_type, 5361 .change_queue_type = scsih_change_queue_type,
5256 .eh_abort_handler = scsih_abort, 5362 .eh_abort_handler = scsih_abort,
5257 .eh_device_reset_handler = scsih_dev_reset, 5363 .eh_device_reset_handler = scsih_dev_reset,
5364 .eh_target_reset_handler = scsih_target_reset,
5258 .eh_host_reset_handler = scsih_host_reset, 5365 .eh_host_reset_handler = scsih_host_reset,
5259 .bios_param = scsih_bios_param, 5366 .bios_param = scsih_bios_param,
5260 .can_queue = 1, 5367 .can_queue = 1,