}
 }
 
-
 /**
  * _scsih_ublock_io_device - set the device state to SDEV_RUNNING
  * @ioc: per adapter object
        _scsih_expander_node_remove(ioc, sas_expander);
 }
 
+/**
+ * _scsih_check_access_status - check access flags
+ * @ioc: per adapter object
+ * @sas_address: sas address
+ * @handle: sas device handle
+ * @access_flags: errors returned during discovery of the device
+ *
+ * Return 0 for success, else failure
+ */
+static u8
+_scsih_check_access_status(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
+   u16 handle, u8 access_status)
+{
+       u8 rc = 1;
+       char *desc = NULL;
+
+       switch (access_status) {
+       case MPI2_SAS_DEVICE0_ASTATUS_NO_ERRORS:
+       case MPI2_SAS_DEVICE0_ASTATUS_SATA_NEEDS_INITIALIZATION:
+               rc = 0;
+               break;
+       case MPI2_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED:
+               desc = "sata capability failed";
+               break;
+       case MPI2_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT:
+               desc = "sata affiliation conflict";
+               break;
+       case MPI2_SAS_DEVICE0_ASTATUS_ROUTE_NOT_ADDRESSABLE:
+               desc = "route not addressable";
+               break;
+       case MPI2_SAS_DEVICE0_ASTATUS_SMP_ERROR_NOT_ADDRESSABLE:
+               desc = "smp error not addressable";
+               break;
+       case MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED:
+               desc = "device blocked";
+               break;
+       case MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED:
+       case MPI2_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN:
+       case MPI2_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT:
+       case MPI2_SAS_DEVICE0_ASTATUS_SIF_DIAG:
+       case MPI2_SAS_DEVICE0_ASTATUS_SIF_IDENTIFICATION:
+       case MPI2_SAS_DEVICE0_ASTATUS_SIF_CHECK_POWER:
+       case MPI2_SAS_DEVICE0_ASTATUS_SIF_PIO_SN:
+       case MPI2_SAS_DEVICE0_ASTATUS_SIF_MDMA_SN:
+       case MPI2_SAS_DEVICE0_ASTATUS_SIF_UDMA_SN:
+       case MPI2_SAS_DEVICE0_ASTATUS_SIF_ZONING_VIOLATION:
+       case MPI2_SAS_DEVICE0_ASTATUS_SIF_NOT_ADDRESSABLE:
+       case MPI2_SAS_DEVICE0_ASTATUS_SIF_MAX:
+               desc = "sata initialization failed";
+               break;
+       default:
+               desc = "unknown";
+               break;
+       }
+
+       if (!rc)
+               return 0;
+
+       printk(MPT2SAS_ERR_FMT "discovery errors(%s): sas_address(0x%016llx), "
+           "handle(0x%04x)\n", ioc->name, desc,
+           (unsigned long long)sas_address, handle);
+       return rc;
+}
+
+static void
+_scsih_check_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
+{
+       Mpi2ConfigReply_t mpi_reply;
+       Mpi2SasDevicePage0_t sas_device_pg0;
+       struct _sas_device *sas_device;
+       u32 ioc_status;
+       unsigned long flags;
+       u64 sas_address;
+       struct scsi_target *starget;
+       struct MPT2SAS_TARGET *sas_target_priv_data;
+       u32 device_info;
+
+       if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
+           MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle)))
+               return;
+
+       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
+       if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
+               return;
+
+       /* check if this is end device */
+       device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
+       if (!(_scsih_is_end_device(device_info)))
+               return;
+
+       spin_lock_irqsave(&ioc->sas_device_lock, flags);
+       sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
+       sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
+           sas_address);
+
+       if (!sas_device) {
+               printk(MPT2SAS_ERR_FMT "device is not present "
+                   "handle(0x%04x), no sas_device!!!\n", ioc->name, handle);
+               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+               return;
+       }
+
+       if (unlikely(sas_device->handle != handle)) {
+               starget = sas_device->starget;
+               sas_target_priv_data = starget->hostdata;
+               starget_printk(KERN_INFO, starget, "handle changed from(0x%04x)"
+                  " to (0x%04x)!!!\n", sas_device->handle, handle);
+               sas_target_priv_data->handle = handle;
+               sas_device->handle = handle;
+       }
+       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+
+       /* check if device is present */
+       if (!(le16_to_cpu(sas_device_pg0.Flags) &
+           MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) {
+               printk(MPT2SAS_ERR_FMT "device is not present "
+                   "handle(0x%04x), flags!!!\n", ioc->name, handle);
+               return;
+       }
+
+       /* check if there were any issues with discovery */
+       if (_scsih_check_access_status(ioc, sas_address, handle,
+           sas_device_pg0.AccessStatus))
+               return;
+       _scsih_ublock_io_device(ioc, handle);
+
+}
+
 /**
  * _scsih_add_device -  creating sas device object
  * @ioc: per adapter object
                return -1;
        }
 
+       sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
+
        /* check if device is present */
        if (!(le16_to_cpu(sas_device_pg0.Flags) &
            MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) {
                return -1;
        }
 
-       /* check if there were any issus with discovery */
-       if (sas_device_pg0.AccessStatus ==
-           MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               printk(MPT2SAS_ERR_FMT "AccessStatus = 0x%02x\n",
-                   ioc->name, sas_device_pg0.AccessStatus);
+       /* check if there were any issues with discovery */
+       if (_scsih_check_access_status(ioc, sas_address, handle,
+           sas_device_pg0.AccessStatus))
                return -1;
-       }
 
        /* check if this is end device */
        device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
                return -1;
        }
 
-       sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
 
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
        sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
            sas_address);
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
-       if (sas_device) {
-               _scsih_ublock_io_device(ioc, handle);
+       if (sas_device)
                return 0;
-       }
 
        sas_device = kzalloc(sizeof(struct _sas_device),
            GFP_KERNEL);
                        mpt2sas_transport_update_links(ioc, sas_address,
                            handle, phy_number, link_rate);
 
-                       if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)
-                               _scsih_ublock_io_device(ioc, handle);
+                       if (link_rate < MPI2_SAS_NEG_LINK_RATE_1_5)
+                               break;
+
+                       _scsih_check_device(ioc, handle);
                        break;
                case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: