Version:  2.0.40 2.2.26 2.4.37 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 3.16

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

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