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