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