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.c153
1 files changed, 138 insertions, 15 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 61199759f8d1..afd3b82f7cd6 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -2384,7 +2384,6 @@ _scsih_fw_event_cleanup_queue(struct MPT2SAS_ADAPTER *ioc)
2384 } 2384 }
2385} 2385}
2386 2386
2387
2388/** 2387/**
2389 * _scsih_ublock_io_device - set the device state to SDEV_RUNNING 2388 * _scsih_ublock_io_device - set the device state to SDEV_RUNNING
2390 * @ioc: per adapter object 2389 * @ioc: per adapter object
@@ -3918,6 +3917,134 @@ _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
3918} 3917}
3919 3918
3920/** 3919/**
3920 * _scsih_check_access_status - check access flags
3921 * @ioc: per adapter object
3922 * @sas_address: sas address
3923 * @handle: sas device handle
3924 * @access_flags: errors returned during discovery of the device
3925 *
3926 * Return 0 for success, else failure
3927 */
3928static u8
3929_scsih_check_access_status(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
3930 u16 handle, u8 access_status)
3931{
3932 u8 rc = 1;
3933 char *desc = NULL;
3934
3935 switch (access_status) {
3936 case MPI2_SAS_DEVICE0_ASTATUS_NO_ERRORS:
3937 case MPI2_SAS_DEVICE0_ASTATUS_SATA_NEEDS_INITIALIZATION:
3938 rc = 0;
3939 break;
3940 case MPI2_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED:
3941 desc = "sata capability failed";
3942 break;
3943 case MPI2_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT:
3944 desc = "sata affiliation conflict";
3945 break;
3946 case MPI2_SAS_DEVICE0_ASTATUS_ROUTE_NOT_ADDRESSABLE:
3947 desc = "route not addressable";
3948 break;
3949 case MPI2_SAS_DEVICE0_ASTATUS_SMP_ERROR_NOT_ADDRESSABLE:
3950 desc = "smp error not addressable";
3951 break;
3952 case MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED:
3953 desc = "device blocked";
3954 break;
3955 case MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED:
3956 case MPI2_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN:
3957 case MPI2_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT:
3958 case MPI2_SAS_DEVICE0_ASTATUS_SIF_DIAG:
3959 case MPI2_SAS_DEVICE0_ASTATUS_SIF_IDENTIFICATION:
3960 case MPI2_SAS_DEVICE0_ASTATUS_SIF_CHECK_POWER:
3961 case MPI2_SAS_DEVICE0_ASTATUS_SIF_PIO_SN:
3962 case MPI2_SAS_DEVICE0_ASTATUS_SIF_MDMA_SN:
3963 case MPI2_SAS_DEVICE0_ASTATUS_SIF_UDMA_SN:
3964 case MPI2_SAS_DEVICE0_ASTATUS_SIF_ZONING_VIOLATION:
3965 case MPI2_SAS_DEVICE0_ASTATUS_SIF_NOT_ADDRESSABLE:
3966 case MPI2_SAS_DEVICE0_ASTATUS_SIF_MAX:
3967 desc = "sata initialization failed";
3968 break;
3969 default:
3970 desc = "unknown";
3971 break;
3972 }
3973
3974 if (!rc)
3975 return 0;
3976
3977 printk(MPT2SAS_ERR_FMT "discovery errors(%s): sas_address(0x%016llx), "
3978 "handle(0x%04x)\n", ioc->name, desc,
3979 (unsigned long long)sas_address, handle);
3980 return rc;
3981}
3982
3983static void
3984_scsih_check_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3985{
3986 Mpi2ConfigReply_t mpi_reply;
3987 Mpi2SasDevicePage0_t sas_device_pg0;
3988 struct _sas_device *sas_device;
3989 u32 ioc_status;
3990 unsigned long flags;
3991 u64 sas_address;
3992 struct scsi_target *starget;
3993 struct MPT2SAS_TARGET *sas_target_priv_data;
3994 u32 device_info;
3995
3996 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
3997 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle)))
3998 return;
3999
4000 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
4001 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
4002 return;
4003
4004 /* check if this is end device */
4005 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
4006 if (!(_scsih_is_end_device(device_info)))
4007 return;
4008
4009 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4010 sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
4011 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
4012 sas_address);
4013
4014 if (!sas_device) {
4015 printk(MPT2SAS_ERR_FMT "device is not present "
4016 "handle(0x%04x), no sas_device!!!\n", ioc->name, handle);
4017 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4018 return;
4019 }
4020
4021 if (unlikely(sas_device->handle != handle)) {
4022 starget = sas_device->starget;
4023 sas_target_priv_data = starget->hostdata;
4024 starget_printk(KERN_INFO, starget, "handle changed from(0x%04x)"
4025 " to (0x%04x)!!!\n", sas_device->handle, handle);
4026 sas_target_priv_data->handle = handle;
4027 sas_device->handle = handle;
4028 }
4029 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4030
4031 /* check if device is present */
4032 if (!(le16_to_cpu(sas_device_pg0.Flags) &
4033 MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) {
4034 printk(MPT2SAS_ERR_FMT "device is not present "
4035 "handle(0x%04x), flags!!!\n", ioc->name, handle);
4036 return;
4037 }
4038
4039 /* check if there were any issues with discovery */
4040 if (_scsih_check_access_status(ioc, sas_address, handle,
4041 sas_device_pg0.AccessStatus))
4042 return;
4043 _scsih_ublock_io_device(ioc, handle);
4044
4045}
4046
4047/**
3921 * _scsih_add_device - creating sas device object 4048 * _scsih_add_device - creating sas device object
3922 * @ioc: per adapter object 4049 * @ioc: per adapter object
3923 * @handle: sas device handle 4050 * @handle: sas device handle
@@ -3955,6 +4082,8 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
3955 return -1; 4082 return -1;
3956 } 4083 }
3957 4084
4085 sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
4086
3958 /* check if device is present */ 4087 /* check if device is present */
3959 if (!(le16_to_cpu(sas_device_pg0.Flags) & 4088 if (!(le16_to_cpu(sas_device_pg0.Flags) &
3960 MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) { 4089 MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) {
@@ -3965,15 +4094,10 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
3965 return -1; 4094 return -1;
3966 } 4095 }
3967 4096
3968 /* check if there were any issus with discovery */ 4097 /* check if there were any issues with discovery */
3969 if (sas_device_pg0.AccessStatus == 4098 if (_scsih_check_access_status(ioc, sas_address, handle,
3970 MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED) { 4099 sas_device_pg0.AccessStatus))
3971 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3972 ioc->name, __FILE__, __LINE__, __func__);
3973 printk(MPT2SAS_ERR_FMT "AccessStatus = 0x%02x\n",
3974 ioc->name, sas_device_pg0.AccessStatus);
3975 return -1; 4100 return -1;
3976 }
3977 4101
3978 /* check if this is end device */ 4102 /* check if this is end device */
3979 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); 4103 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
@@ -3983,17 +4107,14 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
3983 return -1; 4107 return -1;
3984 } 4108 }
3985 4109
3986 sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
3987 4110
3988 spin_lock_irqsave(&ioc->sas_device_lock, flags); 4111 spin_lock_irqsave(&ioc->sas_device_lock, flags);
3989 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 4112 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
3990 sas_address); 4113 sas_address);
3991 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 4114 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3992 4115
3993 if (sas_device) { 4116 if (sas_device)
3994 _scsih_ublock_io_device(ioc, handle);
3995 return 0; 4117 return 0;
3996 }
3997 4118
3998 sas_device = kzalloc(sizeof(struct _sas_device), 4119 sas_device = kzalloc(sizeof(struct _sas_device),
3999 GFP_KERNEL); 4120 GFP_KERNEL);
@@ -4308,8 +4429,10 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4308 mpt2sas_transport_update_links(ioc, sas_address, 4429 mpt2sas_transport_update_links(ioc, sas_address,
4309 handle, phy_number, link_rate); 4430 handle, phy_number, link_rate);
4310 4431
4311 if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5) 4432 if (link_rate < MPI2_SAS_NEG_LINK_RATE_1_5)
4312 _scsih_ublock_io_device(ioc, handle); 4433 break;
4434
4435 _scsih_check_device(ioc, handle);
4313 break; 4436 break;
4314 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 4437 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
4315 4438