Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  *  linux/drivers/message/fusion/mptsas.c
0003  *      For use with LSI PCI chip/adapter(s)
0004  *      running LSI Fusion MPT (Message Passing Technology) firmware.
0005  *
0006  *  Copyright (c) 1999-2008 LSI Corporation
0007  *  (mailto:DL-MPTFusionLinux@lsi.com)
0008  */
0009 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
0010 /*
0011     This program is free software; you can redistribute it and/or modify
0012     it under the terms of the GNU General Public License as published by
0013     the Free Software Foundation; version 2 of the License.
0014 
0015     This program is distributed in the hope that it will be useful,
0016     but WITHOUT ANY WARRANTY; without even the implied warranty of
0017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0018     GNU General Public License for more details.
0019 
0020     NO WARRANTY
0021     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
0022     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
0023     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
0024     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
0025     solely responsible for determining the appropriateness of using and
0026     distributing the Program and assumes all risks associated with its
0027     exercise of rights under this Agreement, including but not limited to
0028     the risks and costs of program errors, damage to or loss of data,
0029     programs or equipment, and unavailability or interruption of operations.
0030 
0031     DISCLAIMER OF LIABILITY
0032     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
0033     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0034     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
0035     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
0036     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
0037     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
0038     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
0039 
0040     You should have received a copy of the GNU General Public License
0041     along with this program; if not, write to the Free Software
0042     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0043 */
0044 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
0045 
0046 #include <linux/module.h>
0047 #include <linux/kernel.h>
0048 #include <linux/slab.h>
0049 #include <linux/init.h>
0050 #include <linux/errno.h>
0051 #include <linux/jiffies.h>
0052 #include <linux/workqueue.h>
0053 #include <linux/delay.h>    /* for mdelay */
0054 
0055 #include <scsi/scsi.h>
0056 #include <scsi/scsi_cmnd.h>
0057 #include <scsi/scsi_device.h>
0058 #include <scsi/scsi_host.h>
0059 #include <scsi/scsi_transport_sas.h>
0060 #include <scsi/scsi_transport.h>
0061 #include <scsi/scsi_dbg.h>
0062 
0063 #include "mptbase.h"
0064 #include "mptscsih.h"
0065 #include "mptsas.h"
0066 
0067 
0068 #define my_NAME     "Fusion MPT SAS Host driver"
0069 #define my_VERSION  MPT_LINUX_VERSION_COMMON
0070 #define MYNAM       "mptsas"
0071 
0072 /*
0073  * Reserved channel for integrated raid
0074  */
0075 #define MPTSAS_RAID_CHANNEL 1
0076 
0077 #define SAS_CONFIG_PAGE_TIMEOUT     30
0078 MODULE_AUTHOR(MODULEAUTHOR);
0079 MODULE_DESCRIPTION(my_NAME);
0080 MODULE_LICENSE("GPL");
0081 MODULE_VERSION(my_VERSION);
0082 
0083 static int mpt_pt_clear;
0084 module_param(mpt_pt_clear, int, 0);
0085 MODULE_PARM_DESC(mpt_pt_clear,
0086         " Clear persistency table: enable=1  "
0087         "(default=MPTSCSIH_PT_CLEAR=0)");
0088 
0089 /* scsi-mid layer global parameter is max_report_luns, which is 511 */
0090 #define MPTSAS_MAX_LUN (16895)
0091 static int max_lun = MPTSAS_MAX_LUN;
0092 module_param(max_lun, int, 0);
0093 MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
0094 
0095 static int mpt_loadtime_max_sectors = 8192;
0096 module_param(mpt_loadtime_max_sectors, int, 0);
0097 MODULE_PARM_DESC(mpt_loadtime_max_sectors,
0098         " Maximum sector define for Host Bus Adaptor.Range 64 to 8192 default=8192");
0099 
0100 static u8   mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
0101 static u8   mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
0102 static u8   mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */
0103 static u8   mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS;
0104 static u8   mptsasDeviceResetCtx = MPT_MAX_PROTOCOL_DRIVERS;
0105 
0106 static void mptsas_firmware_event_work(struct work_struct *work);
0107 static void mptsas_send_sas_event(struct fw_event_work *fw_event);
0108 static void mptsas_send_raid_event(struct fw_event_work *fw_event);
0109 static void mptsas_send_ir2_event(struct fw_event_work *fw_event);
0110 static void mptsas_parse_device_info(struct sas_identify *identify,
0111         struct mptsas_devinfo *device_info);
0112 static inline void mptsas_set_rphy(MPT_ADAPTER *ioc,
0113         struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy);
0114 static struct mptsas_phyinfo    *mptsas_find_phyinfo_by_sas_address
0115         (MPT_ADAPTER *ioc, u64 sas_address);
0116 static int mptsas_sas_device_pg0(MPT_ADAPTER *ioc,
0117     struct mptsas_devinfo *device_info, u32 form, u32 form_specific);
0118 static int mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc,
0119     struct mptsas_enclosure *enclosure, u32 form, u32 form_specific);
0120 static int mptsas_add_end_device(MPT_ADAPTER *ioc,
0121     struct mptsas_phyinfo *phy_info);
0122 static void mptsas_del_end_device(MPT_ADAPTER *ioc,
0123     struct mptsas_phyinfo *phy_info);
0124 static void mptsas_send_link_status_event(struct fw_event_work *fw_event);
0125 static struct mptsas_portinfo   *mptsas_find_portinfo_by_sas_address
0126         (MPT_ADAPTER *ioc, u64 sas_address);
0127 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
0128         struct mptsas_portinfo *port_info, u8 force);
0129 static void mptsas_send_expander_event(struct fw_event_work *fw_event);
0130 static void mptsas_not_responding_devices(MPT_ADAPTER *ioc);
0131 static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
0132 static void mptsas_broadcast_primitive_work(struct fw_event_work *fw_event);
0133 static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
0134 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
0135 void    mptsas_schedule_target_reset(void *ioc);
0136 
0137 static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
0138                     MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
0139 {
0140     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0141         "---- IO UNIT PAGE 0 ------------\n", ioc->name));
0142     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
0143         ioc->name, le16_to_cpu(phy_data->AttachedDeviceHandle)));
0144     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Controller Handle=0x%X\n",
0145         ioc->name, le16_to_cpu(phy_data->ControllerDevHandle)));
0146     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port=0x%X\n",
0147         ioc->name, phy_data->Port));
0148     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port Flags=0x%X\n",
0149         ioc->name, phy_data->PortFlags));
0150     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Flags=0x%X\n",
0151         ioc->name, phy_data->PhyFlags));
0152     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
0153         ioc->name, phy_data->NegotiatedLinkRate));
0154     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0155         "Controller PHY Device Info=0x%X\n", ioc->name,
0156         le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
0157     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DiscoveryStatus=0x%X\n\n",
0158         ioc->name, le32_to_cpu(phy_data->DiscoveryStatus)));
0159 }
0160 
0161 static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
0162 {
0163     __le64 sas_address;
0164 
0165     memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
0166 
0167     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0168         "---- SAS PHY PAGE 0 ------------\n", ioc->name));
0169     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0170         "Attached Device Handle=0x%X\n", ioc->name,
0171         le16_to_cpu(pg0->AttachedDevHandle)));
0172     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
0173         ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
0174     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0175         "Attached PHY Identifier=0x%X\n", ioc->name,
0176         pg0->AttachedPhyIdentifier));
0177     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Attached Device Info=0x%X\n",
0178         ioc->name, le32_to_cpu(pg0->AttachedDeviceInfo)));
0179     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
0180         ioc->name,  pg0->ProgrammedLinkRate));
0181     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Change Count=0x%X\n",
0182         ioc->name, pg0->ChangeCount));
0183     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Info=0x%X\n\n",
0184         ioc->name, le32_to_cpu(pg0->PhyInfo)));
0185 }
0186 
0187 static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
0188 {
0189     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0190         "---- SAS PHY PAGE 1 ------------\n", ioc->name));
0191     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Invalid Dword Count=0x%x\n",
0192         ioc->name,  pg1->InvalidDwordCount));
0193     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0194         "Running Disparity Error Count=0x%x\n", ioc->name,
0195         pg1->RunningDisparityErrorCount));
0196     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0197         "Loss Dword Synch Count=0x%x\n", ioc->name,
0198         pg1->LossDwordSynchCount));
0199     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0200         "PHY Reset Problem Count=0x%x\n\n", ioc->name,
0201         pg1->PhyResetProblemCount));
0202 }
0203 
0204 static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
0205 {
0206     __le64 sas_address;
0207 
0208     memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
0209 
0210     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0211         "---- SAS DEVICE PAGE 0 ---------\n", ioc->name));
0212     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
0213         ioc->name, le16_to_cpu(pg0->DevHandle)));
0214     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Handle=0x%X\n",
0215         ioc->name, le16_to_cpu(pg0->ParentDevHandle)));
0216     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Enclosure Handle=0x%X\n",
0217         ioc->name, le16_to_cpu(pg0->EnclosureHandle)));
0218     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Slot=0x%X\n",
0219         ioc->name, le16_to_cpu(pg0->Slot)));
0220     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
0221         ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
0222     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Target ID=0x%X\n",
0223         ioc->name, pg0->TargetID));
0224     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Bus=0x%X\n",
0225         ioc->name, pg0->Bus));
0226     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Phy Num=0x%X\n",
0227         ioc->name, pg0->PhyNum));
0228     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Access Status=0x%X\n",
0229         ioc->name, le16_to_cpu(pg0->AccessStatus)));
0230     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Device Info=0x%X\n",
0231         ioc->name, le32_to_cpu(pg0->DeviceInfo)));
0232     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Flags=0x%X\n",
0233         ioc->name, le16_to_cpu(pg0->Flags)));
0234     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n\n",
0235         ioc->name, pg0->PhysicalPort));
0236 }
0237 
0238 static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
0239 {
0240     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0241         "---- SAS EXPANDER PAGE 1 ------------\n", ioc->name));
0242     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n",
0243         ioc->name, pg1->PhysicalPort));
0244     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Identifier=0x%X\n",
0245         ioc->name, pg1->PhyIdentifier));
0246     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
0247         ioc->name, pg1->NegotiatedLinkRate));
0248     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
0249         ioc->name, pg1->ProgrammedLinkRate));
0250     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hardware Link Rate=0x%X\n",
0251         ioc->name, pg1->HwLinkRate));
0252     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Owner Device Handle=0x%X\n",
0253         ioc->name, le16_to_cpu(pg1->OwnerDevHandle)));
0254     dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0255         "Attached Device Handle=0x%X\n\n", ioc->name,
0256         le16_to_cpu(pg1->AttachedDevHandle)));
0257 }
0258 
0259 /* inhibit sas firmware event handling */
0260 static void
0261 mptsas_fw_event_off(MPT_ADAPTER *ioc)
0262 {
0263     unsigned long flags;
0264 
0265     spin_lock_irqsave(&ioc->fw_event_lock, flags);
0266     ioc->fw_events_off = 1;
0267     ioc->sas_discovery_quiesce_io = 0;
0268     spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
0269 
0270 }
0271 
0272 /* enable sas firmware event handling */
0273 static void
0274 mptsas_fw_event_on(MPT_ADAPTER *ioc)
0275 {
0276     unsigned long flags;
0277 
0278     spin_lock_irqsave(&ioc->fw_event_lock, flags);
0279     ioc->fw_events_off = 0;
0280     spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
0281 }
0282 
0283 /* queue a sas firmware event */
0284 static void
0285 mptsas_add_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
0286     unsigned long delay)
0287 {
0288     unsigned long flags;
0289 
0290     spin_lock_irqsave(&ioc->fw_event_lock, flags);
0291     list_add_tail(&fw_event->list, &ioc->fw_event_list);
0292     fw_event->users = 1;
0293     INIT_DELAYED_WORK(&fw_event->work, mptsas_firmware_event_work);
0294     devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: add (fw_event=0x%p)"
0295         "on cpuid %d\n", ioc->name, __func__,
0296         fw_event, smp_processor_id()));
0297     queue_delayed_work_on(smp_processor_id(), ioc->fw_event_q,
0298         &fw_event->work, delay);
0299     spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
0300 }
0301 
0302 /* requeue a sas firmware event */
0303 static void
0304 mptsas_requeue_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
0305     unsigned long delay)
0306 {
0307     unsigned long flags;
0308     spin_lock_irqsave(&ioc->fw_event_lock, flags);
0309     devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: reschedule task "
0310         "(fw_event=0x%p)on cpuid %d\n", ioc->name, __func__,
0311         fw_event, smp_processor_id()));
0312     fw_event->retries++;
0313     queue_delayed_work_on(smp_processor_id(), ioc->fw_event_q,
0314         &fw_event->work, msecs_to_jiffies(delay));
0315     spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
0316 }
0317 
0318 static void __mptsas_free_fw_event(MPT_ADAPTER *ioc,
0319                    struct fw_event_work *fw_event)
0320 {
0321     devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: kfree (fw_event=0x%p)\n",
0322         ioc->name, __func__, fw_event));
0323     list_del(&fw_event->list);
0324     kfree(fw_event);
0325 }
0326 
0327 /* free memory associated to a sas firmware event */
0328 static void
0329 mptsas_free_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event)
0330 {
0331     unsigned long flags;
0332 
0333     spin_lock_irqsave(&ioc->fw_event_lock, flags);
0334     fw_event->users--;
0335     if (!fw_event->users)
0336         __mptsas_free_fw_event(ioc, fw_event);
0337     spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
0338 }
0339 
0340 /* walk the firmware event queue, and either stop or wait for
0341  * outstanding events to complete */
0342 static void
0343 mptsas_cleanup_fw_event_q(MPT_ADAPTER *ioc)
0344 {
0345     struct fw_event_work *fw_event;
0346     struct mptsas_target_reset_event *target_reset_list, *n;
0347     MPT_SCSI_HOST   *hd = shost_priv(ioc->sh);
0348     unsigned long flags;
0349 
0350     /* flush the target_reset_list */
0351     if (!list_empty(&hd->target_reset_list)) {
0352         list_for_each_entry_safe(target_reset_list, n,
0353             &hd->target_reset_list, list) {
0354             dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0355                 "%s: removing target reset for id=%d\n",
0356                 ioc->name, __func__,
0357                target_reset_list->sas_event_data.TargetID));
0358             list_del(&target_reset_list->list);
0359             kfree(target_reset_list);
0360         }
0361     }
0362 
0363     if (list_empty(&ioc->fw_event_list) || !ioc->fw_event_q)
0364         return;
0365 
0366     spin_lock_irqsave(&ioc->fw_event_lock, flags);
0367 
0368     while (!list_empty(&ioc->fw_event_list)) {
0369         bool canceled = false;
0370 
0371         fw_event = list_first_entry(&ioc->fw_event_list,
0372                         struct fw_event_work, list);
0373         fw_event->users++;
0374         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
0375         if (cancel_delayed_work_sync(&fw_event->work))
0376             canceled = true;
0377 
0378         spin_lock_irqsave(&ioc->fw_event_lock, flags);
0379         if (canceled)
0380             fw_event->users--;
0381         fw_event->users--;
0382         WARN_ON_ONCE(fw_event->users);
0383         __mptsas_free_fw_event(ioc, fw_event);
0384     }
0385     spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
0386 }
0387 
0388 
0389 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
0390 {
0391     struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
0392     return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
0393 }
0394 
0395 static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
0396 {
0397     struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
0398     return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
0399 }
0400 
0401 /*
0402  * mptsas_find_portinfo_by_handle
0403  *
0404  * This function should be called with the sas_topology_mutex already held
0405  */
0406 static struct mptsas_portinfo *
0407 mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
0408 {
0409     struct mptsas_portinfo *port_info, *rc=NULL;
0410     int i;
0411 
0412     list_for_each_entry(port_info, &ioc->sas_topology, list)
0413         for (i = 0; i < port_info->num_phys; i++)
0414             if (port_info->phy_info[i].identify.handle == handle) {
0415                 rc = port_info;
0416                 goto out;
0417             }
0418  out:
0419     return rc;
0420 }
0421 
0422 /**
0423  *  mptsas_find_portinfo_by_sas_address - find and return portinfo for
0424  *      this sas_address
0425  *  @ioc: Pointer to MPT_ADAPTER structure
0426  *  @sas_address: expander sas address
0427  *
0428  *  This function should be called with the sas_topology_mutex already held.
0429  *
0430  *  Return: %NULL if not found.
0431  **/
0432 static struct mptsas_portinfo *
0433 mptsas_find_portinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
0434 {
0435     struct mptsas_portinfo *port_info, *rc = NULL;
0436     int i;
0437 
0438     if (sas_address >= ioc->hba_port_sas_addr &&
0439         sas_address < (ioc->hba_port_sas_addr +
0440         ioc->hba_port_num_phy))
0441         return ioc->hba_port_info;
0442 
0443     mutex_lock(&ioc->sas_topology_mutex);
0444     list_for_each_entry(port_info, &ioc->sas_topology, list)
0445         for (i = 0; i < port_info->num_phys; i++)
0446             if (port_info->phy_info[i].identify.sas_address ==
0447                 sas_address) {
0448                 rc = port_info;
0449                 goto out;
0450             }
0451  out:
0452     mutex_unlock(&ioc->sas_topology_mutex);
0453     return rc;
0454 }
0455 
0456 /*
0457  * Returns true if there is a scsi end device
0458  */
0459 static inline int
0460 mptsas_is_end_device(struct mptsas_devinfo * attached)
0461 {
0462     if ((attached->sas_address) &&
0463         (attached->device_info &
0464         MPI_SAS_DEVICE_INFO_END_DEVICE) &&
0465         ((attached->device_info &
0466         MPI_SAS_DEVICE_INFO_SSP_TARGET) |
0467         (attached->device_info &
0468         MPI_SAS_DEVICE_INFO_STP_TARGET) |
0469         (attached->device_info &
0470         MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
0471         return 1;
0472     else
0473         return 0;
0474 }
0475 
0476 /* no mutex */
0477 static void
0478 mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
0479 {
0480     struct mptsas_portinfo *port_info;
0481     struct mptsas_phyinfo *phy_info;
0482     u8  i;
0483 
0484     if (!port_details)
0485         return;
0486 
0487     port_info = port_details->port_info;
0488     phy_info = port_info->phy_info;
0489 
0490     dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d "
0491         "bitmask=0x%016llX\n", ioc->name, __func__, port_details,
0492         port_details->num_phys, (unsigned long long)
0493         port_details->phy_bitmask));
0494 
0495     for (i = 0; i < port_info->num_phys; i++, phy_info++) {
0496         if(phy_info->port_details != port_details)
0497             continue;
0498         memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
0499         mptsas_set_rphy(ioc, phy_info, NULL);
0500         phy_info->port_details = NULL;
0501     }
0502     kfree(port_details);
0503 }
0504 
0505 static inline struct sas_rphy *
0506 mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
0507 {
0508     if (phy_info->port_details)
0509         return phy_info->port_details->rphy;
0510     else
0511         return NULL;
0512 }
0513 
0514 static inline void
0515 mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
0516 {
0517     if (phy_info->port_details) {
0518         phy_info->port_details->rphy = rphy;
0519         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
0520             ioc->name, rphy));
0521     }
0522 
0523     if (rphy) {
0524         dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
0525             &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
0526         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
0527             ioc->name, rphy, rphy->dev.release));
0528     }
0529 }
0530 
0531 static inline struct sas_port *
0532 mptsas_get_port(struct mptsas_phyinfo *phy_info)
0533 {
0534     if (phy_info->port_details)
0535         return phy_info->port_details->port;
0536     else
0537         return NULL;
0538 }
0539 
0540 static inline void
0541 mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_port *port)
0542 {
0543     if (phy_info->port_details)
0544         phy_info->port_details->port = port;
0545 
0546     if (port) {
0547         dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
0548             &port->dev, MYIOC_s_FMT "add:", ioc->name));
0549         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "port=%p release=%p\n",
0550             ioc->name, port, port->dev.release));
0551     }
0552 }
0553 
0554 static inline struct scsi_target *
0555 mptsas_get_starget(struct mptsas_phyinfo *phy_info)
0556 {
0557     if (phy_info->port_details)
0558         return phy_info->port_details->starget;
0559     else
0560         return NULL;
0561 }
0562 
0563 static inline void
0564 mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
0565 starget)
0566 {
0567     if (phy_info->port_details)
0568         phy_info->port_details->starget = starget;
0569 }
0570 
0571 /**
0572  *  mptsas_add_device_component - adds a new device component to our lists
0573  *  @ioc: Pointer to MPT_ADAPTER structure
0574  *  @channel: channel number
0575  *  @id: Logical Target ID for reset (if appropriate)
0576  *  @sas_address: expander sas address
0577  *  @device_info: specific bits (flags) for devices
0578  *  @slot: enclosure slot ID
0579  *  @enclosure_logical_id: enclosure WWN
0580  *
0581  **/
0582 static void
0583 mptsas_add_device_component(MPT_ADAPTER *ioc, u8 channel, u8 id,
0584     u64 sas_address, u32 device_info, u16 slot, u64 enclosure_logical_id)
0585 {
0586     struct mptsas_device_info   *sas_info, *next;
0587     struct scsi_device  *sdev;
0588     struct scsi_target  *starget;
0589     struct sas_rphy *rphy;
0590 
0591     /*
0592      * Delete all matching devices out of the list
0593      */
0594     mutex_lock(&ioc->sas_device_info_mutex);
0595     list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
0596         list) {
0597         if (!sas_info->is_logical_volume &&
0598             (sas_info->sas_address == sas_address ||
0599             (sas_info->fw.channel == channel &&
0600              sas_info->fw.id == id))) {
0601             list_del(&sas_info->list);
0602             kfree(sas_info);
0603         }
0604     }
0605 
0606     sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
0607     if (!sas_info)
0608         goto out;
0609 
0610     /*
0611      * Set Firmware mapping
0612      */
0613     sas_info->fw.id = id;
0614     sas_info->fw.channel = channel;
0615 
0616     sas_info->sas_address = sas_address;
0617     sas_info->device_info = device_info;
0618     sas_info->slot = slot;
0619     sas_info->enclosure_logical_id = enclosure_logical_id;
0620     INIT_LIST_HEAD(&sas_info->list);
0621     list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
0622 
0623     /*
0624      * Set OS mapping
0625      */
0626     shost_for_each_device(sdev, ioc->sh) {
0627         starget = scsi_target(sdev);
0628         rphy = dev_to_rphy(starget->dev.parent);
0629         if (rphy->identify.sas_address == sas_address) {
0630             sas_info->os.id = starget->id;
0631             sas_info->os.channel = starget->channel;
0632         }
0633     }
0634 
0635  out:
0636     mutex_unlock(&ioc->sas_device_info_mutex);
0637     return;
0638 }
0639 
0640 /**
0641  *  mptsas_add_device_component_by_fw - adds a new device component by FW ID
0642  *  @ioc: Pointer to MPT_ADAPTER structure
0643  *  @channel: channel number
0644  *  @id: Logical Target ID
0645  *
0646  **/
0647 static void
0648 mptsas_add_device_component_by_fw(MPT_ADAPTER *ioc, u8 channel, u8 id)
0649 {
0650     struct mptsas_devinfo sas_device;
0651     struct mptsas_enclosure enclosure_info;
0652     int rc;
0653 
0654     rc = mptsas_sas_device_pg0(ioc, &sas_device,
0655         (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
0656          MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
0657         (channel << 8) + id);
0658     if (rc)
0659         return;
0660 
0661     memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
0662     mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
0663         (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
0664          MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
0665          sas_device.handle_enclosure);
0666 
0667     mptsas_add_device_component(ioc, sas_device.channel,
0668         sas_device.id, sas_device.sas_address, sas_device.device_info,
0669         sas_device.slot, enclosure_info.enclosure_logical_id);
0670 }
0671 
0672 /**
0673  *  mptsas_add_device_component_starget_ir - Handle Integrated RAID, adding each individual device to list
0674  *  @ioc: Pointer to MPT_ADAPTER structure
0675  *  @starget: SCSI target for this SCSI device
0676  *
0677  **/
0678 static void
0679 mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc,
0680         struct scsi_target *starget)
0681 {
0682     CONFIGPARMS         cfg;
0683     ConfigPageHeader_t      hdr;
0684     dma_addr_t          dma_handle;
0685     pRaidVolumePage0_t      buffer = NULL;
0686     int             i;
0687     RaidPhysDiskPage0_t         phys_disk;
0688     struct mptsas_device_info   *sas_info, *next;
0689 
0690     memset(&cfg, 0 , sizeof(CONFIGPARMS));
0691     memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
0692     hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
0693     /* assumption that all volumes on channel = 0 */
0694     cfg.pageAddr = starget->id;
0695     cfg.cfghdr.hdr = &hdr;
0696     cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
0697     cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
0698 
0699     if (mpt_config(ioc, &cfg) != 0)
0700         goto out;
0701 
0702     if (!hdr.PageLength)
0703         goto out;
0704 
0705     buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
0706                     &dma_handle, GFP_KERNEL);
0707 
0708     if (!buffer)
0709         goto out;
0710 
0711     cfg.physAddr = dma_handle;
0712     cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
0713 
0714     if (mpt_config(ioc, &cfg) != 0)
0715         goto out;
0716 
0717     if (!buffer->NumPhysDisks)
0718         goto out;
0719 
0720     /*
0721      * Adding entry for hidden components
0722      */
0723     for (i = 0; i < buffer->NumPhysDisks; i++) {
0724 
0725         if (mpt_raid_phys_disk_pg0(ioc,
0726             buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
0727             continue;
0728 
0729         mptsas_add_device_component_by_fw(ioc, phys_disk.PhysDiskBus,
0730             phys_disk.PhysDiskID);
0731 
0732         mutex_lock(&ioc->sas_device_info_mutex);
0733         list_for_each_entry(sas_info, &ioc->sas_device_info_list,
0734             list) {
0735             if (!sas_info->is_logical_volume &&
0736                 (sas_info->fw.channel == phys_disk.PhysDiskBus &&
0737                 sas_info->fw.id == phys_disk.PhysDiskID)) {
0738                 sas_info->is_hidden_raid_component = 1;
0739                 sas_info->volume_id = starget->id;
0740             }
0741         }
0742         mutex_unlock(&ioc->sas_device_info_mutex);
0743 
0744     }
0745 
0746     /*
0747      * Delete all matching devices out of the list
0748      */
0749     mutex_lock(&ioc->sas_device_info_mutex);
0750     list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
0751         list) {
0752         if (sas_info->is_logical_volume && sas_info->fw.id ==
0753             starget->id) {
0754             list_del(&sas_info->list);
0755             kfree(sas_info);
0756         }
0757     }
0758 
0759     sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
0760     if (sas_info) {
0761         sas_info->fw.id = starget->id;
0762         sas_info->os.id = starget->id;
0763         sas_info->os.channel = starget->channel;
0764         sas_info->is_logical_volume = 1;
0765         INIT_LIST_HEAD(&sas_info->list);
0766         list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
0767     }
0768     mutex_unlock(&ioc->sas_device_info_mutex);
0769 
0770  out:
0771     if (buffer)
0772         dma_free_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
0773                   buffer, dma_handle);
0774 }
0775 
0776 /**
0777  *  mptsas_add_device_component_starget - adds a SCSI target device component
0778  *  @ioc: Pointer to MPT_ADAPTER structure
0779  *  @starget: SCSI target for this SCSI device
0780  *
0781  **/
0782 static void
0783 mptsas_add_device_component_starget(MPT_ADAPTER *ioc,
0784     struct scsi_target *starget)
0785 {
0786     struct sas_rphy *rphy;
0787     struct mptsas_phyinfo   *phy_info = NULL;
0788     struct mptsas_enclosure enclosure_info;
0789 
0790     rphy = dev_to_rphy(starget->dev.parent);
0791     phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
0792             rphy->identify.sas_address);
0793     if (!phy_info)
0794         return;
0795 
0796     memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
0797     mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
0798         (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
0799         MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
0800         phy_info->attached.handle_enclosure);
0801 
0802     mptsas_add_device_component(ioc, phy_info->attached.channel,
0803         phy_info->attached.id, phy_info->attached.sas_address,
0804         phy_info->attached.device_info,
0805         phy_info->attached.slot, enclosure_info.enclosure_logical_id);
0806 }
0807 
0808 /**
0809  *  mptsas_del_device_component_by_os - Once a device has been removed, we mark the entry in the list as being cached
0810  *  @ioc: Pointer to MPT_ADAPTER structure
0811  *  @channel: os mapped id's
0812  *  @id: Logical Target ID
0813  *
0814  **/
0815 static void
0816 mptsas_del_device_component_by_os(MPT_ADAPTER *ioc, u8 channel, u8 id)
0817 {
0818     struct mptsas_device_info   *sas_info, *next;
0819 
0820     /*
0821      * Set is_cached flag
0822      */
0823     list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
0824         list) {
0825         if (sas_info->os.channel == channel && sas_info->os.id == id)
0826             sas_info->is_cached = 1;
0827     }
0828 }
0829 
0830 /**
0831  *  mptsas_del_device_components - Cleaning the list
0832  *  @ioc: Pointer to MPT_ADAPTER structure
0833  *
0834  **/
0835 static void
0836 mptsas_del_device_components(MPT_ADAPTER *ioc)
0837 {
0838     struct mptsas_device_info   *sas_info, *next;
0839 
0840     mutex_lock(&ioc->sas_device_info_mutex);
0841     list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
0842         list) {
0843         list_del(&sas_info->list);
0844         kfree(sas_info);
0845     }
0846     mutex_unlock(&ioc->sas_device_info_mutex);
0847 }
0848 
0849 
0850 /*
0851  * mptsas_setup_wide_ports
0852  *
0853  * Updates for new and existing narrow/wide port configuration
0854  * in the sas_topology
0855  */
0856 static void
0857 mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
0858 {
0859     struct mptsas_portinfo_details * port_details;
0860     struct mptsas_phyinfo *phy_info, *phy_info_cmp;
0861     u64 sas_address;
0862     int i, j;
0863 
0864     mutex_lock(&ioc->sas_topology_mutex);
0865 
0866     phy_info = port_info->phy_info;
0867     for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
0868         if (phy_info->attached.handle)
0869             continue;
0870         port_details = phy_info->port_details;
0871         if (!port_details)
0872             continue;
0873         if (port_details->num_phys < 2)
0874             continue;
0875         /*
0876          * Removing a phy from a port, letting the last
0877          * phy be removed by firmware events.
0878          */
0879         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0880             "%s: [%p]: deleting phy = %d\n",
0881             ioc->name, __func__, port_details, i));
0882         port_details->num_phys--;
0883         port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
0884         memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
0885         if (phy_info->phy) {
0886             devtprintk(ioc, dev_printk(KERN_DEBUG,
0887                 &phy_info->phy->dev, MYIOC_s_FMT
0888                 "delete phy %d, phy-obj (0x%p)\n", ioc->name,
0889                 phy_info->phy_id, phy_info->phy));
0890             sas_port_delete_phy(port_details->port, phy_info->phy);
0891         }
0892         phy_info->port_details = NULL;
0893     }
0894 
0895     /*
0896      * Populate and refresh the tree
0897      */
0898     phy_info = port_info->phy_info;
0899     for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
0900         sas_address = phy_info->attached.sas_address;
0901         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "phy_id=%d sas_address=0x%018llX\n",
0902             ioc->name, i, (unsigned long long)sas_address));
0903         if (!sas_address)
0904             continue;
0905         port_details = phy_info->port_details;
0906         /*
0907          * Forming a port
0908          */
0909         if (!port_details) {
0910             port_details = kzalloc(sizeof(struct
0911                 mptsas_portinfo_details), GFP_KERNEL);
0912             if (!port_details)
0913                 goto out;
0914             port_details->num_phys = 1;
0915             port_details->port_info = port_info;
0916             if (phy_info->phy_id < 64 )
0917                 port_details->phy_bitmask |=
0918                     (1 << phy_info->phy_id);
0919             phy_info->sas_port_add_phy=1;
0920             dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tForming port\n\t\t"
0921                 "phy_id=%d sas_address=0x%018llX\n",
0922                 ioc->name, i, (unsigned long long)sas_address));
0923             phy_info->port_details = port_details;
0924         }
0925 
0926         if (i == port_info->num_phys - 1)
0927             continue;
0928         phy_info_cmp = &port_info->phy_info[i + 1];
0929         for (j = i + 1 ; j < port_info->num_phys ; j++,
0930             phy_info_cmp++) {
0931             if (!phy_info_cmp->attached.sas_address)
0932                 continue;
0933             if (sas_address != phy_info_cmp->attached.sas_address)
0934                 continue;
0935             if (phy_info_cmp->port_details == port_details )
0936                 continue;
0937             dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0938                 "\t\tphy_id=%d sas_address=0x%018llX\n",
0939                 ioc->name, j, (unsigned long long)
0940                 phy_info_cmp->attached.sas_address));
0941             if (phy_info_cmp->port_details) {
0942                 port_details->rphy =
0943                     mptsas_get_rphy(phy_info_cmp);
0944                 port_details->port =
0945                     mptsas_get_port(phy_info_cmp);
0946                 port_details->starget =
0947                     mptsas_get_starget(phy_info_cmp);
0948                 port_details->num_phys =
0949                     phy_info_cmp->port_details->num_phys;
0950                 if (!phy_info_cmp->port_details->num_phys)
0951                     kfree(phy_info_cmp->port_details);
0952             } else
0953                 phy_info_cmp->sas_port_add_phy=1;
0954             /*
0955              * Adding a phy to a port
0956              */
0957             phy_info_cmp->port_details = port_details;
0958             if (phy_info_cmp->phy_id < 64 )
0959                 port_details->phy_bitmask |=
0960                 (1 << phy_info_cmp->phy_id);
0961             port_details->num_phys++;
0962         }
0963     }
0964 
0965  out:
0966 
0967     for (i = 0; i < port_info->num_phys; i++) {
0968         port_details = port_info->phy_info[i].port_details;
0969         if (!port_details)
0970             continue;
0971         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0972             "%s: [%p]: phy_id=%02d num_phys=%02d "
0973             "bitmask=0x%016llX\n", ioc->name, __func__,
0974             port_details, i, port_details->num_phys,
0975             (unsigned long long)port_details->phy_bitmask));
0976         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n",
0977             ioc->name, port_details->port, port_details->rphy));
0978     }
0979     dsaswideprintk(ioc, printk("\n"));
0980     mutex_unlock(&ioc->sas_topology_mutex);
0981 }
0982 
0983 /**
0984  * mptsas_find_vtarget - find a virtual target device (FC LUN device or
0985  *              SCSI target device)
0986  *
0987  * @ioc: Pointer to MPT_ADAPTER structure
0988  * @channel: channel number
0989  * @id: Logical Target ID
0990  *
0991  **/
0992 static VirtTarget *
0993 mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
0994 {
0995     struct scsi_device      *sdev;
0996     VirtDevice          *vdevice;
0997     VirtTarget          *vtarget = NULL;
0998 
0999     shost_for_each_device(sdev, ioc->sh) {
1000         vdevice = sdev->hostdata;
1001         if ((vdevice == NULL) ||
1002             (vdevice->vtarget == NULL))
1003             continue;
1004         if ((vdevice->vtarget->tflags &
1005             MPT_TARGET_FLAGS_RAID_COMPONENT ||
1006             vdevice->vtarget->raidVolume))
1007             continue;
1008         if (vdevice->vtarget->id == id &&
1009             vdevice->vtarget->channel == channel)
1010             vtarget = vdevice->vtarget;
1011     }
1012     return vtarget;
1013 }
1014 
1015 static void
1016 mptsas_queue_device_delete(MPT_ADAPTER *ioc,
1017     MpiEventDataSasDeviceStatusChange_t *sas_event_data)
1018 {
1019     struct fw_event_work *fw_event;
1020 
1021     fw_event = kzalloc(sizeof(*fw_event) +
1022                sizeof(MpiEventDataSasDeviceStatusChange_t),
1023                GFP_ATOMIC);
1024     if (!fw_event) {
1025         printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
1026             ioc->name, __func__, __LINE__);
1027         return;
1028     }
1029     memcpy(fw_event->event_data, sas_event_data,
1030         sizeof(MpiEventDataSasDeviceStatusChange_t));
1031     fw_event->event = MPI_EVENT_SAS_DEVICE_STATUS_CHANGE;
1032     fw_event->ioc = ioc;
1033     mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
1034 }
1035 
1036 static void
1037 mptsas_queue_rescan(MPT_ADAPTER *ioc)
1038 {
1039     struct fw_event_work *fw_event;
1040 
1041     fw_event = kzalloc(sizeof(*fw_event), GFP_ATOMIC);
1042     if (!fw_event) {
1043         printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
1044             ioc->name, __func__, __LINE__);
1045         return;
1046     }
1047     fw_event->event = -1;
1048     fw_event->ioc = ioc;
1049     mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
1050 }
1051 
1052 
1053 /**
1054  * mptsas_target_reset - Issues TARGET_RESET to end device using
1055  *           handshaking method
1056  *
1057  * @ioc: Pointer to MPT_ADAPTER structure
1058  * @channel: channel number
1059  * @id: Logical Target ID for reset
1060  *
1061  * Return: (1) success
1062  *         (0) failure
1063  *
1064  **/
1065 static int
1066 mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
1067 {
1068     MPT_FRAME_HDR   *mf;
1069     SCSITaskMgmt_t  *pScsiTm;
1070     if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0)
1071         return 0;
1072 
1073 
1074     mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
1075     if (mf == NULL) {
1076         dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1077             "%s, no msg frames @%d!!\n", ioc->name,
1078             __func__, __LINE__));
1079         goto out_fail;
1080     }
1081 
1082     dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1083         ioc->name, mf));
1084 
1085     /* Format the Request
1086      */
1087     pScsiTm = (SCSITaskMgmt_t *) mf;
1088     memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
1089     pScsiTm->TargetID = id;
1090     pScsiTm->Bus = channel;
1091     pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1092     pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
1093     pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
1094 
1095     DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
1096 
1097     dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1098        "TaskMgmt type=%d (sas device delete) fw_channel = %d fw_id = %d)\n",
1099        ioc->name, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, channel, id));
1100 
1101     mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
1102 
1103     return 1;
1104 
1105  out_fail:
1106 
1107     mpt_clear_taskmgmt_in_progress_flag(ioc);
1108     return 0;
1109 }
1110 
1111 static void
1112 mptsas_block_io_sdev(struct scsi_device *sdev, void *data)
1113 {
1114     scsi_device_set_state(sdev, SDEV_BLOCK);
1115 }
1116 
1117 static void
1118 mptsas_block_io_starget(struct scsi_target *starget)
1119 {
1120     if (starget)
1121         starget_for_each_device(starget, NULL, mptsas_block_io_sdev);
1122 }
1123 
1124 /**
1125  * mptsas_target_reset_queue - queue a target reset
1126  *
1127  * @ioc: Pointer to MPT_ADAPTER structure
1128  * @sas_event_data: SAS Device Status Change Event data
1129  *
1130  * Receive request for TARGET_RESET after receiving a firmware
1131  * event NOT_RESPONDING_EVENT, then put command in link list
1132  * and queue if task_queue already in use.
1133  *
1134  **/
1135 static void
1136 mptsas_target_reset_queue(MPT_ADAPTER *ioc,
1137     EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1138 {
1139     MPT_SCSI_HOST   *hd = shost_priv(ioc->sh);
1140     VirtTarget *vtarget = NULL;
1141     struct mptsas_target_reset_event *target_reset_list;
1142     u8      id, channel;
1143 
1144     id = sas_event_data->TargetID;
1145     channel = sas_event_data->Bus;
1146 
1147     vtarget = mptsas_find_vtarget(ioc, channel, id);
1148     if (vtarget) {
1149         mptsas_block_io_starget(vtarget->starget);
1150         vtarget->deleted = 1; /* block IO */
1151     }
1152 
1153     target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event),
1154         GFP_ATOMIC);
1155     if (!target_reset_list) {
1156         dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1157             "%s, failed to allocate mem @%d..!!\n",
1158             ioc->name, __func__, __LINE__));
1159         return;
1160     }
1161 
1162     memcpy(&target_reset_list->sas_event_data, sas_event_data,
1163         sizeof(*sas_event_data));
1164     list_add_tail(&target_reset_list->list, &hd->target_reset_list);
1165 
1166     target_reset_list->time_count = jiffies;
1167 
1168     if (mptsas_target_reset(ioc, channel, id)) {
1169         target_reset_list->target_reset_issued = 1;
1170     }
1171 }
1172 
1173 /**
1174  * mptsas_schedule_target_reset- send pending target reset
1175  * @iocp: per adapter object
1176  *
1177  * This function will delete scheduled target reset from the list and
1178  * try to send next target reset. This will be called from completion
1179  * context of any Task management command.
1180  */
1181 
1182 void
1183 mptsas_schedule_target_reset(void *iocp)
1184 {
1185     MPT_ADAPTER *ioc = (MPT_ADAPTER *)(iocp);
1186     MPT_SCSI_HOST   *hd = shost_priv(ioc->sh);
1187     struct list_head *head = &hd->target_reset_list;
1188     struct mptsas_target_reset_event    *target_reset_list;
1189     u8      id, channel;
1190     /*
1191      * issue target reset to next device in the queue
1192      */
1193 
1194     if (list_empty(head))
1195         return;
1196 
1197     target_reset_list = list_entry(head->next,
1198         struct mptsas_target_reset_event, list);
1199 
1200     id = target_reset_list->sas_event_data.TargetID;
1201     channel = target_reset_list->sas_event_data.Bus;
1202     target_reset_list->time_count = jiffies;
1203 
1204     if (mptsas_target_reset(ioc, channel, id))
1205         target_reset_list->target_reset_issued = 1;
1206     return;
1207 }
1208 
1209 
1210 /**
1211  *  mptsas_taskmgmt_complete - complete SAS task management function
1212  *  @ioc: Pointer to MPT_ADAPTER structure
1213  *  @mf: MPT message frame
1214  *  @mr: SCSI Task Management Reply structure ptr (may be %NULL)
1215  *
1216  *  Completion for TARGET_RESET after NOT_RESPONDING_EVENT, enable work
1217  *  queue to finish off removing device from upper layers, then send next
1218  *  TARGET_RESET in the queue.
1219  **/
1220 static int
1221 mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
1222 {
1223     MPT_SCSI_HOST   *hd = shost_priv(ioc->sh);
1224         struct list_head *head = &hd->target_reset_list;
1225     u8      id, channel;
1226     struct mptsas_target_reset_event    *target_reset_list;
1227     SCSITaskMgmtReply_t *pScsiTmReply;
1228 
1229     dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt completed: "
1230         "(mf = %p, mr = %p)\n", ioc->name, mf, mr));
1231 
1232     pScsiTmReply = (SCSITaskMgmtReply_t *)mr;
1233     if (!pScsiTmReply)
1234         return 0;
1235 
1236     dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1237         "\tTaskMgmt completed: fw_channel = %d, fw_id = %d,\n"
1238         "\ttask_type = 0x%02X, iocstatus = 0x%04X "
1239         "loginfo = 0x%08X,\n\tresponse_code = 0x%02X, "
1240         "term_cmnds = %d\n", ioc->name,
1241         pScsiTmReply->Bus, pScsiTmReply->TargetID,
1242         pScsiTmReply->TaskType,
1243         le16_to_cpu(pScsiTmReply->IOCStatus),
1244         le32_to_cpu(pScsiTmReply->IOCLogInfo),
1245         pScsiTmReply->ResponseCode,
1246         le32_to_cpu(pScsiTmReply->TerminationCount)));
1247 
1248     if (pScsiTmReply->ResponseCode)
1249         mptscsih_taskmgmt_response_code(ioc,
1250         pScsiTmReply->ResponseCode);
1251 
1252     if (pScsiTmReply->TaskType ==
1253         MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK || pScsiTmReply->TaskType ==
1254          MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET) {
1255         ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
1256         ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
1257         memcpy(ioc->taskmgmt_cmds.reply, mr,
1258             min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
1259         if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
1260             ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
1261             complete(&ioc->taskmgmt_cmds.done);
1262             return 1;
1263         }
1264         return 0;
1265     }
1266 
1267     mpt_clear_taskmgmt_in_progress_flag(ioc);
1268 
1269     if (list_empty(head))
1270         return 1;
1271 
1272     target_reset_list = list_entry(head->next,
1273         struct mptsas_target_reset_event, list);
1274 
1275     dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1276         "TaskMgmt: completed (%d seconds)\n",
1277         ioc->name, jiffies_to_msecs(jiffies -
1278         target_reset_list->time_count)/1000));
1279 
1280     id = pScsiTmReply->TargetID;
1281     channel = pScsiTmReply->Bus;
1282     target_reset_list->time_count = jiffies;
1283 
1284     /*
1285      * retry target reset
1286      */
1287     if (!target_reset_list->target_reset_issued) {
1288         if (mptsas_target_reset(ioc, channel, id))
1289             target_reset_list->target_reset_issued = 1;
1290         return 1;
1291     }
1292 
1293     /*
1294      * enable work queue to remove device from upper layers
1295      */
1296     list_del(&target_reset_list->list);
1297     if (!ioc->fw_events_off)
1298         mptsas_queue_device_delete(ioc,
1299             &target_reset_list->sas_event_data);
1300 
1301 
1302     ioc->schedule_target_reset(ioc);
1303 
1304     return 1;
1305 }
1306 
1307 /**
1308  * mptsas_ioc_reset - issue an IOC reset for this reset phase
1309  *
1310  * @ioc: Pointer to MPT_ADAPTER structure
1311  * @reset_phase: id of phase of reset
1312  *
1313  **/
1314 static int
1315 mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1316 {
1317     MPT_SCSI_HOST   *hd;
1318     int rc;
1319 
1320     rc = mptscsih_ioc_reset(ioc, reset_phase);
1321     if ((ioc->bus_type != SAS) || (!rc))
1322         return rc;
1323 
1324     hd = shost_priv(ioc->sh);
1325     if (!hd->ioc)
1326         goto out;
1327 
1328     switch (reset_phase) {
1329     case MPT_IOC_SETUP_RESET:
1330         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1331             "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
1332         mptsas_fw_event_off(ioc);
1333         break;
1334     case MPT_IOC_PRE_RESET:
1335         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1336             "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
1337         break;
1338     case MPT_IOC_POST_RESET:
1339         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1340             "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
1341         if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
1342             ioc->sas_mgmt.status |= MPT_MGMT_STATUS_DID_IOCRESET;
1343             complete(&ioc->sas_mgmt.done);
1344         }
1345         mptsas_cleanup_fw_event_q(ioc);
1346         mptsas_queue_rescan(ioc);
1347         break;
1348     default:
1349         break;
1350     }
1351 
1352  out:
1353     return rc;
1354 }
1355 
1356 
1357 /**
1358  * enum device_state - TUR device state
1359  * @DEVICE_RETRY: need to retry the TUR
1360  * @DEVICE_ERROR: TUR return error, don't add device
1361  * @DEVICE_READY: device can be added
1362  *
1363  */
1364 enum device_state{
1365     DEVICE_RETRY,
1366     DEVICE_ERROR,
1367     DEVICE_READY,
1368 };
1369 
1370 static int
1371 mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
1372         u32 form, u32 form_specific)
1373 {
1374     ConfigExtendedPageHeader_t hdr;
1375     CONFIGPARMS cfg;
1376     SasEnclosurePage0_t *buffer;
1377     dma_addr_t dma_handle;
1378     int error;
1379     __le64 le_identifier;
1380 
1381     memset(&hdr, 0, sizeof(hdr));
1382     hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
1383     hdr.PageNumber = 0;
1384     hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1385     hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
1386 
1387     cfg.cfghdr.ehdr = &hdr;
1388     cfg.physAddr = -1;
1389     cfg.pageAddr = form + form_specific;
1390     cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1391     cfg.dir = 0;    /* read */
1392     cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
1393 
1394     error = mpt_config(ioc, &cfg);
1395     if (error)
1396         goto out;
1397     if (!hdr.ExtPageLength) {
1398         error = -ENXIO;
1399         goto out;
1400     }
1401 
1402     buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
1403                     &dma_handle, GFP_KERNEL);
1404     if (!buffer) {
1405         error = -ENOMEM;
1406         goto out;
1407     }
1408 
1409     cfg.physAddr = dma_handle;
1410     cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1411 
1412     error = mpt_config(ioc, &cfg);
1413     if (error)
1414         goto out_free_consistent;
1415 
1416     /* save config data */
1417     memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
1418     enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
1419     enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
1420     enclosure->flags = le16_to_cpu(buffer->Flags);
1421     enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
1422     enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
1423     enclosure->start_id = buffer->StartTargetID;
1424     enclosure->start_channel = buffer->StartBus;
1425     enclosure->sep_id = buffer->SEPTargetID;
1426     enclosure->sep_channel = buffer->SEPBus;
1427 
1428  out_free_consistent:
1429     dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
1430               dma_handle);
1431  out:
1432     return error;
1433 }
1434 
1435 /**
1436  *  mptsas_add_end_device - report a new end device to sas transport layer
1437  *  @ioc: Pointer to MPT_ADAPTER structure
1438  *  @phy_info: describes attached device
1439  *
1440  *  return (0) success (1) failure
1441  *
1442  **/
1443 static int
1444 mptsas_add_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1445 {
1446     struct sas_rphy *rphy;
1447     struct sas_port *port;
1448     struct sas_identify identify;
1449     char *ds = NULL;
1450     u8 fw_id;
1451 
1452     if (!phy_info) {
1453         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1454             "%s: exit at line=%d\n", ioc->name,
1455              __func__, __LINE__));
1456         return 1;
1457     }
1458 
1459     fw_id = phy_info->attached.id;
1460 
1461     if (mptsas_get_rphy(phy_info)) {
1462         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1463             "%s: fw_id=%d exit at line=%d\n", ioc->name,
1464              __func__, fw_id, __LINE__));
1465         return 2;
1466     }
1467 
1468     port = mptsas_get_port(phy_info);
1469     if (!port) {
1470         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1471             "%s: fw_id=%d exit at line=%d\n", ioc->name,
1472              __func__, fw_id, __LINE__));
1473         return 3;
1474     }
1475 
1476     if (phy_info->attached.device_info &
1477         MPI_SAS_DEVICE_INFO_SSP_TARGET)
1478         ds = "ssp";
1479     if (phy_info->attached.device_info &
1480         MPI_SAS_DEVICE_INFO_STP_TARGET)
1481         ds = "stp";
1482     if (phy_info->attached.device_info &
1483         MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1484         ds = "sata";
1485 
1486     printk(MYIOC_s_INFO_FMT "attaching %s device: fw_channel %d, fw_id %d,"
1487         " phy %d, sas_addr 0x%llx\n", ioc->name, ds,
1488         phy_info->attached.channel, phy_info->attached.id,
1489         phy_info->attached.phy_id, (unsigned long long)
1490         phy_info->attached.sas_address);
1491 
1492     mptsas_parse_device_info(&identify, &phy_info->attached);
1493     rphy = sas_end_device_alloc(port);
1494     if (!rphy) {
1495         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1496             "%s: fw_id=%d exit at line=%d\n", ioc->name,
1497              __func__, fw_id, __LINE__));
1498         return 5; /* non-fatal: an rphy can be added later */
1499     }
1500 
1501     rphy->identify = identify;
1502     if (sas_rphy_add(rphy)) {
1503         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1504             "%s: fw_id=%d exit at line=%d\n", ioc->name,
1505              __func__, fw_id, __LINE__));
1506         sas_rphy_free(rphy);
1507         return 6;
1508     }
1509     mptsas_set_rphy(ioc, phy_info, rphy);
1510     return 0;
1511 }
1512 
1513 /**
1514  *  mptsas_del_end_device - report a deleted end device to sas transport layer
1515  *  @ioc: Pointer to MPT_ADAPTER structure
1516  *  @phy_info: describes attached device
1517  *
1518  **/
1519 static void
1520 mptsas_del_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1521 {
1522     struct sas_rphy *rphy;
1523     struct sas_port *port;
1524     struct mptsas_portinfo *port_info;
1525     struct mptsas_phyinfo *phy_info_parent;
1526     int i;
1527     char *ds = NULL;
1528     u8 fw_id;
1529     u64 sas_address;
1530 
1531     if (!phy_info)
1532         return;
1533 
1534     fw_id = phy_info->attached.id;
1535     sas_address = phy_info->attached.sas_address;
1536 
1537     if (!phy_info->port_details) {
1538         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1539             "%s: fw_id=%d exit at line=%d\n", ioc->name,
1540              __func__, fw_id, __LINE__));
1541         return;
1542     }
1543     rphy = mptsas_get_rphy(phy_info);
1544     if (!rphy) {
1545         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1546             "%s: fw_id=%d exit at line=%d\n", ioc->name,
1547              __func__, fw_id, __LINE__));
1548         return;
1549     }
1550 
1551     if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_INITIATOR
1552         || phy_info->attached.device_info
1553             & MPI_SAS_DEVICE_INFO_SMP_INITIATOR
1554         || phy_info->attached.device_info
1555             & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1556         ds = "initiator";
1557     if (phy_info->attached.device_info &
1558         MPI_SAS_DEVICE_INFO_SSP_TARGET)
1559         ds = "ssp";
1560     if (phy_info->attached.device_info &
1561         MPI_SAS_DEVICE_INFO_STP_TARGET)
1562         ds = "stp";
1563     if (phy_info->attached.device_info &
1564         MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1565         ds = "sata";
1566 
1567     dev_printk(KERN_DEBUG, &rphy->dev, MYIOC_s_FMT
1568         "removing %s device: fw_channel %d, fw_id %d, phy %d,"
1569         "sas_addr 0x%llx\n", ioc->name, ds, phy_info->attached.channel,
1570         phy_info->attached.id, phy_info->attached.phy_id,
1571         (unsigned long long) sas_address);
1572 
1573     port = mptsas_get_port(phy_info);
1574     if (!port) {
1575         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1576             "%s: fw_id=%d exit at line=%d\n", ioc->name,
1577              __func__, fw_id, __LINE__));
1578         return;
1579     }
1580     port_info = phy_info->portinfo;
1581     phy_info_parent = port_info->phy_info;
1582     for (i = 0; i < port_info->num_phys; i++, phy_info_parent++) {
1583         if (!phy_info_parent->phy)
1584             continue;
1585         if (phy_info_parent->attached.sas_address !=
1586             sas_address)
1587             continue;
1588         dev_printk(KERN_DEBUG, &phy_info_parent->phy->dev,
1589             MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n",
1590             ioc->name, phy_info_parent->phy_id,
1591             phy_info_parent->phy);
1592         sas_port_delete_phy(port, phy_info_parent->phy);
1593     }
1594 
1595     dev_printk(KERN_DEBUG, &port->dev, MYIOC_s_FMT
1596         "delete port %d, sas_addr (0x%llx)\n", ioc->name,
1597          port->port_identifier, (unsigned long long)sas_address);
1598     sas_port_delete(port);
1599     mptsas_set_port(ioc, phy_info, NULL);
1600     mptsas_port_delete(ioc, phy_info->port_details);
1601 }
1602 
1603 static struct mptsas_phyinfo *
1604 mptsas_refreshing_device_handles(MPT_ADAPTER *ioc,
1605     struct mptsas_devinfo *sas_device)
1606 {
1607     struct mptsas_phyinfo *phy_info;
1608     struct mptsas_portinfo *port_info;
1609     int i;
1610 
1611     phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
1612         sas_device->sas_address);
1613     if (!phy_info)
1614         goto out;
1615     port_info = phy_info->portinfo;
1616     if (!port_info)
1617         goto out;
1618     mutex_lock(&ioc->sas_topology_mutex);
1619     for (i = 0; i < port_info->num_phys; i++) {
1620         if (port_info->phy_info[i].attached.sas_address !=
1621             sas_device->sas_address)
1622             continue;
1623         port_info->phy_info[i].attached.channel = sas_device->channel;
1624         port_info->phy_info[i].attached.id = sas_device->id;
1625         port_info->phy_info[i].attached.sas_address =
1626             sas_device->sas_address;
1627         port_info->phy_info[i].attached.handle = sas_device->handle;
1628         port_info->phy_info[i].attached.handle_parent =
1629             sas_device->handle_parent;
1630         port_info->phy_info[i].attached.handle_enclosure =
1631             sas_device->handle_enclosure;
1632     }
1633     mutex_unlock(&ioc->sas_topology_mutex);
1634  out:
1635     return phy_info;
1636 }
1637 
1638 /**
1639  * mptsas_firmware_event_work - work thread for processing fw events
1640  * @work: work queue payload containing info describing the event
1641  * Context: user
1642  *
1643  */
1644 static void
1645 mptsas_firmware_event_work(struct work_struct *work)
1646 {
1647     struct fw_event_work *fw_event =
1648         container_of(work, struct fw_event_work, work.work);
1649     MPT_ADAPTER *ioc = fw_event->ioc;
1650 
1651     /* special rescan topology handling */
1652     if (fw_event->event == -1) {
1653         if (ioc->in_rescan) {
1654             devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1655                 "%s: rescan ignored as it is in progress\n",
1656                 ioc->name, __func__));
1657             return;
1658         }
1659         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: rescan after "
1660             "reset\n", ioc->name, __func__));
1661         ioc->in_rescan = 1;
1662         mptsas_not_responding_devices(ioc);
1663         mptsas_scan_sas_topology(ioc);
1664         ioc->in_rescan = 0;
1665         mptsas_free_fw_event(ioc, fw_event);
1666         mptsas_fw_event_on(ioc);
1667         return;
1668     }
1669 
1670     /* events handling turned off during host reset */
1671     if (ioc->fw_events_off) {
1672         mptsas_free_fw_event(ioc, fw_event);
1673         return;
1674     }
1675 
1676     devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: fw_event=(0x%p), "
1677         "event = (0x%02x)\n", ioc->name, __func__, fw_event,
1678         (fw_event->event & 0xFF)));
1679 
1680     switch (fw_event->event) {
1681     case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1682         mptsas_send_sas_event(fw_event);
1683         break;
1684     case MPI_EVENT_INTEGRATED_RAID:
1685         mptsas_send_raid_event(fw_event);
1686         break;
1687     case MPI_EVENT_IR2:
1688         mptsas_send_ir2_event(fw_event);
1689         break;
1690     case MPI_EVENT_PERSISTENT_TABLE_FULL:
1691         mptbase_sas_persist_operation(ioc,
1692             MPI_SAS_OP_CLEAR_NOT_PRESENT);
1693         mptsas_free_fw_event(ioc, fw_event);
1694         break;
1695     case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
1696         mptsas_broadcast_primitive_work(fw_event);
1697         break;
1698     case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
1699         mptsas_send_expander_event(fw_event);
1700         break;
1701     case MPI_EVENT_SAS_PHY_LINK_STATUS:
1702         mptsas_send_link_status_event(fw_event);
1703         break;
1704     case MPI_EVENT_QUEUE_FULL:
1705         mptsas_handle_queue_full_event(fw_event);
1706         break;
1707     }
1708 }
1709 
1710 
1711 
1712 static int
1713 mptsas_slave_configure(struct scsi_device *sdev)
1714 {
1715     struct Scsi_Host    *host = sdev->host;
1716     MPT_SCSI_HOST   *hd = shost_priv(host);
1717     MPT_ADAPTER *ioc = hd->ioc;
1718     VirtDevice  *vdevice = sdev->hostdata;
1719 
1720     if (vdevice->vtarget->deleted) {
1721         sdev_printk(KERN_INFO, sdev, "clearing deleted flag\n");
1722         vdevice->vtarget->deleted = 0;
1723     }
1724 
1725     /*
1726      * RAID volumes placed beyond the last expected port.
1727      * Ignore sending sas mode pages in that case..
1728      */
1729     if (sdev->channel == MPTSAS_RAID_CHANNEL) {
1730         mptsas_add_device_component_starget_ir(ioc, scsi_target(sdev));
1731         goto out;
1732     }
1733 
1734     sas_read_port_mode_page(sdev);
1735 
1736     mptsas_add_device_component_starget(ioc, scsi_target(sdev));
1737 
1738  out:
1739     return mptscsih_slave_configure(sdev);
1740 }
1741 
1742 static int
1743 mptsas_target_alloc(struct scsi_target *starget)
1744 {
1745     struct Scsi_Host *host = dev_to_shost(&starget->dev);
1746     MPT_SCSI_HOST       *hd = shost_priv(host);
1747     VirtTarget      *vtarget;
1748     u8          id, channel;
1749     struct sas_rphy     *rphy;
1750     struct mptsas_portinfo  *p;
1751     int              i;
1752     MPT_ADAPTER     *ioc = hd->ioc;
1753 
1754     vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
1755     if (!vtarget)
1756         return -ENOMEM;
1757 
1758     vtarget->starget = starget;
1759     vtarget->ioc_id = ioc->id;
1760     vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
1761     id = starget->id;
1762     channel = 0;
1763 
1764     /*
1765      * RAID volumes placed beyond the last expected port.
1766      */
1767     if (starget->channel == MPTSAS_RAID_CHANNEL) {
1768         if (!ioc->raid_data.pIocPg2) {
1769             kfree(vtarget);
1770             return -ENXIO;
1771         }
1772         for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
1773             if (id == ioc->raid_data.pIocPg2->
1774                     RaidVolume[i].VolumeID) {
1775                 channel = ioc->raid_data.pIocPg2->
1776                     RaidVolume[i].VolumeBus;
1777             }
1778         }
1779         vtarget->raidVolume = 1;
1780         goto out;
1781     }
1782 
1783     rphy = dev_to_rphy(starget->dev.parent);
1784     mutex_lock(&ioc->sas_topology_mutex);
1785     list_for_each_entry(p, &ioc->sas_topology, list) {
1786         for (i = 0; i < p->num_phys; i++) {
1787             if (p->phy_info[i].attached.sas_address !=
1788                     rphy->identify.sas_address)
1789                 continue;
1790             id = p->phy_info[i].attached.id;
1791             channel = p->phy_info[i].attached.channel;
1792             mptsas_set_starget(&p->phy_info[i], starget);
1793 
1794             /*
1795              * Exposing hidden raid components
1796              */
1797             if (mptscsih_is_phys_disk(ioc, channel, id)) {
1798                 id = mptscsih_raid_id_to_num(ioc,
1799                         channel, id);
1800                 vtarget->tflags |=
1801                     MPT_TARGET_FLAGS_RAID_COMPONENT;
1802                 p->phy_info[i].attached.phys_disk_num = id;
1803             }
1804             mutex_unlock(&ioc->sas_topology_mutex);
1805             goto out;
1806         }
1807     }
1808     mutex_unlock(&ioc->sas_topology_mutex);
1809 
1810     kfree(vtarget);
1811     return -ENXIO;
1812 
1813  out:
1814     vtarget->id = id;
1815     vtarget->channel = channel;
1816     starget->hostdata = vtarget;
1817     return 0;
1818 }
1819 
1820 static void
1821 mptsas_target_destroy(struct scsi_target *starget)
1822 {
1823     struct Scsi_Host *host = dev_to_shost(&starget->dev);
1824     MPT_SCSI_HOST       *hd = shost_priv(host);
1825     struct sas_rphy     *rphy;
1826     struct mptsas_portinfo  *p;
1827     int              i;
1828     MPT_ADAPTER *ioc = hd->ioc;
1829     VirtTarget  *vtarget;
1830 
1831     if (!starget->hostdata)
1832         return;
1833 
1834     vtarget = starget->hostdata;
1835 
1836     mptsas_del_device_component_by_os(ioc, starget->channel,
1837         starget->id);
1838 
1839 
1840     if (starget->channel == MPTSAS_RAID_CHANNEL)
1841         goto out;
1842 
1843     rphy = dev_to_rphy(starget->dev.parent);
1844     list_for_each_entry(p, &ioc->sas_topology, list) {
1845         for (i = 0; i < p->num_phys; i++) {
1846             if (p->phy_info[i].attached.sas_address !=
1847                     rphy->identify.sas_address)
1848                 continue;
1849 
1850             starget_printk(KERN_INFO, starget, MYIOC_s_FMT
1851             "delete device: fw_channel %d, fw_id %d, phy %d, "
1852             "sas_addr 0x%llx\n", ioc->name,
1853             p->phy_info[i].attached.channel,
1854             p->phy_info[i].attached.id,
1855             p->phy_info[i].attached.phy_id, (unsigned long long)
1856             p->phy_info[i].attached.sas_address);
1857 
1858             mptsas_set_starget(&p->phy_info[i], NULL);
1859         }
1860     }
1861 
1862  out:
1863     vtarget->starget = NULL;
1864     kfree(starget->hostdata);
1865     starget->hostdata = NULL;
1866 }
1867 
1868 
1869 static int
1870 mptsas_slave_alloc(struct scsi_device *sdev)
1871 {
1872     struct Scsi_Host    *host = sdev->host;
1873     MPT_SCSI_HOST       *hd = shost_priv(host);
1874     struct sas_rphy     *rphy;
1875     struct mptsas_portinfo  *p;
1876     VirtDevice      *vdevice;
1877     struct scsi_target  *starget;
1878     int             i;
1879     MPT_ADAPTER *ioc = hd->ioc;
1880 
1881     vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
1882     if (!vdevice) {
1883         printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
1884                 ioc->name, sizeof(VirtDevice));
1885         return -ENOMEM;
1886     }
1887     starget = scsi_target(sdev);
1888     vdevice->vtarget = starget->hostdata;
1889 
1890     if (sdev->channel == MPTSAS_RAID_CHANNEL)
1891         goto out;
1892 
1893     rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
1894     mutex_lock(&ioc->sas_topology_mutex);
1895     list_for_each_entry(p, &ioc->sas_topology, list) {
1896         for (i = 0; i < p->num_phys; i++) {
1897             if (p->phy_info[i].attached.sas_address !=
1898                     rphy->identify.sas_address)
1899                 continue;
1900             vdevice->lun = sdev->lun;
1901             /*
1902              * Exposing hidden raid components
1903              */
1904             if (mptscsih_is_phys_disk(ioc,
1905                 p->phy_info[i].attached.channel,
1906                 p->phy_info[i].attached.id))
1907                 sdev->no_uld_attach = 1;
1908             mutex_unlock(&ioc->sas_topology_mutex);
1909             goto out;
1910         }
1911     }
1912     mutex_unlock(&ioc->sas_topology_mutex);
1913 
1914     kfree(vdevice);
1915     return -ENXIO;
1916 
1917  out:
1918     vdevice->vtarget->num_luns++;
1919     sdev->hostdata = vdevice;
1920     return 0;
1921 }
1922 
1923 static int
1924 mptsas_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt)
1925 {
1926     MPT_SCSI_HOST   *hd;
1927     MPT_ADAPTER *ioc;
1928     VirtDevice  *vdevice = SCpnt->device->hostdata;
1929 
1930     if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
1931         SCpnt->result = DID_NO_CONNECT << 16;
1932         scsi_done(SCpnt);
1933         return 0;
1934     }
1935 
1936     hd = shost_priv(shost);
1937     ioc = hd->ioc;
1938 
1939     if (ioc->sas_discovery_quiesce_io)
1940         return SCSI_MLQUEUE_HOST_BUSY;
1941 
1942     if (ioc->debug_level & MPT_DEBUG_SCSI)
1943         scsi_print_command(SCpnt);
1944 
1945     return mptscsih_qcmd(SCpnt);
1946 }
1947 
1948 /**
1949  *  mptsas_eh_timed_out - resets the scsi_cmnd timeout
1950  *      if the device under question is currently in the
1951  *      device removal delay.
1952  *  @sc: scsi command that the midlayer is about to time out
1953  *
1954  **/
1955 static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc)
1956 {
1957     MPT_SCSI_HOST *hd;
1958     MPT_ADAPTER   *ioc;
1959     VirtDevice    *vdevice;
1960     enum blk_eh_timer_return rc = BLK_EH_DONE;
1961 
1962     hd = shost_priv(sc->device->host);
1963     if (hd == NULL) {
1964         printk(KERN_ERR MYNAM ": %s: Can't locate host! (sc=%p)\n",
1965             __func__, sc);
1966         goto done;
1967     }
1968 
1969     ioc = hd->ioc;
1970     if (ioc->bus_type != SAS) {
1971         printk(KERN_ERR MYNAM ": %s: Wrong bus type (sc=%p)\n",
1972             __func__, sc);
1973         goto done;
1974     }
1975 
1976     /* In case if IOC is in reset from internal context.
1977     *  Do not execute EEH for the same IOC. SML should to reset timer.
1978     */
1979     if (ioc->ioc_reset_in_progress) {
1980         dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: ioc is in reset,"
1981             "SML need to reset the timer (sc=%p)\n",
1982             ioc->name, __func__, sc));
1983         rc = BLK_EH_RESET_TIMER;
1984     }
1985     vdevice = sc->device->hostdata;
1986     if (vdevice && vdevice->vtarget && (vdevice->vtarget->inDMD
1987         || vdevice->vtarget->deleted)) {
1988         dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: target removed "
1989             "or in device removal delay (sc=%p)\n",
1990             ioc->name, __func__, sc));
1991         rc = BLK_EH_RESET_TIMER;
1992         goto done;
1993     }
1994 
1995 done:
1996     return rc;
1997 }
1998 
1999 
2000 static struct scsi_host_template mptsas_driver_template = {
2001     .module             = THIS_MODULE,
2002     .proc_name          = "mptsas",
2003     .show_info          = mptscsih_show_info,
2004     .name               = "MPT SAS Host",
2005     .info               = mptscsih_info,
2006     .queuecommand           = mptsas_qcmd,
2007     .target_alloc           = mptsas_target_alloc,
2008     .slave_alloc            = mptsas_slave_alloc,
2009     .slave_configure        = mptsas_slave_configure,
2010     .target_destroy         = mptsas_target_destroy,
2011     .slave_destroy          = mptscsih_slave_destroy,
2012     .change_queue_depth         = mptscsih_change_queue_depth,
2013     .eh_timed_out           = mptsas_eh_timed_out,
2014     .eh_abort_handler       = mptscsih_abort,
2015     .eh_device_reset_handler    = mptscsih_dev_reset,
2016     .eh_host_reset_handler      = mptscsih_host_reset,
2017     .bios_param         = mptscsih_bios_param,
2018     .can_queue          = MPT_SAS_CAN_QUEUE,
2019     .this_id            = -1,
2020     .sg_tablesize           = MPT_SCSI_SG_DEPTH,
2021     .max_sectors            = 8192,
2022     .cmd_per_lun            = 7,
2023     .shost_groups           = mptscsih_host_attr_groups,
2024     .no_write_same          = 1,
2025 };
2026 
2027 static int mptsas_get_linkerrors(struct sas_phy *phy)
2028 {
2029     MPT_ADAPTER *ioc = phy_to_ioc(phy);
2030     ConfigExtendedPageHeader_t hdr;
2031     CONFIGPARMS cfg;
2032     SasPhyPage1_t *buffer;
2033     dma_addr_t dma_handle;
2034     int error;
2035 
2036     /* FIXME: only have link errors on local phys */
2037     if (!scsi_is_sas_phy_local(phy))
2038         return -EINVAL;
2039 
2040     hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
2041     hdr.ExtPageLength = 0;
2042     hdr.PageNumber = 1 /* page number 1*/;
2043     hdr.Reserved1 = 0;
2044     hdr.Reserved2 = 0;
2045     hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2046     hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2047 
2048     cfg.cfghdr.ehdr = &hdr;
2049     cfg.physAddr = -1;
2050     cfg.pageAddr = phy->identify.phy_identifier;
2051     cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2052     cfg.dir = 0;    /* read */
2053     cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2054 
2055     error = mpt_config(ioc, &cfg);
2056     if (error)
2057         return error;
2058     if (!hdr.ExtPageLength)
2059         return -ENXIO;
2060 
2061     buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
2062                     &dma_handle, GFP_KERNEL);
2063     if (!buffer)
2064         return -ENOMEM;
2065 
2066     cfg.physAddr = dma_handle;
2067     cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2068 
2069     error = mpt_config(ioc, &cfg);
2070     if (error)
2071         goto out_free_consistent;
2072 
2073     mptsas_print_phy_pg1(ioc, buffer);
2074 
2075     phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
2076     phy->running_disparity_error_count =
2077         le32_to_cpu(buffer->RunningDisparityErrorCount);
2078     phy->loss_of_dword_sync_count =
2079         le32_to_cpu(buffer->LossDwordSynchCount);
2080     phy->phy_reset_problem_count =
2081         le32_to_cpu(buffer->PhyResetProblemCount);
2082 
2083  out_free_consistent:
2084     dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
2085               dma_handle);
2086     return error;
2087 }
2088 
2089 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2090         MPT_FRAME_HDR *reply)
2091 {
2092     ioc->sas_mgmt.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2093     if (reply != NULL) {
2094         ioc->sas_mgmt.status |= MPT_MGMT_STATUS_RF_VALID;
2095         memcpy(ioc->sas_mgmt.reply, reply,
2096             min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
2097     }
2098 
2099     if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
2100         ioc->sas_mgmt.status &= ~MPT_MGMT_STATUS_PENDING;
2101         complete(&ioc->sas_mgmt.done);
2102         return 1;
2103     }
2104     return 0;
2105 }
2106 
2107 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
2108 {
2109     MPT_ADAPTER *ioc = phy_to_ioc(phy);
2110     SasIoUnitControlRequest_t *req;
2111     SasIoUnitControlReply_t *reply;
2112     MPT_FRAME_HDR *mf;
2113     MPIHeader_t *hdr;
2114     unsigned long timeleft;
2115     int error = -ERESTARTSYS;
2116 
2117     /* FIXME: fusion doesn't allow non-local phy reset */
2118     if (!scsi_is_sas_phy_local(phy))
2119         return -EINVAL;
2120 
2121     /* not implemented for expanders */
2122     if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
2123         return -ENXIO;
2124 
2125     if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
2126         goto out;
2127 
2128     mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2129     if (!mf) {
2130         error = -ENOMEM;
2131         goto out_unlock;
2132     }
2133 
2134     hdr = (MPIHeader_t *) mf;
2135     req = (SasIoUnitControlRequest_t *)mf;
2136     memset(req, 0, sizeof(SasIoUnitControlRequest_t));
2137     req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
2138     req->MsgContext = hdr->MsgContext;
2139     req->Operation = hard_reset ?
2140         MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
2141     req->PhyNum = phy->identify.phy_identifier;
2142 
2143     INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2144     mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2145 
2146     timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
2147             10 * HZ);
2148     if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2149         error = -ETIME;
2150         mpt_free_msg_frame(ioc, mf);
2151         if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2152             goto out_unlock;
2153         if (!timeleft)
2154             mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2155         goto out_unlock;
2156     }
2157 
2158     /* a reply frame is expected */
2159     if ((ioc->sas_mgmt.status &
2160         MPT_MGMT_STATUS_RF_VALID) == 0) {
2161         error = -ENXIO;
2162         goto out_unlock;
2163     }
2164 
2165     /* process the completed Reply Message Frame */
2166     reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
2167     if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
2168         printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
2169             ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo);
2170         error = -ENXIO;
2171         goto out_unlock;
2172     }
2173 
2174     error = 0;
2175 
2176  out_unlock:
2177     CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2178     mutex_unlock(&ioc->sas_mgmt.mutex);
2179  out:
2180     return error;
2181 }
2182 
2183 static int
2184 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
2185 {
2186     MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2187     int i, error;
2188     struct mptsas_portinfo *p;
2189     struct mptsas_enclosure enclosure_info;
2190     u64 enclosure_handle;
2191 
2192     mutex_lock(&ioc->sas_topology_mutex);
2193     list_for_each_entry(p, &ioc->sas_topology, list) {
2194         for (i = 0; i < p->num_phys; i++) {
2195             if (p->phy_info[i].attached.sas_address ==
2196                 rphy->identify.sas_address) {
2197                 enclosure_handle = p->phy_info[i].
2198                     attached.handle_enclosure;
2199                 goto found_info;
2200             }
2201         }
2202     }
2203     mutex_unlock(&ioc->sas_topology_mutex);
2204     return -ENXIO;
2205 
2206  found_info:
2207     mutex_unlock(&ioc->sas_topology_mutex);
2208     memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
2209     error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
2210             (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
2211              MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
2212     if (!error)
2213         *identifier = enclosure_info.enclosure_logical_id;
2214     return error;
2215 }
2216 
2217 static int
2218 mptsas_get_bay_identifier(struct sas_rphy *rphy)
2219 {
2220     MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2221     struct mptsas_portinfo *p;
2222     int i, rc;
2223 
2224     mutex_lock(&ioc->sas_topology_mutex);
2225     list_for_each_entry(p, &ioc->sas_topology, list) {
2226         for (i = 0; i < p->num_phys; i++) {
2227             if (p->phy_info[i].attached.sas_address ==
2228                 rphy->identify.sas_address) {
2229                 rc = p->phy_info[i].attached.slot;
2230                 goto out;
2231             }
2232         }
2233     }
2234     rc = -ENXIO;
2235  out:
2236     mutex_unlock(&ioc->sas_topology_mutex);
2237     return rc;
2238 }
2239 
2240 static void mptsas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
2241         struct sas_rphy *rphy)
2242 {
2243     MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
2244     MPT_FRAME_HDR *mf;
2245     SmpPassthroughRequest_t *smpreq;
2246     int flagsLength;
2247     unsigned long timeleft;
2248     char *psge;
2249     u64 sas_address = 0;
2250     unsigned int reslen = 0;
2251     int ret = -EINVAL;
2252 
2253     /* do we need to support multiple segments? */
2254     if (job->request_payload.sg_cnt > 1 ||
2255         job->reply_payload.sg_cnt > 1) {
2256         printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u, rsp %u\n",
2257             ioc->name, __func__, job->request_payload.payload_len,
2258             job->reply_payload.payload_len);
2259         goto out;
2260     }
2261 
2262     ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2263     if (ret)
2264         goto out;
2265 
2266     mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2267     if (!mf) {
2268         ret = -ENOMEM;
2269         goto out_unlock;
2270     }
2271 
2272     smpreq = (SmpPassthroughRequest_t *)mf;
2273     memset(smpreq, 0, sizeof(*smpreq));
2274 
2275     smpreq->RequestDataLength =
2276         cpu_to_le16(job->request_payload.payload_len - 4);
2277     smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2278 
2279     if (rphy)
2280         sas_address = rphy->identify.sas_address;
2281     else {
2282         struct mptsas_portinfo *port_info;
2283 
2284         mutex_lock(&ioc->sas_topology_mutex);
2285         port_info = ioc->hba_port_info;
2286         if (port_info && port_info->phy_info)
2287             sas_address =
2288                 port_info->phy_info[0].phy->identify.sas_address;
2289         mutex_unlock(&ioc->sas_topology_mutex);
2290     }
2291 
2292     *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2293 
2294     psge = (char *)
2295         (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2296 
2297     /* request */
2298     flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2299                MPI_SGE_FLAGS_END_OF_BUFFER |
2300                MPI_SGE_FLAGS_DIRECTION)
2301                << MPI_SGE_FLAGS_SHIFT;
2302 
2303     if (!dma_map_sg(&ioc->pcidev->dev, job->request_payload.sg_list,
2304             1, DMA_BIDIRECTIONAL))
2305         goto put_mf;
2306 
2307     flagsLength |= (sg_dma_len(job->request_payload.sg_list) - 4);
2308     ioc->add_sge(psge, flagsLength,
2309             sg_dma_address(job->request_payload.sg_list));
2310     psge += ioc->SGE_size;
2311 
2312     /* response */
2313     flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2314         MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2315         MPI_SGE_FLAGS_IOC_TO_HOST |
2316         MPI_SGE_FLAGS_END_OF_BUFFER;
2317 
2318     flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2319 
2320     if (!dma_map_sg(&ioc->pcidev->dev, job->reply_payload.sg_list,
2321             1, DMA_BIDIRECTIONAL))
2322         goto unmap_out;
2323     flagsLength |= sg_dma_len(job->reply_payload.sg_list) + 4;
2324     ioc->add_sge(psge, flagsLength,
2325             sg_dma_address(job->reply_payload.sg_list));
2326 
2327     INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2328     mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2329 
2330     timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2331     if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2332         ret = -ETIME;
2333         mpt_free_msg_frame(ioc, mf);
2334         mf = NULL;
2335         if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2336             goto unmap_in;
2337         if (!timeleft)
2338             mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2339         goto unmap_in;
2340     }
2341     mf = NULL;
2342 
2343     if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2344         SmpPassthroughReply_t *smprep;
2345 
2346         smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2347         memcpy(job->reply, smprep, sizeof(*smprep));
2348         job->reply_len = sizeof(*smprep);
2349         reslen = smprep->ResponseDataLength;
2350     } else {
2351         printk(MYIOC_s_ERR_FMT
2352             "%s: smp passthru reply failed to be returned\n",
2353             ioc->name, __func__);
2354         ret = -ENXIO;
2355     }
2356 
2357 unmap_in:
2358     dma_unmap_sg(&ioc->pcidev->dev, job->reply_payload.sg_list, 1,
2359             DMA_BIDIRECTIONAL);
2360 unmap_out:
2361     dma_unmap_sg(&ioc->pcidev->dev, job->request_payload.sg_list, 1,
2362             DMA_BIDIRECTIONAL);
2363 put_mf:
2364     if (mf)
2365         mpt_free_msg_frame(ioc, mf);
2366 out_unlock:
2367     CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2368     mutex_unlock(&ioc->sas_mgmt.mutex);
2369 out:
2370     bsg_job_done(job, ret, reslen);
2371 }
2372 
2373 static struct sas_function_template mptsas_transport_functions = {
2374     .get_linkerrors     = mptsas_get_linkerrors,
2375     .get_enclosure_identifier = mptsas_get_enclosure_identifier,
2376     .get_bay_identifier = mptsas_get_bay_identifier,
2377     .phy_reset      = mptsas_phy_reset,
2378     .smp_handler        = mptsas_smp_handler,
2379 };
2380 
2381 static struct scsi_transport_template *mptsas_transport_template;
2382 
2383 static int
2384 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
2385 {
2386     ConfigExtendedPageHeader_t hdr;
2387     CONFIGPARMS cfg;
2388     SasIOUnitPage0_t *buffer;
2389     dma_addr_t dma_handle;
2390     int error, i;
2391 
2392     hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
2393     hdr.ExtPageLength = 0;
2394     hdr.PageNumber = 0;
2395     hdr.Reserved1 = 0;
2396     hdr.Reserved2 = 0;
2397     hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2398     hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2399 
2400     cfg.cfghdr.ehdr = &hdr;
2401     cfg.physAddr = -1;
2402     cfg.pageAddr = 0;
2403     cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2404     cfg.dir = 0;    /* read */
2405     cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2406 
2407     error = mpt_config(ioc, &cfg);
2408     if (error)
2409         goto out;
2410     if (!hdr.ExtPageLength) {
2411         error = -ENXIO;
2412         goto out;
2413     }
2414 
2415     buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
2416                     &dma_handle, GFP_KERNEL);
2417     if (!buffer) {
2418         error = -ENOMEM;
2419         goto out;
2420     }
2421 
2422     cfg.physAddr = dma_handle;
2423     cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2424 
2425     error = mpt_config(ioc, &cfg);
2426     if (error)
2427         goto out_free_consistent;
2428 
2429     port_info->num_phys = buffer->NumPhys;
2430     port_info->phy_info = kcalloc(port_info->num_phys,
2431         sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2432     if (!port_info->phy_info) {
2433         error = -ENOMEM;
2434         goto out_free_consistent;
2435     }
2436 
2437     ioc->nvdata_version_persistent =
2438         le16_to_cpu(buffer->NvdataVersionPersistent);
2439     ioc->nvdata_version_default =
2440         le16_to_cpu(buffer->NvdataVersionDefault);
2441 
2442     for (i = 0; i < port_info->num_phys; i++) {
2443         mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
2444         port_info->phy_info[i].phy_id = i;
2445         port_info->phy_info[i].port_id =
2446             buffer->PhyData[i].Port;
2447         port_info->phy_info[i].negotiated_link_rate =
2448             buffer->PhyData[i].NegotiatedLinkRate;
2449         port_info->phy_info[i].portinfo = port_info;
2450         port_info->phy_info[i].handle =
2451             le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
2452     }
2453 
2454  out_free_consistent:
2455     dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
2456               dma_handle);
2457  out:
2458     return error;
2459 }
2460 
2461 static int
2462 mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
2463 {
2464     ConfigExtendedPageHeader_t hdr;
2465     CONFIGPARMS cfg;
2466     SasIOUnitPage1_t *buffer;
2467     dma_addr_t dma_handle;
2468     int error;
2469     u8 device_missing_delay;
2470 
2471     memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
2472     memset(&cfg, 0, sizeof(CONFIGPARMS));
2473 
2474     cfg.cfghdr.ehdr = &hdr;
2475     cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2476     cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2477     cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2478     cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2479     cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
2480     cfg.cfghdr.ehdr->PageNumber = 1;
2481 
2482     error = mpt_config(ioc, &cfg);
2483     if (error)
2484         goto out;
2485     if (!hdr.ExtPageLength) {
2486         error = -ENXIO;
2487         goto out;
2488     }
2489 
2490     buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
2491                     &dma_handle, GFP_KERNEL);
2492     if (!buffer) {
2493         error = -ENOMEM;
2494         goto out;
2495     }
2496 
2497     cfg.physAddr = dma_handle;
2498     cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2499 
2500     error = mpt_config(ioc, &cfg);
2501     if (error)
2502         goto out_free_consistent;
2503 
2504     ioc->io_missing_delay  =
2505         le16_to_cpu(buffer->IODeviceMissingDelay);
2506     device_missing_delay = buffer->ReportDeviceMissingDelay;
2507     ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
2508         (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
2509         device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
2510 
2511  out_free_consistent:
2512     dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
2513               dma_handle);
2514  out:
2515     return error;
2516 }
2517 
2518 static int
2519 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2520         u32 form, u32 form_specific)
2521 {
2522     ConfigExtendedPageHeader_t hdr;
2523     CONFIGPARMS cfg;
2524     SasPhyPage0_t *buffer;
2525     dma_addr_t dma_handle;
2526     int error;
2527 
2528     hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
2529     hdr.ExtPageLength = 0;
2530     hdr.PageNumber = 0;
2531     hdr.Reserved1 = 0;
2532     hdr.Reserved2 = 0;
2533     hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2534     hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2535 
2536     cfg.cfghdr.ehdr = &hdr;
2537     cfg.dir = 0;    /* read */
2538     cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2539 
2540     /* Get Phy Pg 0 for each Phy. */
2541     cfg.physAddr = -1;
2542     cfg.pageAddr = form + form_specific;
2543     cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2544 
2545     error = mpt_config(ioc, &cfg);
2546     if (error)
2547         goto out;
2548 
2549     if (!hdr.ExtPageLength) {
2550         error = -ENXIO;
2551         goto out;
2552     }
2553 
2554     buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
2555                     &dma_handle, GFP_KERNEL);
2556     if (!buffer) {
2557         error = -ENOMEM;
2558         goto out;
2559     }
2560 
2561     cfg.physAddr = dma_handle;
2562     cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2563 
2564     error = mpt_config(ioc, &cfg);
2565     if (error)
2566         goto out_free_consistent;
2567 
2568     mptsas_print_phy_pg0(ioc, buffer);
2569 
2570     phy_info->hw_link_rate = buffer->HwLinkRate;
2571     phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2572     phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2573     phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2574 
2575  out_free_consistent:
2576     dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
2577               dma_handle);
2578  out:
2579     return error;
2580 }
2581 
2582 static int
2583 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
2584         u32 form, u32 form_specific)
2585 {
2586     ConfigExtendedPageHeader_t hdr;
2587     CONFIGPARMS cfg;
2588     SasDevicePage0_t *buffer;
2589     dma_addr_t dma_handle;
2590     __le64 sas_address;
2591     int error=0;
2592 
2593     hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
2594     hdr.ExtPageLength = 0;
2595     hdr.PageNumber = 0;
2596     hdr.Reserved1 = 0;
2597     hdr.Reserved2 = 0;
2598     hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2599     hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
2600 
2601     cfg.cfghdr.ehdr = &hdr;
2602     cfg.pageAddr = form + form_specific;
2603     cfg.physAddr = -1;
2604     cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2605     cfg.dir = 0;    /* read */
2606     cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2607 
2608     memset(device_info, 0, sizeof(struct mptsas_devinfo));
2609     error = mpt_config(ioc, &cfg);
2610     if (error)
2611         goto out;
2612     if (!hdr.ExtPageLength) {
2613         error = -ENXIO;
2614         goto out;
2615     }
2616 
2617     buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
2618                     &dma_handle, GFP_KERNEL);
2619     if (!buffer) {
2620         error = -ENOMEM;
2621         goto out;
2622     }
2623 
2624     cfg.physAddr = dma_handle;
2625     cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2626 
2627     error = mpt_config(ioc, &cfg);
2628 
2629     if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2630         error = -ENODEV;
2631         goto out_free_consistent;
2632     }
2633 
2634     if (error)
2635         goto out_free_consistent;
2636 
2637     mptsas_print_device_pg0(ioc, buffer);
2638 
2639     memset(device_info, 0, sizeof(struct mptsas_devinfo));
2640     device_info->handle = le16_to_cpu(buffer->DevHandle);
2641     device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
2642     device_info->handle_enclosure =
2643         le16_to_cpu(buffer->EnclosureHandle);
2644     device_info->slot = le16_to_cpu(buffer->Slot);
2645     device_info->phy_id = buffer->PhyNum;
2646     device_info->port_id = buffer->PhysicalPort;
2647     device_info->id = buffer->TargetID;
2648     device_info->phys_disk_num = ~0;
2649     device_info->channel = buffer->Bus;
2650     memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2651     device_info->sas_address = le64_to_cpu(sas_address);
2652     device_info->device_info =
2653         le32_to_cpu(buffer->DeviceInfo);
2654     device_info->flags = le16_to_cpu(buffer->Flags);
2655 
2656  out_free_consistent:
2657     dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
2658               dma_handle);
2659  out:
2660     return error;
2661 }
2662 
2663 static int
2664 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
2665         u32 form, u32 form_specific)
2666 {
2667     ConfigExtendedPageHeader_t hdr;
2668     CONFIGPARMS cfg;
2669     SasExpanderPage0_t *buffer;
2670     dma_addr_t dma_handle;
2671     int i, error;
2672     __le64 sas_address;
2673 
2674     memset(port_info, 0, sizeof(struct mptsas_portinfo));
2675     hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
2676     hdr.ExtPageLength = 0;
2677     hdr.PageNumber = 0;
2678     hdr.Reserved1 = 0;
2679     hdr.Reserved2 = 0;
2680     hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2681     hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2682 
2683     cfg.cfghdr.ehdr = &hdr;
2684     cfg.physAddr = -1;
2685     cfg.pageAddr = form + form_specific;
2686     cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2687     cfg.dir = 0;    /* read */
2688     cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2689 
2690     memset(port_info, 0, sizeof(struct mptsas_portinfo));
2691     error = mpt_config(ioc, &cfg);
2692     if (error)
2693         goto out;
2694 
2695     if (!hdr.ExtPageLength) {
2696         error = -ENXIO;
2697         goto out;
2698     }
2699 
2700     buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
2701                     &dma_handle, GFP_KERNEL);
2702     if (!buffer) {
2703         error = -ENOMEM;
2704         goto out;
2705     }
2706 
2707     cfg.physAddr = dma_handle;
2708     cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2709 
2710     error = mpt_config(ioc, &cfg);
2711     if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2712         error = -ENODEV;
2713         goto out_free_consistent;
2714     }
2715 
2716     if (error)
2717         goto out_free_consistent;
2718 
2719     /* save config data */
2720     port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1;
2721     port_info->phy_info = kcalloc(port_info->num_phys,
2722         sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2723     if (!port_info->phy_info) {
2724         error = -ENOMEM;
2725         goto out_free_consistent;
2726     }
2727 
2728     memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2729     for (i = 0; i < port_info->num_phys; i++) {
2730         port_info->phy_info[i].portinfo = port_info;
2731         port_info->phy_info[i].handle =
2732             le16_to_cpu(buffer->DevHandle);
2733         port_info->phy_info[i].identify.sas_address =
2734             le64_to_cpu(sas_address);
2735         port_info->phy_info[i].identify.handle_parent =
2736             le16_to_cpu(buffer->ParentDevHandle);
2737     }
2738 
2739  out_free_consistent:
2740     dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
2741               dma_handle);
2742  out:
2743     return error;
2744 }
2745 
2746 static int
2747 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2748         u32 form, u32 form_specific)
2749 {
2750     ConfigExtendedPageHeader_t hdr;
2751     CONFIGPARMS cfg;
2752     SasExpanderPage1_t *buffer;
2753     dma_addr_t dma_handle;
2754     int error=0;
2755 
2756     hdr.PageVersion = MPI_SASEXPANDER1_PAGEVERSION;
2757     hdr.ExtPageLength = 0;
2758     hdr.PageNumber = 1;
2759     hdr.Reserved1 = 0;
2760     hdr.Reserved2 = 0;
2761     hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2762     hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2763 
2764     cfg.cfghdr.ehdr = &hdr;
2765     cfg.physAddr = -1;
2766     cfg.pageAddr = form + form_specific;
2767     cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2768     cfg.dir = 0;    /* read */
2769     cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2770 
2771     error = mpt_config(ioc, &cfg);
2772     if (error)
2773         goto out;
2774 
2775     if (!hdr.ExtPageLength) {
2776         error = -ENXIO;
2777         goto out;
2778     }
2779 
2780     buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
2781                     &dma_handle, GFP_KERNEL);
2782     if (!buffer) {
2783         error = -ENOMEM;
2784         goto out;
2785     }
2786 
2787     cfg.physAddr = dma_handle;
2788     cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2789 
2790     error = mpt_config(ioc, &cfg);
2791 
2792     if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2793         error = -ENODEV;
2794         goto out_free_consistent;
2795     }
2796 
2797     if (error)
2798         goto out_free_consistent;
2799 
2800 
2801     mptsas_print_expander_pg1(ioc, buffer);
2802 
2803     /* save config data */
2804     phy_info->phy_id = buffer->PhyIdentifier;
2805     phy_info->port_id = buffer->PhysicalPort;
2806     phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
2807     phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2808     phy_info->hw_link_rate = buffer->HwLinkRate;
2809     phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2810     phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2811 
2812  out_free_consistent:
2813     dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
2814               dma_handle);
2815  out:
2816     return error;
2817 }
2818 
2819 struct rep_manu_request{
2820     u8 smp_frame_type;
2821     u8 function;
2822     u8 reserved;
2823     u8 request_length;
2824 };
2825 
2826 struct rep_manu_reply{
2827     u8 smp_frame_type; /* 0x41 */
2828     u8 function; /* 0x01 */
2829     u8 function_result;
2830     u8 response_length;
2831     u16 expander_change_count;
2832     u8 reserved0[2];
2833     u8 sas_format:1;
2834     u8 reserved1:7;
2835     u8 reserved2[3];
2836     u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
2837     u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
2838     u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
2839     u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
2840     u16 component_id;
2841     u8 component_revision_id;
2842     u8 reserved3;
2843     u8 vendor_specific[8];
2844 };
2845 
2846 /**
2847   * mptsas_exp_repmanufacture_info - sets expander manufacturer info
2848   * @ioc: per adapter object
2849   * @sas_address: expander sas address
2850   * @edev: the sas_expander_device object
2851   *
2852   * For an edge expander or a fanout expander:
2853   * fills in the sas_expander_device object when SMP port is created.
2854   *
2855   * Return: 0 for success, non-zero for failure.
2856   */
2857 static int
2858 mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
2859     u64 sas_address, struct sas_expander_device *edev)
2860 {
2861     MPT_FRAME_HDR *mf;
2862     SmpPassthroughRequest_t *smpreq;
2863     SmpPassthroughReply_t *smprep;
2864     struct rep_manu_reply *manufacture_reply;
2865     struct rep_manu_request *manufacture_request;
2866     int ret;
2867     int flagsLength;
2868     unsigned long timeleft;
2869     char *psge;
2870     unsigned long flags;
2871     void *data_out = NULL;
2872     dma_addr_t data_out_dma = 0;
2873     u32 sz;
2874 
2875     spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2876     if (ioc->ioc_reset_in_progress) {
2877         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2878         printk(MYIOC_s_INFO_FMT "%s: host reset in progress!\n",
2879             __func__, ioc->name);
2880         return -EFAULT;
2881     }
2882     spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2883 
2884     ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2885     if (ret)
2886         goto out;
2887 
2888     mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2889     if (!mf) {
2890         ret = -ENOMEM;
2891         goto out_unlock;
2892     }
2893 
2894     smpreq = (SmpPassthroughRequest_t *)mf;
2895     memset(smpreq, 0, sizeof(*smpreq));
2896 
2897     sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
2898 
2899     data_out = dma_alloc_coherent(&ioc->pcidev->dev, sz, &data_out_dma,
2900                       GFP_KERNEL);
2901     if (!data_out) {
2902         printk(KERN_ERR "Memory allocation failure at %s:%d/%s()!\n",
2903             __FILE__, __LINE__, __func__);
2904         ret = -ENOMEM;
2905         goto put_mf;
2906     }
2907 
2908     manufacture_request = data_out;
2909     manufacture_request->smp_frame_type = 0x40;
2910     manufacture_request->function = 1;
2911     manufacture_request->reserved = 0;
2912     manufacture_request->request_length = 0;
2913 
2914     smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2915     smpreq->PhysicalPort = 0xFF;
2916     *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2917     smpreq->RequestDataLength = sizeof(struct rep_manu_request);
2918 
2919     psge = (char *)
2920         (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2921 
2922     flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2923         MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2924         MPI_SGE_FLAGS_HOST_TO_IOC |
2925         MPI_SGE_FLAGS_END_OF_BUFFER;
2926     flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2927     flagsLength |= sizeof(struct rep_manu_request);
2928 
2929     ioc->add_sge(psge, flagsLength, data_out_dma);
2930     psge += ioc->SGE_size;
2931 
2932     flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2933         MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2934         MPI_SGE_FLAGS_IOC_TO_HOST |
2935         MPI_SGE_FLAGS_END_OF_BUFFER;
2936     flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2937     flagsLength |= sizeof(struct rep_manu_reply);
2938     ioc->add_sge(psge, flagsLength, data_out_dma +
2939     sizeof(struct rep_manu_request));
2940 
2941     INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2942     mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2943 
2944     timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2945     if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2946         ret = -ETIME;
2947         mpt_free_msg_frame(ioc, mf);
2948         mf = NULL;
2949         if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2950             goto out_free;
2951         if (!timeleft)
2952             mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2953         goto out_free;
2954     }
2955 
2956     mf = NULL;
2957 
2958     if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2959         u8 *tmp;
2960 
2961         smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2962         if (le16_to_cpu(smprep->ResponseDataLength) !=
2963             sizeof(struct rep_manu_reply))
2964             goto out_free;
2965 
2966         manufacture_reply = data_out + sizeof(struct rep_manu_request);
2967         strncpy(edev->vendor_id, manufacture_reply->vendor_id,
2968             SAS_EXPANDER_VENDOR_ID_LEN);
2969         strncpy(edev->product_id, manufacture_reply->product_id,
2970             SAS_EXPANDER_PRODUCT_ID_LEN);
2971         strncpy(edev->product_rev, manufacture_reply->product_rev,
2972             SAS_EXPANDER_PRODUCT_REV_LEN);
2973         edev->level = manufacture_reply->sas_format;
2974         if (manufacture_reply->sas_format) {
2975             strncpy(edev->component_vendor_id,
2976                 manufacture_reply->component_vendor_id,
2977                 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
2978             tmp = (u8 *)&manufacture_reply->component_id;
2979             edev->component_id = tmp[0] << 8 | tmp[1];
2980             edev->component_revision_id =
2981                 manufacture_reply->component_revision_id;
2982         }
2983     } else {
2984         printk(MYIOC_s_ERR_FMT
2985             "%s: smp passthru reply failed to be returned\n",
2986             ioc->name, __func__);
2987         ret = -ENXIO;
2988     }
2989 out_free:
2990     if (data_out_dma)
2991         dma_free_coherent(&ioc->pcidev->dev, sz, data_out,
2992                   data_out_dma);
2993 put_mf:
2994     if (mf)
2995         mpt_free_msg_frame(ioc, mf);
2996 out_unlock:
2997     CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2998     mutex_unlock(&ioc->sas_mgmt.mutex);
2999 out:
3000     return ret;
3001 }
3002 
3003 static void
3004 mptsas_parse_device_info(struct sas_identify *identify,
3005         struct mptsas_devinfo *device_info)
3006 {
3007     u16 protocols;
3008 
3009     identify->sas_address = device_info->sas_address;
3010     identify->phy_identifier = device_info->phy_id;
3011 
3012     /*
3013      * Fill in Phy Initiator Port Protocol.
3014      * Bits 6:3, more than one bit can be set, fall through cases.
3015      */
3016     protocols = device_info->device_info & 0x78;
3017     identify->initiator_port_protocols = 0;
3018     if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
3019         identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
3020     if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
3021         identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
3022     if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
3023         identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
3024     if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
3025         identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
3026 
3027     /*
3028      * Fill in Phy Target Port Protocol.
3029      * Bits 10:7, more than one bit can be set, fall through cases.
3030      */
3031     protocols = device_info->device_info & 0x780;
3032     identify->target_port_protocols = 0;
3033     if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
3034         identify->target_port_protocols |= SAS_PROTOCOL_SSP;
3035     if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
3036         identify->target_port_protocols |= SAS_PROTOCOL_STP;
3037     if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
3038         identify->target_port_protocols |= SAS_PROTOCOL_SMP;
3039     if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
3040         identify->target_port_protocols |= SAS_PROTOCOL_SATA;
3041 
3042     /*
3043      * Fill in Attached device type.
3044      */
3045     switch (device_info->device_info &
3046             MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
3047     case MPI_SAS_DEVICE_INFO_NO_DEVICE:
3048         identify->device_type = SAS_PHY_UNUSED;
3049         break;
3050     case MPI_SAS_DEVICE_INFO_END_DEVICE:
3051         identify->device_type = SAS_END_DEVICE;
3052         break;
3053     case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
3054         identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
3055         break;
3056     case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
3057         identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
3058         break;
3059     }
3060 }
3061 
3062 static int mptsas_probe_one_phy(struct device *dev,
3063         struct mptsas_phyinfo *phy_info, int index, int local)
3064 {
3065     MPT_ADAPTER *ioc;
3066     struct sas_phy *phy;
3067     struct sas_port *port;
3068     int error = 0;
3069     VirtTarget *vtarget;
3070 
3071     if (!dev) {
3072         error = -ENODEV;
3073         goto out;
3074     }
3075 
3076     if (!phy_info->phy) {
3077         phy = sas_phy_alloc(dev, index);
3078         if (!phy) {
3079             error = -ENOMEM;
3080             goto out;
3081         }
3082     } else
3083         phy = phy_info->phy;
3084 
3085     mptsas_parse_device_info(&phy->identify, &phy_info->identify);
3086 
3087     /*
3088      * Set Negotiated link rate.
3089      */
3090     switch (phy_info->negotiated_link_rate) {
3091     case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
3092         phy->negotiated_linkrate = SAS_PHY_DISABLED;
3093         break;
3094     case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
3095         phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
3096         break;
3097     case MPI_SAS_IOUNIT0_RATE_1_5:
3098         phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
3099         break;
3100     case MPI_SAS_IOUNIT0_RATE_3_0:
3101         phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
3102         break;
3103     case MPI_SAS_IOUNIT0_RATE_6_0:
3104         phy->negotiated_linkrate = SAS_LINK_RATE_6_0_GBPS;
3105         break;
3106     case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
3107     case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
3108     default:
3109         phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
3110         break;
3111     }
3112 
3113     /*
3114      * Set Max hardware link rate.
3115      */
3116     switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
3117     case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
3118         phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
3119         break;
3120     case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
3121         phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
3122         break;
3123     default:
3124         break;
3125     }
3126 
3127     /*
3128      * Set Max programmed link rate.
3129      */
3130     switch (phy_info->programmed_link_rate &
3131             MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
3132     case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
3133         phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
3134         break;
3135     case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
3136         phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
3137         break;
3138     default:
3139         break;
3140     }
3141 
3142     /*
3143      * Set Min hardware link rate.
3144      */
3145     switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
3146     case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
3147         phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
3148         break;
3149     case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
3150         phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
3151         break;
3152     default:
3153         break;
3154     }
3155 
3156     /*
3157      * Set Min programmed link rate.
3158      */
3159     switch (phy_info->programmed_link_rate &
3160             MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
3161     case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
3162         phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
3163         break;
3164     case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
3165         phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
3166         break;
3167     default:
3168         break;
3169     }
3170 
3171     if (!phy_info->phy) {
3172 
3173         error = sas_phy_add(phy);
3174         if (error) {
3175             sas_phy_free(phy);
3176             goto out;
3177         }
3178         phy_info->phy = phy;
3179     }
3180 
3181     if (!phy_info->attached.handle ||
3182             !phy_info->port_details)
3183         goto out;
3184 
3185     port = mptsas_get_port(phy_info);
3186     ioc = phy_to_ioc(phy_info->phy);
3187 
3188     if (phy_info->sas_port_add_phy) {
3189 
3190         if (!port) {
3191             port = sas_port_alloc_num(dev);
3192             if (!port) {
3193                 error = -ENOMEM;
3194                 goto out;
3195             }
3196             error = sas_port_add(port);
3197             if (error) {
3198                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3199                     "%s: exit at line=%d\n", ioc->name,
3200                     __func__, __LINE__));
3201                 goto out;
3202             }
3203             mptsas_set_port(ioc, phy_info, port);
3204             devtprintk(ioc, dev_printk(KERN_DEBUG, &port->dev,
3205                 MYIOC_s_FMT "add port %d, sas_addr (0x%llx)\n",
3206                 ioc->name, port->port_identifier,
3207                 (unsigned long long)phy_info->
3208                 attached.sas_address));
3209         }
3210         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3211             "sas_port_add_phy: phy_id=%d\n",
3212             ioc->name, phy_info->phy_id));
3213         sas_port_add_phy(port, phy_info->phy);
3214         phy_info->sas_port_add_phy = 0;
3215         devtprintk(ioc, dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3216             MYIOC_s_FMT "add phy %d, phy-obj (0x%p)\n", ioc->name,
3217              phy_info->phy_id, phy_info->phy));
3218     }
3219     if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
3220 
3221         struct sas_rphy *rphy;
3222         struct device *parent;
3223         struct sas_identify identify;
3224 
3225         parent = dev->parent->parent;
3226         /*
3227          * Let the hotplug_work thread handle processing
3228          * the adding/removing of devices that occur
3229          * after start of day.
3230          */
3231         if (mptsas_is_end_device(&phy_info->attached) &&
3232             phy_info->attached.handle_parent) {
3233             goto out;
3234         }
3235 
3236         mptsas_parse_device_info(&identify, &phy_info->attached);
3237         if (scsi_is_host_device(parent)) {
3238             struct mptsas_portinfo *port_info;
3239             int i;
3240 
3241             port_info = ioc->hba_port_info;
3242 
3243             for (i = 0; i < port_info->num_phys; i++)
3244                 if (port_info->phy_info[i].identify.sas_address ==
3245                     identify.sas_address) {
3246                     sas_port_mark_backlink(port);
3247                     goto out;
3248                 }
3249 
3250         } else if (scsi_is_sas_rphy(parent)) {
3251             struct sas_rphy *parent_rphy = dev_to_rphy(parent);
3252             if (identify.sas_address ==
3253                 parent_rphy->identify.sas_address) {
3254                 sas_port_mark_backlink(port);
3255                 goto out;
3256             }
3257         }
3258 
3259         switch (identify.device_type) {
3260         case SAS_END_DEVICE:
3261             rphy = sas_end_device_alloc(port);
3262             break;
3263         case SAS_EDGE_EXPANDER_DEVICE:
3264         case SAS_FANOUT_EXPANDER_DEVICE:
3265             rphy = sas_expander_alloc(port, identify.device_type);
3266             break;
3267         default:
3268             rphy = NULL;
3269             break;
3270         }
3271         if (!rphy) {
3272             dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3273                 "%s: exit at line=%d\n", ioc->name,
3274                 __func__, __LINE__));
3275             goto out;
3276         }
3277 
3278         rphy->identify = identify;
3279         error = sas_rphy_add(rphy);
3280         if (error) {
3281             dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3282                 "%s: exit at line=%d\n", ioc->name,
3283                 __func__, __LINE__));
3284             sas_rphy_free(rphy);
3285             goto out;
3286         }
3287         mptsas_set_rphy(ioc, phy_info, rphy);
3288         if (identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
3289             identify.device_type == SAS_FANOUT_EXPANDER_DEVICE)
3290                 mptsas_exp_repmanufacture_info(ioc,
3291                     identify.sas_address,
3292                     rphy_to_expander_device(rphy));
3293     }
3294 
3295     /* If the device exists, verify it wasn't previously flagged
3296     as a missing device.  If so, clear it */
3297     vtarget = mptsas_find_vtarget(ioc,
3298         phy_info->attached.channel,
3299         phy_info->attached.id);
3300     if (vtarget && vtarget->inDMD) {
3301         printk(KERN_INFO "Device returned, unsetting inDMD\n");
3302         vtarget->inDMD = 0;
3303     }
3304 
3305  out:
3306     return error;
3307 }
3308 
3309 static int
3310 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
3311 {
3312     struct mptsas_portinfo *port_info, *hba;
3313     int error = -ENOMEM, i;
3314 
3315     hba = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3316     if (! hba)
3317         goto out;
3318 
3319     error = mptsas_sas_io_unit_pg0(ioc, hba);
3320     if (error)
3321         goto out_free_port_info;
3322 
3323     mptsas_sas_io_unit_pg1(ioc);
3324     mutex_lock(&ioc->sas_topology_mutex);
3325     port_info = ioc->hba_port_info;
3326     if (!port_info) {
3327         ioc->hba_port_info = port_info = hba;
3328         ioc->hba_port_num_phy = port_info->num_phys;
3329         list_add_tail(&port_info->list, &ioc->sas_topology);
3330     } else {
3331         for (i = 0; i < hba->num_phys; i++) {
3332             port_info->phy_info[i].negotiated_link_rate =
3333                 hba->phy_info[i].negotiated_link_rate;
3334             port_info->phy_info[i].handle =
3335                 hba->phy_info[i].handle;
3336             port_info->phy_info[i].port_id =
3337                 hba->phy_info[i].port_id;
3338         }
3339         kfree(hba->phy_info);
3340         kfree(hba);
3341         hba = NULL;
3342     }
3343     mutex_unlock(&ioc->sas_topology_mutex);
3344 #if defined(CPQ_CIM)
3345     ioc->num_ports = port_info->num_phys;
3346 #endif
3347     for (i = 0; i < port_info->num_phys; i++) {
3348         mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
3349             (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
3350              MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
3351         port_info->phy_info[i].identify.handle =
3352             port_info->phy_info[i].handle;
3353         mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
3354             (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3355              MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3356              port_info->phy_info[i].identify.handle);
3357         if (!ioc->hba_port_sas_addr)
3358             ioc->hba_port_sas_addr =
3359                 port_info->phy_info[i].identify.sas_address;
3360         port_info->phy_info[i].identify.phy_id =
3361             port_info->phy_info[i].phy_id = i;
3362         if (port_info->phy_info[i].attached.handle)
3363             mptsas_sas_device_pg0(ioc,
3364                 &port_info->phy_info[i].attached,
3365                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3366                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3367                 port_info->phy_info[i].attached.handle);
3368     }
3369 
3370     mptsas_setup_wide_ports(ioc, port_info);
3371 
3372     for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3373         mptsas_probe_one_phy(&ioc->sh->shost_gendev,
3374             &port_info->phy_info[i], ioc->sas_index, 1);
3375 
3376     return 0;
3377 
3378  out_free_port_info:
3379     kfree(hba);
3380  out:
3381     return error;
3382 }
3383 
3384 static void
3385 mptsas_expander_refresh(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
3386 {
3387     struct mptsas_portinfo *parent;
3388     struct device *parent_dev;
3389     struct sas_rphy *rphy;
3390     int     i;
3391     u64     sas_address; /* expander sas address */
3392     u32     handle;
3393 
3394     handle = port_info->phy_info[0].handle;
3395     sas_address = port_info->phy_info[0].identify.sas_address;
3396     for (i = 0; i < port_info->num_phys; i++) {
3397         mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
3398             (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
3399             MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + handle);
3400 
3401         mptsas_sas_device_pg0(ioc,
3402             &port_info->phy_info[i].identify,
3403             (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3404             MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3405             port_info->phy_info[i].identify.handle);
3406         port_info->phy_info[i].identify.phy_id =
3407             port_info->phy_info[i].phy_id;
3408 
3409         if (port_info->phy_info[i].attached.handle) {
3410             mptsas_sas_device_pg0(ioc,
3411                 &port_info->phy_info[i].attached,
3412                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3413                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3414                 port_info->phy_info[i].attached.handle);
3415             port_info->phy_info[i].attached.phy_id =
3416                 port_info->phy_info[i].phy_id;
3417         }
3418     }
3419 
3420     mutex_lock(&ioc->sas_topology_mutex);
3421     parent = mptsas_find_portinfo_by_handle(ioc,
3422         port_info->phy_info[0].identify.handle_parent);
3423     if (!parent) {
3424         mutex_unlock(&ioc->sas_topology_mutex);
3425         return;
3426     }
3427     for (i = 0, parent_dev = NULL; i < parent->num_phys && !parent_dev;
3428         i++) {
3429         if (parent->phy_info[i].attached.sas_address == sas_address) {
3430             rphy = mptsas_get_rphy(&parent->phy_info[i]);
3431             parent_dev = &rphy->dev;
3432         }
3433     }
3434     mutex_unlock(&ioc->sas_topology_mutex);
3435 
3436     mptsas_setup_wide_ports(ioc, port_info);
3437     for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3438         mptsas_probe_one_phy(parent_dev, &port_info->phy_info[i],
3439             ioc->sas_index, 0);
3440 }
3441 
3442 static void
3443 mptsas_expander_event_add(MPT_ADAPTER *ioc,
3444     MpiEventDataSasExpanderStatusChange_t *expander_data)
3445 {
3446     struct mptsas_portinfo *port_info;
3447     int i;
3448     __le64 sas_address;
3449 
3450     port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3451     BUG_ON(!port_info);
3452     port_info->num_phys = (expander_data->NumPhys) ?
3453         expander_data->NumPhys : 1;
3454     port_info->phy_info = kcalloc(port_info->num_phys,
3455         sizeof(struct mptsas_phyinfo), GFP_KERNEL);
3456     BUG_ON(!port_info->phy_info);
3457     memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3458     for (i = 0; i < port_info->num_phys; i++) {
3459         port_info->phy_info[i].portinfo = port_info;
3460         port_info->phy_info[i].handle =
3461             le16_to_cpu(expander_data->DevHandle);
3462         port_info->phy_info[i].identify.sas_address =
3463             le64_to_cpu(sas_address);
3464         port_info->phy_info[i].identify.handle_parent =
3465             le16_to_cpu(expander_data->ParentDevHandle);
3466     }
3467 
3468     mutex_lock(&ioc->sas_topology_mutex);
3469     list_add_tail(&port_info->list, &ioc->sas_topology);
3470     mutex_unlock(&ioc->sas_topology_mutex);
3471 
3472     printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3473         "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3474         (unsigned long long)sas_address);
3475 
3476     mptsas_expander_refresh(ioc, port_info);
3477 }
3478 
3479 /**
3480  * mptsas_delete_expander_siblings - remove siblings attached to expander
3481  * @ioc: Pointer to MPT_ADAPTER structure
3482  * @parent: the parent port_info object
3483  * @expander: the expander port_info object
3484  **/
3485 static void
3486 mptsas_delete_expander_siblings(MPT_ADAPTER *ioc, struct mptsas_portinfo
3487     *parent, struct mptsas_portinfo *expander)
3488 {
3489     struct mptsas_phyinfo *phy_info;
3490     struct mptsas_portinfo *port_info;
3491     struct sas_rphy *rphy;
3492     int i;
3493 
3494     phy_info = expander->phy_info;
3495     for (i = 0; i < expander->num_phys; i++, phy_info++) {
3496         rphy = mptsas_get_rphy(phy_info);
3497         if (!rphy)
3498             continue;
3499         if (rphy->identify.device_type == SAS_END_DEVICE)
3500             mptsas_del_end_device(ioc, phy_info);
3501     }
3502 
3503     phy_info = expander->phy_info;
3504     for (i = 0; i < expander->num_phys; i++, phy_info++) {
3505         rphy = mptsas_get_rphy(phy_info);
3506         if (!rphy)
3507             continue;
3508         if (rphy->identify.device_type ==
3509             MPI_SAS_DEVICE_INFO_EDGE_EXPANDER ||
3510             rphy->identify.device_type ==
3511             MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
3512             port_info = mptsas_find_portinfo_by_sas_address(ioc,
3513                 rphy->identify.sas_address);
3514             if (!port_info)
3515                 continue;
3516             if (port_info == parent) /* backlink rphy */
3517                 continue;
3518             /*
3519             Delete this expander even if the expdevpage is exists
3520             because the parent expander is already deleted
3521             */
3522             mptsas_expander_delete(ioc, port_info, 1);
3523         }
3524     }
3525 }
3526 
3527 
3528 /**
3529  *  mptsas_expander_delete - remove this expander
3530  *  @ioc: Pointer to MPT_ADAPTER structure
3531  *  @port_info: expander port_info struct
3532  *  @force: Flag to forcefully delete the expander
3533  *
3534  **/
3535 
3536 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
3537         struct mptsas_portinfo *port_info, u8 force)
3538 {
3539 
3540     struct mptsas_portinfo *parent;
3541     int     i;
3542     u64     expander_sas_address;
3543     struct mptsas_phyinfo *phy_info;
3544     struct mptsas_portinfo buffer;
3545     struct mptsas_portinfo_details *port_details;
3546     struct sas_port *port;
3547 
3548     if (!port_info)
3549         return;
3550 
3551     /* see if expander is still there before deleting */
3552     mptsas_sas_expander_pg0(ioc, &buffer,
3553         (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3554         MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
3555         port_info->phy_info[0].identify.handle);
3556 
3557     if (buffer.num_phys) {
3558         kfree(buffer.phy_info);
3559         if (!force)
3560             return;
3561     }
3562 
3563 
3564     /*
3565      * Obtain the port_info instance to the parent port
3566      */
3567     port_details = NULL;
3568     expander_sas_address =
3569         port_info->phy_info[0].identify.sas_address;
3570     parent = mptsas_find_portinfo_by_handle(ioc,
3571         port_info->phy_info[0].identify.handle_parent);
3572     mptsas_delete_expander_siblings(ioc, parent, port_info);
3573     if (!parent)
3574         goto out;
3575 
3576     /*
3577      * Delete rphys in the parent that point
3578      * to this expander.
3579      */
3580     phy_info = parent->phy_info;
3581     port = NULL;
3582     for (i = 0; i < parent->num_phys; i++, phy_info++) {
3583         if (!phy_info->phy)
3584             continue;
3585         if (phy_info->attached.sas_address !=
3586             expander_sas_address)
3587             continue;
3588         if (!port) {
3589             port = mptsas_get_port(phy_info);
3590             port_details = phy_info->port_details;
3591         }
3592         dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3593             MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n", ioc->name,
3594             phy_info->phy_id, phy_info->phy);
3595         sas_port_delete_phy(port, phy_info->phy);
3596     }
3597     if (port) {
3598         dev_printk(KERN_DEBUG, &port->dev,
3599             MYIOC_s_FMT "delete port %d, sas_addr (0x%llx)\n",
3600             ioc->name, port->port_identifier,
3601             (unsigned long long)expander_sas_address);
3602         sas_port_delete(port);
3603         mptsas_port_delete(ioc, port_details);
3604     }
3605  out:
3606 
3607     printk(MYIOC_s_INFO_FMT "delete expander: num_phys %d, "
3608         "sas_addr (0x%llx)\n",  ioc->name, port_info->num_phys,
3609         (unsigned long long)expander_sas_address);
3610 
3611     /*
3612      * free link
3613      */
3614     list_del(&port_info->list);
3615     kfree(port_info->phy_info);
3616     kfree(port_info);
3617 }
3618 
3619 
3620 /**
3621  * mptsas_send_expander_event - expanders events
3622  * @fw_event: event data
3623  *
3624  *
3625  * This function handles adding, removing, and refreshing
3626  * device handles within the expander objects.
3627  */
3628 static void
3629 mptsas_send_expander_event(struct fw_event_work *fw_event)
3630 {
3631     MPT_ADAPTER *ioc;
3632     MpiEventDataSasExpanderStatusChange_t *expander_data;
3633     struct mptsas_portinfo *port_info;
3634     __le64 sas_address;
3635     int i;
3636 
3637     ioc = fw_event->ioc;
3638     expander_data = (MpiEventDataSasExpanderStatusChange_t *)
3639         fw_event->event_data;
3640     memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3641     sas_address = le64_to_cpu(sas_address);
3642     port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3643 
3644     if (expander_data->ReasonCode == MPI_EVENT_SAS_EXP_RC_ADDED) {
3645         if (port_info) {
3646             for (i = 0; i < port_info->num_phys; i++) {
3647                 port_info->phy_info[i].portinfo = port_info;
3648                 port_info->phy_info[i].handle =
3649                     le16_to_cpu(expander_data->DevHandle);
3650                 port_info->phy_info[i].identify.sas_address =
3651                     le64_to_cpu(sas_address);
3652                 port_info->phy_info[i].identify.handle_parent =
3653                     le16_to_cpu(expander_data->ParentDevHandle);
3654             }
3655             mptsas_expander_refresh(ioc, port_info);
3656         } else if (!port_info && expander_data->NumPhys)
3657             mptsas_expander_event_add(ioc, expander_data);
3658     } else if (expander_data->ReasonCode ==
3659         MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING)
3660         mptsas_expander_delete(ioc, port_info, 0);
3661 
3662     mptsas_free_fw_event(ioc, fw_event);
3663 }
3664 
3665 
3666 /**
3667  * mptsas_expander_add - adds a newly discovered expander
3668  * @ioc: Pointer to MPT_ADAPTER structure
3669  * @handle: device handle
3670  *
3671  */
3672 static struct mptsas_portinfo *
3673 mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
3674 {
3675     struct mptsas_portinfo buffer, *port_info;
3676     int i;
3677 
3678     if ((mptsas_sas_expander_pg0(ioc, &buffer,
3679         (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3680         MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)))
3681         return NULL;
3682 
3683     port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3684     if (!port_info) {
3685         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3686         "%s: exit at line=%d\n", ioc->name,
3687         __func__, __LINE__));
3688         return NULL;
3689     }
3690     port_info->num_phys = buffer.num_phys;
3691     port_info->phy_info = buffer.phy_info;
3692     for (i = 0; i < port_info->num_phys; i++)
3693         port_info->phy_info[i].portinfo = port_info;
3694     mutex_lock(&ioc->sas_topology_mutex);
3695     list_add_tail(&port_info->list, &ioc->sas_topology);
3696     mutex_unlock(&ioc->sas_topology_mutex);
3697     printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3698         "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3699         (unsigned long long)buffer.phy_info[0].identify.sas_address);
3700     mptsas_expander_refresh(ioc, port_info);
3701     return port_info;
3702 }
3703 
3704 static void
3705 mptsas_send_link_status_event(struct fw_event_work *fw_event)
3706 {
3707     MPT_ADAPTER *ioc;
3708     MpiEventDataSasPhyLinkStatus_t *link_data;
3709     struct mptsas_portinfo *port_info;
3710     struct mptsas_phyinfo *phy_info = NULL;
3711     __le64 sas_address;
3712     u8 phy_num;
3713     u8 link_rate;
3714 
3715     ioc = fw_event->ioc;
3716     link_data = (MpiEventDataSasPhyLinkStatus_t *)fw_event->event_data;
3717 
3718     memcpy(&sas_address, &link_data->SASAddress, sizeof(__le64));
3719     sas_address = le64_to_cpu(sas_address);
3720     link_rate = link_data->LinkRates >> 4;
3721     phy_num = link_data->PhyNum;
3722 
3723     port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3724     if (port_info) {
3725         phy_info = &port_info->phy_info[phy_num];
3726         if (phy_info)
3727             phy_info->negotiated_link_rate = link_rate;
3728     }
3729 
3730     if (link_rate == MPI_SAS_IOUNIT0_RATE_1_5 ||
3731         link_rate == MPI_SAS_IOUNIT0_RATE_3_0 ||
3732         link_rate == MPI_SAS_IOUNIT0_RATE_6_0) {
3733 
3734         if (!port_info) {
3735             if (ioc->old_sas_discovery_protocal) {
3736                 port_info = mptsas_expander_add(ioc,
3737                     le16_to_cpu(link_data->DevHandle));
3738                 if (port_info)
3739                     goto out;
3740             }
3741             goto out;
3742         }
3743 
3744         if (port_info == ioc->hba_port_info)
3745             mptsas_probe_hba_phys(ioc);
3746         else
3747             mptsas_expander_refresh(ioc, port_info);
3748     } else if (phy_info && phy_info->phy) {
3749         if (link_rate ==  MPI_SAS_IOUNIT0_RATE_PHY_DISABLED)
3750             phy_info->phy->negotiated_linkrate =
3751                 SAS_PHY_DISABLED;
3752         else if (link_rate ==
3753             MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION)
3754             phy_info->phy->negotiated_linkrate =
3755                 SAS_LINK_RATE_FAILED;
3756         else {
3757             phy_info->phy->negotiated_linkrate =
3758                 SAS_LINK_RATE_UNKNOWN;
3759             if (ioc->device_missing_delay &&
3760                 mptsas_is_end_device(&phy_info->attached)) {
3761                 struct scsi_device      *sdev;
3762                 VirtDevice          *vdevice;
3763                 u8  channel, id;
3764                 id = phy_info->attached.id;
3765                 channel = phy_info->attached.channel;
3766                 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3767                 "Link down for fw_id %d:fw_channel %d\n",
3768                     ioc->name, phy_info->attached.id,
3769                     phy_info->attached.channel));
3770 
3771                 shost_for_each_device(sdev, ioc->sh) {
3772                     vdevice = sdev->hostdata;
3773                     if ((vdevice == NULL) ||
3774                         (vdevice->vtarget == NULL))
3775                         continue;
3776                     if ((vdevice->vtarget->tflags &
3777                         MPT_TARGET_FLAGS_RAID_COMPONENT ||
3778                         vdevice->vtarget->raidVolume))
3779                         continue;
3780                     if (vdevice->vtarget->id == id &&
3781                         vdevice->vtarget->channel ==
3782                         channel)
3783                         devtprintk(ioc,
3784                         printk(MYIOC_s_DEBUG_FMT
3785                         "SDEV OUTSTANDING CMDS"
3786                         "%d\n", ioc->name,
3787                         scsi_device_busy(sdev)));
3788                 }
3789 
3790             }
3791         }
3792     }
3793  out:
3794     mptsas_free_fw_event(ioc, fw_event);
3795 }
3796 
3797 static void
3798 mptsas_not_responding_devices(MPT_ADAPTER *ioc)
3799 {
3800     struct mptsas_portinfo buffer, *port_info;
3801     struct mptsas_device_info   *sas_info;
3802     struct mptsas_devinfo sas_device;
3803     u32 handle;
3804     VirtTarget *vtarget = NULL;
3805     struct mptsas_phyinfo *phy_info;
3806     u8 found_expander;
3807     int retval, retry_count;
3808     unsigned long flags;
3809 
3810     mpt_findImVolumes(ioc);
3811 
3812     spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3813     if (ioc->ioc_reset_in_progress) {
3814         dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3815            "%s: exiting due to a parallel reset \n", ioc->name,
3816             __func__));
3817         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3818         return;
3819     }
3820     spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3821 
3822     /* devices, logical volumes */
3823     mutex_lock(&ioc->sas_device_info_mutex);
3824  redo_device_scan:
3825     list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) {
3826         if (sas_info->is_cached)
3827             continue;
3828         if (!sas_info->is_logical_volume) {
3829             sas_device.handle = 0;
3830             retry_count = 0;
3831 retry_page:
3832             retval = mptsas_sas_device_pg0(ioc, &sas_device,
3833                 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID
3834                 << MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3835                 (sas_info->fw.channel << 8) +
3836                 sas_info->fw.id);
3837 
3838             if (sas_device.handle)
3839                 continue;
3840             if (retval == -EBUSY) {
3841                 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3842                 if (ioc->ioc_reset_in_progress) {
3843                     dfailprintk(ioc,
3844                     printk(MYIOC_s_DEBUG_FMT
3845                     "%s: exiting due to reset\n",
3846                     ioc->name, __func__));
3847                     spin_unlock_irqrestore
3848                     (&ioc->taskmgmt_lock, flags);
3849                     mutex_unlock(&ioc->
3850                     sas_device_info_mutex);
3851                     return;
3852                 }
3853                 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
3854                 flags);
3855             }
3856 
3857             if (retval && (retval != -ENODEV)) {
3858                 if (retry_count < 10) {
3859                     retry_count++;
3860                     goto retry_page;
3861                 } else {
3862                     devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3863                     "%s: Config page retry exceeded retry "
3864                     "count deleting device 0x%llx\n",
3865                     ioc->name, __func__,
3866                     sas_info->sas_address));
3867                 }
3868             }
3869 
3870             /* delete device */
3871             vtarget = mptsas_find_vtarget(ioc,
3872                 sas_info->fw.channel, sas_info->fw.id);
3873 
3874             if (vtarget)
3875                 vtarget->deleted = 1;
3876 
3877             phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3878                     sas_info->sas_address);
3879 
3880             mptsas_del_end_device(ioc, phy_info);
3881             goto redo_device_scan;
3882         } else
3883             mptsas_volume_delete(ioc, sas_info->fw.id);
3884     }
3885     mutex_unlock(&ioc->sas_device_info_mutex);
3886 
3887     /* expanders */
3888     mutex_lock(&ioc->sas_topology_mutex);
3889  redo_expander_scan:
3890     list_for_each_entry(port_info, &ioc->sas_topology, list) {
3891 
3892         if (!(port_info->phy_info[0].identify.device_info &
3893             MPI_SAS_DEVICE_INFO_SMP_TARGET))
3894             continue;
3895         found_expander = 0;
3896         handle = 0xFFFF;
3897         while (!mptsas_sas_expander_pg0(ioc, &buffer,
3898             (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3899              MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle) &&
3900             !found_expander) {
3901 
3902             handle = buffer.phy_info[0].handle;
3903             if (buffer.phy_info[0].identify.sas_address ==
3904                 port_info->phy_info[0].identify.sas_address) {
3905                 found_expander = 1;
3906             }
3907             kfree(buffer.phy_info);
3908         }
3909 
3910         if (!found_expander) {
3911             mptsas_expander_delete(ioc, port_info, 0);
3912             goto redo_expander_scan;
3913         }
3914     }
3915     mutex_unlock(&ioc->sas_topology_mutex);
3916 }
3917 
3918 /**
3919  *  mptsas_probe_expanders - adding expanders
3920  *  @ioc: Pointer to MPT_ADAPTER structure
3921  *
3922  **/
3923 static void
3924 mptsas_probe_expanders(MPT_ADAPTER *ioc)
3925 {
3926     struct mptsas_portinfo buffer, *port_info;
3927     u32             handle;
3928     int i;
3929 
3930     handle = 0xFFFF;
3931     while (!mptsas_sas_expander_pg0(ioc, &buffer,
3932         (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3933          MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)) {
3934 
3935         handle = buffer.phy_info[0].handle;
3936         port_info = mptsas_find_portinfo_by_sas_address(ioc,
3937             buffer.phy_info[0].identify.sas_address);
3938 
3939         if (port_info) {
3940             /* refreshing handles */
3941             for (i = 0; i < buffer.num_phys; i++) {
3942                 port_info->phy_info[i].handle = handle;
3943                 port_info->phy_info[i].identify.handle_parent =
3944                     buffer.phy_info[0].identify.handle_parent;
3945             }
3946             mptsas_expander_refresh(ioc, port_info);
3947             kfree(buffer.phy_info);
3948             continue;
3949         }
3950 
3951         port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3952         if (!port_info) {
3953             dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3954             "%s: exit at line=%d\n", ioc->name,
3955             __func__, __LINE__));
3956             return;
3957         }
3958         port_info->num_phys = buffer.num_phys;
3959         port_info->phy_info = buffer.phy_info;
3960         for (i = 0; i < port_info->num_phys; i++)
3961             port_info->phy_info[i].portinfo = port_info;
3962         mutex_lock(&ioc->sas_topology_mutex);
3963         list_add_tail(&port_info->list, &ioc->sas_topology);
3964         mutex_unlock(&ioc->sas_topology_mutex);
3965         printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3966             "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3967         (unsigned long long)buffer.phy_info[0].identify.sas_address);
3968         mptsas_expander_refresh(ioc, port_info);
3969     }
3970 }
3971 
3972 static void
3973 mptsas_probe_devices(MPT_ADAPTER *ioc)
3974 {
3975     u16 handle;
3976     struct mptsas_devinfo sas_device;
3977     struct mptsas_phyinfo *phy_info;
3978 
3979     handle = 0xFFFF;
3980     while (!(mptsas_sas_device_pg0(ioc, &sas_device,
3981         MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
3982 
3983         handle = sas_device.handle;
3984 
3985         if ((sas_device.device_info &
3986              (MPI_SAS_DEVICE_INFO_SSP_TARGET |
3987               MPI_SAS_DEVICE_INFO_STP_TARGET |
3988               MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0)
3989             continue;
3990 
3991         /* If there is no FW B_T mapping for this device then continue
3992          * */
3993         if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
3994             || !(sas_device.flags &
3995             MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
3996             continue;
3997 
3998         phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3999         if (!phy_info)
4000             continue;
4001 
4002         if (mptsas_get_rphy(phy_info))
4003             continue;
4004 
4005         mptsas_add_end_device(ioc, phy_info);
4006     }
4007 }
4008 
4009 /**
4010  *  mptsas_scan_sas_topology - scans new SAS topology
4011  *    (part of probe or rescan)
4012  *  @ioc: Pointer to MPT_ADAPTER structure
4013  *
4014  **/
4015 static void
4016 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
4017 {
4018     struct scsi_device *sdev;
4019     int i;
4020 
4021     mptsas_probe_hba_phys(ioc);
4022     mptsas_probe_expanders(ioc);
4023     mptsas_probe_devices(ioc);
4024 
4025     /*
4026       Reporting RAID volumes.
4027     */
4028     if (!ioc->ir_firmware || !ioc->raid_data.pIocPg2 ||
4029         !ioc->raid_data.pIocPg2->NumActiveVolumes)
4030         return;
4031     for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
4032         sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
4033             ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
4034         if (sdev) {
4035             scsi_device_put(sdev);
4036             continue;
4037         }
4038         printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4039             "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4040             ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID);
4041         scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4042             ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
4043     }
4044 }
4045 
4046 
4047 static void
4048 mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
4049 {
4050     MPT_ADAPTER *ioc;
4051     EventDataQueueFull_t *qfull_data;
4052     struct mptsas_device_info *sas_info;
4053     struct scsi_device  *sdev;
4054     int depth;
4055     int id = -1;
4056     int channel = -1;
4057     int fw_id, fw_channel;
4058     u16 current_depth;
4059 
4060 
4061     ioc = fw_event->ioc;
4062     qfull_data = (EventDataQueueFull_t *)fw_event->event_data;
4063     fw_id = qfull_data->TargetID;
4064     fw_channel = qfull_data->Bus;
4065     current_depth = le16_to_cpu(qfull_data->CurrentDepth);
4066 
4067     /* if hidden raid component, look for the volume id */
4068     mutex_lock(&ioc->sas_device_info_mutex);
4069     if (mptscsih_is_phys_disk(ioc, fw_channel, fw_id)) {
4070         list_for_each_entry(sas_info, &ioc->sas_device_info_list,
4071             list) {
4072             if (sas_info->is_cached ||
4073                 sas_info->is_logical_volume)
4074                 continue;
4075             if (sas_info->is_hidden_raid_component &&
4076                 (sas_info->fw.channel == fw_channel &&
4077                 sas_info->fw.id == fw_id)) {
4078                 id = sas_info->volume_id;
4079                 channel = MPTSAS_RAID_CHANNEL;
4080                 goto out;
4081             }
4082         }
4083     } else {
4084         list_for_each_entry(sas_info, &ioc->sas_device_info_list,
4085             list) {
4086             if (sas_info->is_cached ||
4087                 sas_info->is_hidden_raid_component ||
4088                 sas_info->is_logical_volume)
4089                 continue;
4090             if (sas_info->fw.channel == fw_channel &&
4091                 sas_info->fw.id == fw_id) {
4092                 id = sas_info->os.id;
4093                 channel = sas_info->os.channel;
4094                 goto out;
4095             }
4096         }
4097 
4098     }
4099 
4100  out:
4101     mutex_unlock(&ioc->sas_device_info_mutex);
4102 
4103     if (id != -1) {
4104         shost_for_each_device(sdev, ioc->sh) {
4105             if (sdev->id == id && sdev->channel == channel) {
4106                 if (current_depth > sdev->queue_depth) {
4107                     sdev_printk(KERN_INFO, sdev,
4108                         "strange observation, the queue "
4109                         "depth is (%d) meanwhile fw queue "
4110                         "depth (%d)\n", sdev->queue_depth,
4111                         current_depth);
4112                     continue;
4113                 }
4114                 depth = scsi_track_queue_full(sdev,
4115                     sdev->queue_depth - 1);
4116                 if (depth > 0)
4117                     sdev_printk(KERN_INFO, sdev,
4118                     "Queue depth reduced to (%d)\n",
4119                        depth);
4120                 else if (depth < 0)
4121                     sdev_printk(KERN_INFO, sdev,
4122                     "Tagged Command Queueing is being "
4123                     "disabled\n");
4124                 else if (depth == 0)
4125                     sdev_printk(KERN_DEBUG, sdev,
4126                     "Queue depth not changed yet\n");
4127             }
4128         }
4129     }
4130 
4131     mptsas_free_fw_event(ioc, fw_event);
4132 }
4133 
4134 
4135 static struct mptsas_phyinfo *
4136 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
4137 {
4138     struct mptsas_portinfo *port_info;
4139     struct mptsas_phyinfo *phy_info = NULL;
4140     int i;
4141 
4142     mutex_lock(&ioc->sas_topology_mutex);
4143     list_for_each_entry(port_info, &ioc->sas_topology, list) {
4144         for (i = 0; i < port_info->num_phys; i++) {
4145             if (!mptsas_is_end_device(
4146                 &port_info->phy_info[i].attached))
4147                 continue;
4148             if (port_info->phy_info[i].attached.sas_address
4149                 != sas_address)
4150                 continue;
4151             phy_info = &port_info->phy_info[i];
4152             break;
4153         }
4154     }
4155     mutex_unlock(&ioc->sas_topology_mutex);
4156     return phy_info;
4157 }
4158 
4159 /**
4160  *  mptsas_find_phyinfo_by_phys_disk_num - find phyinfo for the
4161  *    specified @phys_disk_num
4162  *  @ioc: Pointer to MPT_ADAPTER structure
4163  *  @phys_disk_num: (hot plug) physical disk number (for RAID support)
4164  *  @channel: channel number
4165  *  @id: Logical Target ID
4166  *
4167  **/
4168 static struct mptsas_phyinfo *
4169 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
4170     u8 channel, u8 id)
4171 {
4172     struct mptsas_phyinfo *phy_info = NULL;
4173     struct mptsas_portinfo *port_info;
4174     RaidPhysDiskPage1_t *phys_disk = NULL;
4175     int num_paths;
4176     u64 sas_address = 0;
4177     int i;
4178 
4179     phy_info = NULL;
4180     if (!ioc->raid_data.pIocPg3)
4181         return NULL;
4182     /* dual port support */
4183     num_paths = mpt_raid_phys_disk_get_num_paths(ioc, phys_disk_num);
4184     if (!num_paths)
4185         goto out;
4186     phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
4187        (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
4188     if (!phys_disk)
4189         goto out;
4190     mpt_raid_phys_disk_pg1(ioc, phys_disk_num, phys_disk);
4191     for (i = 0; i < num_paths; i++) {
4192         if ((phys_disk->Path[i].Flags & 1) != 0)
4193             /* entry no longer valid */
4194             continue;
4195         if ((id == phys_disk->Path[i].PhysDiskID) &&
4196             (channel == phys_disk->Path[i].PhysDiskBus)) {
4197             memcpy(&sas_address, &phys_disk->Path[i].WWID,
4198                 sizeof(u64));
4199             phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4200                     sas_address);
4201             goto out;
4202         }
4203     }
4204 
4205  out:
4206     kfree(phys_disk);
4207     if (phy_info)
4208         return phy_info;
4209 
4210     /*
4211      * Extra code to handle RAID0 case, where the sas_address is not updated
4212      * in phys_disk_page_1 when hotswapped
4213      */
4214     mutex_lock(&ioc->sas_topology_mutex);
4215     list_for_each_entry(port_info, &ioc->sas_topology, list) {
4216         for (i = 0; i < port_info->num_phys && !phy_info; i++) {
4217             if (!mptsas_is_end_device(
4218                 &port_info->phy_info[i].attached))
4219                 continue;
4220             if (port_info->phy_info[i].attached.phys_disk_num == ~0)
4221                 continue;
4222             if ((port_info->phy_info[i].attached.phys_disk_num ==
4223                 phys_disk_num) &&
4224                 (port_info->phy_info[i].attached.id == id) &&
4225                 (port_info->phy_info[i].attached.channel ==
4226                  channel))
4227                 phy_info = &port_info->phy_info[i];
4228         }
4229     }
4230     mutex_unlock(&ioc->sas_topology_mutex);
4231     return phy_info;
4232 }
4233 
4234 static void
4235 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
4236 {
4237     int rc;
4238 
4239     sdev->no_uld_attach = data ? 1 : 0;
4240     rc = scsi_device_reprobe(sdev);
4241 }
4242 
4243 static void
4244 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
4245 {
4246     starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
4247             mptsas_reprobe_lun);
4248 }
4249 
4250 static void
4251 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
4252 {
4253     CONFIGPARMS         cfg;
4254     ConfigPageHeader_t      hdr;
4255     dma_addr_t          dma_handle;
4256     pRaidVolumePage0_t      buffer = NULL;
4257     RaidPhysDiskPage0_t         phys_disk;
4258     int             i;
4259     struct mptsas_phyinfo   *phy_info;
4260     struct mptsas_devinfo       sas_device;
4261 
4262     memset(&cfg, 0 , sizeof(CONFIGPARMS));
4263     memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4264     hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
4265     cfg.pageAddr = (channel << 8) + id;
4266     cfg.cfghdr.hdr = &hdr;
4267     cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4268     cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
4269 
4270     if (mpt_config(ioc, &cfg) != 0)
4271         goto out;
4272 
4273     if (!hdr.PageLength)
4274         goto out;
4275 
4276     buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
4277                     &dma_handle, GFP_KERNEL);
4278 
4279     if (!buffer)
4280         goto out;
4281 
4282     cfg.physAddr = dma_handle;
4283     cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4284 
4285     if (mpt_config(ioc, &cfg) != 0)
4286         goto out;
4287 
4288     if (!(buffer->VolumeStatus.Flags &
4289         MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
4290         goto out;
4291 
4292     if (!buffer->NumPhysDisks)
4293         goto out;
4294 
4295     for (i = 0; i < buffer->NumPhysDisks; i++) {
4296 
4297         if (mpt_raid_phys_disk_pg0(ioc,
4298             buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
4299             continue;
4300 
4301         if (mptsas_sas_device_pg0(ioc, &sas_device,
4302             (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4303              MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4304             (phys_disk.PhysDiskBus << 8) +
4305             phys_disk.PhysDiskID))
4306             continue;
4307 
4308         /* If there is no FW B_T mapping for this device then continue
4309          * */
4310         if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4311             || !(sas_device.flags &
4312             MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4313             continue;
4314 
4315 
4316         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4317             sas_device.sas_address);
4318         mptsas_add_end_device(ioc, phy_info);
4319     }
4320 
4321  out:
4322     if (buffer)
4323         dma_free_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
4324                   buffer, dma_handle);
4325 }
4326 /*
4327  * Work queue thread to handle SAS hotplug events
4328  */
4329 static void
4330 mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
4331     struct mptsas_hotplug_event *hot_plug_info)
4332 {
4333     struct mptsas_phyinfo *phy_info;
4334     struct scsi_target * starget;
4335     struct mptsas_devinfo sas_device;
4336     VirtTarget *vtarget;
4337     int i;
4338     struct mptsas_portinfo *port_info;
4339 
4340     switch (hot_plug_info->event_type) {
4341 
4342     case MPTSAS_ADD_PHYSDISK:
4343 
4344         if (!ioc->raid_data.pIocPg2)
4345             break;
4346 
4347         for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
4348             if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID ==
4349                 hot_plug_info->id) {
4350                 printk(MYIOC_s_WARN_FMT "firmware bug: unable "
4351                     "to add hidden disk - target_id matches "
4352                     "volume_id\n", ioc->name);
4353                 mptsas_free_fw_event(ioc, fw_event);
4354                 return;
4355             }
4356         }
4357         mpt_findImVolumes(ioc);
4358         fallthrough;
4359 
4360     case MPTSAS_ADD_DEVICE:
4361         memset(&sas_device, 0, sizeof(struct mptsas_devinfo));
4362         mptsas_sas_device_pg0(ioc, &sas_device,
4363             (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4364             MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4365             (hot_plug_info->channel << 8) +
4366             hot_plug_info->id);
4367 
4368         /* If there is no FW B_T mapping for this device then break
4369          * */
4370         if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4371             || !(sas_device.flags &
4372             MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4373             break;
4374 
4375         if (!sas_device.handle)
4376             return;
4377 
4378         phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
4379         /* Device hot plug */
4380         if (!phy_info) {
4381             devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4382                 "%s %d HOT PLUG: "
4383                 "parent handle of device %x\n", ioc->name,
4384                 __func__, __LINE__, sas_device.handle_parent));
4385             port_info = mptsas_find_portinfo_by_handle(ioc,
4386                 sas_device.handle_parent);
4387 
4388             if (port_info == ioc->hba_port_info)
4389                 mptsas_probe_hba_phys(ioc);
4390             else if (port_info)
4391                 mptsas_expander_refresh(ioc, port_info);
4392             else {
4393                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4394                     "%s %d port info is NULL\n",
4395                     ioc->name, __func__, __LINE__));
4396                 break;
4397             }
4398             phy_info = mptsas_refreshing_device_handles
4399                 (ioc, &sas_device);
4400         }
4401 
4402         if (!phy_info) {
4403             dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4404                 "%s %d phy info is NULL\n",
4405                 ioc->name, __func__, __LINE__));
4406             break;
4407         }
4408 
4409         if (mptsas_get_rphy(phy_info))
4410             break;
4411 
4412         mptsas_add_end_device(ioc, phy_info);
4413         break;
4414 
4415     case MPTSAS_DEL_DEVICE:
4416         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4417             hot_plug_info->sas_address);
4418         mptsas_del_end_device(ioc, phy_info);
4419         break;
4420 
4421     case MPTSAS_DEL_PHYSDISK:
4422 
4423         mpt_findImVolumes(ioc);
4424 
4425         phy_info = mptsas_find_phyinfo_by_phys_disk_num(
4426                 ioc, hot_plug_info->phys_disk_num,
4427                 hot_plug_info->channel,
4428                 hot_plug_info->id);
4429         mptsas_del_end_device(ioc, phy_info);
4430         break;
4431 
4432     case MPTSAS_ADD_PHYSDISK_REPROBE:
4433 
4434         if (mptsas_sas_device_pg0(ioc, &sas_device,
4435             (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4436              MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4437             (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4438             dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4439             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4440                  __func__, hot_plug_info->id, __LINE__));
4441             break;
4442         }
4443 
4444         /* If there is no FW B_T mapping for this device then break
4445          * */
4446         if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4447             || !(sas_device.flags &
4448             MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4449             break;
4450 
4451         phy_info = mptsas_find_phyinfo_by_sas_address(
4452             ioc, sas_device.sas_address);
4453 
4454         if (!phy_info) {
4455             dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4456                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4457                  __func__, hot_plug_info->id, __LINE__));
4458             break;
4459         }
4460 
4461         starget = mptsas_get_starget(phy_info);
4462         if (!starget) {
4463             dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4464                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4465                  __func__, hot_plug_info->id, __LINE__));
4466             break;
4467         }
4468 
4469         vtarget = starget->hostdata;
4470         if (!vtarget) {
4471             dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4472                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4473                  __func__, hot_plug_info->id, __LINE__));
4474             break;
4475         }
4476 
4477         mpt_findImVolumes(ioc);
4478 
4479         starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Hidding: "
4480             "fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4481             ioc->name, hot_plug_info->channel, hot_plug_info->id,
4482             hot_plug_info->phys_disk_num, (unsigned long long)
4483             sas_device.sas_address);
4484 
4485         vtarget->id = hot_plug_info->phys_disk_num;
4486         vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
4487         phy_info->attached.phys_disk_num = hot_plug_info->phys_disk_num;
4488         mptsas_reprobe_target(starget, 1);
4489         break;
4490 
4491     case MPTSAS_DEL_PHYSDISK_REPROBE:
4492 
4493         if (mptsas_sas_device_pg0(ioc, &sas_device,
4494             (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4495              MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4496             (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4497                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4498                     "%s: fw_id=%d exit at line=%d\n",
4499                     ioc->name, __func__,
4500                     hot_plug_info->id, __LINE__));
4501             break;
4502         }
4503 
4504         /* If there is no FW B_T mapping for this device then break
4505          * */
4506         if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4507             || !(sas_device.flags &
4508             MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4509             break;
4510 
4511         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4512                 sas_device.sas_address);
4513         if (!phy_info) {
4514             dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4515                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4516              __func__, hot_plug_info->id, __LINE__));
4517             break;
4518         }
4519 
4520         starget = mptsas_get_starget(phy_info);
4521         if (!starget) {
4522             dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4523                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4524              __func__, hot_plug_info->id, __LINE__));
4525             break;
4526         }
4527 
4528         vtarget = starget->hostdata;
4529         if (!vtarget) {
4530             dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4531                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4532              __func__, hot_plug_info->id, __LINE__));
4533             break;
4534         }
4535 
4536         if (!(vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)) {
4537             dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4538                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4539              __func__, hot_plug_info->id, __LINE__));
4540             break;
4541         }
4542 
4543         mpt_findImVolumes(ioc);
4544 
4545         starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Exposing:"
4546             " fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4547             ioc->name, hot_plug_info->channel, hot_plug_info->id,
4548             hot_plug_info->phys_disk_num, (unsigned long long)
4549             sas_device.sas_address);
4550 
4551         vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
4552         vtarget->id = hot_plug_info->id;
4553         phy_info->attached.phys_disk_num = ~0;
4554         mptsas_reprobe_target(starget, 0);
4555         mptsas_add_device_component_by_fw(ioc,
4556             hot_plug_info->channel, hot_plug_info->id);
4557         break;
4558 
4559     case MPTSAS_ADD_RAID:
4560 
4561         mpt_findImVolumes(ioc);
4562         printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4563             "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4564             hot_plug_info->id);
4565         scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4566             hot_plug_info->id, 0);
4567         break;
4568 
4569     case MPTSAS_DEL_RAID:
4570 
4571         mpt_findImVolumes(ioc);
4572         printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4573             "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4574             hot_plug_info->id);
4575         scsi_remove_device(hot_plug_info->sdev);
4576         scsi_device_put(hot_plug_info->sdev);
4577         break;
4578 
4579     case MPTSAS_ADD_INACTIVE_VOLUME:
4580 
4581         mpt_findImVolumes(ioc);
4582         mptsas_adding_inactive_raid_components(ioc,
4583             hot_plug_info->channel, hot_plug_info->id);
4584         break;
4585 
4586     default:
4587         break;
4588     }
4589 
4590     mptsas_free_fw_event(ioc, fw_event);
4591 }
4592 
4593 static void
4594 mptsas_send_sas_event(struct fw_event_work *fw_event)
4595 {
4596     MPT_ADAPTER *ioc;
4597     struct mptsas_hotplug_event hot_plug_info;
4598     EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
4599     u32 device_info;
4600     u64 sas_address;
4601 
4602     ioc = fw_event->ioc;
4603     sas_event_data = (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
4604         fw_event->event_data;
4605     device_info = le32_to_cpu(sas_event_data->DeviceInfo);
4606 
4607     if ((device_info &
4608         (MPI_SAS_DEVICE_INFO_SSP_TARGET |
4609         MPI_SAS_DEVICE_INFO_STP_TARGET |
4610         MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0) {
4611         mptsas_free_fw_event(ioc, fw_event);
4612         return;
4613     }
4614 
4615     if (sas_event_data->ReasonCode ==
4616         MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED) {
4617         mptbase_sas_persist_operation(ioc,
4618         MPI_SAS_OP_CLEAR_NOT_PRESENT);
4619         mptsas_free_fw_event(ioc, fw_event);
4620         return;
4621     }
4622 
4623     switch (sas_event_data->ReasonCode) {
4624     case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
4625     case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
4626         memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4627         hot_plug_info.handle = le16_to_cpu(sas_event_data->DevHandle);
4628         hot_plug_info.channel = sas_event_data->Bus;
4629         hot_plug_info.id = sas_event_data->TargetID;
4630         hot_plug_info.phy_id = sas_event_data->PhyNum;
4631         memcpy(&sas_address, &sas_event_data->SASAddress,
4632             sizeof(u64));
4633         hot_plug_info.sas_address = le64_to_cpu(sas_address);
4634         hot_plug_info.device_info = device_info;
4635         if (sas_event_data->ReasonCode &
4636             MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
4637             hot_plug_info.event_type = MPTSAS_ADD_DEVICE;
4638         else
4639             hot_plug_info.event_type = MPTSAS_DEL_DEVICE;
4640         mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4641         break;
4642 
4643     case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
4644         mptbase_sas_persist_operation(ioc,
4645             MPI_SAS_OP_CLEAR_NOT_PRESENT);
4646         mptsas_free_fw_event(ioc, fw_event);
4647         break;
4648 
4649     case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
4650     /* TODO */
4651     case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
4652     /* TODO */
4653     default:
4654         mptsas_free_fw_event(ioc, fw_event);
4655         break;
4656     }
4657 }
4658 
4659 static void
4660 mptsas_send_raid_event(struct fw_event_work *fw_event)
4661 {
4662     MPT_ADAPTER *ioc;
4663     EVENT_DATA_RAID *raid_event_data;
4664     struct mptsas_hotplug_event hot_plug_info;
4665     int status;
4666     int state;
4667     struct scsi_device *sdev = NULL;
4668     VirtDevice *vdevice = NULL;
4669     RaidPhysDiskPage0_t phys_disk;
4670 
4671     ioc = fw_event->ioc;
4672     raid_event_data = (EVENT_DATA_RAID *)fw_event->event_data;
4673     status = le32_to_cpu(raid_event_data->SettingsStatus);
4674     state = (status >> 8) & 0xff;
4675 
4676     memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4677     hot_plug_info.id = raid_event_data->VolumeID;
4678     hot_plug_info.channel = raid_event_data->VolumeBus;
4679     hot_plug_info.phys_disk_num = raid_event_data->PhysDiskNum;
4680 
4681     if (raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_DELETED ||
4682         raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_CREATED ||
4683         raid_event_data->ReasonCode ==
4684         MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED) {
4685         sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
4686             hot_plug_info.id, 0);
4687         hot_plug_info.sdev = sdev;
4688         if (sdev)
4689             vdevice = sdev->hostdata;
4690     }
4691 
4692     devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4693         "ReasonCode=%02x\n", ioc->name, __func__,
4694         raid_event_data->ReasonCode));
4695 
4696     switch (raid_event_data->ReasonCode) {
4697     case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4698         hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK_REPROBE;
4699         break;
4700     case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4701         hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK_REPROBE;
4702         break;
4703     case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4704         switch (state) {
4705         case MPI_PD_STATE_ONLINE:
4706         case MPI_PD_STATE_NOT_COMPATIBLE:
4707             mpt_raid_phys_disk_pg0(ioc,
4708                 raid_event_data->PhysDiskNum, &phys_disk);
4709             hot_plug_info.id = phys_disk.PhysDiskID;
4710             hot_plug_info.channel = phys_disk.PhysDiskBus;
4711             hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4712             break;
4713         case MPI_PD_STATE_FAILED:
4714         case MPI_PD_STATE_MISSING:
4715         case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
4716         case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
4717         case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
4718             hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4719             break;
4720         default:
4721             break;
4722         }
4723         break;
4724     case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4725         if (!sdev)
4726             break;
4727         vdevice->vtarget->deleted = 1; /* block IO */
4728         hot_plug_info.event_type = MPTSAS_DEL_RAID;
4729         break;
4730     case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4731         if (sdev) {
4732             scsi_device_put(sdev);
4733             break;
4734         }
4735         hot_plug_info.event_type = MPTSAS_ADD_RAID;
4736         break;
4737     case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4738         if (!(status & MPI_RAIDVOL0_STATUS_FLAG_ENABLED)) {
4739             if (!sdev)
4740                 break;
4741             vdevice->vtarget->deleted = 1; /* block IO */
4742             hot_plug_info.event_type = MPTSAS_DEL_RAID;
4743             break;
4744         }
4745         switch (state) {
4746         case MPI_RAIDVOL0_STATUS_STATE_FAILED:
4747         case MPI_RAIDVOL0_STATUS_STATE_MISSING:
4748             if (!sdev)
4749                 break;
4750             vdevice->vtarget->deleted = 1; /* block IO */
4751             hot_plug_info.event_type = MPTSAS_DEL_RAID;
4752             break;
4753         case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
4754         case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
4755             if (sdev) {
4756                 scsi_device_put(sdev);
4757                 break;
4758             }
4759             hot_plug_info.event_type = MPTSAS_ADD_RAID;
4760             break;
4761         default:
4762             break;
4763         }
4764         break;
4765     default:
4766         break;
4767     }
4768 
4769     if (hot_plug_info.event_type != MPTSAS_IGNORE_EVENT)
4770         mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4771     else
4772         mptsas_free_fw_event(ioc, fw_event);
4773 }
4774 
4775 /**
4776  *  mptsas_issue_tm - send mptsas internal tm request
4777  *  @ioc: Pointer to MPT_ADAPTER structure
4778  *  @type: Task Management type
4779  *  @channel: channel number for task management
4780  *  @id: Logical Target ID for reset (if appropriate)
4781  *  @lun: Logical unit for reset (if appropriate)
4782  *  @task_context: Context for the task to be aborted
4783  *  @timeout: timeout for task management control
4784  *  @issue_reset: set to 1 on return if reset is needed, else 0
4785  *
4786  *  Return: 0 on success or -1 on failure.
4787  *
4788  */
4789 static int
4790 mptsas_issue_tm(MPT_ADAPTER *ioc, u8 type, u8 channel, u8 id, u64 lun,
4791     int task_context, ulong timeout, u8 *issue_reset)
4792 {
4793     MPT_FRAME_HDR   *mf;
4794     SCSITaskMgmt_t  *pScsiTm;
4795     int      retval;
4796     unsigned long    timeleft;
4797 
4798     *issue_reset = 0;
4799     mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
4800     if (mf == NULL) {
4801         retval = -1; /* return failure */
4802         dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "TaskMgmt request: no "
4803             "msg frames!!\n", ioc->name));
4804         goto out;
4805     }
4806 
4807     dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request: mr = %p, "
4808         "task_type = 0x%02X,\n\t timeout = %ld, fw_channel = %d, "
4809         "fw_id = %d, lun = %lld,\n\t task_context = 0x%x\n", ioc->name, mf,
4810          type, timeout, channel, id, (unsigned long long)lun,
4811          task_context));
4812 
4813     pScsiTm = (SCSITaskMgmt_t *) mf;
4814     memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
4815     pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
4816     pScsiTm->TaskType = type;
4817     pScsiTm->MsgFlags = 0;
4818     pScsiTm->TargetID = id;
4819     pScsiTm->Bus = channel;
4820     pScsiTm->ChainOffset = 0;
4821     pScsiTm->Reserved = 0;
4822     pScsiTm->Reserved1 = 0;
4823     pScsiTm->TaskMsgContext = task_context;
4824     int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
4825 
4826     INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4827     CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
4828     retval = 0;
4829     mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
4830 
4831     /* Now wait for the command to complete */
4832     timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
4833         timeout*HZ);
4834     if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
4835         retval = -1; /* return failure */
4836         dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
4837             "TaskMgmt request: TIMED OUT!(mr=%p)\n", ioc->name, mf));
4838         mpt_free_msg_frame(ioc, mf);
4839         if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
4840             goto out;
4841         *issue_reset = 1;
4842         goto out;
4843     }
4844 
4845     if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
4846         retval = -1; /* return failure */
4847         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4848             "TaskMgmt request: failed with no reply\n", ioc->name));
4849         goto out;
4850     }
4851 
4852  out:
4853     CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4854     return retval;
4855 }
4856 
4857 /**
4858  *  mptsas_broadcast_primitive_work - Handle broadcast primitives
4859  *  @fw_event: work queue payload containing info describing the event
4860  *
4861  *  This will be handled in workqueue context.
4862  */
4863 static void
4864 mptsas_broadcast_primitive_work(struct fw_event_work *fw_event)
4865 {
4866     MPT_ADAPTER *ioc = fw_event->ioc;
4867     MPT_FRAME_HDR   *mf;
4868     VirtDevice  *vdevice;
4869     int         ii;
4870     struct scsi_cmnd    *sc;
4871     SCSITaskMgmtReply_t *pScsiTmReply;
4872     u8          issue_reset;
4873     int         task_context;
4874     u8          channel, id;
4875     int          lun;
4876     u32          termination_count;
4877     u32          query_count;
4878 
4879     dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4880         "%s - enter\n", ioc->name, __func__));
4881 
4882     mutex_lock(&ioc->taskmgmt_cmds.mutex);
4883     if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
4884         mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4885         mptsas_requeue_fw_event(ioc, fw_event, 1000);
4886         return;
4887     }
4888 
4889     issue_reset = 0;
4890     termination_count = 0;
4891     query_count = 0;
4892     mpt_findImVolumes(ioc);
4893     pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
4894 
4895     for (ii = 0; ii < ioc->req_depth; ii++) {
4896         if (ioc->fw_events_off)
4897             goto out;
4898         sc = mptscsih_get_scsi_lookup(ioc, ii);
4899         if (!sc)
4900             continue;
4901         mf = MPT_INDEX_2_MFPTR(ioc, ii);
4902         if (!mf)
4903             continue;
4904         task_context = mf->u.frame.hwhdr.msgctxu.MsgContext;
4905         vdevice = sc->device->hostdata;
4906         if (!vdevice || !vdevice->vtarget)
4907             continue;
4908         if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
4909             continue; /* skip hidden raid components */
4910         if (vdevice->vtarget->raidVolume)
4911             continue; /* skip hidden raid components */
4912         channel = vdevice->vtarget->channel;
4913         id = vdevice->vtarget->id;
4914         lun = vdevice->lun;
4915         if (mptsas_issue_tm(ioc, MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK,
4916             channel, id, (u64)lun, task_context, 30, &issue_reset))
4917             goto out;
4918         query_count++;
4919         termination_count +=
4920             le32_to_cpu(pScsiTmReply->TerminationCount);
4921         if ((pScsiTmReply->IOCStatus == MPI_IOCSTATUS_SUCCESS) &&
4922             (pScsiTmReply->ResponseCode ==
4923             MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
4924             pScsiTmReply->ResponseCode ==
4925             MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
4926             continue;
4927         if (mptsas_issue_tm(ioc,
4928             MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET,
4929             channel, id, (u64)lun, 0, 30, &issue_reset))
4930             goto out;
4931         termination_count +=
4932             le32_to_cpu(pScsiTmReply->TerminationCount);
4933     }
4934 
4935  out:
4936     dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4937         "%s - exit, query_count = %d termination_count = %d\n",
4938         ioc->name, __func__, query_count, termination_count));
4939 
4940     ioc->broadcast_aen_busy = 0;
4941     mpt_clear_taskmgmt_in_progress_flag(ioc);
4942     mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4943 
4944     if (issue_reset) {
4945         printk(MYIOC_s_WARN_FMT
4946                "Issuing Reset from %s!! doorbell=0x%08x\n",
4947                ioc->name, __func__, mpt_GetIocState(ioc, 0));
4948         mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
4949     }
4950     mptsas_free_fw_event(ioc, fw_event);
4951 }
4952 
4953 /*
4954  * mptsas_send_ir2_event - handle exposing hidden disk when
4955  * an inactive raid volume is added
4956  *
4957  * @ioc: Pointer to MPT_ADAPTER structure
4958  * @ir2_data
4959  *
4960  */
4961 static void
4962 mptsas_send_ir2_event(struct fw_event_work *fw_event)
4963 {
4964     MPT_ADAPTER *ioc;
4965     struct mptsas_hotplug_event hot_plug_info;
4966     MPI_EVENT_DATA_IR2  *ir2_data;
4967     u8 reasonCode;
4968     RaidPhysDiskPage0_t phys_disk;
4969 
4970     ioc = fw_event->ioc;
4971     ir2_data = (MPI_EVENT_DATA_IR2 *)fw_event->event_data;
4972     reasonCode = ir2_data->ReasonCode;
4973 
4974     devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4975         "ReasonCode=%02x\n", ioc->name, __func__, reasonCode));
4976 
4977     memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4978     hot_plug_info.id = ir2_data->TargetID;
4979     hot_plug_info.channel = ir2_data->Bus;
4980     switch (reasonCode) {
4981     case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
4982         hot_plug_info.event_type = MPTSAS_ADD_INACTIVE_VOLUME;
4983         break;
4984     case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
4985         hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4986         hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4987         break;
4988     case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
4989         hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4990         mpt_raid_phys_disk_pg0(ioc,
4991             ir2_data->PhysDiskNum, &phys_disk);
4992         hot_plug_info.id = phys_disk.PhysDiskID;
4993         hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4994         break;
4995     default:
4996         mptsas_free_fw_event(ioc, fw_event);
4997         return;
4998     }
4999     mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
5000 }
5001 
5002 static int
5003 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
5004 {
5005     u32 event = le32_to_cpu(reply->Event);
5006     int event_data_sz;
5007     struct fw_event_work *fw_event;
5008     unsigned long delay;
5009 
5010     if (ioc->bus_type != SAS)
5011         return 0;
5012 
5013     /* events turned off due to host reset or driver unloading */
5014     if (ioc->fw_events_off)
5015         return 0;
5016 
5017     delay = msecs_to_jiffies(1);
5018     switch (event) {
5019     case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
5020     {
5021         EVENT_DATA_SAS_BROADCAST_PRIMITIVE *broadcast_event_data =
5022             (EVENT_DATA_SAS_BROADCAST_PRIMITIVE *)reply->Data;
5023         if (broadcast_event_data->Primitive !=
5024             MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
5025             return 0;
5026         if (ioc->broadcast_aen_busy)
5027             return 0;
5028         ioc->broadcast_aen_busy = 1;
5029         break;
5030     }
5031     case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5032     {
5033         EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data =
5034             (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data;
5035         u16 ioc_stat;
5036         ioc_stat = le16_to_cpu(reply->IOCStatus);
5037 
5038         if (sas_event_data->ReasonCode ==
5039             MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) {
5040             mptsas_target_reset_queue(ioc, sas_event_data);
5041             return 0;
5042         }
5043         if (sas_event_data->ReasonCode ==
5044             MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
5045             ioc->device_missing_delay &&
5046             (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)) {
5047             VirtTarget *vtarget = NULL;
5048             u8      id, channel;
5049 
5050             id = sas_event_data->TargetID;
5051             channel = sas_event_data->Bus;
5052 
5053             vtarget = mptsas_find_vtarget(ioc, channel, id);
5054             if (vtarget) {
5055                 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5056                     "LogInfo (0x%x) available for "
5057                    "INTERNAL_DEVICE_RESET"
5058                    "fw_id %d fw_channel %d\n", ioc->name,
5059                    le32_to_cpu(reply->IOCLogInfo),
5060                    id, channel));
5061                 if (vtarget->raidVolume) {
5062                     devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5063                     "Skipping Raid Volume for inDMD\n",
5064                     ioc->name));
5065                 } else {
5066                     devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5067                     "Setting device flag inDMD\n",
5068                     ioc->name));
5069                     vtarget->inDMD = 1;
5070                 }
5071 
5072             }
5073 
5074         }
5075 
5076         break;
5077     }
5078     case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
5079     {
5080         MpiEventDataSasExpanderStatusChange_t *expander_data =
5081             (MpiEventDataSasExpanderStatusChange_t *)reply->Data;
5082 
5083         if (ioc->old_sas_discovery_protocal)
5084             return 0;
5085 
5086         if (expander_data->ReasonCode ==
5087             MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING &&
5088             ioc->device_missing_delay)
5089             delay = HZ * ioc->device_missing_delay;
5090         break;
5091     }
5092     case MPI_EVENT_SAS_DISCOVERY:
5093     {
5094         u32 discovery_status;
5095         EventDataSasDiscovery_t *discovery_data =
5096             (EventDataSasDiscovery_t *)reply->Data;
5097 
5098         discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus);
5099         ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0;
5100         if (ioc->old_sas_discovery_protocal && !discovery_status)
5101             mptsas_queue_rescan(ioc);
5102         return 0;
5103     }
5104     case MPI_EVENT_INTEGRATED_RAID:
5105     case MPI_EVENT_PERSISTENT_TABLE_FULL:
5106     case MPI_EVENT_IR2:
5107     case MPI_EVENT_SAS_PHY_LINK_STATUS:
5108     case MPI_EVENT_QUEUE_FULL:
5109         break;
5110     default:
5111         return 0;
5112     }
5113 
5114     event_data_sz = ((reply->MsgLength * 4) -
5115         offsetof(EventNotificationReply_t, Data));
5116     fw_event = kzalloc(sizeof(*fw_event) + event_data_sz, GFP_ATOMIC);
5117     if (!fw_event) {
5118         printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name,
5119          __func__, __LINE__);
5120         return 0;
5121     }
5122     memcpy(fw_event->event_data, reply->Data, event_data_sz);
5123     fw_event->event = event;
5124     fw_event->ioc = ioc;
5125     mptsas_add_fw_event(ioc, fw_event, delay);
5126     return 0;
5127 }
5128 
5129 /* Delete a volume when no longer listed in ioc pg2
5130  */
5131 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id)
5132 {
5133     struct scsi_device *sdev;
5134     int i;
5135 
5136     sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, id, 0);
5137     if (!sdev)
5138         return;
5139     if (!ioc->raid_data.pIocPg2)
5140         goto out;
5141     if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
5142         goto out;
5143     for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
5144         if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id)
5145             goto release_sdev;
5146  out:
5147     printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
5148         "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL, id);
5149     scsi_remove_device(sdev);
5150  release_sdev:
5151     scsi_device_put(sdev);
5152 }
5153 
5154 static int
5155 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5156 {
5157     struct Scsi_Host    *sh;
5158     MPT_SCSI_HOST       *hd;
5159     MPT_ADAPTER         *ioc;
5160     unsigned long        flags;
5161     int          ii;
5162     int          numSGE = 0;
5163     int          scale;
5164     int          ioc_cap;
5165     int         error=0;
5166     int         r;
5167 
5168     r = mpt_attach(pdev,id);
5169     if (r)
5170         return r;
5171 
5172     ioc = pci_get_drvdata(pdev);
5173     mptsas_fw_event_off(ioc);
5174     ioc->DoneCtx = mptsasDoneCtx;
5175     ioc->TaskCtx = mptsasTaskCtx;
5176     ioc->InternalCtx = mptsasInternalCtx;
5177     ioc->schedule_target_reset = &mptsas_schedule_target_reset;
5178     ioc->schedule_dead_ioc_flush_running_cmds =
5179                 &mptscsih_flush_running_cmds;
5180     /*  Added sanity check on readiness of the MPT adapter.
5181      */
5182     if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
5183         printk(MYIOC_s_WARN_FMT
5184           "Skipping because it's not operational!\n",
5185           ioc->name);
5186         error = -ENODEV;
5187         goto out_mptsas_probe;
5188     }
5189 
5190     if (!ioc->active) {
5191         printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
5192           ioc->name);
5193         error = -ENODEV;
5194         goto out_mptsas_probe;
5195     }
5196 
5197     /*  Sanity check - ensure at least 1 port is INITIATOR capable
5198      */
5199     ioc_cap = 0;
5200     for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
5201         if (ioc->pfacts[ii].ProtocolFlags &
5202                 MPI_PORTFACTS_PROTOCOL_INITIATOR)
5203             ioc_cap++;
5204     }
5205 
5206     if (!ioc_cap) {
5207         printk(MYIOC_s_WARN_FMT
5208             "Skipping ioc=%p because SCSI Initiator mode "
5209             "is NOT enabled!\n", ioc->name, ioc);
5210         return 0;
5211     }
5212 
5213     sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
5214     if (!sh) {
5215         printk(MYIOC_s_WARN_FMT
5216             "Unable to register controller with SCSI subsystem\n",
5217             ioc->name);
5218         error = -1;
5219         goto out_mptsas_probe;
5220         }
5221 
5222     spin_lock_irqsave(&ioc->FreeQlock, flags);
5223 
5224     /* Attach the SCSI Host to the IOC structure
5225      */
5226     ioc->sh = sh;
5227 
5228     sh->io_port = 0;
5229     sh->n_io_port = 0;
5230     sh->irq = 0;
5231 
5232     /* set 16 byte cdb's */
5233     sh->max_cmd_len = 16;
5234     sh->can_queue = min_t(int, ioc->req_depth - 10, sh->can_queue);
5235     sh->max_id = -1;
5236     sh->max_lun = max_lun;
5237     sh->transportt = mptsas_transport_template;
5238 
5239     /* Required entry.
5240      */
5241     sh->unique_id = ioc->id;
5242 
5243     INIT_LIST_HEAD(&ioc->sas_topology);
5244     mutex_init(&ioc->sas_topology_mutex);
5245     mutex_init(&ioc->sas_discovery_mutex);
5246     mutex_init(&ioc->sas_mgmt.mutex);
5247     init_completion(&ioc->sas_mgmt.done);
5248 
5249     /* Verify that we won't exceed the maximum
5250      * number of chain buffers
5251      * We can optimize:  ZZ = req_sz/sizeof(SGE)
5252      * For 32bit SGE's:
5253      *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
5254      *               + (req_sz - 64)/sizeof(SGE)
5255      * A slightly different algorithm is required for
5256      * 64bit SGEs.
5257      */
5258     scale = ioc->req_sz/ioc->SGE_size;
5259     if (ioc->sg_addr_size == sizeof(u64)) {
5260         numSGE = (scale - 1) *
5261           (ioc->facts.MaxChainDepth-1) + scale +
5262           (ioc->req_sz - 60) / ioc->SGE_size;
5263     } else {
5264         numSGE = 1 + (scale - 1) *
5265           (ioc->facts.MaxChainDepth-1) + scale +
5266           (ioc->req_sz - 64) / ioc->SGE_size;
5267     }
5268 
5269     if (numSGE < sh->sg_tablesize) {
5270         /* Reset this value */
5271         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5272           "Resetting sg_tablesize to %d from %d\n",
5273           ioc->name, numSGE, sh->sg_tablesize));
5274         sh->sg_tablesize = numSGE;
5275     }
5276 
5277     if (mpt_loadtime_max_sectors) {
5278         if (mpt_loadtime_max_sectors < 64 ||
5279             mpt_loadtime_max_sectors > 8192) {
5280             printk(MYIOC_s_INFO_FMT "Invalid value passed for"
5281                 "mpt_loadtime_max_sectors %d."
5282                 "Range from 64 to 8192\n", ioc->name,
5283                 mpt_loadtime_max_sectors);
5284         }
5285         mpt_loadtime_max_sectors &=  0xFFFFFFFE;
5286         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5287             "Resetting max sector to %d from %d\n",
5288           ioc->name, mpt_loadtime_max_sectors, sh->max_sectors));
5289         sh->max_sectors = mpt_loadtime_max_sectors;
5290     }
5291 
5292     hd = shost_priv(sh);
5293     hd->ioc = ioc;
5294 
5295     /* SCSI needs scsi_cmnd lookup table!
5296      * (with size equal to req_depth*PtrSz!)
5297      */
5298     ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
5299     if (!ioc->ScsiLookup) {
5300         error = -ENOMEM;
5301         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5302         goto out_mptsas_probe;
5303     }
5304     spin_lock_init(&ioc->scsi_lookup_lock);
5305 
5306     dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
5307          ioc->name, ioc->ScsiLookup));
5308 
5309     ioc->sas_data.ptClear = mpt_pt_clear;
5310 
5311     hd->last_queue_full = 0;
5312     INIT_LIST_HEAD(&hd->target_reset_list);
5313     INIT_LIST_HEAD(&ioc->sas_device_info_list);
5314     mutex_init(&ioc->sas_device_info_mutex);
5315 
5316     spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5317 
5318     if (ioc->sas_data.ptClear==1) {
5319         mptbase_sas_persist_operation(
5320             ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
5321     }
5322 
5323     error = scsi_add_host(sh, &ioc->pcidev->dev);
5324     if (error) {
5325         dprintk(ioc, printk(MYIOC_s_ERR_FMT
5326           "scsi_add_host failed\n", ioc->name));
5327         goto out_mptsas_probe;
5328     }
5329 
5330     /* older firmware doesn't support expander events */
5331     if ((ioc->facts.HeaderVersion >> 8) < 0xE)
5332         ioc->old_sas_discovery_protocal = 1;
5333     mptsas_scan_sas_topology(ioc);
5334     mptsas_fw_event_on(ioc);
5335     return 0;
5336 
5337  out_mptsas_probe:
5338 
5339     mptscsih_remove(pdev);
5340     return error;
5341 }
5342 
5343 static void
5344 mptsas_shutdown(struct pci_dev *pdev)
5345 {
5346     MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
5347 
5348     mptsas_fw_event_off(ioc);
5349     mptsas_cleanup_fw_event_q(ioc);
5350 }
5351 
5352 static void mptsas_remove(struct pci_dev *pdev)
5353 {
5354     MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
5355     struct mptsas_portinfo *p, *n;
5356     int i;
5357 
5358     if (!ioc->sh) {
5359         printk(MYIOC_s_INFO_FMT "IOC is in Target mode\n", ioc->name);
5360         mpt_detach(pdev);
5361         return;
5362     }
5363 
5364     mptsas_shutdown(pdev);
5365 
5366     mptsas_del_device_components(ioc);
5367 
5368     ioc->sas_discovery_ignore_events = 1;
5369     sas_remove_host(ioc->sh);
5370 
5371     mutex_lock(&ioc->sas_topology_mutex);
5372     list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
5373         list_del(&p->list);
5374         for (i = 0 ; i < p->num_phys ; i++)
5375             mptsas_port_delete(ioc, p->phy_info[i].port_details);
5376 
5377         kfree(p->phy_info);
5378         kfree(p);
5379     }
5380     mutex_unlock(&ioc->sas_topology_mutex);
5381     ioc->hba_port_info = NULL;
5382     mptscsih_remove(pdev);
5383 }
5384 
5385 static struct pci_device_id mptsas_pci_table[] = {
5386     { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
5387         PCI_ANY_ID, PCI_ANY_ID },
5388     { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
5389         PCI_ANY_ID, PCI_ANY_ID },
5390     { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
5391         PCI_ANY_ID, PCI_ANY_ID },
5392     { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
5393         PCI_ANY_ID, PCI_ANY_ID },
5394     { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
5395         PCI_ANY_ID, PCI_ANY_ID },
5396     { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068_820XELP,
5397         PCI_ANY_ID, PCI_ANY_ID },
5398     {0} /* Terminating entry */
5399 };
5400 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
5401 
5402 
5403 static struct pci_driver mptsas_driver = {
5404     .name       = "mptsas",
5405     .id_table   = mptsas_pci_table,
5406     .probe      = mptsas_probe,
5407     .remove     = mptsas_remove,
5408     .shutdown   = mptsas_shutdown,
5409 #ifdef CONFIG_PM
5410     .suspend    = mptscsih_suspend,
5411     .resume     = mptscsih_resume,
5412 #endif
5413 };
5414 
5415 static int __init
5416 mptsas_init(void)
5417 {
5418     int error;
5419 
5420     show_mptmod_ver(my_NAME, my_VERSION);
5421 
5422     mptsas_transport_template =
5423         sas_attach_transport(&mptsas_transport_functions);
5424     if (!mptsas_transport_template)
5425         return -ENODEV;
5426 
5427     mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER,
5428         "mptscsih_io_done");
5429     mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER,
5430         "mptscsih_taskmgmt_complete");
5431     mptsasInternalCtx =
5432         mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER,
5433             "mptscsih_scandv_complete");
5434     mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER,
5435         "mptsas_mgmt_done");
5436     mptsasDeviceResetCtx =
5437         mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER,
5438             "mptsas_taskmgmt_complete");
5439 
5440     mpt_event_register(mptsasDoneCtx, mptsas_event_process);
5441     mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
5442 
5443     error = pci_register_driver(&mptsas_driver);
5444     if (error)
5445         sas_release_transport(mptsas_transport_template);
5446 
5447     return error;
5448 }
5449 
5450 static void __exit
5451 mptsas_exit(void)
5452 {
5453     pci_unregister_driver(&mptsas_driver);
5454     sas_release_transport(mptsas_transport_template);
5455 
5456     mpt_reset_deregister(mptsasDoneCtx);
5457     mpt_event_deregister(mptsasDoneCtx);
5458 
5459     mpt_deregister(mptsasMgmtCtx);
5460     mpt_deregister(mptsasInternalCtx);
5461     mpt_deregister(mptsasTaskCtx);
5462     mpt_deregister(mptsasDoneCtx);
5463     mpt_deregister(mptsasDeviceResetCtx);
5464 }
5465 
5466 module_init(mptsas_init);
5467 module_exit(mptsas_exit);