Version:  2.0.40 2.2.26 2.4.37 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2

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

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