Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[linux-2.6] / drivers / message / fusion / mptsas.c
1 /*
2  *  linux/drivers/message/fusion/mptsas.c
3  *      For use with LSI Logic PCI chip/adapter(s)
4  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5  *
6  *  Copyright (c) 1999-2007 LSI Logic Corporation
7  *  (mailto:DL-MPTFusionLinux@lsi.com)
8  *  Copyright (c) 2005-2007 Dell
9  */
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11 /*
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; version 2 of the License.
15
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20
21     NO WARRANTY
22     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26     solely responsible for determining the appropriateness of using and
27     distributing the Program and assumes all risks associated with its
28     exercise of rights under this Agreement, including but not limited to
29     the risks and costs of program errors, damage to or loss of data,
30     programs or equipment, and unavailability or interruption of operations.
31
32     DISCLAIMER OF LIABILITY
33     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40
41     You should have received a copy of the GNU General Public License
42     along with this program; if not, write to the Free Software
43     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
44 */
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46
47 #include <linux/module.h>
48 #include <linux/kernel.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/jiffies.h>
52 #include <linux/workqueue.h>
53 #include <linux/delay.h>        /* for mdelay */
54
55 #include <scsi/scsi.h>
56 #include <scsi/scsi_cmnd.h>
57 #include <scsi/scsi_device.h>
58 #include <scsi/scsi_host.h>
59 #include <scsi/scsi_transport_sas.h>
60 #include <scsi/scsi_dbg.h>
61
62 #include "mptbase.h"
63 #include "mptscsih.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 int      mptsasDoneCtx = -1;
93 static int      mptsasTaskCtx = -1;
94 static int      mptsasInternalCtx = -1; /* Used only for internal commands */
95 static int      mptsasMgmtCtx = -1;
96
97 static void mptsas_hotplug_work(struct work_struct *work);
98
99 struct mptsas_target_reset_event {
100         struct list_head        list;
101         EVENT_DATA_SAS_DEVICE_STATUS_CHANGE sas_event_data;
102         u8      target_reset_issued;
103 };
104
105 enum mptsas_hotplug_action {
106         MPTSAS_ADD_DEVICE,
107         MPTSAS_DEL_DEVICE,
108         MPTSAS_ADD_RAID,
109         MPTSAS_DEL_RAID,
110         MPTSAS_ADD_INACTIVE_VOLUME,
111         MPTSAS_IGNORE_EVENT,
112 };
113
114 struct mptsas_hotplug_event {
115         struct work_struct      work;
116         MPT_ADAPTER             *ioc;
117         enum mptsas_hotplug_action event_type;
118         u64                     sas_address;
119         u8                      channel;
120         u8                      id;
121         u32                     device_info;
122         u16                     handle;
123         u16                     parent_handle;
124         u8                      phy_id;
125         u8                      phys_disk_num_valid;    /* hrc (hidden raid component) */
126         u8                      phys_disk_num;          /* hrc - unique index*/
127         u8                      hidden_raid_component;  /* hrc - don't expose*/
128 };
129
130 struct mptsas_discovery_event {
131         struct work_struct      work;
132         MPT_ADAPTER             *ioc;
133 };
134
135 /*
136  * SAS topology structures
137  *
138  * The MPT Fusion firmware interface spreads information about the
139  * SAS topology over many manufacture pages, thus we need some data
140  * structure to collect it and process it for the SAS transport class.
141  */
142
143 struct mptsas_devinfo {
144         u16     handle;         /* unique id to address this device */
145         u16     handle_parent;  /* unique id to address parent device */
146         u16     handle_enclosure; /* enclosure identifier of the enclosure */
147         u16     slot;           /* physical slot in enclosure */
148         u8      phy_id;         /* phy number of parent device */
149         u8      port_id;        /* sas physical port this device
150                                    is assoc'd with */
151         u8      id;             /* logical target id of this device */
152         u32     phys_disk_num;  /* phys disk id, for csmi-ioctls */
153         u8      channel;        /* logical bus number of this device */
154         u64     sas_address;    /* WWN of this device,
155                                    SATA is assigned by HBA,expander */
156         u32     device_info;    /* bitfield detailed info about this device */
157 };
158
159 /*
160  * Specific details on ports, wide/narrow
161  */
162 struct mptsas_portinfo_details{
163         u16     num_phys;       /* number of phys belong to this port */
164         u64     phy_bitmask;    /* TODO, extend support for 255 phys */
165         struct sas_rphy *rphy;  /* transport layer rphy object */
166         struct sas_port *port;  /* transport layer port object */
167         struct scsi_target *starget;
168         struct mptsas_portinfo *port_info;
169 };
170
171 struct mptsas_phyinfo {
172         u16     handle;                 /* unique id to address this */
173         u8      phy_id;                 /* phy index */
174         u8      port_id;                /* firmware port identifier */
175         u8      negotiated_link_rate;   /* nego'd link rate for this phy */
176         u8      hw_link_rate;           /* hardware max/min phys link rate */
177         u8      programmed_link_rate;   /* programmed max/min phy link rate */
178         u8      sas_port_add_phy;       /* flag to request sas_port_add_phy*/
179         struct mptsas_devinfo identify; /* point to phy device info */
180         struct mptsas_devinfo attached; /* point to attached device info */
181         struct sas_phy *phy;            /* transport layer phy object */
182         struct mptsas_portinfo *portinfo;
183         struct mptsas_portinfo_details * port_details;
184 };
185
186 struct mptsas_portinfo {
187         struct list_head list;
188         u16             num_phys;       /* number of phys */
189         struct mptsas_phyinfo *phy_info;
190 };
191
192 struct mptsas_enclosure {
193         u64     enclosure_logical_id;   /* The WWN for the enclosure */
194         u16     enclosure_handle;       /* unique id to address this */
195         u16     flags;                  /* details enclosure management */
196         u16     num_slot;               /* num slots */
197         u16     start_slot;             /* first slot */
198         u8      start_id;               /* starting logical target id */
199         u8      start_channel;          /* starting logical channel id */
200         u8      sep_id;                 /* SEP device logical target id */
201         u8      sep_channel;            /* SEP channel logical channel id */
202 };
203
204 static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
205                                         MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
206 {
207         dsasprintk(ioc, printk(KERN_DEBUG "---- IO UNIT PAGE 0 ------------\n"));
208         dsasprintk(ioc, printk(KERN_DEBUG "Handle=0x%X\n",
209                 le16_to_cpu(phy_data->AttachedDeviceHandle)));
210         dsasprintk(ioc, printk(KERN_DEBUG "Controller Handle=0x%X\n",
211                 le16_to_cpu(phy_data->ControllerDevHandle)));
212         dsasprintk(ioc, printk(KERN_DEBUG "Port=0x%X\n", phy_data->Port));
213         dsasprintk(ioc, printk(KERN_DEBUG "Port Flags=0x%X\n", phy_data->PortFlags));
214         dsasprintk(ioc, printk(KERN_DEBUG "PHY Flags=0x%X\n", phy_data->PhyFlags));
215         dsasprintk(ioc, printk(KERN_DEBUG "Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate));
216         dsasprintk(ioc, printk(KERN_DEBUG "Controller PHY Device Info=0x%X\n",
217                 le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
218         dsasprintk(ioc, printk(KERN_DEBUG "DiscoveryStatus=0x%X\n\n",
219                 le32_to_cpu(phy_data->DiscoveryStatus)));
220 }
221
222 static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
223 {
224         __le64 sas_address;
225
226         memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
227
228         dsasprintk(ioc, printk(KERN_DEBUG "---- SAS PHY PAGE 0 ------------\n"));
229         dsasprintk(ioc, printk(KERN_DEBUG "Attached Device Handle=0x%X\n",
230                         le16_to_cpu(pg0->AttachedDevHandle)));
231         dsasprintk(ioc, printk(KERN_DEBUG "SAS Address=0x%llX\n",
232                         (unsigned long long)le64_to_cpu(sas_address)));
233         dsasprintk(ioc, printk(KERN_DEBUG "Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier));
234         dsasprintk(ioc, printk(KERN_DEBUG "Attached Device Info=0x%X\n",
235                         le32_to_cpu(pg0->AttachedDeviceInfo)));
236         dsasprintk(ioc, printk(KERN_DEBUG "Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate));
237         dsasprintk(ioc, printk(KERN_DEBUG "Change Count=0x%X\n", pg0->ChangeCount));
238         dsasprintk(ioc, printk(KERN_DEBUG "PHY Info=0x%X\n\n", le32_to_cpu(pg0->PhyInfo)));
239 }
240
241 static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
242 {
243         dsasprintk(ioc, printk(KERN_DEBUG "---- SAS PHY PAGE 1 ------------\n"));
244         dsasprintk(ioc, printk(KERN_DEBUG "Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount));
245         dsasprintk(ioc, printk(KERN_DEBUG "Running Disparity Error Count=0x%x\n",
246                         pg1->RunningDisparityErrorCount));
247         dsasprintk(ioc, printk(KERN_DEBUG "Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount));
248         dsasprintk(ioc, printk(KERN_DEBUG "PHY Reset Problem Count=0x%x\n\n", pg1->PhyResetProblemCount));
249 }
250
251 static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
252 {
253         __le64 sas_address;
254
255         memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
256
257         dsasprintk(ioc, printk(KERN_DEBUG "---- SAS DEVICE PAGE 0 ---------\n"));
258         dsasprintk(ioc, printk(KERN_DEBUG "Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle)));
259         dsasprintk(ioc, printk(KERN_DEBUG "Parent Handle=0x%X\n" ,le16_to_cpu(pg0->ParentDevHandle)));
260         dsasprintk(ioc, printk(KERN_DEBUG "Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle)));
261         dsasprintk(ioc, printk(KERN_DEBUG "Slot=0x%X\n", le16_to_cpu(pg0->Slot)));
262         dsasprintk(ioc, printk(KERN_DEBUG "SAS Address=0x%llX\n", (unsigned long long)
263             le64_to_cpu(sas_address)));
264         dsasprintk(ioc, printk(KERN_DEBUG "Target ID=0x%X\n", pg0->TargetID));
265         dsasprintk(ioc, printk(KERN_DEBUG "Bus=0x%X\n", pg0->Bus));
266         /* The PhyNum field specifies the PHY number of the parent
267          * device this device is linked to
268          */
269         dsasprintk(ioc, printk(KERN_DEBUG "Parent Phy Num=0x%X\n", pg0->PhyNum));
270         dsasprintk(ioc, printk(KERN_DEBUG "Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus)));
271         dsasprintk(ioc, printk(KERN_DEBUG "Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo)));
272         dsasprintk(ioc, printk(KERN_DEBUG "Flags=0x%X\n", le16_to_cpu(pg0->Flags)));
273         dsasprintk(ioc, printk(KERN_DEBUG "Physical Port=0x%X\n\n", pg0->PhysicalPort));
274 }
275
276 static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
277 {
278         dsasprintk(ioc, printk(KERN_DEBUG "---- SAS EXPANDER PAGE 1 ------------\n"));
279         dsasprintk(ioc, printk(KERN_DEBUG "Physical Port=0x%X\n", pg1->PhysicalPort));
280         dsasprintk(ioc, printk(KERN_DEBUG "PHY Identifier=0x%X\n", pg1->PhyIdentifier));
281         dsasprintk(ioc, printk(KERN_DEBUG "Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate));
282         dsasprintk(ioc, printk(KERN_DEBUG "Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate));
283         dsasprintk(ioc, printk(KERN_DEBUG "Hardware Link Rate=0x%X\n", pg1->HwLinkRate));
284         dsasprintk(ioc, printk(KERN_DEBUG "Owner Device Handle=0x%X\n",
285                         le16_to_cpu(pg1->OwnerDevHandle)));
286         dsasprintk(ioc, printk(KERN_DEBUG "Attached Device Handle=0x%X\n\n",
287                         le16_to_cpu(pg1->AttachedDevHandle)));
288 }
289
290 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
291 {
292         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
293         return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
294 }
295
296 static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
297 {
298         struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
299         return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
300 }
301
302 /*
303  * mptsas_find_portinfo_by_handle
304  *
305  * This function should be called with the sas_topology_mutex already held
306  */
307 static struct mptsas_portinfo *
308 mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
309 {
310         struct mptsas_portinfo *port_info, *rc=NULL;
311         int i;
312
313         list_for_each_entry(port_info, &ioc->sas_topology, list)
314                 for (i = 0; i < port_info->num_phys; i++)
315                         if (port_info->phy_info[i].identify.handle == handle) {
316                                 rc = port_info;
317                                 goto out;
318                         }
319  out:
320         return rc;
321 }
322
323 /*
324  * Returns true if there is a scsi end device
325  */
326 static inline int
327 mptsas_is_end_device(struct mptsas_devinfo * attached)
328 {
329         if ((attached->sas_address) &&
330             (attached->device_info &
331             MPI_SAS_DEVICE_INFO_END_DEVICE) &&
332             ((attached->device_info &
333             MPI_SAS_DEVICE_INFO_SSP_TARGET) |
334             (attached->device_info &
335             MPI_SAS_DEVICE_INFO_STP_TARGET) |
336             (attached->device_info &
337             MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
338                 return 1;
339         else
340                 return 0;
341 }
342
343 /* no mutex */
344 static void
345 mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
346 {
347         struct mptsas_portinfo *port_info;
348         struct mptsas_phyinfo *phy_info;
349         u8      i;
350
351         if (!port_details)
352                 return;
353
354         port_info = port_details->port_info;
355         phy_info = port_info->phy_info;
356
357         dsaswideprintk(ioc, printk(KERN_DEBUG "%s: [%p]: num_phys=%02d "
358             "bitmask=0x%016llX\n", __FUNCTION__, port_details,
359             port_details->num_phys, (unsigned long long)
360             port_details->phy_bitmask));
361
362         for (i = 0; i < port_info->num_phys; i++, phy_info++) {
363                 if(phy_info->port_details != port_details)
364                         continue;
365                 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
366                 phy_info->port_details = NULL;
367         }
368         kfree(port_details);
369 }
370
371 static inline struct sas_rphy *
372 mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
373 {
374         if (phy_info->port_details)
375                 return phy_info->port_details->rphy;
376         else
377                 return NULL;
378 }
379
380 static inline void
381 mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
382 {
383         if (phy_info->port_details) {
384                 phy_info->port_details->rphy = rphy;
385                 dsaswideprintk(ioc, printk(KERN_DEBUG "sas_rphy_add: rphy=%p\n", rphy));
386         }
387
388         if (rphy) {
389                 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
390                     &rphy->dev, "add:"));
391                 dsaswideprintk(ioc, printk(KERN_DEBUG "rphy=%p release=%p\n",
392                         rphy, rphy->dev.release));
393         }
394 }
395
396 static inline struct sas_port *
397 mptsas_get_port(struct mptsas_phyinfo *phy_info)
398 {
399         if (phy_info->port_details)
400                 return phy_info->port_details->port;
401         else
402                 return NULL;
403 }
404
405 static inline void
406 mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_port *port)
407 {
408         if (phy_info->port_details)
409                 phy_info->port_details->port = port;
410
411         if (port) {
412                 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
413                     &port->dev, "add:"));
414                 dsaswideprintk(ioc, printk(KERN_DEBUG "port=%p release=%p\n",
415                         port, port->dev.release));
416         }
417 }
418
419 static inline struct scsi_target *
420 mptsas_get_starget(struct mptsas_phyinfo *phy_info)
421 {
422         if (phy_info->port_details)
423                 return phy_info->port_details->starget;
424         else
425                 return NULL;
426 }
427
428 static inline void
429 mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
430 starget)
431 {
432         if (phy_info->port_details)
433                 phy_info->port_details->starget = starget;
434 }
435
436
437 /*
438  * mptsas_setup_wide_ports
439  *
440  * Updates for new and existing narrow/wide port configuration
441  * in the sas_topology
442  */
443 static void
444 mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
445 {
446         struct mptsas_portinfo_details * port_details;
447         struct mptsas_phyinfo *phy_info, *phy_info_cmp;
448         u64     sas_address;
449         int     i, j;
450
451         mutex_lock(&ioc->sas_topology_mutex);
452
453         phy_info = port_info->phy_info;
454         for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
455                 if (phy_info->attached.handle)
456                         continue;
457                 port_details = phy_info->port_details;
458                 if (!port_details)
459                         continue;
460                 if (port_details->num_phys < 2)
461                         continue;
462                 /*
463                  * Removing a phy from a port, letting the last
464                  * phy be removed by firmware events.
465                  */
466                 dsaswideprintk(ioc, printk(KERN_DEBUG
467                         "%s: [%p]: deleting phy = %d\n",
468                         __FUNCTION__, port_details, i));
469                 port_details->num_phys--;
470                 port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
471                 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
472                 sas_port_delete_phy(port_details->port, phy_info->phy);
473                 phy_info->port_details = NULL;
474         }
475
476         /*
477          * Populate and refresh the tree
478          */
479         phy_info = port_info->phy_info;
480         for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
481                 sas_address = phy_info->attached.sas_address;
482                 dsaswideprintk(ioc, printk(KERN_DEBUG "phy_id=%d sas_address=0x%018llX\n",
483                     i, (unsigned long long)sas_address));
484                 if (!sas_address)
485                         continue;
486                 port_details = phy_info->port_details;
487                 /*
488                  * Forming a port
489                  */
490                 if (!port_details) {
491                         port_details = kzalloc(sizeof(*port_details),
492                                 GFP_KERNEL);
493                         if (!port_details)
494                                 goto out;
495                         port_details->num_phys = 1;
496                         port_details->port_info = port_info;
497                         if (phy_info->phy_id < 64 )
498                                 port_details->phy_bitmask |=
499                                     (1 << phy_info->phy_id);
500                         phy_info->sas_port_add_phy=1;
501                         dsaswideprintk(ioc, printk(KERN_DEBUG "\t\tForming port\n\t\t"
502                             "phy_id=%d sas_address=0x%018llX\n",
503                             i, (unsigned long long)sas_address));
504                         phy_info->port_details = port_details;
505                 }
506
507                 if (i == port_info->num_phys - 1)
508                         continue;
509                 phy_info_cmp = &port_info->phy_info[i + 1];
510                 for (j = i + 1 ; j < port_info->num_phys ; j++,
511                     phy_info_cmp++) {
512                         if (!phy_info_cmp->attached.sas_address)
513                                 continue;
514                         if (sas_address != phy_info_cmp->attached.sas_address)
515                                 continue;
516                         if (phy_info_cmp->port_details == port_details )
517                                 continue;
518                         dsaswideprintk(ioc, printk(KERN_DEBUG
519                             "\t\tphy_id=%d sas_address=0x%018llX\n",
520                             j, (unsigned long long)
521                             phy_info_cmp->attached.sas_address));
522                         if (phy_info_cmp->port_details) {
523                                 port_details->rphy =
524                                     mptsas_get_rphy(phy_info_cmp);
525                                 port_details->port =
526                                     mptsas_get_port(phy_info_cmp);
527                                 port_details->starget =
528                                     mptsas_get_starget(phy_info_cmp);
529                                 port_details->num_phys =
530                                         phy_info_cmp->port_details->num_phys;
531                                 if (!phy_info_cmp->port_details->num_phys)
532                                         kfree(phy_info_cmp->port_details);
533                         } else
534                                 phy_info_cmp->sas_port_add_phy=1;
535                         /*
536                          * Adding a phy to a port
537                          */
538                         phy_info_cmp->port_details = port_details;
539                         if (phy_info_cmp->phy_id < 64 )
540                                 port_details->phy_bitmask |=
541                                 (1 << phy_info_cmp->phy_id);
542                         port_details->num_phys++;
543                 }
544         }
545
546  out:
547
548         for (i = 0; i < port_info->num_phys; i++) {
549                 port_details = port_info->phy_info[i].port_details;
550                 if (!port_details)
551                         continue;
552                 dsaswideprintk(ioc, printk(KERN_DEBUG
553                     "%s: [%p]: phy_id=%02d num_phys=%02d "
554                     "bitmask=0x%016llX\n", __FUNCTION__,
555                     port_details, i, port_details->num_phys,
556                     (unsigned long long)port_details->phy_bitmask));
557                 dsaswideprintk(ioc, printk(KERN_DEBUG"\t\tport = %p rphy=%p\n",
558                         port_details->port, port_details->rphy));
559         }
560         dsaswideprintk(ioc, printk(KERN_DEBUG"\n"));
561         mutex_unlock(&ioc->sas_topology_mutex);
562 }
563
564 /**
565  * csmisas_find_vtarget
566  *
567  * @ioc
568  * @volume_id
569  * @volume_bus
570  *
571  **/
572 static VirtTarget *
573 mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
574 {
575         struct scsi_device              *sdev;
576         VirtDevice                      *vdev;
577         VirtTarget                      *vtarget = NULL;
578
579         shost_for_each_device(sdev, ioc->sh) {
580                 if ((vdev = sdev->hostdata) == NULL)
581                         continue;
582                 if (vdev->vtarget->id == id &&
583                     vdev->vtarget->channel == channel)
584                         vtarget = vdev->vtarget;
585         }
586         return vtarget;
587 }
588
589 /**
590  * mptsas_target_reset
591  *
592  * Issues TARGET_RESET to end device using handshaking method
593  *
594  * @ioc
595  * @channel
596  * @id
597  *
598  * Returns (1) success
599  *         (0) failure
600  *
601  **/
602 static int
603 mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
604 {
605         MPT_FRAME_HDR   *mf;
606         SCSITaskMgmt_t  *pScsiTm;
607
608         if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
609                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames @%d!!\n",
610                     ioc->name,__FUNCTION__, __LINE__));
611                 return 0;
612         }
613
614         /* Format the Request
615          */
616         pScsiTm = (SCSITaskMgmt_t *) mf;
617         memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
618         pScsiTm->TargetID = id;
619         pScsiTm->Bus = channel;
620         pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
621         pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
622         pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
623
624         DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
625
626         if (mpt_send_handshake_request(ioc->TaskCtx, ioc,
627             sizeof(SCSITaskMgmt_t), (u32 *)mf, NO_SLEEP)) {
628                 mpt_free_msg_frame(ioc, mf);
629                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, tm handshake failed @%d!!\n",
630                     ioc->name,__FUNCTION__, __LINE__));
631                 return 0;
632         }
633
634         return 1;
635 }
636
637 /**
638  * mptsas_target_reset_queue
639  *
640  * Receive request for TARGET_RESET after recieving an firmware
641  * event NOT_RESPONDING_EVENT, then put command in link list
642  * and queue if task_queue already in use.
643  *
644  * @ioc
645  * @sas_event_data
646  *
647  **/
648 static void
649 mptsas_target_reset_queue(MPT_ADAPTER *ioc,
650     EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
651 {
652         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
653         VirtTarget *vtarget = NULL;
654         struct mptsas_target_reset_event *target_reset_list;
655         u8              id, channel;
656
657         id = sas_event_data->TargetID;
658         channel = sas_event_data->Bus;
659
660         if (!(vtarget = mptsas_find_vtarget(ioc, channel, id)))
661                 return;
662
663         vtarget->deleted = 1; /* block IO */
664
665         target_reset_list = kzalloc(sizeof(*target_reset_list),
666             GFP_ATOMIC);
667         if (!target_reset_list) {
668                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",
669                     ioc->name,__FUNCTION__, __LINE__));
670                 return;
671         }
672
673         memcpy(&target_reset_list->sas_event_data, sas_event_data,
674                 sizeof(*sas_event_data));
675         list_add_tail(&target_reset_list->list, &hd->target_reset_list);
676
677         if (hd->resetPending)
678                 return;
679
680         if (mptsas_target_reset(ioc, channel, id)) {
681                 target_reset_list->target_reset_issued = 1;
682                 hd->resetPending = 1;
683         }
684 }
685
686 /**
687  * mptsas_dev_reset_complete
688  *
689  * Completion for TARGET_RESET after NOT_RESPONDING_EVENT,
690  * enable work queue to finish off removing device from upper layers.
691  * then send next TARGET_RESET in the queue.
692  *
693  * @ioc
694  *
695  **/
696 static void
697 mptsas_dev_reset_complete(MPT_ADAPTER *ioc)
698 {
699         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
700         struct list_head *head = &hd->target_reset_list;
701         struct mptsas_target_reset_event *target_reset_list;
702         struct mptsas_hotplug_event *ev;
703         EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
704         u8              id, channel;
705         __le64          sas_address;
706
707         if (list_empty(head))
708                 return;
709
710         target_reset_list = list_entry(head->next, struct mptsas_target_reset_event, list);
711
712         sas_event_data = &target_reset_list->sas_event_data;
713         id = sas_event_data->TargetID;
714         channel = sas_event_data->Bus;
715         hd->resetPending = 0;
716
717         /*
718          * retry target reset
719          */
720         if (!target_reset_list->target_reset_issued) {
721                 if (mptsas_target_reset(ioc, channel, id)) {
722                         target_reset_list->target_reset_issued = 1;
723                         hd->resetPending = 1;
724                 }
725                 return;
726         }
727
728         /*
729          * enable work queue to remove device from upper layers
730          */
731         list_del(&target_reset_list->list);
732
733         ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
734         if (!ev) {
735                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",
736                     ioc->name,__FUNCTION__, __LINE__));
737                 return;
738         }
739
740         INIT_WORK(&ev->work, mptsas_hotplug_work);
741         ev->ioc = ioc;
742         ev->handle = le16_to_cpu(sas_event_data->DevHandle);
743         ev->parent_handle =
744             le16_to_cpu(sas_event_data->ParentDevHandle);
745         ev->channel = channel;
746         ev->id =id;
747         ev->phy_id = sas_event_data->PhyNum;
748         memcpy(&sas_address, &sas_event_data->SASAddress,
749             sizeof(__le64));
750         ev->sas_address = le64_to_cpu(sas_address);
751         ev->device_info = le32_to_cpu(sas_event_data->DeviceInfo);
752         ev->event_type = MPTSAS_DEL_DEVICE;
753         schedule_work(&ev->work);
754         kfree(target_reset_list);
755
756         /*
757          * issue target reset to next device in the queue
758          */
759
760         head = &hd->target_reset_list;
761         if (list_empty(head))
762                 return;
763
764         target_reset_list = list_entry(head->next, struct mptsas_target_reset_event,
765             list);
766
767         sas_event_data = &target_reset_list->sas_event_data;
768         id = sas_event_data->TargetID;
769         channel = sas_event_data->Bus;
770
771         if (mptsas_target_reset(ioc, channel, id)) {
772                 target_reset_list->target_reset_issued = 1;
773                 hd->resetPending = 1;
774         }
775 }
776
777 /**
778  * mptsas_taskmgmt_complete
779  *
780  * @ioc
781  * @mf
782  * @mr
783  *
784  **/
785 static int
786 mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
787 {
788         mptsas_dev_reset_complete(ioc);
789         return mptscsih_taskmgmt_complete(ioc, mf, mr);
790 }
791
792 /**
793  * mptscsih_ioc_reset
794  *
795  * @ioc
796  * @reset_phase
797  *
798  **/
799 static int
800 mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
801 {
802         MPT_SCSI_HOST   *hd;
803         struct mptsas_target_reset_event *target_reset_list, *n;
804         int rc;
805
806         rc = mptscsih_ioc_reset(ioc, reset_phase);
807
808         if (ioc->bus_type != SAS)
809                 goto out;
810
811         if (reset_phase != MPT_IOC_POST_RESET)
812                 goto out;
813
814         if (!ioc->sh || !ioc->sh->hostdata)
815                 goto out;
816         hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
817         if (!hd->ioc)
818                 goto out;
819
820         if (list_empty(&hd->target_reset_list))
821                 goto out;
822
823         /* flush the target_reset_list */
824         list_for_each_entry_safe(target_reset_list, n,
825             &hd->target_reset_list, list) {
826                 list_del(&target_reset_list->list);
827                 kfree(target_reset_list);
828         }
829
830  out:
831         return rc;
832 }
833
834 static int
835 mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
836                 u32 form, u32 form_specific)
837 {
838         ConfigExtendedPageHeader_t hdr;
839         CONFIGPARMS cfg;
840         SasEnclosurePage0_t *buffer;
841         dma_addr_t dma_handle;
842         int error;
843         __le64 le_identifier;
844
845         memset(&hdr, 0, sizeof(hdr));
846         hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
847         hdr.PageNumber = 0;
848         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
849         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
850
851         cfg.cfghdr.ehdr = &hdr;
852         cfg.physAddr = -1;
853         cfg.pageAddr = form + form_specific;
854         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
855         cfg.dir = 0;    /* read */
856         cfg.timeout = 10;
857
858         error = mpt_config(ioc, &cfg);
859         if (error)
860                 goto out;
861         if (!hdr.ExtPageLength) {
862                 error = -ENXIO;
863                 goto out;
864         }
865
866         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
867                         &dma_handle);
868         if (!buffer) {
869                 error = -ENOMEM;
870                 goto out;
871         }
872
873         cfg.physAddr = dma_handle;
874         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
875
876         error = mpt_config(ioc, &cfg);
877         if (error)
878                 goto out_free_consistent;
879
880         /* save config data */
881         memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
882         enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
883         enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
884         enclosure->flags = le16_to_cpu(buffer->Flags);
885         enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
886         enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
887         enclosure->start_id = buffer->StartTargetID;
888         enclosure->start_channel = buffer->StartBus;
889         enclosure->sep_id = buffer->SEPTargetID;
890         enclosure->sep_channel = buffer->SEPBus;
891
892  out_free_consistent:
893         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
894                             buffer, dma_handle);
895  out:
896         return error;
897 }
898
899 static int
900 mptsas_slave_configure(struct scsi_device *sdev)
901 {
902
903         if (sdev->channel == MPTSAS_RAID_CHANNEL)
904                 goto out;
905
906         sas_read_port_mode_page(sdev);
907
908  out:
909         return mptscsih_slave_configure(sdev);
910 }
911
912 static int
913 mptsas_target_alloc(struct scsi_target *starget)
914 {
915         struct Scsi_Host *host = dev_to_shost(&starget->dev);
916         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
917         VirtTarget              *vtarget;
918         u8                      id, channel;
919         struct sas_rphy         *rphy;
920         struct mptsas_portinfo  *p;
921         int                      i;
922
923         vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
924         if (!vtarget)
925                 return -ENOMEM;
926
927         vtarget->starget = starget;
928         vtarget->ioc_id = hd->ioc->id;
929         vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
930         id = starget->id;
931         channel = 0;
932
933         /*
934          * RAID volumes placed beyond the last expected port.
935          */
936         if (starget->channel == MPTSAS_RAID_CHANNEL) {
937                 for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
938                         if (id == hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID)
939                                 channel = hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus;
940                 goto out;
941         }
942
943         rphy = dev_to_rphy(starget->dev.parent);
944         mutex_lock(&hd->ioc->sas_topology_mutex);
945         list_for_each_entry(p, &hd->ioc->sas_topology, list) {
946                 for (i = 0; i < p->num_phys; i++) {
947                         if (p->phy_info[i].attached.sas_address !=
948                                         rphy->identify.sas_address)
949                                 continue;
950                         id = p->phy_info[i].attached.id;
951                         channel = p->phy_info[i].attached.channel;
952                         mptsas_set_starget(&p->phy_info[i], starget);
953
954                         /*
955                          * Exposing hidden raid components
956                          */
957                         if (mptscsih_is_phys_disk(hd->ioc, channel, id)) {
958                                 id = mptscsih_raid_id_to_num(hd->ioc,
959                                                 channel, id);
960                                 vtarget->tflags |=
961                                     MPT_TARGET_FLAGS_RAID_COMPONENT;
962                                 p->phy_info[i].attached.phys_disk_num = id;
963                         }
964                         mutex_unlock(&hd->ioc->sas_topology_mutex);
965                         goto out;
966                 }
967         }
968         mutex_unlock(&hd->ioc->sas_topology_mutex);
969
970         kfree(vtarget);
971         return -ENXIO;
972
973  out:
974         vtarget->id = id;
975         vtarget->channel = channel;
976         starget->hostdata = vtarget;
977         return 0;
978 }
979
980 static void
981 mptsas_target_destroy(struct scsi_target *starget)
982 {
983         struct Scsi_Host *host = dev_to_shost(&starget->dev);
984         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
985         struct sas_rphy         *rphy;
986         struct mptsas_portinfo  *p;
987         int                      i;
988
989         if (!starget->hostdata)
990                 return;
991
992         if (starget->channel == MPTSAS_RAID_CHANNEL)
993                 goto out;
994
995         rphy = dev_to_rphy(starget->dev.parent);
996         list_for_each_entry(p, &hd->ioc->sas_topology, list) {
997                 for (i = 0; i < p->num_phys; i++) {
998                         if (p->phy_info[i].attached.sas_address !=
999                                         rphy->identify.sas_address)
1000                                 continue;
1001                         mptsas_set_starget(&p->phy_info[i], NULL);
1002                         goto out;
1003                 }
1004         }
1005
1006  out:
1007         kfree(starget->hostdata);
1008         starget->hostdata = NULL;
1009 }
1010
1011
1012 static int
1013 mptsas_slave_alloc(struct scsi_device *sdev)
1014 {
1015         struct Scsi_Host        *host = sdev->host;
1016         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
1017         struct sas_rphy         *rphy;
1018         struct mptsas_portinfo  *p;
1019         VirtDevice              *vdev;
1020         struct scsi_target      *starget;
1021         int                     i;
1022
1023         vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
1024         if (!vdev) {
1025                 printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
1026                                 hd->ioc->name, sizeof(VirtDevice));
1027                 return -ENOMEM;
1028         }
1029         starget = scsi_target(sdev);
1030         vdev->vtarget = starget->hostdata;
1031
1032         if (sdev->channel == MPTSAS_RAID_CHANNEL)
1033                 goto out;
1034
1035         rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
1036         mutex_lock(&hd->ioc->sas_topology_mutex);
1037         list_for_each_entry(p, &hd->ioc->sas_topology, list) {
1038                 for (i = 0; i < p->num_phys; i++) {
1039                         if (p->phy_info[i].attached.sas_address !=
1040                                         rphy->identify.sas_address)
1041                                 continue;
1042                         vdev->lun = sdev->lun;
1043                         /*
1044                          * Exposing hidden raid components
1045                          */
1046                         if (mptscsih_is_phys_disk(hd->ioc,
1047                             p->phy_info[i].attached.channel,
1048                             p->phy_info[i].attached.id))
1049                                 sdev->no_uld_attach = 1;
1050                         mutex_unlock(&hd->ioc->sas_topology_mutex);
1051                         goto out;
1052                 }
1053         }
1054         mutex_unlock(&hd->ioc->sas_topology_mutex);
1055
1056         kfree(vdev);
1057         return -ENXIO;
1058
1059  out:
1060         vdev->vtarget->num_luns++;
1061         sdev->hostdata = vdev;
1062         return 0;
1063 }
1064
1065 static int
1066 mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1067 {
1068         VirtDevice      *vdev = SCpnt->device->hostdata;
1069
1070         if (!vdev || !vdev->vtarget || vdev->vtarget->deleted) {
1071                 SCpnt->result = DID_NO_CONNECT << 16;
1072                 done(SCpnt);
1073                 return 0;
1074         }
1075
1076 //      scsi_print_command(SCpnt);
1077
1078         return mptscsih_qcmd(SCpnt,done);
1079 }
1080
1081
1082 static struct scsi_host_template mptsas_driver_template = {
1083         .module                         = THIS_MODULE,
1084         .proc_name                      = "mptsas",
1085         .proc_info                      = mptscsih_proc_info,
1086         .name                           = "MPT SPI Host",
1087         .info                           = mptscsih_info,
1088         .queuecommand                   = mptsas_qcmd,
1089         .target_alloc                   = mptsas_target_alloc,
1090         .slave_alloc                    = mptsas_slave_alloc,
1091         .slave_configure                = mptsas_slave_configure,
1092         .target_destroy                 = mptsas_target_destroy,
1093         .slave_destroy                  = mptscsih_slave_destroy,
1094         .change_queue_depth             = mptscsih_change_queue_depth,
1095         .eh_abort_handler               = mptscsih_abort,
1096         .eh_device_reset_handler        = mptscsih_dev_reset,
1097         .eh_bus_reset_handler           = mptscsih_bus_reset,
1098         .eh_host_reset_handler          = mptscsih_host_reset,
1099         .bios_param                     = mptscsih_bios_param,
1100         .can_queue                      = MPT_FC_CAN_QUEUE,
1101         .this_id                        = -1,
1102         .sg_tablesize                   = MPT_SCSI_SG_DEPTH,
1103         .max_sectors                    = 8192,
1104         .cmd_per_lun                    = 7,
1105         .use_clustering                 = ENABLE_CLUSTERING,
1106         .shost_attrs                    = mptscsih_host_attrs,
1107 };
1108
1109 static int mptsas_get_linkerrors(struct sas_phy *phy)
1110 {
1111         MPT_ADAPTER *ioc = phy_to_ioc(phy);
1112         ConfigExtendedPageHeader_t hdr;
1113         CONFIGPARMS cfg;
1114         SasPhyPage1_t *buffer;
1115         dma_addr_t dma_handle;
1116         int error;
1117
1118         /* FIXME: only have link errors on local phys */
1119         if (!scsi_is_sas_phy_local(phy))
1120                 return -EINVAL;
1121
1122         hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
1123         hdr.ExtPageLength = 0;
1124         hdr.PageNumber = 1 /* page number 1*/;
1125         hdr.Reserved1 = 0;
1126         hdr.Reserved2 = 0;
1127         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1128         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1129
1130         cfg.cfghdr.ehdr = &hdr;
1131         cfg.physAddr = -1;
1132         cfg.pageAddr = phy->identify.phy_identifier;
1133         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1134         cfg.dir = 0;    /* read */
1135         cfg.timeout = 10;
1136
1137         error = mpt_config(ioc, &cfg);
1138         if (error)
1139                 return error;
1140         if (!hdr.ExtPageLength)
1141                 return -ENXIO;
1142
1143         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1144                                       &dma_handle);
1145         if (!buffer)
1146                 return -ENOMEM;
1147
1148         cfg.physAddr = dma_handle;
1149         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1150
1151         error = mpt_config(ioc, &cfg);
1152         if (error)
1153                 goto out_free_consistent;
1154
1155         mptsas_print_phy_pg1(ioc, buffer);
1156
1157         phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
1158         phy->running_disparity_error_count =
1159                 le32_to_cpu(buffer->RunningDisparityErrorCount);
1160         phy->loss_of_dword_sync_count =
1161                 le32_to_cpu(buffer->LossDwordSynchCount);
1162         phy->phy_reset_problem_count =
1163                 le32_to_cpu(buffer->PhyResetProblemCount);
1164
1165  out_free_consistent:
1166         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1167                             buffer, dma_handle);
1168         return error;
1169 }
1170
1171 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
1172                 MPT_FRAME_HDR *reply)
1173 {
1174         ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
1175         if (reply != NULL) {
1176                 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
1177                 memcpy(ioc->sas_mgmt.reply, reply,
1178                     min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
1179         }
1180         complete(&ioc->sas_mgmt.done);
1181         return 1;
1182 }
1183
1184 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
1185 {
1186         MPT_ADAPTER *ioc = phy_to_ioc(phy);
1187         SasIoUnitControlRequest_t *req;
1188         SasIoUnitControlReply_t *reply;
1189         MPT_FRAME_HDR *mf;
1190         MPIHeader_t *hdr;
1191         unsigned long timeleft;
1192         int error = -ERESTARTSYS;
1193
1194         /* FIXME: fusion doesn't allow non-local phy reset */
1195         if (!scsi_is_sas_phy_local(phy))
1196                 return -EINVAL;
1197
1198         /* not implemented for expanders */
1199         if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
1200                 return -ENXIO;
1201
1202         if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
1203                 goto out;
1204
1205         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
1206         if (!mf) {
1207                 error = -ENOMEM;
1208                 goto out_unlock;
1209         }
1210
1211         hdr = (MPIHeader_t *) mf;
1212         req = (SasIoUnitControlRequest_t *)mf;
1213         memset(req, 0, sizeof(SasIoUnitControlRequest_t));
1214         req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
1215         req->MsgContext = hdr->MsgContext;
1216         req->Operation = hard_reset ?
1217                 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
1218         req->PhyNum = phy->identify.phy_identifier;
1219
1220         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1221
1222         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
1223                         10 * HZ);
1224         if (!timeleft) {
1225                 /* On timeout reset the board */
1226                 mpt_free_msg_frame(ioc, mf);
1227                 mpt_HardResetHandler(ioc, CAN_SLEEP);
1228                 error = -ETIMEDOUT;
1229                 goto out_unlock;
1230         }
1231
1232         /* a reply frame is expected */
1233         if ((ioc->sas_mgmt.status &
1234             MPT_IOCTL_STATUS_RF_VALID) == 0) {
1235                 error = -ENXIO;
1236                 goto out_unlock;
1237         }
1238
1239         /* process the completed Reply Message Frame */
1240         reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
1241         if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
1242                 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
1243                     __FUNCTION__,
1244                     reply->IOCStatus,
1245                     reply->IOCLogInfo);
1246                 error = -ENXIO;
1247                 goto out_unlock;
1248         }
1249
1250         error = 0;
1251
1252  out_unlock:
1253         mutex_unlock(&ioc->sas_mgmt.mutex);
1254  out:
1255         return error;
1256 }
1257
1258 static int
1259 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
1260 {
1261         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1262         int i, error;
1263         struct mptsas_portinfo *p;
1264         struct mptsas_enclosure enclosure_info;
1265         u64 enclosure_handle;
1266
1267         mutex_lock(&ioc->sas_topology_mutex);
1268         list_for_each_entry(p, &ioc->sas_topology, list) {
1269                 for (i = 0; i < p->num_phys; i++) {
1270                         if (p->phy_info[i].attached.sas_address ==
1271                             rphy->identify.sas_address) {
1272                                 enclosure_handle = p->phy_info[i].
1273                                         attached.handle_enclosure;
1274                                 goto found_info;
1275                         }
1276                 }
1277         }
1278         mutex_unlock(&ioc->sas_topology_mutex);
1279         return -ENXIO;
1280
1281  found_info:
1282         mutex_unlock(&ioc->sas_topology_mutex);
1283         memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
1284         error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
1285                         (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
1286                          MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
1287         if (!error)
1288                 *identifier = enclosure_info.enclosure_logical_id;
1289         return error;
1290 }
1291
1292 static int
1293 mptsas_get_bay_identifier(struct sas_rphy *rphy)
1294 {
1295         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1296         struct mptsas_portinfo *p;
1297         int i, rc;
1298
1299         mutex_lock(&ioc->sas_topology_mutex);
1300         list_for_each_entry(p, &ioc->sas_topology, list) {
1301                 for (i = 0; i < p->num_phys; i++) {
1302                         if (p->phy_info[i].attached.sas_address ==
1303                             rphy->identify.sas_address) {
1304                                 rc = p->phy_info[i].attached.slot;
1305                                 goto out;
1306                         }
1307                 }
1308         }
1309         rc = -ENXIO;
1310  out:
1311         mutex_unlock(&ioc->sas_topology_mutex);
1312         return rc;
1313 }
1314
1315 static struct sas_function_template mptsas_transport_functions = {
1316         .get_linkerrors         = mptsas_get_linkerrors,
1317         .get_enclosure_identifier = mptsas_get_enclosure_identifier,
1318         .get_bay_identifier     = mptsas_get_bay_identifier,
1319         .phy_reset              = mptsas_phy_reset,
1320 };
1321
1322 static struct scsi_transport_template *mptsas_transport_template;
1323
1324 static int
1325 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
1326 {
1327         ConfigExtendedPageHeader_t hdr;
1328         CONFIGPARMS cfg;
1329         SasIOUnitPage0_t *buffer;
1330         dma_addr_t dma_handle;
1331         int error, i;
1332
1333         hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
1334         hdr.ExtPageLength = 0;
1335         hdr.PageNumber = 0;
1336         hdr.Reserved1 = 0;
1337         hdr.Reserved2 = 0;
1338         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1339         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1340
1341         cfg.cfghdr.ehdr = &hdr;
1342         cfg.physAddr = -1;
1343         cfg.pageAddr = 0;
1344         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1345         cfg.dir = 0;    /* read */
1346         cfg.timeout = 10;
1347
1348         error = mpt_config(ioc, &cfg);
1349         if (error)
1350                 goto out;
1351         if (!hdr.ExtPageLength) {
1352                 error = -ENXIO;
1353                 goto out;
1354         }
1355
1356         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1357                                             &dma_handle);
1358         if (!buffer) {
1359                 error = -ENOMEM;
1360                 goto out;
1361         }
1362
1363         cfg.physAddr = dma_handle;
1364         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1365
1366         error = mpt_config(ioc, &cfg);
1367         if (error)
1368                 goto out_free_consistent;
1369
1370         port_info->num_phys = buffer->NumPhys;
1371         port_info->phy_info = kcalloc(port_info->num_phys,
1372                 sizeof(*port_info->phy_info),GFP_KERNEL);
1373         if (!port_info->phy_info) {
1374                 error = -ENOMEM;
1375                 goto out_free_consistent;
1376         }
1377
1378         ioc->nvdata_version_persistent =
1379             le16_to_cpu(buffer->NvdataVersionPersistent);
1380         ioc->nvdata_version_default =
1381             le16_to_cpu(buffer->NvdataVersionDefault);
1382
1383         for (i = 0; i < port_info->num_phys; i++) {
1384                 mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
1385                 port_info->phy_info[i].phy_id = i;
1386                 port_info->phy_info[i].port_id =
1387                     buffer->PhyData[i].Port;
1388                 port_info->phy_info[i].negotiated_link_rate =
1389                     buffer->PhyData[i].NegotiatedLinkRate;
1390                 port_info->phy_info[i].portinfo = port_info;
1391                 port_info->phy_info[i].handle =
1392                     le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
1393         }
1394
1395  out_free_consistent:
1396         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1397                             buffer, dma_handle);
1398  out:
1399         return error;
1400 }
1401
1402 static int
1403 mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
1404 {
1405         ConfigExtendedPageHeader_t hdr;
1406         CONFIGPARMS cfg;
1407         SasIOUnitPage1_t *buffer;
1408         dma_addr_t dma_handle;
1409         int error;
1410         u16 device_missing_delay;
1411
1412         memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
1413         memset(&cfg, 0, sizeof(CONFIGPARMS));
1414
1415         cfg.cfghdr.ehdr = &hdr;
1416         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1417         cfg.timeout = 10;
1418         cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1419         cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1420         cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
1421         cfg.cfghdr.ehdr->PageNumber = 1;
1422
1423         error = mpt_config(ioc, &cfg);
1424         if (error)
1425                 goto out;
1426         if (!hdr.ExtPageLength) {
1427                 error = -ENXIO;
1428                 goto out;
1429         }
1430
1431         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1432                                             &dma_handle);
1433         if (!buffer) {
1434                 error = -ENOMEM;
1435                 goto out;
1436         }
1437
1438         cfg.physAddr = dma_handle;
1439         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1440
1441         error = mpt_config(ioc, &cfg);
1442         if (error)
1443                 goto out_free_consistent;
1444
1445         ioc->io_missing_delay  =
1446             le16_to_cpu(buffer->IODeviceMissingDelay);
1447         device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay);
1448         ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
1449             (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
1450             device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
1451
1452  out_free_consistent:
1453         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1454                             buffer, dma_handle);
1455  out:
1456         return error;
1457 }
1458
1459 static int
1460 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1461                 u32 form, u32 form_specific)
1462 {
1463         ConfigExtendedPageHeader_t hdr;
1464         CONFIGPARMS cfg;
1465         SasPhyPage0_t *buffer;
1466         dma_addr_t dma_handle;
1467         int error;
1468
1469         hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
1470         hdr.ExtPageLength = 0;
1471         hdr.PageNumber = 0;
1472         hdr.Reserved1 = 0;
1473         hdr.Reserved2 = 0;
1474         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1475         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1476
1477         cfg.cfghdr.ehdr = &hdr;
1478         cfg.dir = 0;    /* read */
1479         cfg.timeout = 10;
1480
1481         /* Get Phy Pg 0 for each Phy. */
1482         cfg.physAddr = -1;
1483         cfg.pageAddr = form + form_specific;
1484         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1485
1486         error = mpt_config(ioc, &cfg);
1487         if (error)
1488                 goto out;
1489
1490         if (!hdr.ExtPageLength) {
1491                 error = -ENXIO;
1492                 goto out;
1493         }
1494
1495         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1496                                       &dma_handle);
1497         if (!buffer) {
1498                 error = -ENOMEM;
1499                 goto out;
1500         }
1501
1502         cfg.physAddr = dma_handle;
1503         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1504
1505         error = mpt_config(ioc, &cfg);
1506         if (error)
1507                 goto out_free_consistent;
1508
1509         mptsas_print_phy_pg0(ioc, buffer);
1510
1511         phy_info->hw_link_rate = buffer->HwLinkRate;
1512         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1513         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1514         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1515
1516  out_free_consistent:
1517         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1518                             buffer, dma_handle);
1519  out:
1520         return error;
1521 }
1522
1523 static int
1524 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
1525                 u32 form, u32 form_specific)
1526 {
1527         ConfigExtendedPageHeader_t hdr;
1528         CONFIGPARMS cfg;
1529         SasDevicePage0_t *buffer;
1530         dma_addr_t dma_handle;
1531         __le64 sas_address;
1532         int error=0;
1533
1534         if (ioc->sas_discovery_runtime &&
1535                 mptsas_is_end_device(device_info))
1536                         goto out;
1537
1538         hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
1539         hdr.ExtPageLength = 0;
1540         hdr.PageNumber = 0;
1541         hdr.Reserved1 = 0;
1542         hdr.Reserved2 = 0;
1543         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1544         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1545
1546         cfg.cfghdr.ehdr = &hdr;
1547         cfg.pageAddr = form + form_specific;
1548         cfg.physAddr = -1;
1549         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1550         cfg.dir = 0;    /* read */
1551         cfg.timeout = 10;
1552
1553         memset(device_info, 0, sizeof(struct mptsas_devinfo));
1554         error = mpt_config(ioc, &cfg);
1555         if (error)
1556                 goto out;
1557         if (!hdr.ExtPageLength) {
1558                 error = -ENXIO;
1559                 goto out;
1560         }
1561
1562         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1563                                       &dma_handle);
1564         if (!buffer) {
1565                 error = -ENOMEM;
1566                 goto out;
1567         }
1568
1569         cfg.physAddr = dma_handle;
1570         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1571
1572         error = mpt_config(ioc, &cfg);
1573         if (error)
1574                 goto out_free_consistent;
1575
1576         mptsas_print_device_pg0(ioc, buffer);
1577
1578         device_info->handle = le16_to_cpu(buffer->DevHandle);
1579         device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
1580         device_info->handle_enclosure =
1581             le16_to_cpu(buffer->EnclosureHandle);
1582         device_info->slot = le16_to_cpu(buffer->Slot);
1583         device_info->phy_id = buffer->PhyNum;
1584         device_info->port_id = buffer->PhysicalPort;
1585         device_info->id = buffer->TargetID;
1586         device_info->phys_disk_num = ~0;
1587         device_info->channel = buffer->Bus;
1588         memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
1589         device_info->sas_address = le64_to_cpu(sas_address);
1590         device_info->device_info =
1591             le32_to_cpu(buffer->DeviceInfo);
1592
1593  out_free_consistent:
1594         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1595                             buffer, dma_handle);
1596  out:
1597         return error;
1598 }
1599
1600 static int
1601 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
1602                 u32 form, u32 form_specific)
1603 {
1604         ConfigExtendedPageHeader_t hdr;
1605         CONFIGPARMS cfg;
1606         SasExpanderPage0_t *buffer;
1607         dma_addr_t dma_handle;
1608         int i, error;
1609
1610         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1611         hdr.ExtPageLength = 0;
1612         hdr.PageNumber = 0;
1613         hdr.Reserved1 = 0;
1614         hdr.Reserved2 = 0;
1615         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1616         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1617
1618         cfg.cfghdr.ehdr = &hdr;
1619         cfg.physAddr = -1;
1620         cfg.pageAddr = form + form_specific;
1621         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1622         cfg.dir = 0;    /* read */
1623         cfg.timeout = 10;
1624
1625         memset(port_info, 0, sizeof(struct mptsas_portinfo));
1626         error = mpt_config(ioc, &cfg);
1627         if (error)
1628                 goto out;
1629
1630         if (!hdr.ExtPageLength) {
1631                 error = -ENXIO;
1632                 goto out;
1633         }
1634
1635         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1636                                       &dma_handle);
1637         if (!buffer) {
1638                 error = -ENOMEM;
1639                 goto out;
1640         }
1641
1642         cfg.physAddr = dma_handle;
1643         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1644
1645         error = mpt_config(ioc, &cfg);
1646         if (error)
1647                 goto out_free_consistent;
1648
1649         /* save config data */
1650         port_info->num_phys = buffer->NumPhys;
1651         port_info->phy_info = kcalloc(port_info->num_phys,
1652                 sizeof(*port_info->phy_info),GFP_KERNEL);
1653         if (!port_info->phy_info) {
1654                 error = -ENOMEM;
1655                 goto out_free_consistent;
1656         }
1657
1658         for (i = 0; i < port_info->num_phys; i++) {
1659                 port_info->phy_info[i].portinfo = port_info;
1660                 port_info->phy_info[i].handle =
1661                     le16_to_cpu(buffer->DevHandle);
1662         }
1663
1664  out_free_consistent:
1665         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1666                             buffer, dma_handle);
1667  out:
1668         return error;
1669 }
1670
1671 static int
1672 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1673                 u32 form, u32 form_specific)
1674 {
1675         ConfigExtendedPageHeader_t hdr;
1676         CONFIGPARMS cfg;
1677         SasExpanderPage1_t *buffer;
1678         dma_addr_t dma_handle;
1679         int error=0;
1680
1681         if (ioc->sas_discovery_runtime &&
1682                 mptsas_is_end_device(&phy_info->attached))
1683                         goto out;
1684
1685         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1686         hdr.ExtPageLength = 0;
1687         hdr.PageNumber = 1;
1688         hdr.Reserved1 = 0;
1689         hdr.Reserved2 = 0;
1690         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1691         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1692
1693         cfg.cfghdr.ehdr = &hdr;
1694         cfg.physAddr = -1;
1695         cfg.pageAddr = form + form_specific;
1696         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1697         cfg.dir = 0;    /* read */
1698         cfg.timeout = 10;
1699
1700         error = mpt_config(ioc, &cfg);
1701         if (error)
1702                 goto out;
1703
1704         if (!hdr.ExtPageLength) {
1705                 error = -ENXIO;
1706                 goto out;
1707         }
1708
1709         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1710                                       &dma_handle);
1711         if (!buffer) {
1712                 error = -ENOMEM;
1713                 goto out;
1714         }
1715
1716         cfg.physAddr = dma_handle;
1717         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1718
1719         error = mpt_config(ioc, &cfg);
1720         if (error)
1721                 goto out_free_consistent;
1722
1723
1724         mptsas_print_expander_pg1(ioc, buffer);
1725
1726         /* save config data */
1727         phy_info->phy_id = buffer->PhyIdentifier;
1728         phy_info->port_id = buffer->PhysicalPort;
1729         phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
1730         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1731         phy_info->hw_link_rate = buffer->HwLinkRate;
1732         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1733         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1734
1735  out_free_consistent:
1736         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1737                             buffer, dma_handle);
1738  out:
1739         return error;
1740 }
1741
1742 static void
1743 mptsas_parse_device_info(struct sas_identify *identify,
1744                 struct mptsas_devinfo *device_info)
1745 {
1746         u16 protocols;
1747
1748         identify->sas_address = device_info->sas_address;
1749         identify->phy_identifier = device_info->phy_id;
1750
1751         /*
1752          * Fill in Phy Initiator Port Protocol.
1753          * Bits 6:3, more than one bit can be set, fall through cases.
1754          */
1755         protocols = device_info->device_info & 0x78;
1756         identify->initiator_port_protocols = 0;
1757         if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
1758                 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
1759         if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1760                 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
1761         if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
1762                 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
1763         if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
1764                 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
1765
1766         /*
1767          * Fill in Phy Target Port Protocol.
1768          * Bits 10:7, more than one bit can be set, fall through cases.
1769          */
1770         protocols = device_info->device_info & 0x780;
1771         identify->target_port_protocols = 0;
1772         if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1773                 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
1774         if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
1775                 identify->target_port_protocols |= SAS_PROTOCOL_STP;
1776         if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
1777                 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
1778         if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1779                 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
1780
1781         /*
1782          * Fill in Attached device type.
1783          */
1784         switch (device_info->device_info &
1785                         MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
1786         case MPI_SAS_DEVICE_INFO_NO_DEVICE:
1787                 identify->device_type = SAS_PHY_UNUSED;
1788                 break;
1789         case MPI_SAS_DEVICE_INFO_END_DEVICE:
1790                 identify->device_type = SAS_END_DEVICE;
1791                 break;
1792         case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
1793                 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
1794                 break;
1795         case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
1796                 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
1797                 break;
1798         }
1799 }
1800
1801 static int mptsas_probe_one_phy(struct device *dev,
1802                 struct mptsas_phyinfo *phy_info, int index, int local)
1803 {
1804         MPT_ADAPTER *ioc;
1805         struct sas_phy *phy;
1806         struct sas_port *port;
1807         int error = 0;
1808
1809         if (!dev) {
1810                 error = -ENODEV;
1811                 goto out;
1812         }
1813
1814         if (!phy_info->phy) {
1815                 phy = sas_phy_alloc(dev, index);
1816                 if (!phy) {
1817                         error = -ENOMEM;
1818                         goto out;
1819                 }
1820         } else
1821                 phy = phy_info->phy;
1822
1823         mptsas_parse_device_info(&phy->identify, &phy_info->identify);
1824
1825         /*
1826          * Set Negotiated link rate.
1827          */
1828         switch (phy_info->negotiated_link_rate) {
1829         case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
1830                 phy->negotiated_linkrate = SAS_PHY_DISABLED;
1831                 break;
1832         case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
1833                 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
1834                 break;
1835         case MPI_SAS_IOUNIT0_RATE_1_5:
1836                 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
1837                 break;
1838         case MPI_SAS_IOUNIT0_RATE_3_0:
1839                 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
1840                 break;
1841         case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
1842         case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
1843         default:
1844                 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
1845                 break;
1846         }
1847
1848         /*
1849          * Set Max hardware link rate.
1850          */
1851         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1852         case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
1853                 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1854                 break;
1855         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1856                 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1857                 break;
1858         default:
1859                 break;
1860         }
1861
1862         /*
1863          * Set Max programmed link rate.
1864          */
1865         switch (phy_info->programmed_link_rate &
1866                         MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1867         case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
1868                 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1869                 break;
1870         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1871                 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1872                 break;
1873         default:
1874                 break;
1875         }
1876
1877         /*
1878          * Set Min hardware link rate.
1879          */
1880         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
1881         case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
1882                 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1883                 break;
1884         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1885                 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1886                 break;
1887         default:
1888                 break;
1889         }
1890
1891         /*
1892          * Set Min programmed link rate.
1893          */
1894         switch (phy_info->programmed_link_rate &
1895                         MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
1896         case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
1897                 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1898                 break;
1899         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1900                 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1901                 break;
1902         default:
1903                 break;
1904         }
1905
1906         if (!phy_info->phy) {
1907
1908                 error = sas_phy_add(phy);
1909                 if (error) {
1910                         sas_phy_free(phy);
1911                         goto out;
1912                 }
1913                 phy_info->phy = phy;
1914         }
1915
1916         if (!phy_info->attached.handle ||
1917                         !phy_info->port_details)
1918                 goto out;
1919
1920         port = mptsas_get_port(phy_info);
1921         ioc = phy_to_ioc(phy_info->phy);
1922
1923         if (phy_info->sas_port_add_phy) {
1924
1925                 if (!port) {
1926                         port = sas_port_alloc_num(dev);
1927                         if (!port) {
1928                                 error = -ENOMEM;
1929                                 goto out;
1930                         }
1931                         error = sas_port_add(port);
1932                         if (error) {
1933                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1934                                         "%s: exit at line=%d\n", ioc->name,
1935                                         __FUNCTION__, __LINE__));
1936                                 goto out;
1937                         }
1938                         mptsas_set_port(ioc, phy_info, port);
1939                         dsaswideprintk(ioc, printk(KERN_DEBUG
1940                             "sas_port_alloc: port=%p dev=%p port_id=%d\n",
1941                             port, dev, port->port_identifier));
1942                 }
1943                 dsaswideprintk(ioc, printk(KERN_DEBUG "sas_port_add_phy: phy_id=%d\n",
1944                     phy_info->phy_id));
1945                 sas_port_add_phy(port, phy_info->phy);
1946                 phy_info->sas_port_add_phy = 0;
1947         }
1948
1949         if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
1950
1951                 struct sas_rphy *rphy;
1952                 struct device *parent;
1953                 struct sas_identify identify;
1954
1955                 parent = dev->parent->parent;
1956                 /*
1957                  * Let the hotplug_work thread handle processing
1958                  * the adding/removing of devices that occur
1959                  * after start of day.
1960                  */
1961                 if (ioc->sas_discovery_runtime &&
1962                         mptsas_is_end_device(&phy_info->attached))
1963                                 goto out;
1964
1965                 mptsas_parse_device_info(&identify, &phy_info->attached);
1966                 if (scsi_is_host_device(parent)) {
1967                         struct mptsas_portinfo *port_info;
1968                         int i;
1969
1970                         mutex_lock(&ioc->sas_topology_mutex);
1971                         port_info = mptsas_find_portinfo_by_handle(ioc,
1972                                                                    ioc->handle);
1973                         mutex_unlock(&ioc->sas_topology_mutex);
1974
1975                         for (i = 0; i < port_info->num_phys; i++)
1976                                 if (port_info->phy_info[i].identify.sas_address ==
1977                                     identify.sas_address) {
1978                                         sas_port_mark_backlink(port);
1979                                         goto out;
1980                                 }
1981
1982                 } else if (scsi_is_sas_rphy(parent)) {
1983                         struct sas_rphy *parent_rphy = dev_to_rphy(parent);
1984                         if (identify.sas_address ==
1985                             parent_rphy->identify.sas_address) {
1986                                 sas_port_mark_backlink(port);
1987                                 goto out;
1988                         }
1989                 }
1990
1991                 switch (identify.device_type) {
1992                 case SAS_END_DEVICE:
1993                         rphy = sas_end_device_alloc(port);
1994                         break;
1995                 case SAS_EDGE_EXPANDER_DEVICE:
1996                 case SAS_FANOUT_EXPANDER_DEVICE:
1997                         rphy = sas_expander_alloc(port, identify.device_type);
1998                         break;
1999                 default:
2000                         rphy = NULL;
2001                         break;
2002                 }
2003                 if (!rphy) {
2004                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2005                                 "%s: exit at line=%d\n", ioc->name,
2006                                 __FUNCTION__, __LINE__));
2007                         goto out;
2008                 }
2009
2010                 rphy->identify = identify;
2011                 error = sas_rphy_add(rphy);
2012                 if (error) {
2013                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2014                                 "%s: exit at line=%d\n", ioc->name,
2015                                 __FUNCTION__, __LINE__));
2016                         sas_rphy_free(rphy);
2017                         goto out;
2018                 }
2019                 mptsas_set_rphy(ioc, phy_info, rphy);
2020         }
2021
2022  out:
2023         return error;
2024 }
2025
2026 static int
2027 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
2028 {
2029         struct mptsas_portinfo *port_info, *hba;
2030         int error = -ENOMEM, i;
2031
2032         hba = kzalloc(sizeof(*port_info), GFP_KERNEL);
2033         if (! hba)
2034                 goto out;
2035
2036         error = mptsas_sas_io_unit_pg0(ioc, hba);
2037         if (error)
2038                 goto out_free_port_info;
2039
2040         mptsas_sas_io_unit_pg1(ioc);
2041         mutex_lock(&ioc->sas_topology_mutex);
2042         ioc->handle = hba->phy_info[0].handle;
2043         port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
2044         if (!port_info) {
2045                 port_info = hba;
2046                 list_add_tail(&port_info->list, &ioc->sas_topology);
2047         } else {
2048                 for (i = 0; i < hba->num_phys; i++) {
2049                         port_info->phy_info[i].negotiated_link_rate =
2050                                 hba->phy_info[i].negotiated_link_rate;
2051                         port_info->phy_info[i].handle =
2052                                 hba->phy_info[i].handle;
2053                         port_info->phy_info[i].port_id =
2054                                 hba->phy_info[i].port_id;
2055                 }
2056                 kfree(hba->phy_info);
2057                 kfree(hba);
2058                 hba = NULL;
2059         }
2060         mutex_unlock(&ioc->sas_topology_mutex);
2061         for (i = 0; i < port_info->num_phys; i++) {
2062                 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
2063                         (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
2064                          MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
2065
2066                 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
2067                         (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2068                          MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2069                          port_info->phy_info[i].handle);
2070                 port_info->phy_info[i].identify.phy_id =
2071                     port_info->phy_info[i].phy_id = i;
2072                 if (port_info->phy_info[i].attached.handle)
2073                         mptsas_sas_device_pg0(ioc,
2074                                 &port_info->phy_info[i].attached,
2075                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2076                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2077                                 port_info->phy_info[i].attached.handle);
2078         }
2079
2080         mptsas_setup_wide_ports(ioc, port_info);
2081
2082         for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
2083                 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
2084                     &port_info->phy_info[i], ioc->sas_index, 1);
2085
2086         return 0;
2087
2088  out_free_port_info:
2089         kfree(hba);
2090  out:
2091         return error;
2092 }
2093
2094 static int
2095 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
2096 {
2097         struct mptsas_portinfo *port_info, *p, *ex;
2098         struct device *parent;
2099         struct sas_rphy *rphy;
2100         int error = -ENOMEM, i, j;
2101
2102         ex = kzalloc(sizeof(*port_info), GFP_KERNEL);
2103         if (!ex)
2104                 goto out;
2105
2106         error = mptsas_sas_expander_pg0(ioc, ex,
2107             (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
2108              MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
2109         if (error)
2110                 goto out_free_port_info;
2111
2112         *handle = ex->phy_info[0].handle;
2113
2114         mutex_lock(&ioc->sas_topology_mutex);
2115         port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
2116         if (!port_info) {
2117                 port_info = ex;
2118                 list_add_tail(&port_info->list, &ioc->sas_topology);
2119         } else {
2120                 for (i = 0; i < ex->num_phys; i++) {
2121                         port_info->phy_info[i].handle =
2122                                 ex->phy_info[i].handle;
2123                         port_info->phy_info[i].port_id =
2124                                 ex->phy_info[i].port_id;
2125                 }
2126                 kfree(ex->phy_info);
2127                 kfree(ex);
2128                 ex = NULL;
2129         }
2130         mutex_unlock(&ioc->sas_topology_mutex);
2131
2132         for (i = 0; i < port_info->num_phys; i++) {
2133                 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
2134                         (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
2135                          MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
2136
2137                 if (port_info->phy_info[i].identify.handle) {
2138                         mptsas_sas_device_pg0(ioc,
2139                                 &port_info->phy_info[i].identify,
2140                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2141                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2142                                 port_info->phy_info[i].identify.handle);
2143                         port_info->phy_info[i].identify.phy_id =
2144                             port_info->phy_info[i].phy_id;
2145                 }
2146
2147                 if (port_info->phy_info[i].attached.handle) {
2148                         mptsas_sas_device_pg0(ioc,
2149                                 &port_info->phy_info[i].attached,
2150                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2151                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2152                                 port_info->phy_info[i].attached.handle);
2153                         port_info->phy_info[i].attached.phy_id =
2154                             port_info->phy_info[i].phy_id;
2155                 }
2156         }
2157
2158         parent = &ioc->sh->shost_gendev;
2159         for (i = 0; i < port_info->num_phys; i++) {
2160                 mutex_lock(&ioc->sas_topology_mutex);
2161                 list_for_each_entry(p, &ioc->sas_topology, list) {
2162                         for (j = 0; j < p->num_phys; j++) {
2163                                 if (port_info->phy_info[i].identify.handle !=
2164                                                 p->phy_info[j].attached.handle)
2165                                         continue;
2166                                 rphy = mptsas_get_rphy(&p->phy_info[j]);
2167                                 parent = &rphy->dev;
2168                         }
2169                 }
2170                 mutex_unlock(&ioc->sas_topology_mutex);
2171         }
2172
2173         mptsas_setup_wide_ports(ioc, port_info);
2174
2175         for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
2176                 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
2177                     ioc->sas_index, 0);
2178
2179         return 0;
2180
2181  out_free_port_info:
2182         if (ex) {
2183                 kfree(ex->phy_info);
2184                 kfree(ex);
2185         }
2186  out:
2187         return error;
2188 }
2189
2190 /*
2191  * mptsas_delete_expander_phys
2192  *
2193  *
2194  * This will traverse topology, and remove expanders
2195  * that are no longer present
2196  */
2197 static void
2198 mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
2199 {
2200         struct mptsas_portinfo buffer;
2201         struct mptsas_portinfo *port_info, *n, *parent;
2202         struct mptsas_phyinfo *phy_info;
2203         struct sas_port * port;
2204         int i;
2205         u64     expander_sas_address;
2206
2207         mutex_lock(&ioc->sas_topology_mutex);
2208         list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
2209
2210                 if (port_info->phy_info &&
2211                     (!(port_info->phy_info[0].identify.device_info &
2212                     MPI_SAS_DEVICE_INFO_SMP_TARGET)))
2213                         continue;
2214
2215                 if (mptsas_sas_expander_pg0(ioc, &buffer,
2216                      (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
2217                      MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
2218                      port_info->phy_info[0].handle)) {
2219
2220                         /*
2221                          * Obtain the port_info instance to the parent port
2222                          */
2223                         parent = mptsas_find_portinfo_by_handle(ioc,
2224                             port_info->phy_info[0].identify.handle_parent);
2225
2226                         if (!parent)
2227                                 goto next_port;
2228
2229                         expander_sas_address =
2230                                 port_info->phy_info[0].identify.sas_address;
2231
2232                         /*
2233                          * Delete rphys in the parent that point
2234                          * to this expander.  The transport layer will
2235                          * cleanup all the children.
2236                          */
2237                         phy_info = parent->phy_info;
2238                         for (i = 0; i < parent->num_phys; i++, phy_info++) {
2239                                 port = mptsas_get_port(phy_info);
2240                                 if (!port)
2241                                         continue;
2242                                 if (phy_info->attached.sas_address !=
2243                                         expander_sas_address)
2244                                         continue;
2245                                 dsaswideprintk(ioc,
2246                                         dev_printk(KERN_DEBUG, &port->dev,
2247                                         "delete port (%d)\n", port->port_identifier));
2248                                 sas_port_delete(port);
2249                                 mptsas_port_delete(ioc, phy_info->port_details);
2250                         }
2251  next_port:
2252
2253                         phy_info = port_info->phy_info;
2254                         for (i = 0; i < port_info->num_phys; i++, phy_info++)
2255                                 mptsas_port_delete(ioc, phy_info->port_details);
2256
2257                         list_del(&port_info->list);
2258                         kfree(port_info->phy_info);
2259                         kfree(port_info);
2260                 }
2261                 /*
2262                 * Free this memory allocated from inside
2263                 * mptsas_sas_expander_pg0
2264                 */
2265                 kfree(buffer.phy_info);
2266         }
2267         mutex_unlock(&ioc->sas_topology_mutex);
2268 }
2269
2270 /*
2271  * Start of day discovery
2272  */
2273 static void
2274 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
2275 {
2276         u32 handle = 0xFFFF;
2277         int i;
2278
2279         mutex_lock(&ioc->sas_discovery_mutex);
2280         mptsas_probe_hba_phys(ioc);
2281         while (!mptsas_probe_expander_phys(ioc, &handle))
2282                 ;
2283         /*
2284           Reporting RAID volumes.
2285         */
2286         if (!ioc->ir_firmware)
2287                 goto out;
2288         if (!ioc->raid_data.pIocPg2)
2289                 goto out;
2290         if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
2291                 goto out;
2292         for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
2293                 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
2294                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
2295         }
2296  out:
2297         mutex_unlock(&ioc->sas_discovery_mutex);
2298 }
2299
2300 /*
2301  * Work queue thread to handle Runtime discovery
2302  * Mere purpose is the hot add/delete of expanders
2303  *(Mutex UNLOCKED)
2304  */
2305 static void
2306 __mptsas_discovery_work(MPT_ADAPTER *ioc)
2307 {
2308         u32 handle = 0xFFFF;
2309
2310         ioc->sas_discovery_runtime=1;
2311         mptsas_delete_expander_phys(ioc);
2312         mptsas_probe_hba_phys(ioc);
2313         while (!mptsas_probe_expander_phys(ioc, &handle))
2314                 ;
2315         ioc->sas_discovery_runtime=0;
2316 }
2317
2318 /*
2319  * Work queue thread to handle Runtime discovery
2320  * Mere purpose is the hot add/delete of expanders
2321  *(Mutex LOCKED)
2322  */
2323 static void
2324 mptsas_discovery_work(struct work_struct *work)
2325 {
2326         struct mptsas_discovery_event *ev =
2327                 container_of(work, struct mptsas_discovery_event, work);
2328         MPT_ADAPTER *ioc = ev->ioc;
2329
2330         mutex_lock(&ioc->sas_discovery_mutex);
2331         __mptsas_discovery_work(ioc);
2332         mutex_unlock(&ioc->sas_discovery_mutex);
2333         kfree(ev);
2334 }
2335
2336 static struct mptsas_phyinfo *
2337 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
2338 {
2339         struct mptsas_portinfo *port_info;
2340         struct mptsas_phyinfo *phy_info = NULL;
2341         int i;
2342
2343         mutex_lock(&ioc->sas_topology_mutex);
2344         list_for_each_entry(port_info, &ioc->sas_topology, list) {
2345                 for (i = 0; i < port_info->num_phys; i++) {
2346                         if (!mptsas_is_end_device(
2347                                 &port_info->phy_info[i].attached))
2348                                 continue;
2349                         if (port_info->phy_info[i].attached.sas_address
2350                             != sas_address)
2351                                 continue;
2352                         phy_info = &port_info->phy_info[i];
2353                         break;
2354                 }
2355         }
2356         mutex_unlock(&ioc->sas_topology_mutex);
2357         return phy_info;
2358 }
2359
2360 static struct mptsas_phyinfo *
2361 mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u8 channel, u8 id)
2362 {
2363         struct mptsas_portinfo *port_info;
2364         struct mptsas_phyinfo *phy_info = NULL;
2365         int i;
2366
2367         mutex_lock(&ioc->sas_topology_mutex);
2368         list_for_each_entry(port_info, &ioc->sas_topology, list) {
2369                 for (i = 0; i < port_info->num_phys; i++) {
2370                         if (!mptsas_is_end_device(
2371                                 &port_info->phy_info[i].attached))
2372                                 continue;
2373                         if (port_info->phy_info[i].attached.id != id)
2374                                 continue;
2375                         if (port_info->phy_info[i].attached.channel != channel)
2376                                 continue;
2377                         phy_info = &port_info->phy_info[i];
2378                         break;
2379                 }
2380         }
2381         mutex_unlock(&ioc->sas_topology_mutex);
2382         return phy_info;
2383 }
2384
2385 static struct mptsas_phyinfo *
2386 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2387 {
2388         struct mptsas_portinfo *port_info;
2389         struct mptsas_phyinfo *phy_info = NULL;
2390         int i;
2391
2392         mutex_lock(&ioc->sas_topology_mutex);
2393         list_for_each_entry(port_info, &ioc->sas_topology, list) {
2394                 for (i = 0; i < port_info->num_phys; i++) {
2395                         if (!mptsas_is_end_device(
2396                                 &port_info->phy_info[i].attached))
2397                                 continue;
2398                         if (port_info->phy_info[i].attached.phys_disk_num == ~0)
2399                                 continue;
2400                         if (port_info->phy_info[i].attached.phys_disk_num != id)
2401                                 continue;
2402                         if (port_info->phy_info[i].attached.channel != channel)
2403                                 continue;
2404                         phy_info = &port_info->phy_info[i];
2405                         break;
2406                 }
2407         }
2408         mutex_unlock(&ioc->sas_topology_mutex);
2409         return phy_info;
2410 }
2411
2412 /*
2413  * Work queue thread to clear the persitency table
2414  */
2415 static void
2416 mptsas_persist_clear_table(struct work_struct *work)
2417 {
2418         MPT_ADAPTER *ioc = container_of(work, MPT_ADAPTER, sas_persist_task);
2419
2420         mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2421 }
2422
2423 static void
2424 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
2425 {
2426         int rc;
2427
2428         sdev->no_uld_attach = data ? 1 : 0;
2429         rc = scsi_device_reprobe(sdev);
2430 }
2431
2432 static void
2433 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
2434 {
2435         starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
2436                         mptsas_reprobe_lun);
2437 }
2438
2439 static void
2440 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
2441 {
2442         CONFIGPARMS                     cfg;
2443         ConfigPageHeader_t              hdr;
2444         dma_addr_t                      dma_handle;
2445         pRaidVolumePage0_t              buffer = NULL;
2446         RaidPhysDiskPage0_t             phys_disk;
2447         int                             i;
2448         struct mptsas_hotplug_event     *ev;
2449
2450         memset(&cfg, 0 , sizeof(CONFIGPARMS));
2451         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
2452         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
2453         cfg.pageAddr = (channel << 8) + id;
2454         cfg.cfghdr.hdr = &hdr;
2455         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2456
2457         if (mpt_config(ioc, &cfg) != 0)
2458                 goto out;
2459
2460         if (!hdr.PageLength)
2461                 goto out;
2462
2463         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
2464             &dma_handle);
2465
2466         if (!buffer)
2467                 goto out;
2468
2469         cfg.physAddr = dma_handle;
2470         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2471
2472         if (mpt_config(ioc, &cfg) != 0)
2473                 goto out;
2474
2475         if (!(buffer->VolumeStatus.Flags &
2476             MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
2477                 goto out;
2478
2479         if (!buffer->NumPhysDisks)
2480                 goto out;
2481
2482         for (i = 0; i < buffer->NumPhysDisks; i++) {
2483
2484                 if (mpt_raid_phys_disk_pg0(ioc,
2485                     buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
2486                         continue;
2487
2488                 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2489                 if (!ev) {
2490                         printk(KERN_WARNING "mptsas: lost hotplug event\n");
2491                         goto out;
2492                 }
2493
2494                 INIT_WORK(&ev->work, mptsas_hotplug_work);
2495                 ev->ioc = ioc;
2496                 ev->id = phys_disk.PhysDiskID;
2497                 ev->channel = phys_disk.PhysDiskBus;
2498                 ev->phys_disk_num_valid = 1;
2499                 ev->phys_disk_num = phys_disk.PhysDiskNum;
2500                 ev->event_type = MPTSAS_ADD_DEVICE;
2501                 schedule_work(&ev->work);
2502         }
2503
2504  out:
2505         if (buffer)
2506                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
2507                     dma_handle);
2508 }
2509 /*
2510  * Work queue thread to handle SAS hotplug events
2511  */
2512 static void
2513 mptsas_hotplug_work(struct work_struct *work)
2514 {
2515         struct mptsas_hotplug_event *ev =
2516                 container_of(work, struct mptsas_hotplug_event, work);
2517
2518         MPT_ADAPTER *ioc = ev->ioc;
2519         struct mptsas_phyinfo *phy_info;
2520         struct sas_rphy *rphy;
2521         struct sas_port *port;
2522         struct scsi_device *sdev;
2523         struct scsi_target * starget;
2524         struct sas_identify identify;
2525         char *ds = NULL;
2526         struct mptsas_devinfo sas_device;
2527         VirtTarget *vtarget;
2528         VirtDevice *vdevice;
2529
2530         mutex_lock(&ioc->sas_discovery_mutex);
2531         switch (ev->event_type) {
2532         case MPTSAS_DEL_DEVICE:
2533
2534                 phy_info = NULL;
2535                 if (ev->phys_disk_num_valid) {
2536                         if (ev->hidden_raid_component){
2537                                 if (mptsas_sas_device_pg0(ioc, &sas_device,
2538                                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2539                                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2540                                     (ev->channel << 8) + ev->id)) {
2541                                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2542                                         "%s: exit at line=%d\n", ioc->name,
2543                                                 __FUNCTION__, __LINE__));
2544                                         break;
2545                                 }
2546                                 phy_info = mptsas_find_phyinfo_by_sas_address(
2547                                     ioc, sas_device.sas_address);
2548                         }else
2549                                 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
2550                                     ioc, ev->channel, ev->phys_disk_num);
2551                 }
2552
2553                 if (!phy_info)
2554                         phy_info = mptsas_find_phyinfo_by_target(ioc,
2555                             ev->channel, ev->id);
2556
2557                 /*
2558                  * Sanity checks, for non-existing phys and remote rphys.
2559                  */
2560                 if (!phy_info){
2561                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2562                                 "%s: exit at line=%d\n", ioc->name,
2563                                 __FUNCTION__, __LINE__));
2564                         break;
2565                 }
2566                 if (!phy_info->port_details) {
2567                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2568                                 "%s: exit at line=%d\n", ioc->name,
2569                                 __FUNCTION__, __LINE__));
2570                         break;
2571                 }
2572                 rphy = mptsas_get_rphy(phy_info);
2573                 if (!rphy) {
2574                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2575                                 "%s: exit at line=%d\n", ioc->name,
2576                                 __FUNCTION__, __LINE__));
2577                         break;
2578                 }
2579
2580                 port = mptsas_get_port(phy_info);
2581                 if (!port) {
2582                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2583                                 "%s: exit at line=%d\n", ioc->name,
2584                                 __FUNCTION__, __LINE__));
2585                         break;
2586                 }
2587
2588                 starget = mptsas_get_starget(phy_info);
2589                 if (starget) {
2590                         vtarget = starget->hostdata;
2591
2592                         if (!vtarget) {
2593                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2594                                         "%s: exit at line=%d\n", ioc->name,
2595                                         __FUNCTION__, __LINE__));
2596                                 break;
2597                         }
2598
2599                         /*
2600                          * Handling  RAID components
2601                          */
2602                         if (ev->phys_disk_num_valid &&
2603                             ev->hidden_raid_component) {
2604                                 printk(MYIOC_s_INFO_FMT
2605                                     "RAID Hidding: channel=%d, id=%d, "
2606                                     "physdsk %d \n", ioc->name, ev->channel,
2607                                     ev->id, ev->phys_disk_num);
2608                                 vtarget->id = ev->phys_disk_num;
2609                                 vtarget->tflags |=
2610                                     MPT_TARGET_FLAGS_RAID_COMPONENT;
2611                                 mptsas_reprobe_target(starget, 1);
2612                                 phy_info->attached.phys_disk_num =
2613                                     ev->phys_disk_num;
2614                         break;
2615                         }
2616                 }
2617
2618                 if (phy_info->attached.device_info &
2619                     MPI_SAS_DEVICE_INFO_SSP_TARGET)
2620                         ds = "ssp";
2621                 if (phy_info->attached.device_info &
2622                     MPI_SAS_DEVICE_INFO_STP_TARGET)
2623                         ds = "stp";
2624                 if (phy_info->attached.device_info &
2625                     MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2626                         ds = "sata";
2627
2628                 printk(MYIOC_s_INFO_FMT
2629                        "removing %s device, channel %d, id %d, phy %d\n",
2630                        ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
2631                 dev_printk(KERN_DEBUG, &port->dev,
2632                     "delete port (%d)\n", port->port_identifier);
2633                 sas_port_delete(port);
2634                 mptsas_port_delete(ioc, phy_info->port_details);
2635                 break;
2636         case MPTSAS_ADD_DEVICE:
2637
2638                 if (ev->phys_disk_num_valid)
2639                         mpt_findImVolumes(ioc);
2640
2641                 /*
2642                  * Refresh sas device pg0 data
2643                  */
2644                 if (mptsas_sas_device_pg0(ioc, &sas_device,
2645                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2646                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2647                         (ev->channel << 8) + ev->id)) {
2648                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2649                                         "%s: exit at line=%d\n", ioc->name,
2650                                         __FUNCTION__, __LINE__));
2651                         break;
2652                 }
2653
2654                 __mptsas_discovery_work(ioc);
2655
2656                 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
2657                                 sas_device.sas_address);
2658
2659                 if (!phy_info || !phy_info->port_details) {
2660                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2661                                 "%s: exit at line=%d\n", ioc->name,
2662                                 __FUNCTION__, __LINE__));
2663                         break;
2664                 }
2665
2666                 starget = mptsas_get_starget(phy_info);
2667                 if (starget && (!ev->hidden_raid_component)){
2668
2669                         vtarget = starget->hostdata;
2670
2671                         if (!vtarget) {
2672                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2673                                         "%s: exit at line=%d\n", ioc->name,
2674                                         __FUNCTION__, __LINE__));
2675                                 break;
2676                         }
2677                         /*
2678                          * Handling  RAID components
2679                          */
2680                         if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
2681                                 printk(MYIOC_s_INFO_FMT
2682                                     "RAID Exposing: channel=%d, id=%d, "
2683                                     "physdsk %d \n", ioc->name, ev->channel,
2684                                     ev->id, ev->phys_disk_num);
2685                                 vtarget->tflags &=
2686                                     ~MPT_TARGET_FLAGS_RAID_COMPONENT;
2687                                 vtarget->id = ev->id;
2688                                 mptsas_reprobe_target(starget, 0);
2689                                 phy_info->attached.phys_disk_num = ~0;
2690                         }
2691                         break;
2692                 }
2693
2694                 if (mptsas_get_rphy(phy_info)) {
2695                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2696                                 "%s: exit at line=%d\n", ioc->name,
2697                                 __FUNCTION__, __LINE__));
2698                         if (ev->channel) printk("%d\n", __LINE__);
2699                         break;
2700                 }
2701
2702                 port = mptsas_get_port(phy_info);
2703                 if (!port) {
2704                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2705                                 "%s: exit at line=%d\n", ioc->name,
2706                                 __FUNCTION__, __LINE__));
2707                         break;
2708                 }
2709                 memcpy(&phy_info->attached, &sas_device,
2710                     sizeof(struct mptsas_devinfo));
2711
2712                 if (phy_info->attached.device_info &
2713                     MPI_SAS_DEVICE_INFO_SSP_TARGET)
2714                         ds = "ssp";
2715                 if (phy_info->attached.device_info &
2716                     MPI_SAS_DEVICE_INFO_STP_TARGET)
2717                         ds = "stp";
2718                 if (phy_info->attached.device_info &
2719                     MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2720                         ds = "sata";
2721
2722                 printk(MYIOC_s_INFO_FMT
2723                        "attaching %s device, channel %d, id %d, phy %d\n",
2724                        ioc->name, ds, ev->channel, ev->id, ev->phy_id);
2725
2726                 mptsas_parse_device_info(&identify, &phy_info->attached);
2727                 rphy = sas_end_device_alloc(port);
2728                 if (!rphy) {
2729                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2730                                 "%s: exit at line=%d\n", ioc->name,
2731                                 __FUNCTION__, __LINE__));
2732                         break; /* non-fatal: an rphy can be added later */
2733                 }
2734
2735                 rphy->identify = identify;
2736                 if (sas_rphy_add(rphy)) {
2737                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2738                                 "%s: exit at line=%d\n", ioc->name,
2739                                 __FUNCTION__, __LINE__));
2740                         sas_rphy_free(rphy);
2741                         break;
2742                 }
2743                 mptsas_set_rphy(ioc, phy_info, rphy);
2744                 break;
2745         case MPTSAS_ADD_RAID:
2746                 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2747                     ev->id, 0);
2748                 if (sdev) {
2749                         scsi_device_put(sdev);
2750                         break;
2751                 }
2752                 printk(MYIOC_s_INFO_FMT
2753                        "attaching raid volume, channel %d, id %d\n",
2754                        ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2755                 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ev->id, 0);
2756                 mpt_findImVolumes(ioc);
2757                 break;
2758         case MPTSAS_DEL_RAID:
2759                 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2760                     ev->id, 0);
2761                 if (!sdev)
2762                         break;
2763                 printk(MYIOC_s_INFO_FMT
2764                        "removing raid volume, channel %d, id %d\n",
2765                        ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2766                 vdevice = sdev->hostdata;
2767                 scsi_remove_device(sdev);
2768                 scsi_device_put(sdev);
2769                 mpt_findImVolumes(ioc);
2770                 break;
2771         case MPTSAS_ADD_INACTIVE_VOLUME:
2772                 mptsas_adding_inactive_raid_components(ioc,
2773                     ev->channel, ev->id);
2774                 break;
2775         case MPTSAS_IGNORE_EVENT:
2776         default:
2777                 break;
2778         }
2779
2780         mutex_unlock(&ioc->sas_discovery_mutex);
2781         kfree(ev);
2782 }
2783
2784 static void
2785 mptsas_send_sas_event(MPT_ADAPTER *ioc,
2786                 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
2787 {
2788         struct mptsas_hotplug_event *ev;
2789         u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
2790         __le64 sas_address;
2791
2792         if ((device_info &
2793              (MPI_SAS_DEVICE_INFO_SSP_TARGET |
2794               MPI_SAS_DEVICE_INFO_STP_TARGET |
2795               MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
2796                 return;
2797
2798         switch (sas_event_data->ReasonCode) {
2799         case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
2800
2801                 mptsas_target_reset_queue(ioc, sas_event_data);
2802                 break;
2803
2804         case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
2805                 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2806                 if (!ev) {
2807                         printk(KERN_WARNING "mptsas: lost hotplug event\n");
2808                         break;
2809                 }
2810
2811                 INIT_WORK(&ev->work, mptsas_hotplug_work);
2812                 ev->ioc = ioc;
2813                 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
2814                 ev->parent_handle =
2815                     le16_to_cpu(sas_event_data->ParentDevHandle);
2816                 ev->channel = sas_event_data->Bus;
2817                 ev->id = sas_event_data->TargetID;
2818                 ev->phy_id = sas_event_data->PhyNum;
2819                 memcpy(&sas_address, &sas_event_data->SASAddress,
2820                     sizeof(__le64));
2821                 ev->sas_address = le64_to_cpu(sas_address);
2822                 ev->device_info = device_info;
2823
2824                 if (sas_event_data->ReasonCode &
2825                     MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
2826                         ev->event_type = MPTSAS_ADD_DEVICE;
2827                 else
2828                         ev->event_type = MPTSAS_DEL_DEVICE;
2829                 schedule_work(&ev->work);
2830                 break;
2831         case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
2832         /*
2833          * Persistent table is full.
2834          */
2835                 INIT_WORK(&ioc->sas_persist_task,
2836                     mptsas_persist_clear_table);
2837                 schedule_work(&ioc->sas_persist_task);
2838                 break;
2839         /*
2840          * TODO, handle other events
2841          */
2842         case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
2843         case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
2844         case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
2845         case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
2846         case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
2847         case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
2848         case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
2849         default:
2850                 break;
2851         }
2852 }
2853 static void
2854 mptsas_send_raid_event(MPT_ADAPTER *ioc,
2855                 EVENT_DATA_RAID *raid_event_data)
2856 {
2857         struct mptsas_hotplug_event *ev;
2858         int status = le32_to_cpu(raid_event_data->SettingsStatus);
2859         int state = (status >> 8) & 0xff;
2860
2861         if (ioc->bus_type != SAS)
2862                 return;
2863
2864         ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2865         if (!ev) {
2866                 printk(KERN_WARNING "mptsas: lost hotplug event\n");
2867                 return;
2868         }
2869
2870         INIT_WORK(&ev->work, mptsas_hotplug_work);
2871         ev->ioc = ioc;
2872         ev->id = raid_event_data->VolumeID;
2873         ev->channel = raid_event_data->VolumeBus;
2874         ev->event_type = MPTSAS_IGNORE_EVENT;
2875
2876         switch (raid_event_data->ReasonCode) {
2877         case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
2878                 ev->phys_disk_num_valid = 1;
2879                 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2880                 ev->event_type = MPTSAS_ADD_DEVICE;
2881                 break;
2882         case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
2883                 ev->phys_disk_num_valid = 1;
2884                 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2885                 ev->hidden_raid_component = 1;
2886                 ev->event_type = MPTSAS_DEL_DEVICE;
2887                 break;
2888         case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
2889                 switch (state) {
2890                 case MPI_PD_STATE_ONLINE:
2891                 case MPI_PD_STATE_NOT_COMPATIBLE:
2892                         ev->phys_disk_num_valid = 1;
2893                         ev->phys_disk_num = raid_event_data->PhysDiskNum;
2894                         ev->hidden_raid_component = 1;
2895                         ev->event_type = MPTSAS_ADD_DEVICE;
2896                         break;
2897                 case MPI_PD_STATE_MISSING:
2898                 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
2899                 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
2900                 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
2901                         ev->phys_disk_num_valid = 1;
2902                         ev->phys_disk_num = raid_event_data->PhysDiskNum;
2903                         ev->event_type = MPTSAS_DEL_DEVICE;
2904                         break;
2905                 default:
2906                         break;
2907                 }
2908                 break;
2909         case MPI_EVENT_RAID_RC_VOLUME_DELETED:
2910                 ev->event_type = MPTSAS_DEL_RAID;
2911                 break;
2912         case MPI_EVENT_RAID_RC_VOLUME_CREATED:
2913                 ev->event_type = MPTSAS_ADD_RAID;
2914                 break;
2915         case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
2916                 switch (state) {
2917                 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
2918                 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
2919                         ev->event_type = MPTSAS_DEL_RAID;
2920                         break;
2921                 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
2922                 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
2923                         ev->event_type = MPTSAS_ADD_RAID;
2924                         break;
2925                 default:
2926                         break;
2927                 }
2928                 break;
2929         default:
2930                 break;
2931         }
2932         schedule_work(&ev->work);
2933 }
2934
2935 static void
2936 mptsas_send_discovery_event(MPT_ADAPTER *ioc,
2937         EVENT_DATA_SAS_DISCOVERY *discovery_data)
2938 {
2939         struct mptsas_discovery_event *ev;
2940
2941         /*
2942          * DiscoveryStatus
2943          *
2944          * This flag will be non-zero when firmware
2945          * kicks off discovery, and return to zero
2946          * once its completed.
2947          */
2948         if (discovery_data->DiscoveryStatus)
2949                 return;
2950
2951         ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2952         if (!ev)
2953                 return;
2954         INIT_WORK(&ev->work, mptsas_discovery_work);
2955         ev->ioc = ioc;
2956         schedule_work(&ev->work);
2957 };
2958
2959 /*
2960  * mptsas_send_ir2_event - handle exposing hidden disk when
2961  * an inactive raid volume is added
2962  *
2963  * @ioc: Pointer to MPT_ADAPTER structure
2964  * @ir2_data
2965  *
2966  */
2967 static void
2968 mptsas_send_ir2_event(MPT_ADAPTER *ioc, PTR_MPI_EVENT_DATA_IR2 ir2_data)
2969 {
2970         struct mptsas_hotplug_event *ev;
2971
2972         if (ir2_data->ReasonCode !=
2973             MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED)
2974                 return;
2975
2976         ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2977         if (!ev)
2978                 return;
2979
2980         INIT_WORK(&ev->work, mptsas_hotplug_work);
2981         ev->ioc = ioc;
2982         ev->id = ir2_data->TargetID;
2983         ev->channel = ir2_data->Bus;
2984         ev->event_type = MPTSAS_ADD_INACTIVE_VOLUME;
2985
2986         schedule_work(&ev->work);
2987 };
2988
2989 static int
2990 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
2991 {
2992         int rc=1;
2993         u8 event = le32_to_cpu(reply->Event) & 0xFF;
2994
2995         if (!ioc->sh)
2996                 goto out;
2997
2998         /*
2999          * sas_discovery_ignore_events
3000          *
3001          * This flag is to prevent anymore processing of
3002          * sas events once mptsas_remove function is called.
3003          */
3004         if (ioc->sas_discovery_ignore_events) {
3005                 rc = mptscsih_event_process(ioc, reply);
3006                 goto out;
3007         }
3008
3009         switch (event) {
3010         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
3011                 mptsas_send_sas_event(ioc,
3012                         (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
3013                 break;
3014         case MPI_EVENT_INTEGRATED_RAID:
3015                 mptsas_send_raid_event(ioc,
3016                         (EVENT_DATA_RAID *)reply->Data);
3017                 break;
3018         case MPI_EVENT_PERSISTENT_TABLE_FULL:
3019                 INIT_WORK(&ioc->sas_persist_task,
3020                     mptsas_persist_clear_table);
3021                 schedule_work(&ioc->sas_persist_task);
3022                 break;
3023          case MPI_EVENT_SAS_DISCOVERY:
3024                 mptsas_send_discovery_event(ioc,
3025                         (EVENT_DATA_SAS_DISCOVERY *)reply->Data);
3026                 break;
3027         case MPI_EVENT_IR2:
3028                 mptsas_send_ir2_event(ioc,
3029                     (PTR_MPI_EVENT_DATA_IR2)reply->Data);
3030                 break;
3031         default:
3032                 rc = mptscsih_event_process(ioc, reply);
3033                 break;
3034         }
3035  out:
3036
3037         return rc;
3038 }
3039
3040 static int
3041 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3042 {
3043         struct Scsi_Host        *sh;
3044         MPT_SCSI_HOST           *hd;
3045         MPT_ADAPTER             *ioc;
3046         unsigned long            flags;
3047         int                      ii;
3048         int                      numSGE = 0;
3049         int                      scale;
3050         int                      ioc_cap;
3051         int                     error=0;
3052         int                     r;
3053
3054         r = mpt_attach(pdev,id);
3055         if (r)
3056                 return r;
3057
3058         ioc = pci_get_drvdata(pdev);
3059         ioc->DoneCtx = mptsasDoneCtx;
3060         ioc->TaskCtx = mptsasTaskCtx;
3061         ioc->InternalCtx = mptsasInternalCtx;
3062
3063         /*  Added sanity check on readiness of the MPT adapter.
3064          */
3065         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
3066                 printk(MYIOC_s_WARN_FMT
3067                   "Skipping because it's not operational!\n",
3068                   ioc->name);
3069                 error = -ENODEV;
3070                 goto out_mptsas_probe;
3071         }
3072
3073         if (!ioc->active) {
3074                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
3075                   ioc->name);
3076                 error = -ENODEV;
3077                 goto out_mptsas_probe;
3078         }
3079
3080         /*  Sanity check - ensure at least 1 port is INITIATOR capable
3081          */
3082         ioc_cap = 0;
3083         for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
3084                 if (ioc->pfacts[ii].ProtocolFlags &
3085                                 MPI_PORTFACTS_PROTOCOL_INITIATOR)
3086                         ioc_cap++;
3087         }
3088
3089         if (!ioc_cap) {
3090                 printk(MYIOC_s_WARN_FMT
3091                         "Skipping ioc=%p because SCSI Initiator mode "
3092                         "is NOT enabled!\n", ioc->name, ioc);
3093                 return 0;
3094         }
3095
3096         sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
3097         if (!sh) {
3098                 printk(MYIOC_s_WARN_FMT
3099                         "Unable to register controller with SCSI subsystem\n",
3100                         ioc->name);
3101                 error = -1;
3102                 goto out_mptsas_probe;
3103         }
3104
3105         spin_lock_irqsave(&ioc->FreeQlock, flags);
3106
3107         /* Attach the SCSI Host to the IOC structure
3108          */
3109         ioc->sh = sh;
3110
3111         sh->io_port = 0;
3112         sh->n_io_port = 0;
3113         sh->irq = 0;
3114
3115         /* set 16 byte cdb's */
3116         sh->max_cmd_len = 16;
3117
3118         sh->max_id = ioc->pfacts[0].PortSCSIID;
3119         sh->max_lun = max_lun;
3120
3121         sh->transportt = mptsas_transport_template;
3122
3123         sh->this_id = ioc->pfacts[0].PortSCSIID;
3124
3125         /* Required entry.
3126          */
3127         sh->unique_id = ioc->id;
3128
3129         INIT_LIST_HEAD(&ioc->sas_topology);
3130         mutex_init(&ioc->sas_topology_mutex);
3131         mutex_init(&ioc->sas_discovery_mutex);
3132         mutex_init(&ioc->sas_mgmt.mutex);
3133         init_completion(&ioc->sas_mgmt.done);
3134
3135         /* Verify that we won't exceed the maximum
3136          * number of chain buffers
3137          * We can optimize:  ZZ = req_sz/sizeof(SGE)
3138          * For 32bit SGE's:
3139          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
3140          *               + (req_sz - 64)/sizeof(SGE)
3141          * A slightly different algorithm is required for
3142          * 64bit SGEs.
3143          */
3144         scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3145         if (sizeof(dma_addr_t) == sizeof(u64)) {
3146                 numSGE = (scale - 1) *
3147                   (ioc->facts.MaxChainDepth-1) + scale +
3148                   (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
3149                   sizeof(u32));
3150         } else {
3151                 numSGE = 1 + (scale - 1) *
3152                   (ioc->facts.MaxChainDepth-1) + scale +
3153                   (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
3154                   sizeof(u32));
3155         }
3156
3157         if (numSGE < sh->sg_tablesize) {
3158                 /* Reset this value */
3159                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3160                   "Resetting sg_tablesize to %d from %d\n",
3161                   ioc->name, numSGE, sh->sg_tablesize));
3162                 sh->sg_tablesize = numSGE;
3163         }
3164
3165         hd = (MPT_SCSI_HOST *) sh->hostdata;
3166         hd->ioc = ioc;
3167
3168         /* SCSI needs scsi_cmnd lookup table!
3169          * (with size equal to req_depth*PtrSz!)
3170          */
3171         hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
3172         if (!hd->ScsiLookup) {
3173                 error = -ENOMEM;
3174                 goto out_mptsas_probe;
3175         }
3176
3177         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
3178                  ioc->name, hd->ScsiLookup));
3179
3180         /* Clear the TM flags
3181          */
3182         hd->tmPending = 0;
3183         hd->tmState = TM_STATE_NONE;
3184         hd->resetPending = 0;
3185         hd->abortSCpnt = NULL;
3186
3187         /* Clear the pointer used to store
3188          * single-threaded commands, i.e., those
3189          * issued during a bus scan, dv and
3190          * configuration pages.
3191          */
3192         hd->cmdPtr = NULL;
3193
3194         /* Initialize this SCSI Hosts' timers
3195          * To use, set the timer expires field
3196          * and add_timer
3197          */
3198         init_timer(&hd->timer);
3199         hd->timer.data = (unsigned long) hd;
3200         hd->timer.function = mptscsih_timer_expired;
3201
3202         ioc->sas_data.ptClear = mpt_pt_clear;
3203
3204         init_waitqueue_head(&hd->scandv_waitq);
3205         hd->scandv_wait_done = 0;
3206         hd->last_queue_full = 0;
3207         INIT_LIST_HEAD(&hd->target_reset_list);
3208         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3209
3210         if (ioc->sas_data.ptClear==1) {
3211                 mptbase_sas_persist_operation(
3212                     ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
3213         }
3214
3215         error = scsi_add_host(sh, &ioc->pcidev->dev);
3216         if (error) {
3217                 dprintk(ioc, printk(KERN_ERR MYNAM
3218                   "scsi_add_host failed\n"));
3219                 goto out_mptsas_probe;
3220         }
3221
3222         mptsas_scan_sas_topology(ioc);
3223
3224         return 0;
3225
3226  out_mptsas_probe:
3227
3228         mptscsih_remove(pdev);
3229         return error;
3230 }
3231
3232 static void __devexit mptsas_remove(struct pci_dev *pdev)
3233 {
3234         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
3235         struct mptsas_portinfo *p, *n;
3236         int i;
3237
3238         ioc->sas_discovery_ignore_events = 1;
3239         sas_remove_host(ioc->sh);
3240
3241         mutex_lock(&ioc->sas_topology_mutex);
3242         list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
3243                 list_del(&p->list);
3244                 for (i = 0 ; i < p->num_phys ; i++)
3245                         mptsas_port_delete(ioc, p->phy_info[i].port_details);
3246                 kfree(p->phy_info);
3247                 kfree(p);
3248         }
3249         mutex_unlock(&ioc->sas_topology_mutex);
3250
3251         mptscsih_remove(pdev);
3252 }
3253
3254 static struct pci_device_id mptsas_pci_table[] = {
3255         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
3256                 PCI_ANY_ID, PCI_ANY_ID },
3257         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
3258                 PCI_ANY_ID, PCI_ANY_ID },
3259         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
3260                 PCI_ANY_ID, PCI_ANY_ID },
3261         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
3262                 PCI_ANY_ID, PCI_ANY_ID },
3263         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
3264                 PCI_ANY_ID, PCI_ANY_ID },
3265         {0}     /* Terminating entry */
3266 };
3267 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
3268
3269
3270 static struct pci_driver mptsas_driver = {
3271         .name           = "mptsas",
3272         .id_table       = mptsas_pci_table,
3273         .probe          = mptsas_probe,
3274         .remove         = __devexit_p(mptsas_remove),
3275         .shutdown       = mptscsih_shutdown,
3276 #ifdef CONFIG_PM
3277         .suspend        = mptscsih_suspend,
3278         .resume         = mptscsih_resume,
3279 #endif
3280 };
3281
3282 static int __init
3283 mptsas_init(void)
3284 {
3285         int error;
3286
3287         show_mptmod_ver(my_NAME, my_VERSION);
3288
3289         mptsas_transport_template =
3290             sas_attach_transport(&mptsas_transport_functions);
3291         if (!mptsas_transport_template)
3292                 return -ENODEV;
3293
3294         mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
3295         mptsasTaskCtx = mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
3296         mptsasInternalCtx =
3297                 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
3298         mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
3299
3300         mpt_event_register(mptsasDoneCtx, mptsas_event_process);
3301         mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
3302
3303         error = pci_register_driver(&mptsas_driver);
3304         if (error)
3305                 sas_release_transport(mptsas_transport_template);
3306
3307         return error;
3308 }
3309
3310 static void __exit
3311 mptsas_exit(void)
3312 {
3313         pci_unregister_driver(&mptsas_driver);
3314         sas_release_transport(mptsas_transport_template);
3315
3316         mpt_reset_deregister(mptsasDoneCtx);
3317         mpt_event_deregister(mptsasDoneCtx);
3318
3319         mpt_deregister(mptsasMgmtCtx);
3320         mpt_deregister(mptsasInternalCtx);
3321         mpt_deregister(mptsasTaskCtx);
3322         mpt_deregister(mptsasDoneCtx);
3323 }
3324
3325 module_init(mptsas_init);
3326 module_exit(mptsas_exit);