Version:  2.0.40 2.2.26 2.4.37 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18

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

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