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