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