Version:  2.0.40 2.2.26 2.4.37 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15

Linux/drivers/message/fusion/mptsas.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us