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