root/drivers/message/fusion/mptsas.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mptsas_print_phy_data
  2. mptsas_print_phy_pg0
  3. mptsas_print_phy_pg1
  4. mptsas_print_device_pg0
  5. mptsas_print_expander_pg1
  6. mptsas_fw_event_off
  7. mptsas_fw_event_on
  8. mptsas_add_fw_event
  9. mptsas_requeue_fw_event
  10. mptsas_free_fw_event
  11. mptsas_cleanup_fw_event_q
  12. phy_to_ioc
  13. rphy_to_ioc
  14. mptsas_find_portinfo_by_handle
  15. mptsas_find_portinfo_by_sas_address
  16. mptsas_is_end_device
  17. mptsas_port_delete
  18. mptsas_get_rphy
  19. mptsas_set_rphy
  20. mptsas_get_port
  21. mptsas_set_port
  22. mptsas_get_starget
  23. mptsas_set_starget
  24. mptsas_add_device_component
  25. mptsas_add_device_component_by_fw
  26. mptsas_add_device_component_starget_ir
  27. mptsas_add_device_component_starget
  28. mptsas_del_device_component_by_os
  29. mptsas_del_device_components
  30. mptsas_setup_wide_ports
  31. mptsas_find_vtarget
  32. mptsas_queue_device_delete
  33. mptsas_queue_rescan
  34. mptsas_target_reset
  35. mptsas_block_io_sdev
  36. mptsas_block_io_starget
  37. mptsas_target_reset_queue
  38. mptsas_schedule_target_reset
  39. mptsas_taskmgmt_complete
  40. mptsas_ioc_reset
  41. mptsas_sas_enclosure_pg0
  42. mptsas_add_end_device
  43. mptsas_del_end_device
  44. mptsas_refreshing_device_handles
  45. mptsas_firmware_event_work
  46. mptsas_slave_configure
  47. mptsas_target_alloc
  48. mptsas_target_destroy
  49. mptsas_slave_alloc
  50. mptsas_qcmd
  51. mptsas_eh_timed_out
  52. mptsas_get_linkerrors
  53. mptsas_mgmt_done
  54. mptsas_phy_reset
  55. mptsas_get_enclosure_identifier
  56. mptsas_get_bay_identifier
  57. mptsas_smp_handler
  58. mptsas_sas_io_unit_pg0
  59. mptsas_sas_io_unit_pg1
  60. mptsas_sas_phy_pg0
  61. mptsas_sas_device_pg0
  62. mptsas_sas_expander_pg0
  63. mptsas_sas_expander_pg1
  64. mptsas_exp_repmanufacture_info
  65. mptsas_parse_device_info
  66. mptsas_probe_one_phy
  67. mptsas_probe_hba_phys
  68. mptsas_expander_refresh
  69. mptsas_expander_event_add
  70. mptsas_delete_expander_siblings
  71. mptsas_expander_delete
  72. mptsas_send_expander_event
  73. mptsas_expander_add
  74. mptsas_send_link_status_event
  75. mptsas_not_responding_devices
  76. mptsas_probe_expanders
  77. mptsas_probe_devices
  78. mptsas_scan_sas_topology
  79. mptsas_handle_queue_full_event
  80. mptsas_find_phyinfo_by_sas_address
  81. mptsas_find_phyinfo_by_phys_disk_num
  82. mptsas_reprobe_lun
  83. mptsas_reprobe_target
  84. mptsas_adding_inactive_raid_components
  85. mptsas_hotplug_work
  86. mptsas_send_sas_event
  87. mptsas_send_raid_event
  88. mptsas_issue_tm
  89. mptsas_broadcast_primitive_work
  90. mptsas_send_ir2_event
  91. mptsas_event_process
  92. mptsas_volume_delete
  93. mptsas_probe
  94. mptsas_shutdown
  95. mptsas_remove
  96. mptsas_init
  97. mptsas_exit

   1 /*
   2  *  linux/drivers/message/fusion/mptsas.c
   3  *      For use with LSI PCI chip/adapter(s)
   4  *      running LSI Fusion MPT (Message Passing Technology) firmware.
   5  *
   6  *  Copyright (c) 1999-2008 LSI Corporation
   7  *  (mailto:DL-MPTFusionLinux@lsi.com)
   8  */
   9 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  10 /*
  11     This program is free software; you can redistribute it and/or modify
  12     it under the terms of the GNU General Public License as published by
  13     the Free Software Foundation; version 2 of the License.
  14 
  15     This program is distributed in the hope that it will be useful,
  16     but WITHOUT ANY WARRANTY; without even the implied warranty of
  17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18     GNU General Public License for more details.
  19 
  20     NO WARRANTY
  21     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
  22     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
  23     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
  24     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
  25     solely responsible for determining the appropriateness of using and
  26     distributing the Program and assumes all risks associated with its
  27     exercise of rights under this Agreement, including but not limited to
  28     the risks and costs of program errors, damage to or loss of data,
  29     programs or equipment, and unavailability or interruption of operations.
  30 
  31     DISCLAIMER OF LIABILITY
  32     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
  33     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  34     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
  35     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  36     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  37     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
  38     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
  39 
  40     You should have received a copy of the GNU General Public License
  41     along with this program; if not, write to the Free Software
  42     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  43 */
  44 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  45 
  46 #include <linux/module.h>
  47 #include <linux/kernel.h>
  48 #include <linux/slab.h>
  49 #include <linux/init.h>
  50 #include <linux/errno.h>
  51 #include <linux/jiffies.h>
  52 #include <linux/workqueue.h>
  53 #include <linux/delay.h>        /* for mdelay */
  54 
  55 #include <scsi/scsi.h>
  56 #include <scsi/scsi_cmnd.h>
  57 #include <scsi/scsi_device.h>
  58 #include <scsi/scsi_host.h>
  59 #include <scsi/scsi_transport_sas.h>
  60 #include <scsi/scsi_transport.h>
  61 #include <scsi/scsi_dbg.h>
  62 
  63 #include "mptbase.h"
  64 #include "mptscsih.h"
  65 #include "mptsas.h"
  66 
  67 
  68 #define my_NAME         "Fusion MPT SAS Host driver"
  69 #define my_VERSION      MPT_LINUX_VERSION_COMMON
  70 #define MYNAM           "mptsas"
  71 
  72 /*
  73  * Reserved channel for integrated raid
  74  */
  75 #define MPTSAS_RAID_CHANNEL     1
  76 
  77 #define SAS_CONFIG_PAGE_TIMEOUT         30
  78 MODULE_AUTHOR(MODULEAUTHOR);
  79 MODULE_DESCRIPTION(my_NAME);
  80 MODULE_LICENSE("GPL");
  81 MODULE_VERSION(my_VERSION);
  82 
  83 static int mpt_pt_clear;
  84 module_param(mpt_pt_clear, int, 0);
  85 MODULE_PARM_DESC(mpt_pt_clear,
  86                 " Clear persistency table: enable=1  "
  87                 "(default=MPTSCSIH_PT_CLEAR=0)");
  88 
  89 /* scsi-mid layer global parmeter is max_report_luns, which is 511 */
  90 #define MPTSAS_MAX_LUN (16895)
  91 static int max_lun = MPTSAS_MAX_LUN;
  92 module_param(max_lun, int, 0);
  93 MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
  94 
  95 static int mpt_loadtime_max_sectors = 8192;
  96 module_param(mpt_loadtime_max_sectors, int, 0);
  97 MODULE_PARM_DESC(mpt_loadtime_max_sectors,
  98                 " Maximum sector define for Host Bus Adaptor.Range 64 to 8192 default=8192");
  99 
 100 static u8       mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
 101 static u8       mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
 102 static u8       mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */
 103 static u8       mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS;
 104 static u8       mptsasDeviceResetCtx = MPT_MAX_PROTOCOL_DRIVERS;
 105 
 106 static void mptsas_firmware_event_work(struct work_struct *work);
 107 static void mptsas_send_sas_event(struct fw_event_work *fw_event);
 108 static void mptsas_send_raid_event(struct fw_event_work *fw_event);
 109 static void mptsas_send_ir2_event(struct fw_event_work *fw_event);
 110 static void mptsas_parse_device_info(struct sas_identify *identify,
 111                 struct mptsas_devinfo *device_info);
 112 static inline void mptsas_set_rphy(MPT_ADAPTER *ioc,
 113                 struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy);
 114 static struct mptsas_phyinfo    *mptsas_find_phyinfo_by_sas_address
 115                 (MPT_ADAPTER *ioc, u64 sas_address);
 116 static int mptsas_sas_device_pg0(MPT_ADAPTER *ioc,
 117         struct mptsas_devinfo *device_info, u32 form, u32 form_specific);
 118 static int mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc,
 119         struct mptsas_enclosure *enclosure, u32 form, u32 form_specific);
 120 static int mptsas_add_end_device(MPT_ADAPTER *ioc,
 121         struct mptsas_phyinfo *phy_info);
 122 static void mptsas_del_end_device(MPT_ADAPTER *ioc,
 123         struct mptsas_phyinfo *phy_info);
 124 static void mptsas_send_link_status_event(struct fw_event_work *fw_event);
 125 static struct mptsas_portinfo   *mptsas_find_portinfo_by_sas_address
 126                 (MPT_ADAPTER *ioc, u64 sas_address);
 127 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
 128                 struct mptsas_portinfo *port_info, u8 force);
 129 static void mptsas_send_expander_event(struct fw_event_work *fw_event);
 130 static void mptsas_not_responding_devices(MPT_ADAPTER *ioc);
 131 static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
 132 static void mptsas_broadcast_primitive_work(struct fw_event_work *fw_event);
 133 static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
 134 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
 135 void    mptsas_schedule_target_reset(void *ioc);
 136 
 137 static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
 138                                         MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
 139 {
 140         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 141             "---- IO UNIT PAGE 0 ------------\n", ioc->name));
 142         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
 143             ioc->name, le16_to_cpu(phy_data->AttachedDeviceHandle)));
 144         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Controller Handle=0x%X\n",
 145             ioc->name, le16_to_cpu(phy_data->ControllerDevHandle)));
 146         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port=0x%X\n",
 147             ioc->name, phy_data->Port));
 148         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port Flags=0x%X\n",
 149             ioc->name, phy_data->PortFlags));
 150         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Flags=0x%X\n",
 151             ioc->name, phy_data->PhyFlags));
 152         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
 153             ioc->name, phy_data->NegotiatedLinkRate));
 154         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 155             "Controller PHY Device Info=0x%X\n", ioc->name,
 156             le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
 157         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DiscoveryStatus=0x%X\n\n",
 158             ioc->name, le32_to_cpu(phy_data->DiscoveryStatus)));
 159 }
 160 
 161 static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
 162 {
 163         __le64 sas_address;
 164 
 165         memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
 166 
 167         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 168             "---- SAS PHY PAGE 0 ------------\n", ioc->name));
 169         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 170             "Attached Device Handle=0x%X\n", ioc->name,
 171             le16_to_cpu(pg0->AttachedDevHandle)));
 172         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
 173             ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
 174         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 175             "Attached PHY Identifier=0x%X\n", ioc->name,
 176             pg0->AttachedPhyIdentifier));
 177         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Attached Device Info=0x%X\n",
 178             ioc->name, le32_to_cpu(pg0->AttachedDeviceInfo)));
 179         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
 180             ioc->name,  pg0->ProgrammedLinkRate));
 181         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Change Count=0x%X\n",
 182             ioc->name, pg0->ChangeCount));
 183         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Info=0x%X\n\n",
 184             ioc->name, le32_to_cpu(pg0->PhyInfo)));
 185 }
 186 
 187 static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
 188 {
 189         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 190             "---- SAS PHY PAGE 1 ------------\n", ioc->name));
 191         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Invalid Dword Count=0x%x\n",
 192             ioc->name,  pg1->InvalidDwordCount));
 193         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 194             "Running Disparity Error Count=0x%x\n", ioc->name,
 195             pg1->RunningDisparityErrorCount));
 196         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 197             "Loss Dword Synch Count=0x%x\n", ioc->name,
 198             pg1->LossDwordSynchCount));
 199         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 200             "PHY Reset Problem Count=0x%x\n\n", ioc->name,
 201             pg1->PhyResetProblemCount));
 202 }
 203 
 204 static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
 205 {
 206         __le64 sas_address;
 207 
 208         memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
 209 
 210         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 211             "---- SAS DEVICE PAGE 0 ---------\n", ioc->name));
 212         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
 213             ioc->name, le16_to_cpu(pg0->DevHandle)));
 214         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Handle=0x%X\n",
 215             ioc->name, le16_to_cpu(pg0->ParentDevHandle)));
 216         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Enclosure Handle=0x%X\n",
 217             ioc->name, le16_to_cpu(pg0->EnclosureHandle)));
 218         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Slot=0x%X\n",
 219             ioc->name, le16_to_cpu(pg0->Slot)));
 220         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
 221             ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
 222         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Target ID=0x%X\n",
 223             ioc->name, pg0->TargetID));
 224         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Bus=0x%X\n",
 225             ioc->name, pg0->Bus));
 226         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Phy Num=0x%X\n",
 227             ioc->name, pg0->PhyNum));
 228         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Access Status=0x%X\n",
 229             ioc->name, le16_to_cpu(pg0->AccessStatus)));
 230         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Device Info=0x%X\n",
 231             ioc->name, le32_to_cpu(pg0->DeviceInfo)));
 232         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Flags=0x%X\n",
 233             ioc->name, le16_to_cpu(pg0->Flags)));
 234         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n\n",
 235             ioc->name, pg0->PhysicalPort));
 236 }
 237 
 238 static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
 239 {
 240         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 241             "---- SAS EXPANDER PAGE 1 ------------\n", ioc->name));
 242         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n",
 243             ioc->name, pg1->PhysicalPort));
 244         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Identifier=0x%X\n",
 245             ioc->name, pg1->PhyIdentifier));
 246         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
 247             ioc->name, pg1->NegotiatedLinkRate));
 248         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
 249             ioc->name, pg1->ProgrammedLinkRate));
 250         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hardware Link Rate=0x%X\n",
 251             ioc->name, pg1->HwLinkRate));
 252         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Owner Device Handle=0x%X\n",
 253             ioc->name, le16_to_cpu(pg1->OwnerDevHandle)));
 254         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 255             "Attached Device Handle=0x%X\n\n", ioc->name,
 256             le16_to_cpu(pg1->AttachedDevHandle)));
 257 }
 258 
 259 /* inhibit sas firmware event handling */
 260 static void
 261 mptsas_fw_event_off(MPT_ADAPTER *ioc)
 262 {
 263         unsigned long flags;
 264 
 265         spin_lock_irqsave(&ioc->fw_event_lock, flags);
 266         ioc->fw_events_off = 1;
 267         ioc->sas_discovery_quiesce_io = 0;
 268         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
 269 
 270 }
 271 
 272 /* enable sas firmware event handling */
 273 static void
 274 mptsas_fw_event_on(MPT_ADAPTER *ioc)
 275 {
 276         unsigned long flags;
 277 
 278         spin_lock_irqsave(&ioc->fw_event_lock, flags);
 279         ioc->fw_events_off = 0;
 280         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
 281 }
 282 
 283 /* queue a sas firmware event */
 284 static void
 285 mptsas_add_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
 286     unsigned long delay)
 287 {
 288         unsigned long flags;
 289 
 290         spin_lock_irqsave(&ioc->fw_event_lock, flags);
 291         list_add_tail(&fw_event->list, &ioc->fw_event_list);
 292         INIT_DELAYED_WORK(&fw_event->work, mptsas_firmware_event_work);
 293         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: add (fw_event=0x%p)"
 294                 "on cpuid %d\n", ioc->name, __func__,
 295                 fw_event, smp_processor_id()));
 296         queue_delayed_work_on(smp_processor_id(), ioc->fw_event_q,
 297             &fw_event->work, delay);
 298         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
 299 }
 300 
 301 /* requeue a sas firmware event */
 302 static void
 303 mptsas_requeue_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
 304     unsigned long delay)
 305 {
 306         unsigned long flags;
 307         spin_lock_irqsave(&ioc->fw_event_lock, flags);
 308         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: reschedule task "
 309             "(fw_event=0x%p)on cpuid %d\n", ioc->name, __func__,
 310                 fw_event, smp_processor_id()));
 311         fw_event->retries++;
 312         queue_delayed_work_on(smp_processor_id(), ioc->fw_event_q,
 313             &fw_event->work, msecs_to_jiffies(delay));
 314         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
 315 }
 316 
 317 /* free memory associated to a sas firmware event */
 318 static void
 319 mptsas_free_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event)
 320 {
 321         unsigned long flags;
 322 
 323         spin_lock_irqsave(&ioc->fw_event_lock, flags);
 324         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: kfree (fw_event=0x%p)\n",
 325             ioc->name, __func__, fw_event));
 326         list_del(&fw_event->list);
 327         kfree(fw_event);
 328         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
 329 }
 330 
 331 /* walk the firmware event queue, and either stop or wait for
 332  * outstanding events to complete */
 333 static void
 334 mptsas_cleanup_fw_event_q(MPT_ADAPTER *ioc)
 335 {
 336         struct fw_event_work *fw_event, *next;
 337         struct mptsas_target_reset_event *target_reset_list, *n;
 338         MPT_SCSI_HOST   *hd = shost_priv(ioc->sh);
 339 
 340         /* flush the target_reset_list */
 341         if (!list_empty(&hd->target_reset_list)) {
 342                 list_for_each_entry_safe(target_reset_list, n,
 343                     &hd->target_reset_list, list) {
 344                         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 345                             "%s: removing target reset for id=%d\n",
 346                             ioc->name, __func__,
 347                            target_reset_list->sas_event_data.TargetID));
 348                         list_del(&target_reset_list->list);
 349                         kfree(target_reset_list);
 350                 }
 351         }
 352 
 353         if (list_empty(&ioc->fw_event_list) ||
 354              !ioc->fw_event_q || in_interrupt())
 355                 return;
 356 
 357         list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) {
 358                 if (cancel_delayed_work(&fw_event->work))
 359                         mptsas_free_fw_event(ioc, fw_event);
 360         }
 361 }
 362 
 363 
 364 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
 365 {
 366         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
 367         return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
 368 }
 369 
 370 static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
 371 {
 372         struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
 373         return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
 374 }
 375 
 376 /*
 377  * mptsas_find_portinfo_by_handle
 378  *
 379  * This function should be called with the sas_topology_mutex already held
 380  */
 381 static struct mptsas_portinfo *
 382 mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
 383 {
 384         struct mptsas_portinfo *port_info, *rc=NULL;
 385         int i;
 386 
 387         list_for_each_entry(port_info, &ioc->sas_topology, list)
 388                 for (i = 0; i < port_info->num_phys; i++)
 389                         if (port_info->phy_info[i].identify.handle == handle) {
 390                                 rc = port_info;
 391                                 goto out;
 392                         }
 393  out:
 394         return rc;
 395 }
 396 
 397 /**
 398  *      mptsas_find_portinfo_by_sas_address -
 399  *      @ioc: Pointer to MPT_ADAPTER structure
 400  *      @handle:
 401  *
 402  *      This function should be called with the sas_topology_mutex already held
 403  *
 404  **/
 405 static struct mptsas_portinfo *
 406 mptsas_find_portinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
 407 {
 408         struct mptsas_portinfo *port_info, *rc = NULL;
 409         int i;
 410 
 411         if (sas_address >= ioc->hba_port_sas_addr &&
 412             sas_address < (ioc->hba_port_sas_addr +
 413             ioc->hba_port_num_phy))
 414                 return ioc->hba_port_info;
 415 
 416         mutex_lock(&ioc->sas_topology_mutex);
 417         list_for_each_entry(port_info, &ioc->sas_topology, list)
 418                 for (i = 0; i < port_info->num_phys; i++)
 419                         if (port_info->phy_info[i].identify.sas_address ==
 420                             sas_address) {
 421                                 rc = port_info;
 422                                 goto out;
 423                         }
 424  out:
 425         mutex_unlock(&ioc->sas_topology_mutex);
 426         return rc;
 427 }
 428 
 429 /*
 430  * Returns true if there is a scsi end device
 431  */
 432 static inline int
 433 mptsas_is_end_device(struct mptsas_devinfo * attached)
 434 {
 435         if ((attached->sas_address) &&
 436             (attached->device_info &
 437             MPI_SAS_DEVICE_INFO_END_DEVICE) &&
 438             ((attached->device_info &
 439             MPI_SAS_DEVICE_INFO_SSP_TARGET) |
 440             (attached->device_info &
 441             MPI_SAS_DEVICE_INFO_STP_TARGET) |
 442             (attached->device_info &
 443             MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
 444                 return 1;
 445         else
 446                 return 0;
 447 }
 448 
 449 /* no mutex */
 450 static void
 451 mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
 452 {
 453         struct mptsas_portinfo *port_info;
 454         struct mptsas_phyinfo *phy_info;
 455         u8      i;
 456 
 457         if (!port_details)
 458                 return;
 459 
 460         port_info = port_details->port_info;
 461         phy_info = port_info->phy_info;
 462 
 463         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d "
 464             "bitmask=0x%016llX\n", ioc->name, __func__, port_details,
 465             port_details->num_phys, (unsigned long long)
 466             port_details->phy_bitmask));
 467 
 468         for (i = 0; i < port_info->num_phys; i++, phy_info++) {
 469                 if(phy_info->port_details != port_details)
 470                         continue;
 471                 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
 472                 mptsas_set_rphy(ioc, phy_info, NULL);
 473                 phy_info->port_details = NULL;
 474         }
 475         kfree(port_details);
 476 }
 477 
 478 static inline struct sas_rphy *
 479 mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
 480 {
 481         if (phy_info->port_details)
 482                 return phy_info->port_details->rphy;
 483         else
 484                 return NULL;
 485 }
 486 
 487 static inline void
 488 mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
 489 {
 490         if (phy_info->port_details) {
 491                 phy_info->port_details->rphy = rphy;
 492                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
 493                     ioc->name, rphy));
 494         }
 495 
 496         if (rphy) {
 497                 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
 498                     &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
 499                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
 500                     ioc->name, rphy, rphy->dev.release));
 501         }
 502 }
 503 
 504 static inline struct sas_port *
 505 mptsas_get_port(struct mptsas_phyinfo *phy_info)
 506 {
 507         if (phy_info->port_details)
 508                 return phy_info->port_details->port;
 509         else
 510                 return NULL;
 511 }
 512 
 513 static inline void
 514 mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_port *port)
 515 {
 516         if (phy_info->port_details)
 517                 phy_info->port_details->port = port;
 518 
 519         if (port) {
 520                 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
 521                     &port->dev, MYIOC_s_FMT "add:", ioc->name));
 522                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "port=%p release=%p\n",
 523                     ioc->name, port, port->dev.release));
 524         }
 525 }
 526 
 527 static inline struct scsi_target *
 528 mptsas_get_starget(struct mptsas_phyinfo *phy_info)
 529 {
 530         if (phy_info->port_details)
 531                 return phy_info->port_details->starget;
 532         else
 533                 return NULL;
 534 }
 535 
 536 static inline void
 537 mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
 538 starget)
 539 {
 540         if (phy_info->port_details)
 541                 phy_info->port_details->starget = starget;
 542 }
 543 
 544 /**
 545  *      mptsas_add_device_component -
 546  *      @ioc: Pointer to MPT_ADAPTER structure
 547  *      @channel: fw mapped id's
 548  *      @id:
 549  *      @sas_address:
 550  *      @device_info:
 551  *
 552  **/
 553 static void
 554 mptsas_add_device_component(MPT_ADAPTER *ioc, u8 channel, u8 id,
 555         u64 sas_address, u32 device_info, u16 slot, u64 enclosure_logical_id)
 556 {
 557         struct mptsas_device_info       *sas_info, *next;
 558         struct scsi_device      *sdev;
 559         struct scsi_target      *starget;
 560         struct sas_rphy *rphy;
 561 
 562         /*
 563          * Delete all matching devices out of the list
 564          */
 565         mutex_lock(&ioc->sas_device_info_mutex);
 566         list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
 567             list) {
 568                 if (!sas_info->is_logical_volume &&
 569                     (sas_info->sas_address == sas_address ||
 570                     (sas_info->fw.channel == channel &&
 571                      sas_info->fw.id == id))) {
 572                         list_del(&sas_info->list);
 573                         kfree(sas_info);
 574                 }
 575         }
 576 
 577         sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
 578         if (!sas_info)
 579                 goto out;
 580 
 581         /*
 582          * Set Firmware mapping
 583          */
 584         sas_info->fw.id = id;
 585         sas_info->fw.channel = channel;
 586 
 587         sas_info->sas_address = sas_address;
 588         sas_info->device_info = device_info;
 589         sas_info->slot = slot;
 590         sas_info->enclosure_logical_id = enclosure_logical_id;
 591         INIT_LIST_HEAD(&sas_info->list);
 592         list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
 593 
 594         /*
 595          * Set OS mapping
 596          */
 597         shost_for_each_device(sdev, ioc->sh) {
 598                 starget = scsi_target(sdev);
 599                 rphy = dev_to_rphy(starget->dev.parent);
 600                 if (rphy->identify.sas_address == sas_address) {
 601                         sas_info->os.id = starget->id;
 602                         sas_info->os.channel = starget->channel;
 603                 }
 604         }
 605 
 606  out:
 607         mutex_unlock(&ioc->sas_device_info_mutex);
 608         return;
 609 }
 610 
 611 /**
 612  *      mptsas_add_device_component_by_fw -
 613  *      @ioc: Pointer to MPT_ADAPTER structure
 614  *      @channel:  fw mapped id's
 615  *      @id:
 616  *
 617  **/
 618 static void
 619 mptsas_add_device_component_by_fw(MPT_ADAPTER *ioc, u8 channel, u8 id)
 620 {
 621         struct mptsas_devinfo sas_device;
 622         struct mptsas_enclosure enclosure_info;
 623         int rc;
 624 
 625         rc = mptsas_sas_device_pg0(ioc, &sas_device,
 626             (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
 627              MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
 628             (channel << 8) + id);
 629         if (rc)
 630                 return;
 631 
 632         memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
 633         mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
 634             (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
 635              MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
 636              sas_device.handle_enclosure);
 637 
 638         mptsas_add_device_component(ioc, sas_device.channel,
 639             sas_device.id, sas_device.sas_address, sas_device.device_info,
 640             sas_device.slot, enclosure_info.enclosure_logical_id);
 641 }
 642 
 643 /**
 644  *      mptsas_add_device_component_starget_ir - Handle Integrated RAID, adding each individual device to list
 645  *      @ioc: Pointer to MPT_ADAPTER structure
 646  *      @channel: fw mapped id's
 647  *      @id:
 648  *
 649  **/
 650 static void
 651 mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc,
 652                 struct scsi_target *starget)
 653 {
 654         CONFIGPARMS                     cfg;
 655         ConfigPageHeader_t              hdr;
 656         dma_addr_t                      dma_handle;
 657         pRaidVolumePage0_t              buffer = NULL;
 658         int                             i;
 659         RaidPhysDiskPage0_t             phys_disk;
 660         struct mptsas_device_info       *sas_info, *next;
 661 
 662         memset(&cfg, 0 , sizeof(CONFIGPARMS));
 663         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
 664         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
 665         /* assumption that all volumes on channel = 0 */
 666         cfg.pageAddr = starget->id;
 667         cfg.cfghdr.hdr = &hdr;
 668         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
 669         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
 670 
 671         if (mpt_config(ioc, &cfg) != 0)
 672                 goto out;
 673 
 674         if (!hdr.PageLength)
 675                 goto out;
 676 
 677         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
 678             &dma_handle);
 679 
 680         if (!buffer)
 681                 goto out;
 682 
 683         cfg.physAddr = dma_handle;
 684         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
 685 
 686         if (mpt_config(ioc, &cfg) != 0)
 687                 goto out;
 688 
 689         if (!buffer->NumPhysDisks)
 690                 goto out;
 691 
 692         /*
 693          * Adding entry for hidden components
 694          */
 695         for (i = 0; i < buffer->NumPhysDisks; i++) {
 696 
 697                 if (mpt_raid_phys_disk_pg0(ioc,
 698                     buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
 699                         continue;
 700 
 701                 mptsas_add_device_component_by_fw(ioc, phys_disk.PhysDiskBus,
 702                     phys_disk.PhysDiskID);
 703 
 704                 mutex_lock(&ioc->sas_device_info_mutex);
 705                 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
 706                     list) {
 707                         if (!sas_info->is_logical_volume &&
 708                             (sas_info->fw.channel == phys_disk.PhysDiskBus &&
 709                             sas_info->fw.id == phys_disk.PhysDiskID)) {
 710                                 sas_info->is_hidden_raid_component = 1;
 711                                 sas_info->volume_id = starget->id;
 712                         }
 713                 }
 714                 mutex_unlock(&ioc->sas_device_info_mutex);
 715 
 716         }
 717 
 718         /*
 719          * Delete all matching devices out of the list
 720          */
 721         mutex_lock(&ioc->sas_device_info_mutex);
 722         list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
 723             list) {
 724                 if (sas_info->is_logical_volume && sas_info->fw.id ==
 725                     starget->id) {
 726                         list_del(&sas_info->list);
 727                         kfree(sas_info);
 728                 }
 729         }
 730 
 731         sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
 732         if (sas_info) {
 733                 sas_info->fw.id = starget->id;
 734                 sas_info->os.id = starget->id;
 735                 sas_info->os.channel = starget->channel;
 736                 sas_info->is_logical_volume = 1;
 737                 INIT_LIST_HEAD(&sas_info->list);
 738                 list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
 739         }
 740         mutex_unlock(&ioc->sas_device_info_mutex);
 741 
 742  out:
 743         if (buffer)
 744                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
 745                     dma_handle);
 746 }
 747 
 748 /**
 749  *      mptsas_add_device_component_starget -
 750  *      @ioc: Pointer to MPT_ADAPTER structure
 751  *      @starget:
 752  *
 753  **/
 754 static void
 755 mptsas_add_device_component_starget(MPT_ADAPTER *ioc,
 756         struct scsi_target *starget)
 757 {
 758         VirtTarget      *vtarget;
 759         struct sas_rphy *rphy;
 760         struct mptsas_phyinfo   *phy_info = NULL;
 761         struct mptsas_enclosure enclosure_info;
 762 
 763         rphy = dev_to_rphy(starget->dev.parent);
 764         vtarget = starget->hostdata;
 765         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
 766                         rphy->identify.sas_address);
 767         if (!phy_info)
 768                 return;
 769 
 770         memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
 771         mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
 772                 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
 773                 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
 774                 phy_info->attached.handle_enclosure);
 775 
 776         mptsas_add_device_component(ioc, phy_info->attached.channel,
 777                 phy_info->attached.id, phy_info->attached.sas_address,
 778                 phy_info->attached.device_info,
 779                 phy_info->attached.slot, enclosure_info.enclosure_logical_id);
 780 }
 781 
 782 /**
 783  *      mptsas_del_device_component_by_os - Once a device has been removed, we mark the entry in the list as being cached
 784  *      @ioc: Pointer to MPT_ADAPTER structure
 785  *      @channel: os mapped id's
 786  *      @id:
 787  *
 788  **/
 789 static void
 790 mptsas_del_device_component_by_os(MPT_ADAPTER *ioc, u8 channel, u8 id)
 791 {
 792         struct mptsas_device_info       *sas_info, *next;
 793 
 794         /*
 795          * Set is_cached flag
 796          */
 797         list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
 798                 list) {
 799                 if (sas_info->os.channel == channel && sas_info->os.id == id)
 800                         sas_info->is_cached = 1;
 801         }
 802 }
 803 
 804 /**
 805  *      mptsas_del_device_components - Cleaning the list
 806  *      @ioc: Pointer to MPT_ADAPTER structure
 807  *
 808  **/
 809 static void
 810 mptsas_del_device_components(MPT_ADAPTER *ioc)
 811 {
 812         struct mptsas_device_info       *sas_info, *next;
 813 
 814         mutex_lock(&ioc->sas_device_info_mutex);
 815         list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
 816                 list) {
 817                 list_del(&sas_info->list);
 818                 kfree(sas_info);
 819         }
 820         mutex_unlock(&ioc->sas_device_info_mutex);
 821 }
 822 
 823 
 824 /*
 825  * mptsas_setup_wide_ports
 826  *
 827  * Updates for new and existing narrow/wide port configuration
 828  * in the sas_topology
 829  */
 830 static void
 831 mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
 832 {
 833         struct mptsas_portinfo_details * port_details;
 834         struct mptsas_phyinfo *phy_info, *phy_info_cmp;
 835         u64     sas_address;
 836         int     i, j;
 837 
 838         mutex_lock(&ioc->sas_topology_mutex);
 839 
 840         phy_info = port_info->phy_info;
 841         for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
 842                 if (phy_info->attached.handle)
 843                         continue;
 844                 port_details = phy_info->port_details;
 845                 if (!port_details)
 846                         continue;
 847                 if (port_details->num_phys < 2)
 848                         continue;
 849                 /*
 850                  * Removing a phy from a port, letting the last
 851                  * phy be removed by firmware events.
 852                  */
 853                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 854                     "%s: [%p]: deleting phy = %d\n",
 855                     ioc->name, __func__, port_details, i));
 856                 port_details->num_phys--;
 857                 port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
 858                 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
 859                 if (phy_info->phy) {
 860                         devtprintk(ioc, dev_printk(KERN_DEBUG,
 861                                 &phy_info->phy->dev, MYIOC_s_FMT
 862                                 "delete phy %d, phy-obj (0x%p)\n", ioc->name,
 863                                 phy_info->phy_id, phy_info->phy));
 864                         sas_port_delete_phy(port_details->port, phy_info->phy);
 865                 }
 866                 phy_info->port_details = NULL;
 867         }
 868 
 869         /*
 870          * Populate and refresh the tree
 871          */
 872         phy_info = port_info->phy_info;
 873         for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
 874                 sas_address = phy_info->attached.sas_address;
 875                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "phy_id=%d sas_address=0x%018llX\n",
 876                     ioc->name, i, (unsigned long long)sas_address));
 877                 if (!sas_address)
 878                         continue;
 879                 port_details = phy_info->port_details;
 880                 /*
 881                  * Forming a port
 882                  */
 883                 if (!port_details) {
 884                         port_details = kzalloc(sizeof(struct
 885                                 mptsas_portinfo_details), GFP_KERNEL);
 886                         if (!port_details)
 887                                 goto out;
 888                         port_details->num_phys = 1;
 889                         port_details->port_info = port_info;
 890                         if (phy_info->phy_id < 64 )
 891                                 port_details->phy_bitmask |=
 892                                     (1 << phy_info->phy_id);
 893                         phy_info->sas_port_add_phy=1;
 894                         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tForming port\n\t\t"
 895                             "phy_id=%d sas_address=0x%018llX\n",
 896                             ioc->name, i, (unsigned long long)sas_address));
 897                         phy_info->port_details = port_details;
 898                 }
 899 
 900                 if (i == port_info->num_phys - 1)
 901                         continue;
 902                 phy_info_cmp = &port_info->phy_info[i + 1];
 903                 for (j = i + 1 ; j < port_info->num_phys ; j++,
 904                     phy_info_cmp++) {
 905                         if (!phy_info_cmp->attached.sas_address)
 906                                 continue;
 907                         if (sas_address != phy_info_cmp->attached.sas_address)
 908                                 continue;
 909                         if (phy_info_cmp->port_details == port_details )
 910                                 continue;
 911                         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 912                             "\t\tphy_id=%d sas_address=0x%018llX\n",
 913                             ioc->name, j, (unsigned long long)
 914                             phy_info_cmp->attached.sas_address));
 915                         if (phy_info_cmp->port_details) {
 916                                 port_details->rphy =
 917                                     mptsas_get_rphy(phy_info_cmp);
 918                                 port_details->port =
 919                                     mptsas_get_port(phy_info_cmp);
 920                                 port_details->starget =
 921                                     mptsas_get_starget(phy_info_cmp);
 922                                 port_details->num_phys =
 923                                         phy_info_cmp->port_details->num_phys;
 924                                 if (!phy_info_cmp->port_details->num_phys)
 925                                         kfree(phy_info_cmp->port_details);
 926                         } else
 927                                 phy_info_cmp->sas_port_add_phy=1;
 928                         /*
 929                          * Adding a phy to a port
 930                          */
 931                         phy_info_cmp->port_details = port_details;
 932                         if (phy_info_cmp->phy_id < 64 )
 933                                 port_details->phy_bitmask |=
 934                                 (1 << phy_info_cmp->phy_id);
 935                         port_details->num_phys++;
 936                 }
 937         }
 938 
 939  out:
 940 
 941         for (i = 0; i < port_info->num_phys; i++) {
 942                 port_details = port_info->phy_info[i].port_details;
 943                 if (!port_details)
 944                         continue;
 945                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 946                     "%s: [%p]: phy_id=%02d num_phys=%02d "
 947                     "bitmask=0x%016llX\n", ioc->name, __func__,
 948                     port_details, i, port_details->num_phys,
 949                     (unsigned long long)port_details->phy_bitmask));
 950                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n",
 951                     ioc->name, port_details->port, port_details->rphy));
 952         }
 953         dsaswideprintk(ioc, printk("\n"));
 954         mutex_unlock(&ioc->sas_topology_mutex);
 955 }
 956 
 957 /**
 958  * csmisas_find_vtarget
 959  *
 960  * @ioc
 961  * @volume_id
 962  * @volume_bus
 963  *
 964  **/
 965 static VirtTarget *
 966 mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
 967 {
 968         struct scsi_device              *sdev;
 969         VirtDevice                      *vdevice;
 970         VirtTarget                      *vtarget = NULL;
 971 
 972         shost_for_each_device(sdev, ioc->sh) {
 973                 vdevice = sdev->hostdata;
 974                 if ((vdevice == NULL) ||
 975                         (vdevice->vtarget == NULL))
 976                         continue;
 977                 if ((vdevice->vtarget->tflags &
 978                     MPT_TARGET_FLAGS_RAID_COMPONENT ||
 979                     vdevice->vtarget->raidVolume))
 980                         continue;
 981                 if (vdevice->vtarget->id == id &&
 982                         vdevice->vtarget->channel == channel)
 983                         vtarget = vdevice->vtarget;
 984         }
 985         return vtarget;
 986 }
 987 
 988 static void
 989 mptsas_queue_device_delete(MPT_ADAPTER *ioc,
 990         MpiEventDataSasDeviceStatusChange_t *sas_event_data)
 991 {
 992         struct fw_event_work *fw_event;
 993 
 994         fw_event = kzalloc(sizeof(*fw_event) +
 995                            sizeof(MpiEventDataSasDeviceStatusChange_t),
 996                            GFP_ATOMIC);
 997         if (!fw_event) {
 998                 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
 999                     ioc->name, __func__, __LINE__);
1000                 return;
1001         }
1002         memcpy(fw_event->event_data, sas_event_data,
1003             sizeof(MpiEventDataSasDeviceStatusChange_t));
1004         fw_event->event = MPI_EVENT_SAS_DEVICE_STATUS_CHANGE;
1005         fw_event->ioc = ioc;
1006         mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
1007 }
1008 
1009 static void
1010 mptsas_queue_rescan(MPT_ADAPTER *ioc)
1011 {
1012         struct fw_event_work *fw_event;
1013 
1014         fw_event = kzalloc(sizeof(*fw_event), GFP_ATOMIC);
1015         if (!fw_event) {
1016                 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
1017                     ioc->name, __func__, __LINE__);
1018                 return;
1019         }
1020         fw_event->event = -1;
1021         fw_event->ioc = ioc;
1022         mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
1023 }
1024 
1025 
1026 /**
1027  * mptsas_target_reset
1028  *
1029  * Issues TARGET_RESET to end device using handshaking method
1030  *
1031  * @ioc
1032  * @channel
1033  * @id
1034  *
1035  * Returns (1) success
1036  *         (0) failure
1037  *
1038  **/
1039 static int
1040 mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
1041 {
1042         MPT_FRAME_HDR   *mf;
1043         SCSITaskMgmt_t  *pScsiTm;
1044         if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0)
1045                 return 0;
1046 
1047 
1048         mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
1049         if (mf == NULL) {
1050                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1051                         "%s, no msg frames @%d!!\n", ioc->name,
1052                         __func__, __LINE__));
1053                 goto out_fail;
1054         }
1055 
1056         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1057                 ioc->name, mf));
1058 
1059         /* Format the Request
1060          */
1061         pScsiTm = (SCSITaskMgmt_t *) mf;
1062         memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
1063         pScsiTm->TargetID = id;
1064         pScsiTm->Bus = channel;
1065         pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1066         pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
1067         pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
1068 
1069         DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
1070 
1071         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1072            "TaskMgmt type=%d (sas device delete) fw_channel = %d fw_id = %d)\n",
1073            ioc->name, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, channel, id));
1074 
1075         mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
1076 
1077         return 1;
1078 
1079  out_fail:
1080 
1081         mpt_clear_taskmgmt_in_progress_flag(ioc);
1082         return 0;
1083 }
1084 
1085 static void
1086 mptsas_block_io_sdev(struct scsi_device *sdev, void *data)
1087 {
1088         scsi_device_set_state(sdev, SDEV_BLOCK);
1089 }
1090 
1091 static void
1092 mptsas_block_io_starget(struct scsi_target *starget)
1093 {
1094         if (starget)
1095                 starget_for_each_device(starget, NULL, mptsas_block_io_sdev);
1096 }
1097 
1098 /**
1099  * mptsas_target_reset_queue
1100  *
1101  * Receive request for TARGET_RESET after receiving an firmware
1102  * event NOT_RESPONDING_EVENT, then put command in link list
1103  * and queue if task_queue already in use.
1104  *
1105  * @ioc
1106  * @sas_event_data
1107  *
1108  **/
1109 static void
1110 mptsas_target_reset_queue(MPT_ADAPTER *ioc,
1111     EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1112 {
1113         MPT_SCSI_HOST   *hd = shost_priv(ioc->sh);
1114         VirtTarget *vtarget = NULL;
1115         struct mptsas_target_reset_event *target_reset_list;
1116         u8              id, channel;
1117 
1118         id = sas_event_data->TargetID;
1119         channel = sas_event_data->Bus;
1120 
1121         vtarget = mptsas_find_vtarget(ioc, channel, id);
1122         if (vtarget) {
1123                 mptsas_block_io_starget(vtarget->starget);
1124                 vtarget->deleted = 1; /* block IO */
1125         }
1126 
1127         target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event),
1128             GFP_ATOMIC);
1129         if (!target_reset_list) {
1130                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1131                         "%s, failed to allocate mem @%d..!!\n",
1132                         ioc->name, __func__, __LINE__));
1133                 return;
1134         }
1135 
1136         memcpy(&target_reset_list->sas_event_data, sas_event_data,
1137                 sizeof(*sas_event_data));
1138         list_add_tail(&target_reset_list->list, &hd->target_reset_list);
1139 
1140         target_reset_list->time_count = jiffies;
1141 
1142         if (mptsas_target_reset(ioc, channel, id)) {
1143                 target_reset_list->target_reset_issued = 1;
1144         }
1145 }
1146 
1147 /**
1148  * mptsas_schedule_target_reset- send pending target reset
1149  * @iocp: per adapter object
1150  *
1151  * This function will delete scheduled target reset from the list and
1152  * try to send next target reset. This will be called from completion
1153  * context of any Task management command.
1154  */
1155 
1156 void
1157 mptsas_schedule_target_reset(void *iocp)
1158 {
1159         MPT_ADAPTER *ioc = (MPT_ADAPTER *)(iocp);
1160         MPT_SCSI_HOST   *hd = shost_priv(ioc->sh);
1161         struct list_head *head = &hd->target_reset_list;
1162         struct mptsas_target_reset_event        *target_reset_list;
1163         u8              id, channel;
1164         /*
1165          * issue target reset to next device in the queue
1166          */
1167 
1168         if (list_empty(head))
1169                 return;
1170 
1171         target_reset_list = list_entry(head->next,
1172                 struct mptsas_target_reset_event, list);
1173 
1174         id = target_reset_list->sas_event_data.TargetID;
1175         channel = target_reset_list->sas_event_data.Bus;
1176         target_reset_list->time_count = jiffies;
1177 
1178         if (mptsas_target_reset(ioc, channel, id))
1179                 target_reset_list->target_reset_issued = 1;
1180         return;
1181 }
1182 
1183 
1184 /**
1185  *      mptsas_taskmgmt_complete - complete SAS task management function
1186  *      @ioc: Pointer to MPT_ADAPTER structure
1187  *
1188  *      Completion for TARGET_RESET after NOT_RESPONDING_EVENT, enable work
1189  *      queue to finish off removing device from upper layers. then send next
1190  *      TARGET_RESET in the queue.
1191  **/
1192 static int
1193 mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
1194 {
1195         MPT_SCSI_HOST   *hd = shost_priv(ioc->sh);
1196         struct list_head *head = &hd->target_reset_list;
1197         u8              id, channel;
1198         struct mptsas_target_reset_event        *target_reset_list;
1199         SCSITaskMgmtReply_t *pScsiTmReply;
1200 
1201         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt completed: "
1202             "(mf = %p, mr = %p)\n", ioc->name, mf, mr));
1203 
1204         pScsiTmReply = (SCSITaskMgmtReply_t *)mr;
1205         if (!pScsiTmReply)
1206                 return 0;
1207 
1208         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1209             "\tTaskMgmt completed: fw_channel = %d, fw_id = %d,\n"
1210             "\ttask_type = 0x%02X, iocstatus = 0x%04X "
1211             "loginfo = 0x%08X,\n\tresponse_code = 0x%02X, "
1212             "term_cmnds = %d\n", ioc->name,
1213             pScsiTmReply->Bus, pScsiTmReply->TargetID,
1214             pScsiTmReply->TaskType,
1215             le16_to_cpu(pScsiTmReply->IOCStatus),
1216             le32_to_cpu(pScsiTmReply->IOCLogInfo),
1217             pScsiTmReply->ResponseCode,
1218             le32_to_cpu(pScsiTmReply->TerminationCount)));
1219 
1220         if (pScsiTmReply->ResponseCode)
1221                 mptscsih_taskmgmt_response_code(ioc,
1222                 pScsiTmReply->ResponseCode);
1223 
1224         if (pScsiTmReply->TaskType ==
1225             MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK || pScsiTmReply->TaskType ==
1226              MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET) {
1227                 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
1228                 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
1229                 memcpy(ioc->taskmgmt_cmds.reply, mr,
1230                     min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
1231                 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
1232                         ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
1233                         complete(&ioc->taskmgmt_cmds.done);
1234                         return 1;
1235                 }
1236                 return 0;
1237         }
1238 
1239         mpt_clear_taskmgmt_in_progress_flag(ioc);
1240 
1241         if (list_empty(head))
1242                 return 1;
1243 
1244         target_reset_list = list_entry(head->next,
1245             struct mptsas_target_reset_event, list);
1246 
1247         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1248             "TaskMgmt: completed (%d seconds)\n",
1249             ioc->name, jiffies_to_msecs(jiffies -
1250             target_reset_list->time_count)/1000));
1251 
1252         id = pScsiTmReply->TargetID;
1253         channel = pScsiTmReply->Bus;
1254         target_reset_list->time_count = jiffies;
1255 
1256         /*
1257          * retry target reset
1258          */
1259         if (!target_reset_list->target_reset_issued) {
1260                 if (mptsas_target_reset(ioc, channel, id))
1261                         target_reset_list->target_reset_issued = 1;
1262                 return 1;
1263         }
1264 
1265         /*
1266          * enable work queue to remove device from upper layers
1267          */
1268         list_del(&target_reset_list->list);
1269         if (!ioc->fw_events_off)
1270                 mptsas_queue_device_delete(ioc,
1271                         &target_reset_list->sas_event_data);
1272 
1273 
1274         ioc->schedule_target_reset(ioc);
1275 
1276         return 1;
1277 }
1278 
1279 /**
1280  * mptscsih_ioc_reset
1281  *
1282  * @ioc
1283  * @reset_phase
1284  *
1285  **/
1286 static int
1287 mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1288 {
1289         MPT_SCSI_HOST   *hd;
1290         int rc;
1291 
1292         rc = mptscsih_ioc_reset(ioc, reset_phase);
1293         if ((ioc->bus_type != SAS) || (!rc))
1294                 return rc;
1295 
1296         hd = shost_priv(ioc->sh);
1297         if (!hd->ioc)
1298                 goto out;
1299 
1300         switch (reset_phase) {
1301         case MPT_IOC_SETUP_RESET:
1302                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1303                     "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
1304                 mptsas_fw_event_off(ioc);
1305                 break;
1306         case MPT_IOC_PRE_RESET:
1307                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1308                     "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
1309                 break;
1310         case MPT_IOC_POST_RESET:
1311                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1312                     "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
1313                 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
1314                         ioc->sas_mgmt.status |= MPT_MGMT_STATUS_DID_IOCRESET;
1315                         complete(&ioc->sas_mgmt.done);
1316                 }
1317                 mptsas_cleanup_fw_event_q(ioc);
1318                 mptsas_queue_rescan(ioc);
1319                 break;
1320         default:
1321                 break;
1322         }
1323 
1324  out:
1325         return rc;
1326 }
1327 
1328 
1329 /**
1330  * enum device_state -
1331  * @DEVICE_RETRY: need to retry the TUR
1332  * @DEVICE_ERROR: TUR return error, don't add device
1333  * @DEVICE_READY: device can be added
1334  *
1335  */
1336 enum device_state{
1337         DEVICE_RETRY,
1338         DEVICE_ERROR,
1339         DEVICE_READY,
1340 };
1341 
1342 static int
1343 mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
1344                 u32 form, u32 form_specific)
1345 {
1346         ConfigExtendedPageHeader_t hdr;
1347         CONFIGPARMS cfg;
1348         SasEnclosurePage0_t *buffer;
1349         dma_addr_t dma_handle;
1350         int error;
1351         __le64 le_identifier;
1352 
1353         memset(&hdr, 0, sizeof(hdr));
1354         hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
1355         hdr.PageNumber = 0;
1356         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1357         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
1358 
1359         cfg.cfghdr.ehdr = &hdr;
1360         cfg.physAddr = -1;
1361         cfg.pageAddr = form + form_specific;
1362         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1363         cfg.dir = 0;    /* read */
1364         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
1365 
1366         error = mpt_config(ioc, &cfg);
1367         if (error)
1368                 goto out;
1369         if (!hdr.ExtPageLength) {
1370                 error = -ENXIO;
1371                 goto out;
1372         }
1373 
1374         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1375                         &dma_handle);
1376         if (!buffer) {
1377                 error = -ENOMEM;
1378                 goto out;
1379         }
1380 
1381         cfg.physAddr = dma_handle;
1382         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1383 
1384         error = mpt_config(ioc, &cfg);
1385         if (error)
1386                 goto out_free_consistent;
1387 
1388         /* save config data */
1389         memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
1390         enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
1391         enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
1392         enclosure->flags = le16_to_cpu(buffer->Flags);
1393         enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
1394         enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
1395         enclosure->start_id = buffer->StartTargetID;
1396         enclosure->start_channel = buffer->StartBus;
1397         enclosure->sep_id = buffer->SEPTargetID;
1398         enclosure->sep_channel = buffer->SEPBus;
1399 
1400  out_free_consistent:
1401         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1402                             buffer, dma_handle);
1403  out:
1404         return error;
1405 }
1406 
1407 /**
1408  *      mptsas_add_end_device - report a new end device to sas transport layer
1409  *      @ioc: Pointer to MPT_ADAPTER structure
1410  *      @phy_info: describes attached device
1411  *
1412  *      return (0) success (1) failure
1413  *
1414  **/
1415 static int
1416 mptsas_add_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1417 {
1418         struct sas_rphy *rphy;
1419         struct sas_port *port;
1420         struct sas_identify identify;
1421         char *ds = NULL;
1422         u8 fw_id;
1423 
1424         if (!phy_info) {
1425                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1426                         "%s: exit at line=%d\n", ioc->name,
1427                          __func__, __LINE__));
1428                 return 1;
1429         }
1430 
1431         fw_id = phy_info->attached.id;
1432 
1433         if (mptsas_get_rphy(phy_info)) {
1434                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1435                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1436                          __func__, fw_id, __LINE__));
1437                 return 2;
1438         }
1439 
1440         port = mptsas_get_port(phy_info);
1441         if (!port) {
1442                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1443                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1444                          __func__, fw_id, __LINE__));
1445                 return 3;
1446         }
1447 
1448         if (phy_info->attached.device_info &
1449             MPI_SAS_DEVICE_INFO_SSP_TARGET)
1450                 ds = "ssp";
1451         if (phy_info->attached.device_info &
1452             MPI_SAS_DEVICE_INFO_STP_TARGET)
1453                 ds = "stp";
1454         if (phy_info->attached.device_info &
1455             MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1456                 ds = "sata";
1457 
1458         printk(MYIOC_s_INFO_FMT "attaching %s device: fw_channel %d, fw_id %d,"
1459             " phy %d, sas_addr 0x%llx\n", ioc->name, ds,
1460             phy_info->attached.channel, phy_info->attached.id,
1461             phy_info->attached.phy_id, (unsigned long long)
1462             phy_info->attached.sas_address);
1463 
1464         mptsas_parse_device_info(&identify, &phy_info->attached);
1465         rphy = sas_end_device_alloc(port);
1466         if (!rphy) {
1467                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1468                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1469                          __func__, fw_id, __LINE__));
1470                 return 5; /* non-fatal: an rphy can be added later */
1471         }
1472 
1473         rphy->identify = identify;
1474         if (sas_rphy_add(rphy)) {
1475                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1476                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1477                          __func__, fw_id, __LINE__));
1478                 sas_rphy_free(rphy);
1479                 return 6;
1480         }
1481         mptsas_set_rphy(ioc, phy_info, rphy);
1482         return 0;
1483 }
1484 
1485 /**
1486  *      mptsas_del_end_device - report a deleted end device to sas transport layer
1487  *      @ioc: Pointer to MPT_ADAPTER structure
1488  *      @phy_info: describes attached device
1489  *
1490  **/
1491 static void
1492 mptsas_del_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1493 {
1494         struct sas_rphy *rphy;
1495         struct sas_port *port;
1496         struct mptsas_portinfo *port_info;
1497         struct mptsas_phyinfo *phy_info_parent;
1498         int i;
1499         char *ds = NULL;
1500         u8 fw_id;
1501         u64 sas_address;
1502 
1503         if (!phy_info)
1504                 return;
1505 
1506         fw_id = phy_info->attached.id;
1507         sas_address = phy_info->attached.sas_address;
1508 
1509         if (!phy_info->port_details) {
1510                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1511                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1512                          __func__, fw_id, __LINE__));
1513                 return;
1514         }
1515         rphy = mptsas_get_rphy(phy_info);
1516         if (!rphy) {
1517                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1518                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1519                          __func__, fw_id, __LINE__));
1520                 return;
1521         }
1522 
1523         if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_INITIATOR
1524                 || phy_info->attached.device_info
1525                         & MPI_SAS_DEVICE_INFO_SMP_INITIATOR
1526                 || phy_info->attached.device_info
1527                         & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1528                 ds = "initiator";
1529         if (phy_info->attached.device_info &
1530             MPI_SAS_DEVICE_INFO_SSP_TARGET)
1531                 ds = "ssp";
1532         if (phy_info->attached.device_info &
1533             MPI_SAS_DEVICE_INFO_STP_TARGET)
1534                 ds = "stp";
1535         if (phy_info->attached.device_info &
1536             MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1537                 ds = "sata";
1538 
1539         dev_printk(KERN_DEBUG, &rphy->dev, MYIOC_s_FMT
1540             "removing %s device: fw_channel %d, fw_id %d, phy %d,"
1541             "sas_addr 0x%llx\n", ioc->name, ds, phy_info->attached.channel,
1542             phy_info->attached.id, phy_info->attached.phy_id,
1543             (unsigned long long) sas_address);
1544 
1545         port = mptsas_get_port(phy_info);
1546         if (!port) {
1547                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1548                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1549                          __func__, fw_id, __LINE__));
1550                 return;
1551         }
1552         port_info = phy_info->portinfo;
1553         phy_info_parent = port_info->phy_info;
1554         for (i = 0; i < port_info->num_phys; i++, phy_info_parent++) {
1555                 if (!phy_info_parent->phy)
1556                         continue;
1557                 if (phy_info_parent->attached.sas_address !=
1558                     sas_address)
1559                         continue;
1560                 dev_printk(KERN_DEBUG, &phy_info_parent->phy->dev,
1561                     MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n",
1562                     ioc->name, phy_info_parent->phy_id,
1563                     phy_info_parent->phy);
1564                 sas_port_delete_phy(port, phy_info_parent->phy);
1565         }
1566 
1567         dev_printk(KERN_DEBUG, &port->dev, MYIOC_s_FMT
1568             "delete port %d, sas_addr (0x%llx)\n", ioc->name,
1569              port->port_identifier, (unsigned long long)sas_address);
1570         sas_port_delete(port);
1571         mptsas_set_port(ioc, phy_info, NULL);
1572         mptsas_port_delete(ioc, phy_info->port_details);
1573 }
1574 
1575 static struct mptsas_phyinfo *
1576 mptsas_refreshing_device_handles(MPT_ADAPTER *ioc,
1577         struct mptsas_devinfo *sas_device)
1578 {
1579         struct mptsas_phyinfo *phy_info;
1580         struct mptsas_portinfo *port_info;
1581         int i;
1582 
1583         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
1584             sas_device->sas_address);
1585         if (!phy_info)
1586                 goto out;
1587         port_info = phy_info->portinfo;
1588         if (!port_info)
1589                 goto out;
1590         mutex_lock(&ioc->sas_topology_mutex);
1591         for (i = 0; i < port_info->num_phys; i++) {
1592                 if (port_info->phy_info[i].attached.sas_address !=
1593                         sas_device->sas_address)
1594                         continue;
1595                 port_info->phy_info[i].attached.channel = sas_device->channel;
1596                 port_info->phy_info[i].attached.id = sas_device->id;
1597                 port_info->phy_info[i].attached.sas_address =
1598                     sas_device->sas_address;
1599                 port_info->phy_info[i].attached.handle = sas_device->handle;
1600                 port_info->phy_info[i].attached.handle_parent =
1601                     sas_device->handle_parent;
1602                 port_info->phy_info[i].attached.handle_enclosure =
1603                     sas_device->handle_enclosure;
1604         }
1605         mutex_unlock(&ioc->sas_topology_mutex);
1606  out:
1607         return phy_info;
1608 }
1609 
1610 /**
1611  * mptsas_firmware_event_work - work thread for processing fw events
1612  * @work: work queue payload containing info describing the event
1613  * Context: user
1614  *
1615  */
1616 static void
1617 mptsas_firmware_event_work(struct work_struct *work)
1618 {
1619         struct fw_event_work *fw_event =
1620                 container_of(work, struct fw_event_work, work.work);
1621         MPT_ADAPTER *ioc = fw_event->ioc;
1622 
1623         /* special rescan topology handling */
1624         if (fw_event->event == -1) {
1625                 if (ioc->in_rescan) {
1626                         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1627                                 "%s: rescan ignored as it is in progress\n",
1628                                 ioc->name, __func__));
1629                         return;
1630                 }
1631                 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: rescan after "
1632                     "reset\n", ioc->name, __func__));
1633                 ioc->in_rescan = 1;
1634                 mptsas_not_responding_devices(ioc);
1635                 mptsas_scan_sas_topology(ioc);
1636                 ioc->in_rescan = 0;
1637                 mptsas_free_fw_event(ioc, fw_event);
1638                 mptsas_fw_event_on(ioc);
1639                 return;
1640         }
1641 
1642         /* events handling turned off during host reset */
1643         if (ioc->fw_events_off) {
1644                 mptsas_free_fw_event(ioc, fw_event);
1645                 return;
1646         }
1647 
1648         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: fw_event=(0x%p), "
1649             "event = (0x%02x)\n", ioc->name, __func__, fw_event,
1650             (fw_event->event & 0xFF)));
1651 
1652         switch (fw_event->event) {
1653         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1654                 mptsas_send_sas_event(fw_event);
1655                 break;
1656         case MPI_EVENT_INTEGRATED_RAID:
1657                 mptsas_send_raid_event(fw_event);
1658                 break;
1659         case MPI_EVENT_IR2:
1660                 mptsas_send_ir2_event(fw_event);
1661                 break;
1662         case MPI_EVENT_PERSISTENT_TABLE_FULL:
1663                 mptbase_sas_persist_operation(ioc,
1664                     MPI_SAS_OP_CLEAR_NOT_PRESENT);
1665                 mptsas_free_fw_event(ioc, fw_event);
1666                 break;
1667         case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
1668                 mptsas_broadcast_primitive_work(fw_event);
1669                 break;
1670         case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
1671                 mptsas_send_expander_event(fw_event);
1672                 break;
1673         case MPI_EVENT_SAS_PHY_LINK_STATUS:
1674                 mptsas_send_link_status_event(fw_event);
1675                 break;
1676         case MPI_EVENT_QUEUE_FULL:
1677                 mptsas_handle_queue_full_event(fw_event);
1678                 break;
1679         }
1680 }
1681 
1682 
1683 
1684 static int
1685 mptsas_slave_configure(struct scsi_device *sdev)
1686 {
1687         struct Scsi_Host        *host = sdev->host;
1688         MPT_SCSI_HOST   *hd = shost_priv(host);
1689         MPT_ADAPTER     *ioc = hd->ioc;
1690         VirtDevice      *vdevice = sdev->hostdata;
1691 
1692         if (vdevice->vtarget->deleted) {
1693                 sdev_printk(KERN_INFO, sdev, "clearing deleted flag\n");
1694                 vdevice->vtarget->deleted = 0;
1695         }
1696 
1697         /*
1698          * RAID volumes placed beyond the last expected port.
1699          * Ignore sending sas mode pages in that case..
1700          */
1701         if (sdev->channel == MPTSAS_RAID_CHANNEL) {
1702                 mptsas_add_device_component_starget_ir(ioc, scsi_target(sdev));
1703                 goto out;
1704         }
1705 
1706         sas_read_port_mode_page(sdev);
1707 
1708         mptsas_add_device_component_starget(ioc, scsi_target(sdev));
1709 
1710  out:
1711         return mptscsih_slave_configure(sdev);
1712 }
1713 
1714 static int
1715 mptsas_target_alloc(struct scsi_target *starget)
1716 {
1717         struct Scsi_Host *host = dev_to_shost(&starget->dev);
1718         MPT_SCSI_HOST           *hd = shost_priv(host);
1719         VirtTarget              *vtarget;
1720         u8                      id, channel;
1721         struct sas_rphy         *rphy;
1722         struct mptsas_portinfo  *p;
1723         int                      i;
1724         MPT_ADAPTER             *ioc = hd->ioc;
1725 
1726         vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
1727         if (!vtarget)
1728                 return -ENOMEM;
1729 
1730         vtarget->starget = starget;
1731         vtarget->ioc_id = ioc->id;
1732         vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
1733         id = starget->id;
1734         channel = 0;
1735 
1736         /*
1737          * RAID volumes placed beyond the last expected port.
1738          */
1739         if (starget->channel == MPTSAS_RAID_CHANNEL) {
1740                 if (!ioc->raid_data.pIocPg2) {
1741                         kfree(vtarget);
1742                         return -ENXIO;
1743                 }
1744                 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
1745                         if (id == ioc->raid_data.pIocPg2->
1746                                         RaidVolume[i].VolumeID) {
1747                                 channel = ioc->raid_data.pIocPg2->
1748                                         RaidVolume[i].VolumeBus;
1749                         }
1750                 }
1751                 vtarget->raidVolume = 1;
1752                 goto out;
1753         }
1754 
1755         rphy = dev_to_rphy(starget->dev.parent);
1756         mutex_lock(&ioc->sas_topology_mutex);
1757         list_for_each_entry(p, &ioc->sas_topology, list) {
1758                 for (i = 0; i < p->num_phys; i++) {
1759                         if (p->phy_info[i].attached.sas_address !=
1760                                         rphy->identify.sas_address)
1761                                 continue;
1762                         id = p->phy_info[i].attached.id;
1763                         channel = p->phy_info[i].attached.channel;
1764                         mptsas_set_starget(&p->phy_info[i], starget);
1765 
1766                         /*
1767                          * Exposing hidden raid components
1768                          */
1769                         if (mptscsih_is_phys_disk(ioc, channel, id)) {
1770                                 id = mptscsih_raid_id_to_num(ioc,
1771                                                 channel, id);
1772                                 vtarget->tflags |=
1773                                     MPT_TARGET_FLAGS_RAID_COMPONENT;
1774                                 p->phy_info[i].attached.phys_disk_num = id;
1775                         }
1776                         mutex_unlock(&ioc->sas_topology_mutex);
1777                         goto out;
1778                 }
1779         }
1780         mutex_unlock(&ioc->sas_topology_mutex);
1781 
1782         kfree(vtarget);
1783         return -ENXIO;
1784 
1785  out:
1786         vtarget->id = id;
1787         vtarget->channel = channel;
1788         starget->hostdata = vtarget;
1789         return 0;
1790 }
1791 
1792 static void
1793 mptsas_target_destroy(struct scsi_target *starget)
1794 {
1795         struct Scsi_Host *host = dev_to_shost(&starget->dev);
1796         MPT_SCSI_HOST           *hd = shost_priv(host);
1797         struct sas_rphy         *rphy;
1798         struct mptsas_portinfo  *p;
1799         int                      i;
1800         MPT_ADAPTER     *ioc = hd->ioc;
1801         VirtTarget      *vtarget;
1802 
1803         if (!starget->hostdata)
1804                 return;
1805 
1806         vtarget = starget->hostdata;
1807 
1808         mptsas_del_device_component_by_os(ioc, starget->channel,
1809             starget->id);
1810 
1811 
1812         if (starget->channel == MPTSAS_RAID_CHANNEL)
1813                 goto out;
1814 
1815         rphy = dev_to_rphy(starget->dev.parent);
1816         list_for_each_entry(p, &ioc->sas_topology, list) {
1817                 for (i = 0; i < p->num_phys; i++) {
1818                         if (p->phy_info[i].attached.sas_address !=
1819                                         rphy->identify.sas_address)
1820                                 continue;
1821 
1822                         starget_printk(KERN_INFO, starget, MYIOC_s_FMT
1823                         "delete device: fw_channel %d, fw_id %d, phy %d, "
1824                         "sas_addr 0x%llx\n", ioc->name,
1825                         p->phy_info[i].attached.channel,
1826                         p->phy_info[i].attached.id,
1827                         p->phy_info[i].attached.phy_id, (unsigned long long)
1828                         p->phy_info[i].attached.sas_address);
1829 
1830                         mptsas_set_starget(&p->phy_info[i], NULL);
1831                 }
1832         }
1833 
1834  out:
1835         vtarget->starget = NULL;
1836         kfree(starget->hostdata);
1837         starget->hostdata = NULL;
1838 }
1839 
1840 
1841 static int
1842 mptsas_slave_alloc(struct scsi_device *sdev)
1843 {
1844         struct Scsi_Host        *host = sdev->host;
1845         MPT_SCSI_HOST           *hd = shost_priv(host);
1846         struct sas_rphy         *rphy;
1847         struct mptsas_portinfo  *p;
1848         VirtDevice              *vdevice;
1849         struct scsi_target      *starget;
1850         int                     i;
1851         MPT_ADAPTER *ioc = hd->ioc;
1852 
1853         vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
1854         if (!vdevice) {
1855                 printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
1856                                 ioc->name, sizeof(VirtDevice));
1857                 return -ENOMEM;
1858         }
1859         starget = scsi_target(sdev);
1860         vdevice->vtarget = starget->hostdata;
1861 
1862         if (sdev->channel == MPTSAS_RAID_CHANNEL)
1863                 goto out;
1864 
1865         rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
1866         mutex_lock(&ioc->sas_topology_mutex);
1867         list_for_each_entry(p, &ioc->sas_topology, list) {
1868                 for (i = 0; i < p->num_phys; i++) {
1869                         if (p->phy_info[i].attached.sas_address !=
1870                                         rphy->identify.sas_address)
1871                                 continue;
1872                         vdevice->lun = sdev->lun;
1873                         /*
1874                          * Exposing hidden raid components
1875                          */
1876                         if (mptscsih_is_phys_disk(ioc,
1877                             p->phy_info[i].attached.channel,
1878                             p->phy_info[i].attached.id))
1879                                 sdev->no_uld_attach = 1;
1880                         mutex_unlock(&ioc->sas_topology_mutex);
1881                         goto out;
1882                 }
1883         }
1884         mutex_unlock(&ioc->sas_topology_mutex);
1885 
1886         kfree(vdevice);
1887         return -ENXIO;
1888 
1889  out:
1890         vdevice->vtarget->num_luns++;
1891         sdev->hostdata = vdevice;
1892         return 0;
1893 }
1894 
1895 static int
1896 mptsas_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt)
1897 {
1898         MPT_SCSI_HOST   *hd;
1899         MPT_ADAPTER     *ioc;
1900         VirtDevice      *vdevice = SCpnt->device->hostdata;
1901 
1902         if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
1903                 SCpnt->result = DID_NO_CONNECT << 16;
1904                 SCpnt->scsi_done(SCpnt);
1905                 return 0;
1906         }
1907 
1908         hd = shost_priv(shost);
1909         ioc = hd->ioc;
1910 
1911         if (ioc->sas_discovery_quiesce_io)
1912                 return SCSI_MLQUEUE_HOST_BUSY;
1913 
1914         if (ioc->debug_level & MPT_DEBUG_SCSI)
1915                 scsi_print_command(SCpnt);
1916 
1917         return mptscsih_qcmd(SCpnt);
1918 }
1919 
1920 /**
1921  *      mptsas_mptsas_eh_timed_out - resets the scsi_cmnd timeout
1922  *              if the device under question is currently in the
1923  *              device removal delay.
1924  *      @sc: scsi command that the midlayer is about to time out
1925  *
1926  **/
1927 static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc)
1928 {
1929         MPT_SCSI_HOST *hd;
1930         MPT_ADAPTER   *ioc;
1931         VirtDevice    *vdevice;
1932         enum blk_eh_timer_return rc = BLK_EH_DONE;
1933 
1934         hd = shost_priv(sc->device->host);
1935         if (hd == NULL) {
1936                 printk(KERN_ERR MYNAM ": %s: Can't locate host! (sc=%p)\n",
1937                     __func__, sc);
1938                 goto done;
1939         }
1940 
1941         ioc = hd->ioc;
1942         if (ioc->bus_type != SAS) {
1943                 printk(KERN_ERR MYNAM ": %s: Wrong bus type (sc=%p)\n",
1944                     __func__, sc);
1945                 goto done;
1946         }
1947 
1948         /* In case if IOC is in reset from internal context.
1949         *  Do not execute EEH for the same IOC. SML should to reset timer.
1950         */
1951         if (ioc->ioc_reset_in_progress) {
1952                 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: ioc is in reset,"
1953                     "SML need to reset the timer (sc=%p)\n",
1954                     ioc->name, __func__, sc));
1955                 rc = BLK_EH_RESET_TIMER;
1956         }
1957         vdevice = sc->device->hostdata;
1958         if (vdevice && vdevice->vtarget && (vdevice->vtarget->inDMD
1959                 || vdevice->vtarget->deleted)) {
1960                 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: target removed "
1961                     "or in device removal delay (sc=%p)\n",
1962                     ioc->name, __func__, sc));
1963                 rc = BLK_EH_RESET_TIMER;
1964                 goto done;
1965         }
1966 
1967 done:
1968         return rc;
1969 }
1970 
1971 
1972 static struct scsi_host_template mptsas_driver_template = {
1973         .module                         = THIS_MODULE,
1974         .proc_name                      = "mptsas",
1975         .show_info                      = mptscsih_show_info,
1976         .name                           = "MPT SAS Host",
1977         .info                           = mptscsih_info,
1978         .queuecommand                   = mptsas_qcmd,
1979         .target_alloc                   = mptsas_target_alloc,
1980         .slave_alloc                    = mptsas_slave_alloc,
1981         .slave_configure                = mptsas_slave_configure,
1982         .target_destroy                 = mptsas_target_destroy,
1983         .slave_destroy                  = mptscsih_slave_destroy,
1984         .change_queue_depth             = mptscsih_change_queue_depth,
1985         .eh_timed_out                   = mptsas_eh_timed_out,
1986         .eh_abort_handler               = mptscsih_abort,
1987         .eh_device_reset_handler        = mptscsih_dev_reset,
1988         .eh_host_reset_handler          = mptscsih_host_reset,
1989         .bios_param                     = mptscsih_bios_param,
1990         .can_queue                      = MPT_SAS_CAN_QUEUE,
1991         .this_id                        = -1,
1992         .sg_tablesize                   = MPT_SCSI_SG_DEPTH,
1993         .max_sectors                    = 8192,
1994         .cmd_per_lun                    = 7,
1995         .shost_attrs                    = mptscsih_host_attrs,
1996         .no_write_same                  = 1,
1997 };
1998 
1999 static int mptsas_get_linkerrors(struct sas_phy *phy)
2000 {
2001         MPT_ADAPTER *ioc = phy_to_ioc(phy);
2002         ConfigExtendedPageHeader_t hdr;
2003         CONFIGPARMS cfg;
2004         SasPhyPage1_t *buffer;
2005         dma_addr_t dma_handle;
2006         int error;
2007 
2008         /* FIXME: only have link errors on local phys */
2009         if (!scsi_is_sas_phy_local(phy))
2010                 return -EINVAL;
2011 
2012         hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
2013         hdr.ExtPageLength = 0;
2014         hdr.PageNumber = 1 /* page number 1*/;
2015         hdr.Reserved1 = 0;
2016         hdr.Reserved2 = 0;
2017         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2018         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2019 
2020         cfg.cfghdr.ehdr = &hdr;
2021         cfg.physAddr = -1;
2022         cfg.pageAddr = phy->identify.phy_identifier;
2023         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2024         cfg.dir = 0;    /* read */
2025         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2026 
2027         error = mpt_config(ioc, &cfg);
2028         if (error)
2029                 return error;
2030         if (!hdr.ExtPageLength)
2031                 return -ENXIO;
2032 
2033         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2034                                       &dma_handle);
2035         if (!buffer)
2036                 return -ENOMEM;
2037 
2038         cfg.physAddr = dma_handle;
2039         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2040 
2041         error = mpt_config(ioc, &cfg);
2042         if (error)
2043                 goto out_free_consistent;
2044 
2045         mptsas_print_phy_pg1(ioc, buffer);
2046 
2047         phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
2048         phy->running_disparity_error_count =
2049                 le32_to_cpu(buffer->RunningDisparityErrorCount);
2050         phy->loss_of_dword_sync_count =
2051                 le32_to_cpu(buffer->LossDwordSynchCount);
2052         phy->phy_reset_problem_count =
2053                 le32_to_cpu(buffer->PhyResetProblemCount);
2054 
2055  out_free_consistent:
2056         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2057                             buffer, dma_handle);
2058         return error;
2059 }
2060 
2061 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2062                 MPT_FRAME_HDR *reply)
2063 {
2064         ioc->sas_mgmt.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2065         if (reply != NULL) {
2066                 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_RF_VALID;
2067                 memcpy(ioc->sas_mgmt.reply, reply,
2068                     min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
2069         }
2070 
2071         if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
2072                 ioc->sas_mgmt.status &= ~MPT_MGMT_STATUS_PENDING;
2073                 complete(&ioc->sas_mgmt.done);
2074                 return 1;
2075         }
2076         return 0;
2077 }
2078 
2079 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
2080 {
2081         MPT_ADAPTER *ioc = phy_to_ioc(phy);
2082         SasIoUnitControlRequest_t *req;
2083         SasIoUnitControlReply_t *reply;
2084         MPT_FRAME_HDR *mf;
2085         MPIHeader_t *hdr;
2086         unsigned long timeleft;
2087         int error = -ERESTARTSYS;
2088 
2089         /* FIXME: fusion doesn't allow non-local phy reset */
2090         if (!scsi_is_sas_phy_local(phy))
2091                 return -EINVAL;
2092 
2093         /* not implemented for expanders */
2094         if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
2095                 return -ENXIO;
2096 
2097         if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
2098                 goto out;
2099 
2100         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2101         if (!mf) {
2102                 error = -ENOMEM;
2103                 goto out_unlock;
2104         }
2105 
2106         hdr = (MPIHeader_t *) mf;
2107         req = (SasIoUnitControlRequest_t *)mf;
2108         memset(req, 0, sizeof(SasIoUnitControlRequest_t));
2109         req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
2110         req->MsgContext = hdr->MsgContext;
2111         req->Operation = hard_reset ?
2112                 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
2113         req->PhyNum = phy->identify.phy_identifier;
2114 
2115         INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2116         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2117 
2118         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
2119                         10 * HZ);
2120         if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2121                 error = -ETIME;
2122                 mpt_free_msg_frame(ioc, mf);
2123                 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2124                         goto out_unlock;
2125                 if (!timeleft)
2126                         mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2127                 goto out_unlock;
2128         }
2129 
2130         /* a reply frame is expected */
2131         if ((ioc->sas_mgmt.status &
2132             MPT_MGMT_STATUS_RF_VALID) == 0) {
2133                 error = -ENXIO;
2134                 goto out_unlock;
2135         }
2136 
2137         /* process the completed Reply Message Frame */
2138         reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
2139         if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
2140                 printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
2141                     ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo);
2142                 error = -ENXIO;
2143                 goto out_unlock;
2144         }
2145 
2146         error = 0;
2147 
2148  out_unlock:
2149         CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2150         mutex_unlock(&ioc->sas_mgmt.mutex);
2151  out:
2152         return error;
2153 }
2154 
2155 static int
2156 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
2157 {
2158         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2159         int i, error;
2160         struct mptsas_portinfo *p;
2161         struct mptsas_enclosure enclosure_info;
2162         u64 enclosure_handle;
2163 
2164         mutex_lock(&ioc->sas_topology_mutex);
2165         list_for_each_entry(p, &ioc->sas_topology, list) {
2166                 for (i = 0; i < p->num_phys; i++) {
2167                         if (p->phy_info[i].attached.sas_address ==
2168                             rphy->identify.sas_address) {
2169                                 enclosure_handle = p->phy_info[i].
2170                                         attached.handle_enclosure;
2171                                 goto found_info;
2172                         }
2173                 }
2174         }
2175         mutex_unlock(&ioc->sas_topology_mutex);
2176         return -ENXIO;
2177 
2178  found_info:
2179         mutex_unlock(&ioc->sas_topology_mutex);
2180         memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
2181         error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
2182                         (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
2183                          MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
2184         if (!error)
2185                 *identifier = enclosure_info.enclosure_logical_id;
2186         return error;
2187 }
2188 
2189 static int
2190 mptsas_get_bay_identifier(struct sas_rphy *rphy)
2191 {
2192         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2193         struct mptsas_portinfo *p;
2194         int i, rc;
2195 
2196         mutex_lock(&ioc->sas_topology_mutex);
2197         list_for_each_entry(p, &ioc->sas_topology, list) {
2198                 for (i = 0; i < p->num_phys; i++) {
2199                         if (p->phy_info[i].attached.sas_address ==
2200                             rphy->identify.sas_address) {
2201                                 rc = p->phy_info[i].attached.slot;
2202                                 goto out;
2203                         }
2204                 }
2205         }
2206         rc = -ENXIO;
2207  out:
2208         mutex_unlock(&ioc->sas_topology_mutex);
2209         return rc;
2210 }
2211 
2212 static void mptsas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
2213                 struct sas_rphy *rphy)
2214 {
2215         MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
2216         MPT_FRAME_HDR *mf;
2217         SmpPassthroughRequest_t *smpreq;
2218         int flagsLength;
2219         unsigned long timeleft;
2220         char *psge;
2221         u64 sas_address = 0;
2222         unsigned int reslen = 0;
2223         int ret = -EINVAL;
2224 
2225         /* do we need to support multiple segments? */
2226         if (job->request_payload.sg_cnt > 1 ||
2227             job->reply_payload.sg_cnt > 1) {
2228                 printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u, rsp %u\n",
2229                     ioc->name, __func__, job->request_payload.payload_len,
2230                     job->reply_payload.payload_len);
2231                 goto out;
2232         }
2233 
2234         ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2235         if (ret)
2236                 goto out;
2237 
2238         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2239         if (!mf) {
2240                 ret = -ENOMEM;
2241                 goto out_unlock;
2242         }
2243 
2244         smpreq = (SmpPassthroughRequest_t *)mf;
2245         memset(smpreq, 0, sizeof(*smpreq));
2246 
2247         smpreq->RequestDataLength =
2248                 cpu_to_le16(job->request_payload.payload_len - 4);
2249         smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2250 
2251         if (rphy)
2252                 sas_address = rphy->identify.sas_address;
2253         else {
2254                 struct mptsas_portinfo *port_info;
2255 
2256                 mutex_lock(&ioc->sas_topology_mutex);
2257                 port_info = ioc->hba_port_info;
2258                 if (port_info && port_info->phy_info)
2259                         sas_address =
2260                                 port_info->phy_info[0].phy->identify.sas_address;
2261                 mutex_unlock(&ioc->sas_topology_mutex);
2262         }
2263 
2264         *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2265 
2266         psge = (char *)
2267                 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2268 
2269         /* request */
2270         flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2271                        MPI_SGE_FLAGS_END_OF_BUFFER |
2272                        MPI_SGE_FLAGS_DIRECTION)
2273                        << MPI_SGE_FLAGS_SHIFT;
2274 
2275         if (!dma_map_sg(&ioc->pcidev->dev, job->request_payload.sg_list,
2276                         1, PCI_DMA_BIDIRECTIONAL))
2277                 goto put_mf;
2278 
2279         flagsLength |= (sg_dma_len(job->request_payload.sg_list) - 4);
2280         ioc->add_sge(psge, flagsLength,
2281                         sg_dma_address(job->request_payload.sg_list));
2282         psge += ioc->SGE_size;
2283 
2284         /* response */
2285         flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2286                 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2287                 MPI_SGE_FLAGS_IOC_TO_HOST |
2288                 MPI_SGE_FLAGS_END_OF_BUFFER;
2289 
2290         flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2291 
2292         if (!dma_map_sg(&ioc->pcidev->dev, job->reply_payload.sg_list,
2293                         1, PCI_DMA_BIDIRECTIONAL))
2294                 goto unmap_out;
2295         flagsLength |= sg_dma_len(job->reply_payload.sg_list) + 4;
2296         ioc->add_sge(psge, flagsLength,
2297                         sg_dma_address(job->reply_payload.sg_list));
2298 
2299         INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2300         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2301 
2302         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2303         if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2304                 ret = -ETIME;
2305                 mpt_free_msg_frame(ioc, mf);
2306                 mf = NULL;
2307                 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2308                         goto unmap_in;
2309                 if (!timeleft)
2310                         mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2311                 goto unmap_in;
2312         }
2313         mf = NULL;
2314 
2315         if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2316                 SmpPassthroughReply_t *smprep;
2317 
2318                 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2319                 memcpy(job->reply, smprep, sizeof(*smprep));
2320                 job->reply_len = sizeof(*smprep);
2321                 reslen = smprep->ResponseDataLength;
2322         } else {
2323                 printk(MYIOC_s_ERR_FMT
2324                     "%s: smp passthru reply failed to be returned\n",
2325                     ioc->name, __func__);
2326                 ret = -ENXIO;
2327         }
2328 
2329 unmap_in:
2330         dma_unmap_sg(&ioc->pcidev->dev, job->reply_payload.sg_list, 1,
2331                         PCI_DMA_BIDIRECTIONAL);
2332 unmap_out:
2333         dma_unmap_sg(&ioc->pcidev->dev, job->request_payload.sg_list, 1,
2334                         PCI_DMA_BIDIRECTIONAL);
2335 put_mf:
2336         if (mf)
2337                 mpt_free_msg_frame(ioc, mf);
2338 out_unlock:
2339         CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2340         mutex_unlock(&ioc->sas_mgmt.mutex);
2341 out:
2342         bsg_job_done(job, ret, reslen);
2343 }
2344 
2345 static struct sas_function_template mptsas_transport_functions = {
2346         .get_linkerrors         = mptsas_get_linkerrors,
2347         .get_enclosure_identifier = mptsas_get_enclosure_identifier,
2348         .get_bay_identifier     = mptsas_get_bay_identifier,
2349         .phy_reset              = mptsas_phy_reset,
2350         .smp_handler            = mptsas_smp_handler,
2351 };
2352 
2353 static struct scsi_transport_template *mptsas_transport_template;
2354 
2355 static int
2356 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
2357 {
2358         ConfigExtendedPageHeader_t hdr;
2359         CONFIGPARMS cfg;
2360         SasIOUnitPage0_t *buffer;
2361         dma_addr_t dma_handle;
2362         int error, i;
2363 
2364         hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
2365         hdr.ExtPageLength = 0;
2366         hdr.PageNumber = 0;
2367         hdr.Reserved1 = 0;
2368         hdr.Reserved2 = 0;
2369         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2370         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2371 
2372         cfg.cfghdr.ehdr = &hdr;
2373         cfg.physAddr = -1;
2374         cfg.pageAddr = 0;
2375         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2376         cfg.dir = 0;    /* read */
2377         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2378 
2379         error = mpt_config(ioc, &cfg);
2380         if (error)
2381                 goto out;
2382         if (!hdr.ExtPageLength) {
2383                 error = -ENXIO;
2384                 goto out;
2385         }
2386 
2387         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2388                                             &dma_handle);
2389         if (!buffer) {
2390                 error = -ENOMEM;
2391                 goto out;
2392         }
2393 
2394         cfg.physAddr = dma_handle;
2395         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2396 
2397         error = mpt_config(ioc, &cfg);
2398         if (error)
2399                 goto out_free_consistent;
2400 
2401         port_info->num_phys = buffer->NumPhys;
2402         port_info->phy_info = kcalloc(port_info->num_phys,
2403                 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2404         if (!port_info->phy_info) {
2405                 error = -ENOMEM;
2406                 goto out_free_consistent;
2407         }
2408 
2409         ioc->nvdata_version_persistent =
2410             le16_to_cpu(buffer->NvdataVersionPersistent);
2411         ioc->nvdata_version_default =
2412             le16_to_cpu(buffer->NvdataVersionDefault);
2413 
2414         for (i = 0; i < port_info->num_phys; i++) {
2415                 mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
2416                 port_info->phy_info[i].phy_id = i;
2417                 port_info->phy_info[i].port_id =
2418                     buffer->PhyData[i].Port;
2419                 port_info->phy_info[i].negotiated_link_rate =
2420                     buffer->PhyData[i].NegotiatedLinkRate;
2421                 port_info->phy_info[i].portinfo = port_info;
2422                 port_info->phy_info[i].handle =
2423                     le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
2424         }
2425 
2426  out_free_consistent:
2427         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2428                             buffer, dma_handle);
2429  out:
2430         return error;
2431 }
2432 
2433 static int
2434 mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
2435 {
2436         ConfigExtendedPageHeader_t hdr;
2437         CONFIGPARMS cfg;
2438         SasIOUnitPage1_t *buffer;
2439         dma_addr_t dma_handle;
2440         int error;
2441         u8 device_missing_delay;
2442 
2443         memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
2444         memset(&cfg, 0, sizeof(CONFIGPARMS));
2445 
2446         cfg.cfghdr.ehdr = &hdr;
2447         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2448         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2449         cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2450         cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2451         cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
2452         cfg.cfghdr.ehdr->PageNumber = 1;
2453 
2454         error = mpt_config(ioc, &cfg);
2455         if (error)
2456                 goto out;
2457         if (!hdr.ExtPageLength) {
2458                 error = -ENXIO;
2459                 goto out;
2460         }
2461 
2462         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2463                                             &dma_handle);
2464         if (!buffer) {
2465                 error = -ENOMEM;
2466                 goto out;
2467         }
2468 
2469         cfg.physAddr = dma_handle;
2470         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2471 
2472         error = mpt_config(ioc, &cfg);
2473         if (error)
2474                 goto out_free_consistent;
2475 
2476         ioc->io_missing_delay  =
2477             le16_to_cpu(buffer->IODeviceMissingDelay);
2478         device_missing_delay = buffer->ReportDeviceMissingDelay;
2479         ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
2480             (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
2481             device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
2482 
2483  out_free_consistent:
2484         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2485                             buffer, dma_handle);
2486  out:
2487         return error;
2488 }
2489 
2490 static int
2491 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2492                 u32 form, u32 form_specific)
2493 {
2494         ConfigExtendedPageHeader_t hdr;
2495         CONFIGPARMS cfg;
2496         SasPhyPage0_t *buffer;
2497         dma_addr_t dma_handle;
2498         int error;
2499 
2500         hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
2501         hdr.ExtPageLength = 0;
2502         hdr.PageNumber = 0;
2503         hdr.Reserved1 = 0;
2504         hdr.Reserved2 = 0;
2505         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2506         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2507 
2508         cfg.cfghdr.ehdr = &hdr;
2509         cfg.dir = 0;    /* read */
2510         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2511 
2512         /* Get Phy Pg 0 for each Phy. */
2513         cfg.physAddr = -1;
2514         cfg.pageAddr = form + form_specific;
2515         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2516 
2517         error = mpt_config(ioc, &cfg);
2518         if (error)
2519                 goto out;
2520 
2521         if (!hdr.ExtPageLength) {
2522                 error = -ENXIO;
2523                 goto out;
2524         }
2525 
2526         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2527                                       &dma_handle);
2528         if (!buffer) {
2529                 error = -ENOMEM;
2530                 goto out;
2531         }
2532 
2533         cfg.physAddr = dma_handle;
2534         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2535 
2536         error = mpt_config(ioc, &cfg);
2537         if (error)
2538                 goto out_free_consistent;
2539 
2540         mptsas_print_phy_pg0(ioc, buffer);
2541 
2542         phy_info->hw_link_rate = buffer->HwLinkRate;
2543         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2544         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2545         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2546 
2547  out_free_consistent:
2548         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2549                             buffer, dma_handle);
2550  out:
2551         return error;
2552 }
2553 
2554 static int
2555 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
2556                 u32 form, u32 form_specific)
2557 {
2558         ConfigExtendedPageHeader_t hdr;
2559         CONFIGPARMS cfg;
2560         SasDevicePage0_t *buffer;
2561         dma_addr_t dma_handle;
2562         __le64 sas_address;
2563         int error=0;
2564 
2565         hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
2566         hdr.ExtPageLength = 0;
2567         hdr.PageNumber = 0;
2568         hdr.Reserved1 = 0;
2569         hdr.Reserved2 = 0;
2570         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2571         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
2572 
2573         cfg.cfghdr.ehdr = &hdr;
2574         cfg.pageAddr = form + form_specific;
2575         cfg.physAddr = -1;
2576         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2577         cfg.dir = 0;    /* read */
2578         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2579 
2580         memset(device_info, 0, sizeof(struct mptsas_devinfo));
2581         error = mpt_config(ioc, &cfg);
2582         if (error)
2583                 goto out;
2584         if (!hdr.ExtPageLength) {
2585                 error = -ENXIO;
2586                 goto out;
2587         }
2588 
2589         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2590                                       &dma_handle);
2591         if (!buffer) {
2592                 error = -ENOMEM;
2593                 goto out;
2594         }
2595 
2596         cfg.physAddr = dma_handle;
2597         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2598 
2599         error = mpt_config(ioc, &cfg);
2600 
2601         if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2602                 error = -ENODEV;
2603                 goto out_free_consistent;
2604         }
2605 
2606         if (error)
2607                 goto out_free_consistent;
2608 
2609         mptsas_print_device_pg0(ioc, buffer);
2610 
2611         memset(device_info, 0, sizeof(struct mptsas_devinfo));
2612         device_info->handle = le16_to_cpu(buffer->DevHandle);
2613         device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
2614         device_info->handle_enclosure =
2615             le16_to_cpu(buffer->EnclosureHandle);
2616         device_info->slot = le16_to_cpu(buffer->Slot);
2617         device_info->phy_id = buffer->PhyNum;
2618         device_info->port_id = buffer->PhysicalPort;
2619         device_info->id = buffer->TargetID;
2620         device_info->phys_disk_num = ~0;
2621         device_info->channel = buffer->Bus;
2622         memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2623         device_info->sas_address = le64_to_cpu(sas_address);
2624         device_info->device_info =
2625             le32_to_cpu(buffer->DeviceInfo);
2626         device_info->flags = le16_to_cpu(buffer->Flags);
2627 
2628  out_free_consistent:
2629         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2630                             buffer, dma_handle);
2631  out:
2632         return error;
2633 }
2634 
2635 static int
2636 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
2637                 u32 form, u32 form_specific)
2638 {
2639         ConfigExtendedPageHeader_t hdr;
2640         CONFIGPARMS cfg;
2641         SasExpanderPage0_t *buffer;
2642         dma_addr_t dma_handle;
2643         int i, error;
2644         __le64 sas_address;
2645 
2646         memset(port_info, 0, sizeof(struct mptsas_portinfo));
2647         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
2648         hdr.ExtPageLength = 0;
2649         hdr.PageNumber = 0;
2650         hdr.Reserved1 = 0;
2651         hdr.Reserved2 = 0;
2652         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2653         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2654 
2655         cfg.cfghdr.ehdr = &hdr;
2656         cfg.physAddr = -1;
2657         cfg.pageAddr = form + form_specific;
2658         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2659         cfg.dir = 0;    /* read */
2660         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2661 
2662         memset(port_info, 0, sizeof(struct mptsas_portinfo));
2663         error = mpt_config(ioc, &cfg);
2664         if (error)
2665                 goto out;
2666 
2667         if (!hdr.ExtPageLength) {
2668                 error = -ENXIO;
2669                 goto out;
2670         }
2671 
2672         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2673                                       &dma_handle);
2674         if (!buffer) {
2675                 error = -ENOMEM;
2676                 goto out;
2677         }
2678 
2679         cfg.physAddr = dma_handle;
2680         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2681 
2682         error = mpt_config(ioc, &cfg);
2683         if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2684                 error = -ENODEV;
2685                 goto out_free_consistent;
2686         }
2687 
2688         if (error)
2689                 goto out_free_consistent;
2690 
2691         /* save config data */
2692         port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1;
2693         port_info->phy_info = kcalloc(port_info->num_phys,
2694                 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2695         if (!port_info->phy_info) {
2696                 error = -ENOMEM;
2697                 goto out_free_consistent;
2698         }
2699 
2700         memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2701         for (i = 0; i < port_info->num_phys; i++) {
2702                 port_info->phy_info[i].portinfo = port_info;
2703                 port_info->phy_info[i].handle =
2704                     le16_to_cpu(buffer->DevHandle);
2705                 port_info->phy_info[i].identify.sas_address =
2706                     le64_to_cpu(sas_address);
2707                 port_info->phy_info[i].identify.handle_parent =
2708                     le16_to_cpu(buffer->ParentDevHandle);
2709         }
2710 
2711  out_free_consistent:
2712         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2713                             buffer, dma_handle);
2714  out:
2715         return error;
2716 }
2717 
2718 static int
2719 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2720                 u32 form, u32 form_specific)
2721 {
2722         ConfigExtendedPageHeader_t hdr;
2723         CONFIGPARMS cfg;
2724         SasExpanderPage1_t *buffer;
2725         dma_addr_t dma_handle;
2726         int error=0;
2727 
2728         hdr.PageVersion = MPI_SASEXPANDER1_PAGEVERSION;
2729         hdr.ExtPageLength = 0;
2730         hdr.PageNumber = 1;
2731         hdr.Reserved1 = 0;
2732         hdr.Reserved2 = 0;
2733         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2734         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2735 
2736         cfg.cfghdr.ehdr = &hdr;
2737         cfg.physAddr = -1;
2738         cfg.pageAddr = form + form_specific;
2739         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2740         cfg.dir = 0;    /* read */
2741         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2742 
2743         error = mpt_config(ioc, &cfg);
2744         if (error)
2745                 goto out;
2746 
2747         if (!hdr.ExtPageLength) {
2748                 error = -ENXIO;
2749                 goto out;
2750         }
2751 
2752         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2753                                       &dma_handle);
2754         if (!buffer) {
2755                 error = -ENOMEM;
2756                 goto out;
2757         }
2758 
2759         cfg.physAddr = dma_handle;
2760         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2761 
2762         error = mpt_config(ioc, &cfg);
2763 
2764         if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2765                 error = -ENODEV;
2766                 goto out_free_consistent;
2767         }
2768 
2769         if (error)
2770                 goto out_free_consistent;
2771 
2772 
2773         mptsas_print_expander_pg1(ioc, buffer);
2774 
2775         /* save config data */
2776         phy_info->phy_id = buffer->PhyIdentifier;
2777         phy_info->port_id = buffer->PhysicalPort;
2778         phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
2779         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2780         phy_info->hw_link_rate = buffer->HwLinkRate;
2781         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2782         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2783 
2784  out_free_consistent:
2785         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2786                             buffer, dma_handle);
2787  out:
2788         return error;
2789 }
2790 
2791 struct rep_manu_request{
2792         u8 smp_frame_type;
2793         u8 function;
2794         u8 reserved;
2795         u8 request_length;
2796 };
2797 
2798 struct rep_manu_reply{
2799         u8 smp_frame_type; /* 0x41 */
2800         u8 function; /* 0x01 */
2801         u8 function_result;
2802         u8 response_length;
2803         u16 expander_change_count;
2804         u8 reserved0[2];
2805         u8 sas_format:1;
2806         u8 reserved1:7;
2807         u8 reserved2[3];
2808         u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
2809         u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
2810         u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
2811         u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
2812         u16 component_id;
2813         u8 component_revision_id;
2814         u8 reserved3;
2815         u8 vendor_specific[8];
2816 };
2817 
2818 /**
2819   * mptsas_exp_repmanufacture_info -
2820   * @ioc: per adapter object
2821   * @sas_address: expander sas address
2822   * @edev: the sas_expander_device object
2823   *
2824   * Fills in the sas_expander_device object when SMP port is created.
2825   *
2826   * Returns 0 for success, non-zero for failure.
2827   */
2828 static int
2829 mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
2830         u64 sas_address, struct sas_expander_device *edev)
2831 {
2832         MPT_FRAME_HDR *mf;
2833         SmpPassthroughRequest_t *smpreq;
2834         SmpPassthroughReply_t *smprep;
2835         struct rep_manu_reply *manufacture_reply;
2836         struct rep_manu_request *manufacture_request;
2837         int ret;
2838         int flagsLength;
2839         unsigned long timeleft;
2840         char *psge;
2841         unsigned long flags;
2842         void *data_out = NULL;
2843         dma_addr_t data_out_dma = 0;
2844         u32 sz;
2845 
2846         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2847         if (ioc->ioc_reset_in_progress) {
2848                 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2849                 printk(MYIOC_s_INFO_FMT "%s: host reset in progress!\n",
2850                         __func__, ioc->name);
2851                 return -EFAULT;
2852         }
2853         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2854 
2855         ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2856         if (ret)
2857                 goto out;
2858 
2859         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2860         if (!mf) {
2861                 ret = -ENOMEM;
2862                 goto out_unlock;
2863         }
2864 
2865         smpreq = (SmpPassthroughRequest_t *)mf;
2866         memset(smpreq, 0, sizeof(*smpreq));
2867 
2868         sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
2869 
2870         data_out = pci_alloc_consistent(ioc->pcidev, sz, &data_out_dma);
2871         if (!data_out) {
2872                 printk(KERN_ERR "Memory allocation failure at %s:%d/%s()!\n",
2873                         __FILE__, __LINE__, __func__);
2874                 ret = -ENOMEM;
2875                 goto put_mf;
2876         }
2877 
2878         manufacture_request = data_out;
2879         manufacture_request->smp_frame_type = 0x40;
2880         manufacture_request->function = 1;
2881         manufacture_request->reserved = 0;
2882         manufacture_request->request_length = 0;
2883 
2884         smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2885         smpreq->PhysicalPort = 0xFF;
2886         *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2887         smpreq->RequestDataLength = sizeof(struct rep_manu_request);
2888 
2889         psge = (char *)
2890                 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2891 
2892         flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2893                 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2894                 MPI_SGE_FLAGS_HOST_TO_IOC |
2895                 MPI_SGE_FLAGS_END_OF_BUFFER;
2896         flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2897         flagsLength |= sizeof(struct rep_manu_request);
2898 
2899         ioc->add_sge(psge, flagsLength, data_out_dma);
2900         psge += ioc->SGE_size;
2901 
2902         flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2903                 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2904                 MPI_SGE_FLAGS_IOC_TO_HOST |
2905                 MPI_SGE_FLAGS_END_OF_BUFFER;
2906         flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2907         flagsLength |= sizeof(struct rep_manu_reply);
2908         ioc->add_sge(psge, flagsLength, data_out_dma +
2909         sizeof(struct rep_manu_request));
2910 
2911         INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2912         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2913 
2914         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2915         if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2916                 ret = -ETIME;
2917                 mpt_free_msg_frame(ioc, mf);
2918                 mf = NULL;
2919                 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2920                         goto out_free;
2921                 if (!timeleft)
2922                         mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2923                 goto out_free;
2924         }
2925 
2926         mf = NULL;
2927 
2928         if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2929                 u8 *tmp;
2930 
2931                 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2932                 if (le16_to_cpu(smprep->ResponseDataLength) !=
2933                     sizeof(struct rep_manu_reply))
2934                         goto out_free;
2935 
2936                 manufacture_reply = data_out + sizeof(struct rep_manu_request);
2937                 strncpy(edev->vendor_id, manufacture_reply->vendor_id,
2938                         SAS_EXPANDER_VENDOR_ID_LEN);
2939                 strncpy(edev->product_id, manufacture_reply->product_id,
2940                         SAS_EXPANDER_PRODUCT_ID_LEN);
2941                 strncpy(edev->product_rev, manufacture_reply->product_rev,
2942                         SAS_EXPANDER_PRODUCT_REV_LEN);
2943                 edev->level = manufacture_reply->sas_format;
2944                 if (manufacture_reply->sas_format) {
2945                         strncpy(edev->component_vendor_id,
2946                                 manufacture_reply->component_vendor_id,
2947                                 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
2948                         tmp = (u8 *)&manufacture_reply->component_id;
2949                         edev->component_id = tmp[0] << 8 | tmp[1];
2950                         edev->component_revision_id =
2951                                 manufacture_reply->component_revision_id;
2952                 }
2953         } else {
2954                 printk(MYIOC_s_ERR_FMT
2955                         "%s: smp passthru reply failed to be returned\n",
2956                         ioc->name, __func__);
2957                 ret = -ENXIO;
2958         }
2959 out_free:
2960         if (data_out_dma)
2961                 pci_free_consistent(ioc->pcidev, sz, data_out, data_out_dma);
2962 put_mf:
2963         if (mf)
2964                 mpt_free_msg_frame(ioc, mf);
2965 out_unlock:
2966         CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2967         mutex_unlock(&ioc->sas_mgmt.mutex);
2968 out:
2969         return ret;
2970 }
2971 
2972 static void
2973 mptsas_parse_device_info(struct sas_identify *identify,
2974                 struct mptsas_devinfo *device_info)
2975 {
2976         u16 protocols;
2977 
2978         identify->sas_address = device_info->sas_address;
2979         identify->phy_identifier = device_info->phy_id;
2980 
2981         /*
2982          * Fill in Phy Initiator Port Protocol.
2983          * Bits 6:3, more than one bit can be set, fall through cases.
2984          */
2985         protocols = device_info->device_info & 0x78;
2986         identify->initiator_port_protocols = 0;
2987         if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
2988                 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
2989         if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
2990                 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
2991         if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
2992                 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
2993         if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
2994                 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
2995 
2996         /*
2997          * Fill in Phy Target Port Protocol.
2998          * Bits 10:7, more than one bit can be set, fall through cases.
2999          */
3000         protocols = device_info->device_info & 0x780;
3001         identify->target_port_protocols = 0;
3002         if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
3003                 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
3004         if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
3005                 identify->target_port_protocols |= SAS_PROTOCOL_STP;
3006         if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
3007                 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
3008         if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
3009                 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
3010 
3011         /*
3012          * Fill in Attached device type.
3013          */
3014         switch (device_info->device_info &
3015                         MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
3016         case MPI_SAS_DEVICE_INFO_NO_DEVICE:
3017                 identify->device_type = SAS_PHY_UNUSED;
3018                 break;
3019         case MPI_SAS_DEVICE_INFO_END_DEVICE:
3020                 identify->device_type = SAS_END_DEVICE;
3021                 break;
3022         case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
3023                 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
3024                 break;
3025         case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
3026                 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
3027                 break;
3028         }
3029 }
3030 
3031 static int mptsas_probe_one_phy(struct device *dev,
3032                 struct mptsas_phyinfo *phy_info, int index, int local)
3033 {
3034         MPT_ADAPTER *ioc;
3035         struct sas_phy *phy;
3036         struct sas_port *port;
3037         int error = 0;
3038         VirtTarget *vtarget;
3039 
3040         if (!dev) {
3041                 error = -ENODEV;
3042                 goto out;
3043         }
3044 
3045         if (!phy_info->phy) {
3046                 phy = sas_phy_alloc(dev, index);
3047                 if (!phy) {
3048                         error = -ENOMEM;
3049                         goto out;
3050                 }
3051         } else
3052                 phy = phy_info->phy;
3053 
3054         mptsas_parse_device_info(&phy->identify, &phy_info->identify);
3055 
3056         /*
3057          * Set Negotiated link rate.
3058          */
3059         switch (phy_info->negotiated_link_rate) {
3060         case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
3061                 phy->negotiated_linkrate = SAS_PHY_DISABLED;
3062                 break;
3063         case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
3064                 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
3065                 break;
3066         case MPI_SAS_IOUNIT0_RATE_1_5:
3067                 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
3068                 break;
3069         case MPI_SAS_IOUNIT0_RATE_3_0:
3070                 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
3071                 break;
3072         case MPI_SAS_IOUNIT0_RATE_6_0:
3073                 phy->negotiated_linkrate = SAS_LINK_RATE_6_0_GBPS;
3074                 break;
3075         case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
3076         case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
3077         default:
3078                 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
3079                 break;
3080         }
3081 
3082         /*
3083          * Set Max hardware link rate.
3084          */
3085         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
3086         case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
3087                 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
3088                 break;
3089         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
3090                 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
3091                 break;
3092         default:
3093                 break;
3094         }
3095 
3096         /*
3097          * Set Max programmed link rate.
3098          */
3099         switch (phy_info->programmed_link_rate &
3100                         MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
3101         case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
3102                 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
3103                 break;
3104         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
3105                 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
3106                 break;
3107         default:
3108                 break;
3109         }
3110 
3111         /*
3112          * Set Min hardware link rate.
3113          */
3114         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
3115         case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
3116                 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
3117                 break;
3118         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
3119                 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
3120                 break;
3121         default:
3122                 break;
3123         }
3124 
3125         /*
3126          * Set Min programmed link rate.
3127          */
3128         switch (phy_info->programmed_link_rate &
3129                         MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
3130         case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
3131                 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
3132                 break;
3133         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
3134                 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
3135                 break;
3136         default:
3137                 break;
3138         }
3139 
3140         if (!phy_info->phy) {
3141 
3142                 error = sas_phy_add(phy);
3143                 if (error) {
3144                         sas_phy_free(phy);
3145                         goto out;
3146                 }
3147                 phy_info->phy = phy;
3148         }
3149 
3150         if (!phy_info->attached.handle ||
3151                         !phy_info->port_details)
3152                 goto out;
3153 
3154         port = mptsas_get_port(phy_info);
3155         ioc = phy_to_ioc(phy_info->phy);
3156 
3157         if (phy_info->sas_port_add_phy) {
3158 
3159                 if (!port) {
3160                         port = sas_port_alloc_num(dev);
3161                         if (!port) {
3162                                 error = -ENOMEM;
3163                                 goto out;
3164                         }
3165                         error = sas_port_add(port);
3166                         if (error) {
3167                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3168                                         "%s: exit at line=%d\n", ioc->name,
3169                                         __func__, __LINE__));
3170                                 goto out;
3171                         }
3172                         mptsas_set_port(ioc, phy_info, port);
3173                         devtprintk(ioc, dev_printk(KERN_DEBUG, &port->dev,
3174                             MYIOC_s_FMT "add port %d, sas_addr (0x%llx)\n",
3175                             ioc->name, port->port_identifier,
3176                             (unsigned long long)phy_info->
3177                             attached.sas_address));
3178                 }
3179                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3180                         "sas_port_add_phy: phy_id=%d\n",
3181                         ioc->name, phy_info->phy_id));
3182                 sas_port_add_phy(port, phy_info->phy);
3183                 phy_info->sas_port_add_phy = 0;
3184                 devtprintk(ioc, dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3185                     MYIOC_s_FMT "add phy %d, phy-obj (0x%p)\n", ioc->name,
3186                      phy_info->phy_id, phy_info->phy));
3187         }
3188         if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
3189 
3190                 struct sas_rphy *rphy;
3191                 struct device *parent;
3192                 struct sas_identify identify;
3193 
3194                 parent = dev->parent->parent;
3195                 /*
3196                  * Let the hotplug_work thread handle processing
3197                  * the adding/removing of devices that occur
3198                  * after start of day.
3199                  */
3200                 if (mptsas_is_end_device(&phy_info->attached) &&
3201                     phy_info->attached.handle_parent) {
3202                         goto out;
3203                 }
3204 
3205                 mptsas_parse_device_info(&identify, &phy_info->attached);
3206                 if (scsi_is_host_device(parent)) {
3207                         struct mptsas_portinfo *port_info;
3208                         int i;
3209 
3210                         port_info = ioc->hba_port_info;
3211 
3212                         for (i = 0; i < port_info->num_phys; i++)
3213                                 if (port_info->phy_info[i].identify.sas_address ==
3214                                     identify.sas_address) {
3215                                         sas_port_mark_backlink(port);
3216                                         goto out;
3217                                 }
3218 
3219                 } else if (scsi_is_sas_rphy(parent)) {
3220                         struct sas_rphy *parent_rphy = dev_to_rphy(parent);
3221                         if (identify.sas_address ==
3222                             parent_rphy->identify.sas_address) {
3223                                 sas_port_mark_backlink(port);
3224                                 goto out;
3225                         }
3226                 }
3227 
3228                 switch (identify.device_type) {
3229                 case SAS_END_DEVICE:
3230                         rphy = sas_end_device_alloc(port);
3231                         break;
3232                 case SAS_EDGE_EXPANDER_DEVICE:
3233                 case SAS_FANOUT_EXPANDER_DEVICE:
3234                         rphy = sas_expander_alloc(port, identify.device_type);
3235                         break;
3236                 default:
3237                         rphy = NULL;
3238                         break;
3239                 }
3240                 if (!rphy) {
3241                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3242                                 "%s: exit at line=%d\n", ioc->name,
3243                                 __func__, __LINE__));
3244                         goto out;
3245                 }
3246 
3247                 rphy->identify = identify;
3248                 error = sas_rphy_add(rphy);
3249                 if (error) {
3250                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3251                                 "%s: exit at line=%d\n", ioc->name,
3252                                 __func__, __LINE__));
3253                         sas_rphy_free(rphy);
3254                         goto out;
3255                 }
3256                 mptsas_set_rphy(ioc, phy_info, rphy);
3257                 if (identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
3258                         identify.device_type == SAS_FANOUT_EXPANDER_DEVICE)
3259                                 mptsas_exp_repmanufacture_info(ioc,
3260                                         identify.sas_address,
3261                                         rphy_to_expander_device(rphy));
3262         }
3263 
3264         /* If the device exists,verify it wasn't previously flagged
3265         as a missing device.  If so, clear it */
3266         vtarget = mptsas_find_vtarget(ioc,
3267             phy_info->attached.channel,
3268             phy_info->attached.id);
3269         if (vtarget && vtarget->inDMD) {
3270                 printk(KERN_INFO "Device returned, unsetting inDMD\n");
3271                 vtarget->inDMD = 0;
3272         }
3273 
3274  out:
3275         return error;
3276 }
3277 
3278 static int
3279 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
3280 {
3281         struct mptsas_portinfo *port_info, *hba;
3282         int error = -ENOMEM, i;
3283 
3284         hba = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3285         if (! hba)
3286                 goto out;
3287 
3288         error = mptsas_sas_io_unit_pg0(ioc, hba);
3289         if (error)
3290                 goto out_free_port_info;
3291 
3292         mptsas_sas_io_unit_pg1(ioc);
3293         mutex_lock(&ioc->sas_topology_mutex);
3294         port_info = ioc->hba_port_info;
3295         if (!port_info) {
3296                 ioc->hba_port_info = port_info = hba;
3297                 ioc->hba_port_num_phy = port_info->num_phys;
3298                 list_add_tail(&port_info->list, &ioc->sas_topology);
3299         } else {
3300                 for (i = 0; i < hba->num_phys; i++) {
3301                         port_info->phy_info[i].negotiated_link_rate =
3302                                 hba->phy_info[i].negotiated_link_rate;
3303                         port_info->phy_info[i].handle =
3304                                 hba->phy_info[i].handle;
3305                         port_info->phy_info[i].port_id =
3306                                 hba->phy_info[i].port_id;
3307                 }
3308                 kfree(hba->phy_info);
3309                 kfree(hba);
3310                 hba = NULL;
3311         }
3312         mutex_unlock(&ioc->sas_topology_mutex);
3313 #if defined(CPQ_CIM)
3314         ioc->num_ports = port_info->num_phys;
3315 #endif
3316         for (i = 0; i < port_info->num_phys; i++) {
3317                 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
3318                         (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
3319                          MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
3320                 port_info->phy_info[i].identify.handle =
3321                     port_info->phy_info[i].handle;
3322                 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
3323                         (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3324                          MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3325                          port_info->phy_info[i].identify.handle);
3326                 if (!ioc->hba_port_sas_addr)
3327                         ioc->hba_port_sas_addr =
3328                             port_info->phy_info[i].identify.sas_address;
3329                 port_info->phy_info[i].identify.phy_id =
3330                     port_info->phy_info[i].phy_id = i;
3331                 if (port_info->phy_info[i].attached.handle)
3332                         mptsas_sas_device_pg0(ioc,
3333                                 &port_info->phy_info[i].attached,
3334                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3335                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3336                                 port_info->phy_info[i].attached.handle);
3337         }
3338 
3339         mptsas_setup_wide_ports(ioc, port_info);
3340 
3341         for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3342                 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
3343                     &port_info->phy_info[i], ioc->sas_index, 1);
3344 
3345         return 0;
3346 
3347  out_free_port_info:
3348         kfree(hba);
3349  out:
3350         return error;
3351 }
3352 
3353 static void
3354 mptsas_expander_refresh(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
3355 {
3356         struct mptsas_portinfo *parent;
3357         struct device *parent_dev;
3358         struct sas_rphy *rphy;
3359         int             i;
3360         u64             sas_address; /* expander sas address */
3361         u32             handle;
3362 
3363         handle = port_info->phy_info[0].handle;
3364         sas_address = port_info->phy_info[0].identify.sas_address;
3365         for (i = 0; i < port_info->num_phys; i++) {
3366                 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
3367                     (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
3368                     MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + handle);
3369 
3370                 mptsas_sas_device_pg0(ioc,
3371                     &port_info->phy_info[i].identify,
3372                     (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3373                     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3374                     port_info->phy_info[i].identify.handle);
3375                 port_info->phy_info[i].identify.phy_id =
3376                     port_info->phy_info[i].phy_id;
3377 
3378                 if (port_info->phy_info[i].attached.handle) {
3379                         mptsas_sas_device_pg0(ioc,
3380                             &port_info->phy_info[i].attached,
3381                             (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3382                              MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3383                             port_info->phy_info[i].attached.handle);
3384                         port_info->phy_info[i].attached.phy_id =
3385                             port_info->phy_info[i].phy_id;
3386                 }
3387         }
3388 
3389         mutex_lock(&ioc->sas_topology_mutex);
3390         parent = mptsas_find_portinfo_by_handle(ioc,
3391             port_info->phy_info[0].identify.handle_parent);
3392         if (!parent) {
3393                 mutex_unlock(&ioc->sas_topology_mutex);
3394                 return;
3395         }
3396         for (i = 0, parent_dev = NULL; i < parent->num_phys && !parent_dev;
3397             i++) {
3398                 if (parent->phy_info[i].attached.sas_address == sas_address) {
3399                         rphy = mptsas_get_rphy(&parent->phy_info[i]);
3400                         parent_dev = &rphy->dev;
3401                 }
3402         }
3403         mutex_unlock(&ioc->sas_topology_mutex);
3404 
3405         mptsas_setup_wide_ports(ioc, port_info);
3406         for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3407                 mptsas_probe_one_phy(parent_dev, &port_info->phy_info[i],
3408                     ioc->sas_index, 0);
3409 }
3410 
3411 static void
3412 mptsas_expander_event_add(MPT_ADAPTER *ioc,
3413     MpiEventDataSasExpanderStatusChange_t *expander_data)
3414 {
3415         struct mptsas_portinfo *port_info;
3416         int i;
3417         __le64 sas_address;
3418 
3419         port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3420         if (!port_info)
3421                 BUG();
3422         port_info->num_phys = (expander_data->NumPhys) ?
3423             expander_data->NumPhys : 1;
3424         port_info->phy_info = kcalloc(port_info->num_phys,
3425             sizeof(struct mptsas_phyinfo), GFP_KERNEL);
3426         if (!port_info->phy_info)
3427                 BUG();
3428         memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3429         for (i = 0; i < port_info->num_phys; i++) {
3430                 port_info->phy_info[i].portinfo = port_info;
3431                 port_info->phy_info[i].handle =
3432                     le16_to_cpu(expander_data->DevHandle);
3433                 port_info->phy_info[i].identify.sas_address =
3434                     le64_to_cpu(sas_address);
3435                 port_info->phy_info[i].identify.handle_parent =
3436                     le16_to_cpu(expander_data->ParentDevHandle);
3437         }
3438 
3439         mutex_lock(&ioc->sas_topology_mutex);
3440         list_add_tail(&port_info->list, &ioc->sas_topology);
3441         mutex_unlock(&ioc->sas_topology_mutex);
3442 
3443         printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3444             "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3445             (unsigned long long)sas_address);
3446 
3447         mptsas_expander_refresh(ioc, port_info);
3448 }
3449 
3450 /**
3451  * mptsas_delete_expander_siblings - remove siblings attached to expander
3452  * @ioc: Pointer to MPT_ADAPTER structure
3453  * @parent: the parent port_info object
3454  * @expander: the expander port_info object
3455  **/
3456 static void
3457 mptsas_delete_expander_siblings(MPT_ADAPTER *ioc, struct mptsas_portinfo
3458     *parent, struct mptsas_portinfo *expander)
3459 {
3460         struct mptsas_phyinfo *phy_info;
3461         struct mptsas_portinfo *port_info;
3462         struct sas_rphy *rphy;
3463         int i;
3464 
3465         phy_info = expander->phy_info;
3466         for (i = 0; i < expander->num_phys; i++, phy_info++) {
3467                 rphy = mptsas_get_rphy(phy_info);
3468                 if (!rphy)
3469                         continue;
3470                 if (rphy->identify.device_type == SAS_END_DEVICE)
3471                         mptsas_del_end_device(ioc, phy_info);
3472         }
3473 
3474         phy_info = expander->phy_info;
3475         for (i = 0; i < expander->num_phys; i++, phy_info++) {
3476                 rphy = mptsas_get_rphy(phy_info);
3477                 if (!rphy)
3478                         continue;
3479                 if (rphy->identify.device_type ==
3480                     MPI_SAS_DEVICE_INFO_EDGE_EXPANDER ||
3481                     rphy->identify.device_type ==
3482                     MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
3483                         port_info = mptsas_find_portinfo_by_sas_address(ioc,
3484                             rphy->identify.sas_address);
3485                         if (!port_info)
3486                                 continue;
3487                         if (port_info == parent) /* backlink rphy */
3488                                 continue;
3489                         /*
3490                         Delete this expander even if the expdevpage is exists
3491                         because the parent expander is already deleted
3492                         */
3493                         mptsas_expander_delete(ioc, port_info, 1);
3494                 }
3495         }
3496 }
3497 
3498 
3499 /**
3500  *      mptsas_expander_delete - remove this expander
3501  *      @ioc: Pointer to MPT_ADAPTER structure
3502  *      @port_info: expander port_info struct
3503  *      @force: Flag to forcefully delete the expander
3504  *
3505  **/
3506 
3507 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
3508                 struct mptsas_portinfo *port_info, u8 force)
3509 {
3510 
3511         struct mptsas_portinfo *parent;
3512         int             i;
3513         u64             expander_sas_address;
3514         struct mptsas_phyinfo *phy_info;
3515         struct mptsas_portinfo buffer;
3516         struct mptsas_portinfo_details *port_details;
3517         struct sas_port *port;
3518 
3519         if (!port_info)
3520                 return;
3521 
3522         /* see if expander is still there before deleting */
3523         mptsas_sas_expander_pg0(ioc, &buffer,
3524             (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3525             MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
3526             port_info->phy_info[0].identify.handle);
3527 
3528         if (buffer.num_phys) {
3529                 kfree(buffer.phy_info);
3530                 if (!force)
3531                         return;
3532         }
3533 
3534 
3535         /*
3536          * Obtain the port_info instance to the parent port
3537          */
3538         port_details = NULL;
3539         expander_sas_address =
3540             port_info->phy_info[0].identify.sas_address;
3541         parent = mptsas_find_portinfo_by_handle(ioc,
3542             port_info->phy_info[0].identify.handle_parent);
3543         mptsas_delete_expander_siblings(ioc, parent, port_info);
3544         if (!parent)
3545                 goto out;
3546 
3547         /*
3548          * Delete rphys in the parent that point
3549          * to this expander.
3550          */
3551         phy_info = parent->phy_info;
3552         port = NULL;
3553         for (i = 0; i < parent->num_phys; i++, phy_info++) {
3554                 if (!phy_info->phy)
3555                         continue;
3556                 if (phy_info->attached.sas_address !=
3557                     expander_sas_address)
3558                         continue;
3559                 if (!port) {
3560                         port = mptsas_get_port(phy_info);
3561                         port_details = phy_info->port_details;
3562                 }
3563                 dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3564                     MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n", ioc->name,
3565                     phy_info->phy_id, phy_info->phy);
3566                 sas_port_delete_phy(port, phy_info->phy);
3567         }
3568         if (port) {
3569                 dev_printk(KERN_DEBUG, &port->dev,
3570                     MYIOC_s_FMT "delete port %d, sas_addr (0x%llx)\n",
3571                     ioc->name, port->port_identifier,
3572                     (unsigned long long)expander_sas_address);
3573                 sas_port_delete(port);
3574                 mptsas_port_delete(ioc, port_details);
3575         }
3576  out:
3577 
3578         printk(MYIOC_s_INFO_FMT "delete expander: num_phys %d, "
3579             "sas_addr (0x%llx)\n",  ioc->name, port_info->num_phys,
3580             (unsigned long long)expander_sas_address);
3581 
3582         /*
3583          * free link
3584          */
3585         list_del(&port_info->list);
3586         kfree(port_info->phy_info);
3587         kfree(port_info);
3588 }
3589 
3590 
3591 /**
3592  * mptsas_send_expander_event - expanders events
3593  * @ioc: Pointer to MPT_ADAPTER structure
3594  * @expander_data: event data
3595  *
3596  *
3597  * This function handles adding, removing, and refreshing
3598  * device handles within the expander objects.
3599  */
3600 static void
3601 mptsas_send_expander_event(struct fw_event_work *fw_event)
3602 {
3603         MPT_ADAPTER *ioc;
3604         MpiEventDataSasExpanderStatusChange_t *expander_data;
3605         struct mptsas_portinfo *port_info;
3606         __le64 sas_address;
3607         int i;
3608 
3609         ioc = fw_event->ioc;
3610         expander_data = (MpiEventDataSasExpanderStatusChange_t *)
3611             fw_event->event_data;
3612         memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3613         sas_address = le64_to_cpu(sas_address);
3614         port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3615 
3616         if (expander_data->ReasonCode == MPI_EVENT_SAS_EXP_RC_ADDED) {
3617                 if (port_info) {
3618                         for (i = 0; i < port_info->num_phys; i++) {
3619                                 port_info->phy_info[i].portinfo = port_info;
3620                                 port_info->phy_info[i].handle =
3621                                     le16_to_cpu(expander_data->DevHandle);
3622                                 port_info->phy_info[i].identify.sas_address =
3623                                     le64_to_cpu(sas_address);
3624                                 port_info->phy_info[i].identify.handle_parent =
3625                                     le16_to_cpu(expander_data->ParentDevHandle);
3626                         }
3627                         mptsas_expander_refresh(ioc, port_info);
3628                 } else if (!port_info && expander_data->NumPhys)
3629                         mptsas_expander_event_add(ioc, expander_data);
3630         } else if (expander_data->ReasonCode ==
3631             MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING)
3632                 mptsas_expander_delete(ioc, port_info, 0);
3633 
3634         mptsas_free_fw_event(ioc, fw_event);
3635 }
3636 
3637 
3638 /**
3639  * mptsas_expander_add -
3640  * @ioc: Pointer to MPT_ADAPTER structure
3641  * @handle:
3642  *
3643  */
3644 static struct mptsas_portinfo *
3645 mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
3646 {
3647         struct mptsas_portinfo buffer, *port_info;
3648         int i;
3649 
3650         if ((mptsas_sas_expander_pg0(ioc, &buffer,
3651             (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3652             MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)))
3653                 return NULL;
3654 
3655         port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_ATOMIC);
3656         if (!port_info) {
3657                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3658                 "%s: exit at line=%d\n", ioc->name,
3659                 __func__, __LINE__));
3660                 return NULL;
3661         }
3662         port_info->num_phys = buffer.num_phys;
3663         port_info->phy_info = buffer.phy_info;
3664         for (i = 0; i < port_info->num_phys; i++)
3665                 port_info->phy_info[i].portinfo = port_info;
3666         mutex_lock(&ioc->sas_topology_mutex);
3667         list_add_tail(&port_info->list, &ioc->sas_topology);
3668         mutex_unlock(&ioc->sas_topology_mutex);
3669         printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3670             "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3671             (unsigned long long)buffer.phy_info[0].identify.sas_address);
3672         mptsas_expander_refresh(ioc, port_info);
3673         return port_info;
3674 }
3675 
3676 static void
3677 mptsas_send_link_status_event(struct fw_event_work *fw_event)
3678 {
3679         MPT_ADAPTER *ioc;
3680         MpiEventDataSasPhyLinkStatus_t *link_data;
3681         struct mptsas_portinfo *port_info;
3682         struct mptsas_phyinfo *phy_info = NULL;
3683         __le64 sas_address;
3684         u8 phy_num;
3685         u8 link_rate;
3686 
3687         ioc = fw_event->ioc;
3688         link_data = (MpiEventDataSasPhyLinkStatus_t *)fw_event->event_data;
3689 
3690         memcpy(&sas_address, &link_data->SASAddress, sizeof(__le64));
3691         sas_address = le64_to_cpu(sas_address);
3692         link_rate = link_data->LinkRates >> 4;
3693         phy_num = link_data->PhyNum;
3694 
3695         port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3696         if (port_info) {
3697                 phy_info = &port_info->phy_info[phy_num];
3698                 if (phy_info)
3699                         phy_info->negotiated_link_rate = link_rate;
3700         }
3701 
3702         if (link_rate == MPI_SAS_IOUNIT0_RATE_1_5 ||
3703             link_rate == MPI_SAS_IOUNIT0_RATE_3_0 ||
3704             link_rate == MPI_SAS_IOUNIT0_RATE_6_0) {
3705 
3706                 if (!port_info) {
3707                         if (ioc->old_sas_discovery_protocal) {
3708                                 port_info = mptsas_expander_add(ioc,
3709                                         le16_to_cpu(link_data->DevHandle));
3710                                 if (port_info)
3711                                         goto out;
3712                         }
3713                         goto out;
3714                 }
3715 
3716                 if (port_info == ioc->hba_port_info)
3717                         mptsas_probe_hba_phys(ioc);
3718                 else
3719                         mptsas_expander_refresh(ioc, port_info);
3720         } else if (phy_info && phy_info->phy) {
3721                 if (link_rate ==  MPI_SAS_IOUNIT0_RATE_PHY_DISABLED)
3722                         phy_info->phy->negotiated_linkrate =
3723                             SAS_PHY_DISABLED;
3724                 else if (link_rate ==
3725                     MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION)
3726                         phy_info->phy->negotiated_linkrate =
3727                             SAS_LINK_RATE_FAILED;
3728                 else {
3729                         phy_info->phy->negotiated_linkrate =
3730                             SAS_LINK_RATE_UNKNOWN;
3731                         if (ioc->device_missing_delay &&
3732                             mptsas_is_end_device(&phy_info->attached)) {
3733                                 struct scsi_device              *sdev;
3734                                 VirtDevice                      *vdevice;
3735                                 u8      channel, id;
3736                                 id = phy_info->attached.id;
3737                                 channel = phy_info->attached.channel;
3738                                 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3739                                 "Link down for fw_id %d:fw_channel %d\n",
3740                                     ioc->name, phy_info->attached.id,
3741                                     phy_info->attached.channel));
3742 
3743                                 shost_for_each_device(sdev, ioc->sh) {
3744                                         vdevice = sdev->hostdata;
3745                                         if ((vdevice == NULL) ||
3746                                                 (vdevice->vtarget == NULL))
3747                                                 continue;
3748                                         if ((vdevice->vtarget->tflags &
3749                                             MPT_TARGET_FLAGS_RAID_COMPONENT ||
3750                                             vdevice->vtarget->raidVolume))
3751                                                 continue;
3752                                         if (vdevice->vtarget->id == id &&
3753                                                 vdevice->vtarget->channel ==
3754                                                 channel)
3755                                                 devtprintk(ioc,
3756                                                 printk(MYIOC_s_DEBUG_FMT
3757                                                 "SDEV OUTSTANDING CMDS"
3758                                                 "%d\n", ioc->name,
3759                                                 atomic_read(&sdev->device_busy)));
3760                                 }
3761 
3762                         }
3763                 }
3764         }
3765  out:
3766         mptsas_free_fw_event(ioc, fw_event);
3767 }
3768 
3769 static void
3770 mptsas_not_responding_devices(MPT_ADAPTER *ioc)
3771 {
3772         struct mptsas_portinfo buffer, *port_info;
3773         struct mptsas_device_info       *sas_info;
3774         struct mptsas_devinfo sas_device;
3775         u32     handle;
3776         VirtTarget *vtarget = NULL;
3777         struct mptsas_phyinfo *phy_info;
3778         u8 found_expander;
3779         int retval, retry_count;
3780         unsigned long flags;
3781 
3782         mpt_findImVolumes(ioc);
3783 
3784         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3785         if (ioc->ioc_reset_in_progress) {
3786                 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3787                    "%s: exiting due to a parallel reset \n", ioc->name,
3788                     __func__));
3789                 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3790                 return;
3791         }
3792         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3793 
3794         /* devices, logical volumes */
3795         mutex_lock(&ioc->sas_device_info_mutex);
3796  redo_device_scan:
3797         list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) {
3798                 if (sas_info->is_cached)
3799                         continue;
3800                 if (!sas_info->is_logical_volume) {
3801                         sas_device.handle = 0;
3802                         retry_count = 0;
3803 retry_page:
3804                         retval = mptsas_sas_device_pg0(ioc, &sas_device,
3805                                 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID
3806                                 << MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3807                                 (sas_info->fw.channel << 8) +
3808                                 sas_info->fw.id);
3809 
3810                         if (sas_device.handle)
3811                                 continue;
3812                         if (retval == -EBUSY) {
3813                                 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3814                                 if (ioc->ioc_reset_in_progress) {
3815                                         dfailprintk(ioc,
3816                                         printk(MYIOC_s_DEBUG_FMT
3817                                         "%s: exiting due to reset\n",
3818                                         ioc->name, __func__));
3819                                         spin_unlock_irqrestore
3820                                         (&ioc->taskmgmt_lock, flags);
3821                                         mutex_unlock(&ioc->
3822                                         sas_device_info_mutex);
3823                                         return;
3824                                 }
3825                                 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
3826                                 flags);
3827                         }
3828 
3829                         if (retval && (retval != -ENODEV)) {
3830                                 if (retry_count < 10) {
3831                                         retry_count++;
3832                                         goto retry_page;
3833                                 } else {
3834                                         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3835                                         "%s: Config page retry exceeded retry "
3836                                         "count deleting device 0x%llx\n",
3837                                         ioc->name, __func__,
3838                                         sas_info->sas_address));
3839                                 }
3840                         }
3841 
3842                         /* delete device */
3843                         vtarget = mptsas_find_vtarget(ioc,
3844                                 sas_info->fw.channel, sas_info->fw.id);
3845 
3846                         if (vtarget)
3847                                 vtarget->deleted = 1;
3848 
3849                         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3850                                         sas_info->sas_address);
3851 
3852                         mptsas_del_end_device(ioc, phy_info);
3853                         goto redo_device_scan;
3854                 } else
3855                         mptsas_volume_delete(ioc, sas_info->fw.id);
3856         }
3857         mutex_unlock(&ioc->sas_device_info_mutex);
3858 
3859         /* expanders */
3860         mutex_lock(&ioc->sas_topology_mutex);
3861  redo_expander_scan:
3862         list_for_each_entry(port_info, &ioc->sas_topology, list) {
3863 
3864                 if (!(port_info->phy_info[0].identify.device_info &
3865                     MPI_SAS_DEVICE_INFO_SMP_TARGET))
3866                         continue;
3867                 found_expander = 0;
3868                 handle = 0xFFFF;
3869                 while (!mptsas_sas_expander_pg0(ioc, &buffer,
3870                     (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3871                      MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle) &&
3872                     !found_expander) {
3873 
3874                         handle = buffer.phy_info[0].handle;
3875                         if (buffer.phy_info[0].identify.sas_address ==
3876                             port_info->phy_info[0].identify.sas_address) {
3877                                 found_expander = 1;
3878                         }
3879                         kfree(buffer.phy_info);
3880                 }
3881 
3882                 if (!found_expander) {
3883                         mptsas_expander_delete(ioc, port_info, 0);
3884                         goto redo_expander_scan;
3885                 }
3886         }
3887         mutex_unlock(&ioc->sas_topology_mutex);
3888 }
3889 
3890 /**
3891  *      mptsas_probe_expanders - adding expanders
3892  *      @ioc: Pointer to MPT_ADAPTER structure
3893  *
3894  **/
3895 static void
3896 mptsas_probe_expanders(MPT_ADAPTER *ioc)
3897 {
3898         struct mptsas_portinfo buffer, *port_info;
3899         u32                     handle;
3900         int i;
3901 
3902         handle = 0xFFFF;
3903         while (!mptsas_sas_expander_pg0(ioc, &buffer,
3904             (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3905              MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)) {
3906 
3907                 handle = buffer.phy_info[0].handle;
3908                 port_info = mptsas_find_portinfo_by_sas_address(ioc,
3909                     buffer.phy_info[0].identify.sas_address);
3910 
3911                 if (port_info) {
3912                         /* refreshing handles */
3913                         for (i = 0; i < buffer.num_phys; i++) {
3914                                 port_info->phy_info[i].handle = handle;
3915                                 port_info->phy_info[i].identify.handle_parent =
3916                                     buffer.phy_info[0].identify.handle_parent;
3917                         }
3918                         mptsas_expander_refresh(ioc, port_info);
3919                         kfree(buffer.phy_info);
3920                         continue;
3921                 }
3922 
3923                 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3924                 if (!port_info) {
3925                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3926                         "%s: exit at line=%d\n", ioc->name,
3927                         __func__, __LINE__));
3928                         return;
3929                 }
3930                 port_info->num_phys = buffer.num_phys;
3931                 port_info->phy_info = buffer.phy_info;
3932                 for (i = 0; i < port_info->num_phys; i++)
3933                         port_info->phy_info[i].portinfo = port_info;
3934                 mutex_lock(&ioc->sas_topology_mutex);
3935                 list_add_tail(&port_info->list, &ioc->sas_topology);
3936                 mutex_unlock(&ioc->sas_topology_mutex);
3937                 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3938                     "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3939             (unsigned long long)buffer.phy_info[0].identify.sas_address);
3940                 mptsas_expander_refresh(ioc, port_info);
3941         }
3942 }
3943 
3944 static void
3945 mptsas_probe_devices(MPT_ADAPTER *ioc)
3946 {
3947         u16 handle;
3948         struct mptsas_devinfo sas_device;
3949         struct mptsas_phyinfo *phy_info;
3950 
3951         handle = 0xFFFF;
3952         while (!(mptsas_sas_device_pg0(ioc, &sas_device,
3953             MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
3954 
3955                 handle = sas_device.handle;
3956 
3957                 if ((sas_device.device_info &
3958                      (MPI_SAS_DEVICE_INFO_SSP_TARGET |
3959                       MPI_SAS_DEVICE_INFO_STP_TARGET |
3960                       MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0)
3961                         continue;
3962 
3963                 /* If there is no FW B_T mapping for this device then continue
3964                  * */
3965                 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
3966                         || !(sas_device.flags &
3967                         MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
3968                         continue;
3969 
3970                 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3971                 if (!phy_info)
3972                         continue;
3973 
3974                 if (mptsas_get_rphy(phy_info))
3975                         continue;
3976 
3977                 mptsas_add_end_device(ioc, phy_info);
3978         }
3979 }
3980 
3981 /**
3982  *      mptsas_scan_sas_topology -
3983  *      @ioc: Pointer to MPT_ADAPTER structure
3984  *      @sas_address:
3985  *
3986  **/
3987 static void
3988 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
3989 {
3990         struct scsi_device *sdev;
3991         int i;
3992 
3993         mptsas_probe_hba_phys(ioc);
3994         mptsas_probe_expanders(ioc);
3995         mptsas_probe_devices(ioc);
3996 
3997         /*
3998           Reporting RAID volumes.
3999         */
4000         if (!ioc->ir_firmware || !ioc->raid_data.pIocPg2 ||
4001             !ioc->raid_data.pIocPg2->NumActiveVolumes)
4002                 return;
4003         for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
4004                 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
4005                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
4006                 if (sdev) {
4007                         scsi_device_put(sdev);
4008                         continue;
4009                 }
4010                 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4011                     "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4012                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID);
4013                 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4014                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
4015         }
4016 }
4017 
4018 
4019 static void
4020 mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
4021 {
4022         MPT_ADAPTER *ioc;
4023         EventDataQueueFull_t *qfull_data;
4024         struct mptsas_device_info *sas_info;
4025         struct scsi_device      *sdev;
4026         int depth;
4027         int id = -1;
4028         int channel = -1;
4029         int fw_id, fw_channel;
4030         u16 current_depth;
4031 
4032 
4033         ioc = fw_event->ioc;
4034         qfull_data = (EventDataQueueFull_t *)fw_event->event_data;
4035         fw_id = qfull_data->TargetID;
4036         fw_channel = qfull_data->Bus;
4037         current_depth = le16_to_cpu(qfull_data->CurrentDepth);
4038 
4039         /* if hidden raid component, look for the volume id */
4040         mutex_lock(&ioc->sas_device_info_mutex);
4041         if (mptscsih_is_phys_disk(ioc, fw_channel, fw_id)) {
4042                 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
4043                     list) {
4044                         if (sas_info->is_cached ||
4045                             sas_info->is_logical_volume)
4046                                 continue;
4047                         if (sas_info->is_hidden_raid_component &&
4048                             (sas_info->fw.channel == fw_channel &&
4049                             sas_info->fw.id == fw_id)) {
4050                                 id = sas_info->volume_id;
4051                                 channel = MPTSAS_RAID_CHANNEL;
4052                                 goto out;
4053                         }
4054                 }
4055         } else {
4056                 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
4057                     list) {
4058                         if (sas_info->is_cached ||
4059                             sas_info->is_hidden_raid_component ||
4060                             sas_info->is_logical_volume)
4061                                 continue;
4062                         if (sas_info->fw.channel == fw_channel &&
4063                             sas_info->fw.id == fw_id) {
4064                                 id = sas_info->os.id;
4065                                 channel = sas_info->os.channel;
4066                                 goto out;
4067                         }
4068                 }
4069 
4070         }
4071 
4072  out:
4073         mutex_unlock(&ioc->sas_device_info_mutex);
4074 
4075         if (id != -1) {
4076                 shost_for_each_device(sdev, ioc->sh) {
4077                         if (sdev->id == id && sdev->channel == channel) {
4078                                 if (current_depth > sdev->queue_depth) {
4079                                         sdev_printk(KERN_INFO, sdev,
4080                                             "strange observation, the queue "
4081                                             "depth is (%d) meanwhile fw queue "
4082                                             "depth (%d)\n", sdev->queue_depth,
4083                                             current_depth);
4084                                         continue;
4085                                 }
4086                                 depth = scsi_track_queue_full(sdev,
4087                                         sdev->queue_depth - 1);
4088                                 if (depth > 0)
4089                                         sdev_printk(KERN_INFO, sdev,
4090                                         "Queue depth reduced to (%d)\n",
4091                                            depth);
4092                                 else if (depth < 0)
4093                                         sdev_printk(KERN_INFO, sdev,
4094                                         "Tagged Command Queueing is being "
4095                                         "disabled\n");
4096                                 else if (depth == 0)
4097                                         sdev_printk(KERN_DEBUG, sdev,
4098                                         "Queue depth not changed yet\n");
4099                         }
4100                 }
4101         }
4102 
4103         mptsas_free_fw_event(ioc, fw_event);
4104 }
4105 
4106 
4107 static struct mptsas_phyinfo *
4108 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
4109 {
4110         struct mptsas_portinfo *port_info;
4111         struct mptsas_phyinfo *phy_info = NULL;
4112         int i;
4113 
4114         mutex_lock(&ioc->sas_topology_mutex);
4115         list_for_each_entry(port_info, &ioc->sas_topology, list) {
4116                 for (i = 0; i < port_info->num_phys; i++) {
4117                         if (!mptsas_is_end_device(
4118                                 &port_info->phy_info[i].attached))
4119                                 continue;
4120                         if (port_info->phy_info[i].attached.sas_address
4121                             != sas_address)
4122                                 continue;
4123                         phy_info = &port_info->phy_info[i];
4124                         break;
4125                 }
4126         }
4127         mutex_unlock(&ioc->sas_topology_mutex);
4128         return phy_info;
4129 }
4130 
4131 /**
4132  *      mptsas_find_phyinfo_by_phys_disk_num -
4133  *      @ioc: Pointer to MPT_ADAPTER structure
4134  *      @phys_disk_num:
4135  *      @channel:
4136  *      @id:
4137  *
4138  **/
4139 static struct mptsas_phyinfo *
4140 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
4141         u8 channel, u8 id)
4142 {
4143         struct mptsas_phyinfo *phy_info = NULL;
4144         struct mptsas_portinfo *port_info;
4145         RaidPhysDiskPage1_t *phys_disk = NULL;
4146         int num_paths;
4147         u64 sas_address = 0;
4148         int i;
4149 
4150         phy_info = NULL;
4151         if (!ioc->raid_data.pIocPg3)
4152                 return NULL;
4153         /* dual port support */
4154         num_paths = mpt_raid_phys_disk_get_num_paths(ioc, phys_disk_num);
4155         if (!num_paths)
4156                 goto out;
4157         phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
4158            (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
4159         if (!phys_disk)
4160                 goto out;
4161         mpt_raid_phys_disk_pg1(ioc, phys_disk_num, phys_disk);
4162         for (i = 0; i < num_paths; i++) {
4163                 if ((phys_disk->Path[i].Flags & 1) != 0)
4164                         /* entry no longer valid */
4165                         continue;
4166                 if ((id == phys_disk->Path[i].PhysDiskID) &&
4167                     (channel == phys_disk->Path[i].PhysDiskBus)) {
4168                         memcpy(&sas_address, &phys_disk->Path[i].WWID,
4169                                 sizeof(u64));
4170                         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4171                                         sas_address);
4172                         goto out;
4173                 }
4174         }
4175 
4176  out:
4177         kfree(phys_disk);
4178         if (phy_info)
4179                 return phy_info;
4180 
4181         /*
4182          * Extra code to handle RAID0 case, where the sas_address is not updated
4183          * in phys_disk_page_1 when hotswapped
4184          */
4185         mutex_lock(&ioc->sas_topology_mutex);
4186         list_for_each_entry(port_info, &ioc->sas_topology, list) {
4187                 for (i = 0; i < port_info->num_phys && !phy_info; i++) {
4188                         if (!mptsas_is_end_device(
4189                                 &port_info->phy_info[i].attached))
4190                                 continue;
4191                         if (port_info->phy_info[i].attached.phys_disk_num == ~0)
4192                                 continue;
4193                         if ((port_info->phy_info[i].attached.phys_disk_num ==
4194                             phys_disk_num) &&
4195                             (port_info->phy_info[i].attached.id == id) &&
4196                             (port_info->phy_info[i].attached.channel ==
4197                              channel))
4198                                 phy_info = &port_info->phy_info[i];
4199                 }
4200         }
4201         mutex_unlock(&ioc->sas_topology_mutex);
4202         return phy_info;
4203 }
4204 
4205 static void
4206 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
4207 {
4208         int rc;
4209 
4210         sdev->no_uld_attach = data ? 1 : 0;
4211         rc = scsi_device_reprobe(sdev);
4212 }
4213 
4214 static void
4215 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
4216 {
4217         starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
4218                         mptsas_reprobe_lun);
4219 }
4220 
4221 static void
4222 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
4223 {
4224         CONFIGPARMS                     cfg;
4225         ConfigPageHeader_t              hdr;
4226         dma_addr_t                      dma_handle;
4227         pRaidVolumePage0_t              buffer = NULL;
4228         RaidPhysDiskPage0_t             phys_disk;
4229         int                             i;
4230         struct mptsas_phyinfo   *phy_info;
4231         struct mptsas_devinfo           sas_device;
4232 
4233         memset(&cfg, 0 , sizeof(CONFIGPARMS));
4234         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4235         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
4236         cfg.pageAddr = (channel << 8) + id;
4237         cfg.cfghdr.hdr = &hdr;
4238         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4239         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
4240 
4241         if (mpt_config(ioc, &cfg) != 0)
4242                 goto out;
4243 
4244         if (!hdr.PageLength)
4245                 goto out;
4246 
4247         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4248             &dma_handle);
4249 
4250         if (!buffer)
4251                 goto out;
4252 
4253         cfg.physAddr = dma_handle;
4254         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4255 
4256         if (mpt_config(ioc, &cfg) != 0)
4257                 goto out;
4258 
4259         if (!(buffer->VolumeStatus.Flags &
4260             MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
4261                 goto out;
4262 
4263         if (!buffer->NumPhysDisks)
4264                 goto out;
4265 
4266         for (i = 0; i < buffer->NumPhysDisks; i++) {
4267 
4268                 if (mpt_raid_phys_disk_pg0(ioc,
4269                     buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
4270                         continue;
4271 
4272                 if (mptsas_sas_device_pg0(ioc, &sas_device,
4273                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4274                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4275                         (phys_disk.PhysDiskBus << 8) +
4276                         phys_disk.PhysDiskID))
4277                         continue;
4278 
4279                 /* If there is no FW B_T mapping for this device then continue
4280                  * */
4281                 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4282                         || !(sas_device.flags &
4283                         MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4284                         continue;
4285 
4286 
4287                 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4288                     sas_device.sas_address);
4289                 mptsas_add_end_device(ioc, phy_info);
4290         }
4291 
4292  out:
4293         if (buffer)
4294                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4295                     dma_handle);
4296 }
4297 /*
4298  * Work queue thread to handle SAS hotplug events
4299  */
4300 static void
4301 mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
4302     struct mptsas_hotplug_event *hot_plug_info)
4303 {
4304         struct mptsas_phyinfo *phy_info;
4305         struct scsi_target * starget;
4306         struct mptsas_devinfo sas_device;
4307         VirtTarget *vtarget;
4308         int i;
4309         struct mptsas_portinfo *port_info;
4310 
4311         switch (hot_plug_info->event_type) {
4312 
4313         case MPTSAS_ADD_PHYSDISK:
4314 
4315                 if (!ioc->raid_data.pIocPg2)
4316                         break;
4317 
4318                 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
4319                         if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID ==
4320                             hot_plug_info->id) {
4321                                 printk(MYIOC_s_WARN_FMT "firmware bug: unable "
4322                                     "to add hidden disk - target_id matches "
4323                                     "volume_id\n", ioc->name);
4324                                 mptsas_free_fw_event(ioc, fw_event);
4325                                 return;
4326                         }
4327                 }
4328                 mpt_findImVolumes(ioc);
4329                 /* fall through */
4330 
4331         case MPTSAS_ADD_DEVICE:
4332                 memset(&sas_device, 0, sizeof(struct mptsas_devinfo));
4333                 mptsas_sas_device_pg0(ioc, &sas_device,
4334                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4335                     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4336                     (hot_plug_info->channel << 8) +
4337                     hot_plug_info->id);
4338 
4339                 /* If there is no FW B_T mapping for this device then break
4340                  * */
4341                 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4342                         || !(sas_device.flags &
4343                         MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4344                         break;
4345 
4346                 if (!sas_device.handle)
4347                         return;
4348 
4349                 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
4350                 /* Device hot plug */
4351                 if (!phy_info) {
4352                         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4353                                 "%s %d HOT PLUG: "
4354                                 "parent handle of device %x\n", ioc->name,
4355                                 __func__, __LINE__, sas_device.handle_parent));
4356                         port_info = mptsas_find_portinfo_by_handle(ioc,
4357                                 sas_device.handle_parent);
4358 
4359                         if (port_info == ioc->hba_port_info)
4360                                 mptsas_probe_hba_phys(ioc);
4361                         else if (port_info)
4362                                 mptsas_expander_refresh(ioc, port_info);
4363                         else {
4364                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4365                                         "%s %d port info is NULL\n",
4366                                         ioc->name, __func__, __LINE__));
4367                                 break;
4368                         }
4369                         phy_info = mptsas_refreshing_device_handles
4370                                 (ioc, &sas_device);
4371                 }
4372 
4373                 if (!phy_info) {
4374                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4375                                 "%s %d phy info is NULL\n",
4376                                 ioc->name, __func__, __LINE__));
4377                         break;
4378                 }
4379 
4380                 if (mptsas_get_rphy(phy_info))
4381                         break;
4382 
4383                 mptsas_add_end_device(ioc, phy_info);
4384                 break;
4385 
4386         case MPTSAS_DEL_DEVICE:
4387                 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4388                     hot_plug_info->sas_address);
4389                 mptsas_del_end_device(ioc, phy_info);
4390                 break;
4391 
4392         case MPTSAS_DEL_PHYSDISK:
4393 
4394                 mpt_findImVolumes(ioc);
4395 
4396                 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
4397                                 ioc, hot_plug_info->phys_disk_num,
4398                                 hot_plug_info->channel,
4399                                 hot_plug_info->id);
4400                 mptsas_del_end_device(ioc, phy_info);
4401                 break;
4402 
4403         case MPTSAS_ADD_PHYSDISK_REPROBE:
4404 
4405                 if (mptsas_sas_device_pg0(ioc, &sas_device,
4406                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4407                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4408                     (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4409                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4410                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
4411                                  __func__, hot_plug_info->id, __LINE__));
4412                         break;
4413                 }
4414 
4415                 /* If there is no FW B_T mapping for this device then break
4416                  * */
4417                 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4418                         || !(sas_device.flags &
4419                         MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4420                         break;
4421 
4422                 phy_info = mptsas_find_phyinfo_by_sas_address(
4423                     ioc, sas_device.sas_address);
4424 
4425                 if (!phy_info) {
4426                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4427                                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4428                                  __func__, hot_plug_info->id, __LINE__));
4429                         break;
4430                 }
4431 
4432                 starget = mptsas_get_starget(phy_info);
4433                 if (!starget) {
4434                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4435                                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4436                                  __func__, hot_plug_info->id, __LINE__));
4437                         break;
4438                 }
4439 
4440                 vtarget = starget->hostdata;
4441                 if (!vtarget) {
4442                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4443                                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4444                                  __func__, hot_plug_info->id, __LINE__));
4445                         break;
4446                 }
4447 
4448                 mpt_findImVolumes(ioc);
4449 
4450                 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Hidding: "
4451                     "fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4452                     ioc->name, hot_plug_info->channel, hot_plug_info->id,
4453                     hot_plug_info->phys_disk_num, (unsigned long long)
4454                     sas_device.sas_address);
4455 
4456                 vtarget->id = hot_plug_info->phys_disk_num;
4457                 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
4458                 phy_info->attached.phys_disk_num = hot_plug_info->phys_disk_num;
4459                 mptsas_reprobe_target(starget, 1);
4460                 break;
4461 
4462         case MPTSAS_DEL_PHYSDISK_REPROBE:
4463 
4464                 if (mptsas_sas_device_pg0(ioc, &sas_device,
4465                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4466                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4467                         (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4468                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4469                                     "%s: fw_id=%d exit at line=%d\n",
4470                                     ioc->name, __func__,
4471                                     hot_plug_info->id, __LINE__));
4472                         break;
4473                 }
4474 
4475                 /* If there is no FW B_T mapping for this device then break
4476                  * */
4477                 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4478                         || !(sas_device.flags &
4479                         MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4480                         break;
4481 
4482                 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4483                                 sas_device.sas_address);
4484                 if (!phy_info) {
4485                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4486                             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4487                          __func__, hot_plug_info->id, __LINE__));
4488                         break;
4489                 }
4490 
4491                 starget = mptsas_get_starget(phy_info);
4492                 if (!starget) {
4493                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4494                             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4495                          __func__, hot_plug_info->id, __LINE__));
4496                         break;
4497                 }
4498 
4499                 vtarget = starget->hostdata;
4500                 if (!vtarget) {
4501                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4502                             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4503                          __func__, hot_plug_info->id, __LINE__));
4504                         break;
4505                 }
4506 
4507                 if (!(vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)) {
4508                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4509                             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4510                          __func__, hot_plug_info->id, __LINE__));
4511                         break;
4512                 }
4513 
4514                 mpt_findImVolumes(ioc);
4515 
4516                 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Exposing:"
4517                     " fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4518                     ioc->name, hot_plug_info->channel, hot_plug_info->id,
4519                     hot_plug_info->phys_disk_num, (unsigned long long)
4520                     sas_device.sas_address);
4521 
4522                 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
4523                 vtarget->id = hot_plug_info->id;
4524                 phy_info->attached.phys_disk_num = ~0;
4525                 mptsas_reprobe_target(starget, 0);
4526                 mptsas_add_device_component_by_fw(ioc,
4527                     hot_plug_info->channel, hot_plug_info->id);
4528                 break;
4529 
4530         case MPTSAS_ADD_RAID:
4531 
4532                 mpt_findImVolumes(ioc);
4533                 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4534                     "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4535                     hot_plug_info->id);
4536                 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4537                     hot_plug_info->id, 0);
4538                 break;
4539 
4540         case MPTSAS_DEL_RAID:
4541 
4542                 mpt_findImVolumes(ioc);
4543                 printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4544                     "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4545                     hot_plug_info->id);
4546                 scsi_remove_device(hot_plug_info->sdev);
4547                 scsi_device_put(hot_plug_info->sdev);
4548                 break;
4549 
4550         case MPTSAS_ADD_INACTIVE_VOLUME:
4551 
4552                 mpt_findImVolumes(ioc);
4553                 mptsas_adding_inactive_raid_components(ioc,
4554                     hot_plug_info->channel, hot_plug_info->id);
4555                 break;
4556 
4557         default:
4558                 break;
4559         }
4560 
4561         mptsas_free_fw_event(ioc, fw_event);
4562 }
4563 
4564 static void
4565 mptsas_send_sas_event(struct fw_event_work *fw_event)
4566 {
4567         MPT_ADAPTER *ioc;
4568         struct mptsas_hotplug_event hot_plug_info;
4569         EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
4570         u32 device_info;
4571         u64 sas_address;
4572 
4573         ioc = fw_event->ioc;
4574         sas_event_data = (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
4575             fw_event->event_data;
4576         device_info = le32_to_cpu(sas_event_data->DeviceInfo);
4577 
4578         if ((device_info &
4579                 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
4580                 MPI_SAS_DEVICE_INFO_STP_TARGET |
4581                 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0) {
4582                 mptsas_free_fw_event(ioc, fw_event);
4583                 return;
4584         }
4585 
4586         if (sas_event_data->ReasonCode ==
4587                 MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED) {
4588                 mptbase_sas_persist_operation(ioc,
4589                 MPI_SAS_OP_CLEAR_NOT_PRESENT);
4590                 mptsas_free_fw_event(ioc, fw_event);
4591                 return;
4592         }
4593 
4594         switch (sas_event_data->ReasonCode) {
4595         case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
4596         case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
4597                 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4598                 hot_plug_info.handle = le16_to_cpu(sas_event_data->DevHandle);
4599                 hot_plug_info.channel = sas_event_data->Bus;
4600                 hot_plug_info.id = sas_event_data->TargetID;
4601                 hot_plug_info.phy_id = sas_event_data->PhyNum;
4602                 memcpy(&sas_address, &sas_event_data->SASAddress,
4603                     sizeof(u64));
4604                 hot_plug_info.sas_address = le64_to_cpu(sas_address);
4605                 hot_plug_info.device_info = device_info;
4606                 if (sas_event_data->ReasonCode &
4607                     MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
4608                         hot_plug_info.event_type = MPTSAS_ADD_DEVICE;
4609                 else
4610                         hot_plug_info.event_type = MPTSAS_DEL_DEVICE;
4611                 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4612                 break;
4613 
4614         case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
4615                 mptbase_sas_persist_operation(ioc,
4616                     MPI_SAS_OP_CLEAR_NOT_PRESENT);
4617                 mptsas_free_fw_event(ioc, fw_event);
4618                 break;
4619 
4620         case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
4621         /* TODO */
4622         case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
4623         /* TODO */
4624         default:
4625                 mptsas_free_fw_event(ioc, fw_event);
4626                 break;
4627         }
4628 }
4629 
4630 static void
4631 mptsas_send_raid_event(struct fw_event_work *fw_event)
4632 {
4633         MPT_ADAPTER *ioc;
4634         EVENT_DATA_RAID *raid_event_data;
4635         struct mptsas_hotplug_event hot_plug_info;
4636         int status;
4637         int state;
4638         struct scsi_device *sdev = NULL;
4639         VirtDevice *vdevice = NULL;
4640         RaidPhysDiskPage0_t phys_disk;
4641 
4642         ioc = fw_event->ioc;
4643         raid_event_data = (EVENT_DATA_RAID *)fw_event->event_data;
4644         status = le32_to_cpu(raid_event_data->SettingsStatus);
4645         state = (status >> 8) & 0xff;
4646 
4647         memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4648         hot_plug_info.id = raid_event_data->VolumeID;
4649         hot_plug_info.channel = raid_event_data->VolumeBus;
4650         hot_plug_info.phys_disk_num = raid_event_data->PhysDiskNum;
4651 
4652         if (raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_DELETED ||
4653             raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_CREATED ||
4654             raid_event_data->ReasonCode ==
4655             MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED) {
4656                 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
4657                     hot_plug_info.id, 0);
4658                 hot_plug_info.sdev = sdev;
4659                 if (sdev)
4660                         vdevice = sdev->hostdata;
4661         }
4662 
4663         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4664             "ReasonCode=%02x\n", ioc->name, __func__,
4665             raid_event_data->ReasonCode));
4666 
4667         switch (raid_event_data->ReasonCode) {
4668         case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4669                 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK_REPROBE;
4670                 break;
4671         case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4672                 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK_REPROBE;
4673                 break;
4674         case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4675                 switch (state) {
4676                 case MPI_PD_STATE_ONLINE:
4677                 case MPI_PD_STATE_NOT_COMPATIBLE:
4678                         mpt_raid_phys_disk_pg0(ioc,
4679                             raid_event_data->PhysDiskNum, &phys_disk);
4680                         hot_plug_info.id = phys_disk.PhysDiskID;
4681                         hot_plug_info.channel = phys_disk.PhysDiskBus;
4682                         hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4683                         break;
4684                 case MPI_PD_STATE_FAILED:
4685                 case MPI_PD_STATE_MISSING:
4686                 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
4687                 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
4688                 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
4689                         hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4690                         break;
4691                 default:
4692                         break;
4693                 }
4694                 break;
4695         case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4696                 if (!sdev)
4697                         break;
4698                 vdevice->vtarget->deleted = 1; /* block IO */
4699                 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4700                 break;
4701         case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4702                 if (sdev) {
4703                         scsi_device_put(sdev);
4704                         break;
4705                 }
4706                 hot_plug_info.event_type = MPTSAS_ADD_RAID;
4707                 break;
4708         case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4709                 if (!(status & MPI_RAIDVOL0_STATUS_FLAG_ENABLED)) {
4710                         if (!sdev)
4711                                 break;
4712                         vdevice->vtarget->deleted = 1; /* block IO */
4713                         hot_plug_info.event_type = MPTSAS_DEL_RAID;
4714                         break;
4715                 }
4716                 switch (state) {
4717                 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
4718                 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
4719                         if (!sdev)
4720                                 break;
4721                         vdevice->vtarget->deleted = 1; /* block IO */
4722                         hot_plug_info.event_type = MPTSAS_DEL_RAID;
4723                         break;
4724                 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
4725                 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
4726                         if (sdev) {
4727                                 scsi_device_put(sdev);
4728                                 break;
4729                         }
4730                         hot_plug_info.event_type = MPTSAS_ADD_RAID;
4731                         break;
4732                 default:
4733                         break;
4734                 }
4735                 break;
4736         default:
4737                 break;
4738         }
4739 
4740         if (hot_plug_info.event_type != MPTSAS_IGNORE_EVENT)
4741                 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4742         else
4743                 mptsas_free_fw_event(ioc, fw_event);
4744 }
4745 
4746 /**
4747  *      mptsas_issue_tm - send mptsas internal tm request
4748  *      @ioc: Pointer to MPT_ADAPTER structure
4749  *      @type: Task Management type
4750  *      @channel: channel number for task management
4751  *      @id: Logical Target ID for reset (if appropriate)
4752  *      @lun: Logical unit for reset (if appropriate)
4753  *      @task_context: Context for the task to be aborted
4754  *      @timeout: timeout for task management control
4755  *
4756  *      return 0 on success and -1 on failure:
4757  *
4758  */
4759 static int
4760 mptsas_issue_tm(MPT_ADAPTER *ioc, u8 type, u8 channel, u8 id, u64 lun,
4761         int task_context, ulong timeout, u8 *issue_reset)
4762 {
4763         MPT_FRAME_HDR   *mf;
4764         SCSITaskMgmt_t  *pScsiTm;
4765         int              retval;
4766         unsigned long    timeleft;
4767 
4768         *issue_reset = 0;
4769         mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
4770         if (mf == NULL) {
4771                 retval = -1; /* return failure */
4772                 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "TaskMgmt request: no "
4773                     "msg frames!!\n", ioc->name));
4774                 goto out;
4775         }
4776 
4777         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request: mr = %p, "
4778             "task_type = 0x%02X,\n\t timeout = %ld, fw_channel = %d, "
4779             "fw_id = %d, lun = %lld,\n\t task_context = 0x%x\n", ioc->name, mf,
4780              type, timeout, channel, id, (unsigned long long)lun,
4781              task_context));
4782 
4783         pScsiTm = (SCSITaskMgmt_t *) mf;
4784         memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
4785         pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
4786         pScsiTm->TaskType = type;
4787         pScsiTm->MsgFlags = 0;
4788         pScsiTm->TargetID = id;
4789         pScsiTm->Bus = channel;
4790         pScsiTm->ChainOffset = 0;
4791         pScsiTm->Reserved = 0;
4792         pScsiTm->Reserved1 = 0;
4793         pScsiTm->TaskMsgContext = task_context;
4794         int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
4795 
4796         INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4797         CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
4798         retval = 0;
4799         mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
4800 
4801         /* Now wait for the command to complete */
4802         timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
4803             timeout*HZ);
4804         if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
4805                 retval = -1; /* return failure */
4806                 dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
4807                     "TaskMgmt request: TIMED OUT!(mr=%p)\n", ioc->name, mf));
4808                 mpt_free_msg_frame(ioc, mf);
4809                 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
4810                         goto out;
4811                 *issue_reset = 1;
4812                 goto out;
4813         }
4814 
4815         if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
4816                 retval = -1; /* return failure */
4817                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4818                     "TaskMgmt request: failed with no reply\n", ioc->name));
4819                 goto out;
4820         }
4821 
4822  out:
4823         CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4824         return retval;
4825 }
4826 
4827 /**
4828  *      mptsas_broadcast_primitive_work - Handle broadcast primitives
4829  *      @work: work queue payload containing info describing the event
4830  *
4831  *      this will be handled in workqueue context.
4832  */
4833 static void
4834 mptsas_broadcast_primitive_work(struct fw_event_work *fw_event)
4835 {
4836         MPT_ADAPTER *ioc = fw_event->ioc;
4837         MPT_FRAME_HDR   *mf;
4838         VirtDevice      *vdevice;
4839         int                     ii;
4840         struct scsi_cmnd        *sc;
4841         SCSITaskMgmtReply_t     *pScsiTmReply;
4842         u8                      issue_reset;
4843         int                     task_context;
4844         u8                      channel, id;
4845         int                      lun;
4846         u32                      termination_count;
4847         u32                      query_count;
4848 
4849         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4850             "%s - enter\n", ioc->name, __func__));
4851 
4852         mutex_lock(&ioc->taskmgmt_cmds.mutex);
4853         if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
4854                 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4855                 mptsas_requeue_fw_event(ioc, fw_event, 1000);
4856                 return;
4857         }
4858 
4859         issue_reset = 0;
4860         termination_count = 0;
4861         query_count = 0;
4862         mpt_findImVolumes(ioc);
4863         pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
4864 
4865         for (ii = 0; ii < ioc->req_depth; ii++) {
4866                 if (ioc->fw_events_off)
4867                         goto out;
4868                 sc = mptscsih_get_scsi_lookup(ioc, ii);
4869                 if (!sc)
4870                         continue;
4871                 mf = MPT_INDEX_2_MFPTR(ioc, ii);
4872                 if (!mf)
4873                         continue;
4874                 task_context = mf->u.frame.hwhdr.msgctxu.MsgContext;
4875                 vdevice = sc->device->hostdata;
4876                 if (!vdevice || !vdevice->vtarget)
4877                         continue;
4878                 if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
4879                         continue; /* skip hidden raid components */
4880                 if (vdevice->vtarget->raidVolume)
4881                         continue; /* skip hidden raid components */
4882                 channel = vdevice->vtarget->channel;
4883                 id = vdevice->vtarget->id;
4884                 lun = vdevice->lun;
4885                 if (mptsas_issue_tm(ioc, MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK,
4886                     channel, id, (u64)lun, task_context, 30, &issue_reset))
4887                         goto out;
4888                 query_count++;
4889                 termination_count +=
4890                     le32_to_cpu(pScsiTmReply->TerminationCount);
4891                 if ((pScsiTmReply->IOCStatus == MPI_IOCSTATUS_SUCCESS) &&
4892                     (pScsiTmReply->ResponseCode ==
4893                     MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
4894                     pScsiTmReply->ResponseCode ==
4895                     MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
4896                         continue;
4897                 if (mptsas_issue_tm(ioc,
4898                     MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET,
4899                     channel, id, (u64)lun, 0, 30, &issue_reset))
4900                         goto out;
4901                 termination_count +=
4902                     le32_to_cpu(pScsiTmReply->TerminationCount);
4903         }
4904 
4905  out:
4906         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4907             "%s - exit, query_count = %d termination_count = %d\n",
4908             ioc->name, __func__, query_count, termination_count));
4909 
4910         ioc->broadcast_aen_busy = 0;
4911         mpt_clear_taskmgmt_in_progress_flag(ioc);
4912         mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4913 
4914         if (issue_reset) {
4915                 printk(MYIOC_s_WARN_FMT
4916                        "Issuing Reset from %s!! doorbell=0x%08x\n",
4917                        ioc->name, __func__, mpt_GetIocState(ioc, 0));
4918                 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
4919         }
4920         mptsas_free_fw_event(ioc, fw_event);
4921 }
4922 
4923 /*
4924  * mptsas_send_ir2_event - handle exposing hidden disk when
4925  * an inactive raid volume is added
4926  *
4927  * @ioc: Pointer to MPT_ADAPTER structure
4928  * @ir2_data
4929  *
4930  */
4931 static void
4932 mptsas_send_ir2_event(struct fw_event_work *fw_event)
4933 {
4934         MPT_ADAPTER     *ioc;
4935         struct mptsas_hotplug_event hot_plug_info;
4936         MPI_EVENT_DATA_IR2      *ir2_data;
4937         u8 reasonCode;
4938         RaidPhysDiskPage0_t phys_disk;
4939 
4940         ioc = fw_event->ioc;
4941         ir2_data = (MPI_EVENT_DATA_IR2 *)fw_event->event_data;
4942         reasonCode = ir2_data->ReasonCode;
4943 
4944         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4945             "ReasonCode=%02x\n", ioc->name, __func__, reasonCode));
4946 
4947         memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4948         hot_plug_info.id = ir2_data->TargetID;
4949         hot_plug_info.channel = ir2_data->Bus;
4950         switch (reasonCode) {
4951         case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
4952                 hot_plug_info.event_type = MPTSAS_ADD_INACTIVE_VOLUME;
4953                 break;
4954         case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
4955                 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4956                 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4957                 break;
4958         case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
4959                 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4960                 mpt_raid_phys_disk_pg0(ioc,
4961                     ir2_data->PhysDiskNum, &phys_disk);
4962                 hot_plug_info.id = phys_disk.PhysDiskID;
4963                 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4964                 break;
4965         default:
4966                 mptsas_free_fw_event(ioc, fw_event);
4967                 return;
4968         }
4969         mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4970 }
4971 
4972 static int
4973 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
4974 {
4975         u32 event = le32_to_cpu(reply->Event);
4976         int event_data_sz;
4977         struct fw_event_work *fw_event;
4978         unsigned long delay;
4979 
4980         if (ioc->bus_type != SAS)
4981                 return 0;
4982 
4983         /* events turned off due to host reset or driver unloading */
4984         if (ioc->fw_events_off)
4985                 return 0;
4986 
4987         delay = msecs_to_jiffies(1);
4988         switch (event) {
4989         case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
4990         {
4991                 EVENT_DATA_SAS_BROADCAST_PRIMITIVE *broadcast_event_data =
4992                     (EVENT_DATA_SAS_BROADCAST_PRIMITIVE *)reply->Data;
4993                 if (broadcast_event_data->Primitive !=
4994                     MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
4995                         return 0;
4996                 if (ioc->broadcast_aen_busy)
4997                         return 0;
4998                 ioc->broadcast_aen_busy = 1;
4999                 break;
5000         }
5001         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5002         {
5003                 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data =
5004                     (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data;
5005                 u16     ioc_stat;
5006                 ioc_stat = le16_to_cpu(reply->IOCStatus);
5007 
5008                 if (sas_event_data->ReasonCode ==
5009                     MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) {
5010                         mptsas_target_reset_queue(ioc, sas_event_data);
5011                         return 0;
5012                 }
5013                 if (sas_event_data->ReasonCode ==
5014                         MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
5015                         ioc->device_missing_delay &&
5016                         (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)) {
5017                         VirtTarget *vtarget = NULL;
5018                         u8              id, channel;
5019 
5020                         id = sas_event_data->TargetID;
5021                         channel = sas_event_data->Bus;
5022 
5023                         vtarget = mptsas_find_vtarget(ioc, channel, id);
5024                         if (vtarget) {
5025                                 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5026                                     "LogInfo (0x%x) available for "
5027                                    "INTERNAL_DEVICE_RESET"
5028                                    "fw_id %d fw_channel %d\n", ioc->name,
5029                                    le32_to_cpu(reply->IOCLogInfo),
5030                                    id, channel));
5031                                 if (vtarget->raidVolume) {
5032                                         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5033                                         "Skipping Raid Volume for inDMD\n",
5034                                         ioc->name));
5035                                 } else {
5036                                         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5037                                         "Setting device flag inDMD\n",
5038                                         ioc->name));
5039                                         vtarget->inDMD = 1;
5040                                 }
5041 
5042                         }
5043 
5044                 }
5045 
5046                 break;
5047         }
5048         case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
5049         {
5050                 MpiEventDataSasExpanderStatusChange_t *expander_data =
5051                     (MpiEventDataSasExpanderStatusChange_t *)reply->Data;
5052 
5053                 if (ioc->old_sas_discovery_protocal)
5054                         return 0;
5055 
5056                 if (expander_data->ReasonCode ==
5057                     MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING &&
5058                     ioc->device_missing_delay)
5059                         delay = HZ * ioc->device_missing_delay;
5060                 break;
5061         }
5062         case MPI_EVENT_SAS_DISCOVERY:
5063         {
5064                 u32 discovery_status;
5065                 EventDataSasDiscovery_t *discovery_data =
5066                     (EventDataSasDiscovery_t *)reply->Data;
5067 
5068                 discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus);
5069                 ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0;
5070                 if (ioc->old_sas_discovery_protocal && !discovery_status)
5071                         mptsas_queue_rescan(ioc);
5072                 return 0;
5073         }
5074         case MPI_EVENT_INTEGRATED_RAID:
5075         case MPI_EVENT_PERSISTENT_TABLE_FULL:
5076         case MPI_EVENT_IR2:
5077         case MPI_EVENT_SAS_PHY_LINK_STATUS:
5078         case MPI_EVENT_QUEUE_FULL:
5079                 break;
5080         default:
5081                 return 0;
5082         }
5083 
5084         event_data_sz = ((reply->MsgLength * 4) -
5085             offsetof(EventNotificationReply_t, Data));
5086         fw_event = kzalloc(sizeof(*fw_event) + event_data_sz, GFP_ATOMIC);
5087         if (!fw_event) {
5088                 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name,
5089                  __func__, __LINE__);
5090                 return 0;
5091         }
5092         memcpy(fw_event->event_data, reply->Data, event_data_sz);
5093         fw_event->event = event;
5094         fw_event->ioc = ioc;
5095         mptsas_add_fw_event(ioc, fw_event, delay);
5096         return 0;
5097 }
5098 
5099 /* Delete a volume when no longer listed in ioc pg2
5100  */
5101 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id)
5102 {
5103         struct scsi_device *sdev;
5104         int i;
5105 
5106         sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, id, 0);
5107         if (!sdev)
5108                 return;
5109         if (!ioc->raid_data.pIocPg2)
5110                 goto out;
5111         if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
5112                 goto out;
5113         for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
5114                 if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id)
5115                         goto release_sdev;
5116  out:
5117         printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
5118             "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL, id);
5119         scsi_remove_device(sdev);
5120  release_sdev:
5121         scsi_device_put(sdev);
5122 }
5123 
5124 static int
5125 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5126 {
5127         struct Scsi_Host        *sh;
5128         MPT_SCSI_HOST           *hd;
5129         MPT_ADAPTER             *ioc;
5130         unsigned long            flags;
5131         int                      ii;
5132         int                      numSGE = 0;
5133         int                      scale;
5134         int                      ioc_cap;
5135         int                     error=0;
5136         int                     r;
5137 
5138         r = mpt_attach(pdev,id);
5139         if (r)
5140                 return r;
5141 
5142         ioc = pci_get_drvdata(pdev);
5143         mptsas_fw_event_off(ioc);
5144         ioc->DoneCtx = mptsasDoneCtx;
5145         ioc->TaskCtx = mptsasTaskCtx;
5146         ioc->InternalCtx = mptsasInternalCtx;
5147         ioc->schedule_target_reset = &mptsas_schedule_target_reset;
5148         ioc->schedule_dead_ioc_flush_running_cmds =
5149                                 &mptscsih_flush_running_cmds;
5150         /*  Added sanity check on readiness of the MPT adapter.
5151          */
5152         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
5153                 printk(MYIOC_s_WARN_FMT
5154                   "Skipping because it's not operational!\n",
5155                   ioc->name);
5156                 error = -ENODEV;
5157                 goto out_mptsas_probe;
5158         }
5159 
5160         if (!ioc->active) {
5161                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
5162                   ioc->name);
5163                 error = -ENODEV;
5164                 goto out_mptsas_probe;
5165         }
5166 
5167         /*  Sanity check - ensure at least 1 port is INITIATOR capable
5168          */
5169         ioc_cap = 0;
5170         for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
5171                 if (ioc->pfacts[ii].ProtocolFlags &
5172                                 MPI_PORTFACTS_PROTOCOL_INITIATOR)
5173                         ioc_cap++;
5174         }
5175 
5176         if (!ioc_cap) {
5177                 printk(MYIOC_s_WARN_FMT
5178                         "Skipping ioc=%p because SCSI Initiator mode "
5179                         "is NOT enabled!\n", ioc->name, ioc);
5180                 return 0;
5181         }
5182 
5183         sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
5184         if (!sh) {
5185                 printk(MYIOC_s_WARN_FMT
5186                         "Unable to register controller with SCSI subsystem\n",
5187                         ioc->name);
5188                 error = -1;
5189                 goto out_mptsas_probe;
5190         }
5191 
5192         spin_lock_irqsave(&ioc->FreeQlock, flags);
5193 
5194         /* Attach the SCSI Host to the IOC structure
5195          */
5196         ioc->sh = sh;
5197 
5198         sh->io_port = 0;
5199         sh->n_io_port = 0;
5200         sh->irq = 0;
5201 
5202         /* set 16 byte cdb's */
5203         sh->max_cmd_len = 16;
5204         sh->can_queue = min_t(int, ioc->req_depth - 10, sh->can_queue);
5205         sh->max_id = -1;
5206         sh->max_lun = max_lun;
5207         sh->transportt = mptsas_transport_template;
5208 
5209         /* Required entry.
5210          */
5211         sh->unique_id = ioc->id;
5212 
5213         INIT_LIST_HEAD(&ioc->sas_topology);
5214         mutex_init(&ioc->sas_topology_mutex);
5215         mutex_init(&ioc->sas_discovery_mutex);
5216         mutex_init(&ioc->sas_mgmt.mutex);
5217         init_completion(&ioc->sas_mgmt.done);
5218 
5219         /* Verify that we won't exceed the maximum
5220          * number of chain buffers
5221          * We can optimize:  ZZ = req_sz/sizeof(SGE)
5222          * For 32bit SGE's:
5223          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
5224          *               + (req_sz - 64)/sizeof(SGE)
5225          * A slightly different algorithm is required for
5226          * 64bit SGEs.
5227          */
5228         scale = ioc->req_sz/ioc->SGE_size;
5229         if (ioc->sg_addr_size == sizeof(u64)) {
5230                 numSGE = (scale - 1) *
5231                   (ioc->facts.MaxChainDepth-1) + scale +
5232                   (ioc->req_sz - 60) / ioc->SGE_size;
5233         } else {
5234                 numSGE = 1 + (scale - 1) *
5235                   (ioc->facts.MaxChainDepth-1) + scale +
5236                   (ioc->req_sz - 64) / ioc->SGE_size;
5237         }
5238 
5239         if (numSGE < sh->sg_tablesize) {
5240                 /* Reset this value */
5241                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5242                   "Resetting sg_tablesize to %d from %d\n",
5243                   ioc->name, numSGE, sh->sg_tablesize));
5244                 sh->sg_tablesize = numSGE;
5245         }
5246 
5247         if (mpt_loadtime_max_sectors) {
5248                 if (mpt_loadtime_max_sectors < 64 ||
5249                         mpt_loadtime_max_sectors > 8192) {
5250                         printk(MYIOC_s_INFO_FMT "Invalid value passed for"
5251                                 "mpt_loadtime_max_sectors %d."
5252                                 "Range from 64 to 8192\n", ioc->name,
5253                                 mpt_loadtime_max_sectors);
5254                 }
5255                 mpt_loadtime_max_sectors &=  0xFFFFFFFE;
5256                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5257                         "Resetting max sector to %d from %d\n",
5258                   ioc->name, mpt_loadtime_max_sectors, sh->max_sectors));
5259                 sh->max_sectors = mpt_loadtime_max_sectors;
5260         }
5261 
5262         hd = shost_priv(sh);
5263         hd->ioc = ioc;
5264 
5265         /* SCSI needs scsi_cmnd lookup table!
5266          * (with size equal to req_depth*PtrSz!)
5267          */
5268         ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
5269         if (!ioc->ScsiLookup) {
5270                 error = -ENOMEM;
5271                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5272                 goto out_mptsas_probe;
5273         }
5274         spin_lock_init(&ioc->scsi_lookup_lock);
5275 
5276         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
5277                  ioc->name, ioc->ScsiLookup));
5278 
5279         ioc->sas_data.ptClear = mpt_pt_clear;
5280 
5281         hd->last_queue_full = 0;
5282         INIT_LIST_HEAD(&hd->target_reset_list);
5283         INIT_LIST_HEAD(&ioc->sas_device_info_list);
5284         mutex_init(&ioc->sas_device_info_mutex);
5285 
5286         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5287 
5288         if (ioc->sas_data.ptClear==1) {
5289                 mptbase_sas_persist_operation(
5290                     ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
5291         }
5292 
5293         error = scsi_add_host(sh, &ioc->pcidev->dev);
5294         if (error) {
5295                 dprintk(ioc, printk(MYIOC_s_ERR_FMT
5296                   "scsi_add_host failed\n", ioc->name));
5297                 goto out_mptsas_probe;
5298         }
5299 
5300         /* older firmware doesn't support expander events */
5301         if ((ioc->facts.HeaderVersion >> 8) < 0xE)
5302                 ioc->old_sas_discovery_protocal = 1;
5303         mptsas_scan_sas_topology(ioc);
5304         mptsas_fw_event_on(ioc);
5305         return 0;
5306 
5307  out_mptsas_probe:
5308 
5309         mptscsih_remove(pdev);
5310         return error;
5311 }
5312 
5313 static void
5314 mptsas_shutdown(struct pci_dev *pdev)
5315 {
5316         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
5317 
5318         mptsas_fw_event_off(ioc);
5319         mptsas_cleanup_fw_event_q(ioc);
5320 }
5321 
5322 static void mptsas_remove(struct pci_dev *pdev)
5323 {
5324         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
5325         struct mptsas_portinfo *p, *n;
5326         int i;
5327 
5328         if (!ioc->sh) {
5329                 printk(MYIOC_s_INFO_FMT "IOC is in Target mode\n", ioc->name);
5330                 mpt_detach(pdev);
5331                 return;
5332         }
5333 
5334         mptsas_shutdown(pdev);
5335 
5336         mptsas_del_device_components(ioc);
5337 
5338         ioc->sas_discovery_ignore_events = 1;
5339         sas_remove_host(ioc->sh);
5340 
5341         mutex_lock(&ioc->sas_topology_mutex);
5342         list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
5343                 list_del(&p->list);
5344                 for (i = 0 ; i < p->num_phys ; i++)
5345                         mptsas_port_delete(ioc, p->phy_info[i].port_details);
5346 
5347                 kfree(p->phy_info);
5348                 kfree(p);
5349         }
5350         mutex_unlock(&ioc->sas_topology_mutex);
5351         ioc->hba_port_info = NULL;
5352         mptscsih_remove(pdev);
5353 }
5354 
5355 static struct pci_device_id mptsas_pci_table[] = {
5356         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
5357                 PCI_ANY_ID, PCI_ANY_ID },
5358         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
5359                 PCI_ANY_ID, PCI_ANY_ID },
5360         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
5361                 PCI_ANY_ID, PCI_ANY_ID },
5362         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
5363                 PCI_ANY_ID, PCI_ANY_ID },
5364         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
5365                 PCI_ANY_ID, PCI_ANY_ID },
5366         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068_820XELP,
5367                 PCI_ANY_ID, PCI_ANY_ID },
5368         {0}     /* Terminating entry */
5369 };
5370 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
5371 
5372 
5373 static struct pci_driver mptsas_driver = {
5374         .name           = "mptsas",
5375         .id_table       = mptsas_pci_table,
5376         .probe          = mptsas_probe,
5377         .remove         = mptsas_remove,
5378         .shutdown       = mptsas_shutdown,
5379 #ifdef CONFIG_PM
5380         .suspend        = mptscsih_suspend,
5381         .resume         = mptscsih_resume,
5382 #endif
5383 };
5384 
5385 static int __init
5386 mptsas_init(void)
5387 {
5388         int error;
5389 
5390         show_mptmod_ver(my_NAME, my_VERSION);
5391 
5392         mptsas_transport_template =
5393             sas_attach_transport(&mptsas_transport_functions);
5394         if (!mptsas_transport_template)
5395                 return -ENODEV;
5396 
5397         mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER,
5398             "mptscsih_io_done");
5399         mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER,
5400             "mptscsih_taskmgmt_complete");
5401         mptsasInternalCtx =
5402                 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER,
5403                     "mptscsih_scandv_complete");
5404         mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER,
5405             "mptsas_mgmt_done");
5406         mptsasDeviceResetCtx =
5407                 mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER,
5408                     "mptsas_taskmgmt_complete");
5409 
5410         mpt_event_register(mptsasDoneCtx, mptsas_event_process);
5411         mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
5412 
5413         error = pci_register_driver(&mptsas_driver);
5414         if (error)
5415                 sas_release_transport(mptsas_transport_template);
5416 
5417         return error;
5418 }
5419 
5420 static void __exit
5421 mptsas_exit(void)
5422 {
5423         pci_unregister_driver(&mptsas_driver);
5424         sas_release_transport(mptsas_transport_template);
5425 
5426         mpt_reset_deregister(mptsasDoneCtx);
5427         mpt_event_deregister(mptsasDoneCtx);
5428 
5429         mpt_deregister(mptsasMgmtCtx);
5430         mpt_deregister(mptsasInternalCtx);
5431         mpt_deregister(mptsasTaskCtx);
5432         mpt_deregister(mptsasDoneCtx);
5433         mpt_deregister(mptsasDeviceResetCtx);
5434 }
5435 
5436 module_init(mptsas_init);
5437 module_exit(mptsas_exit);

/* [<][>][^][v][top][bottom][index][help] */