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