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