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