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