diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 153 |
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 | */ | ||
3928 | static 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 | |||
3983 | static 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 | ||