[GFS2] Fix up merge of Linus' kernel into GFS2
[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         /* FIXME: only have link errors on local phys */
856         if (!scsi_is_sas_phy_local(phy))
857                 return -EINVAL;
858
859         hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
860         hdr.ExtPageLength = 0;
861         hdr.PageNumber = 1 /* page number 1*/;
862         hdr.Reserved1 = 0;
863         hdr.Reserved2 = 0;
864         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
865         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
866
867         cfg.cfghdr.ehdr = &hdr;
868         cfg.physAddr = -1;
869         cfg.pageAddr = phy->identify.phy_identifier;
870         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
871         cfg.dir = 0;    /* read */
872         cfg.timeout = 10;
873
874         error = mpt_config(ioc, &cfg);
875         if (error)
876                 return error;
877         if (!hdr.ExtPageLength)
878                 return -ENXIO;
879
880         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
881                                       &dma_handle);
882         if (!buffer)
883                 return -ENOMEM;
884
885         cfg.physAddr = dma_handle;
886         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
887
888         error = mpt_config(ioc, &cfg);
889         if (error)
890                 goto out_free_consistent;
891
892         mptsas_print_phy_pg1(buffer);
893
894         phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
895         phy->running_disparity_error_count =
896                 le32_to_cpu(buffer->RunningDisparityErrorCount);
897         phy->loss_of_dword_sync_count =
898                 le32_to_cpu(buffer->LossDwordSynchCount);
899         phy->phy_reset_problem_count =
900                 le32_to_cpu(buffer->PhyResetProblemCount);
901
902  out_free_consistent:
903         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
904                             buffer, dma_handle);
905         return error;
906 }
907
908 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
909                 MPT_FRAME_HDR *reply)
910 {
911         ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
912         if (reply != NULL) {
913                 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
914                 memcpy(ioc->sas_mgmt.reply, reply,
915                     min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
916         }
917         complete(&ioc->sas_mgmt.done);
918         return 1;
919 }
920
921 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
922 {
923         MPT_ADAPTER *ioc = phy_to_ioc(phy);
924         SasIoUnitControlRequest_t *req;
925         SasIoUnitControlReply_t *reply;
926         MPT_FRAME_HDR *mf;
927         MPIHeader_t *hdr;
928         unsigned long timeleft;
929         int error = -ERESTARTSYS;
930
931         /* FIXME: fusion doesn't allow non-local phy reset */
932         if (!scsi_is_sas_phy_local(phy))
933                 return -EINVAL;
934
935         /* not implemented for expanders */
936         if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
937                 return -ENXIO;
938
939         if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
940                 goto out;
941
942         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
943         if (!mf) {
944                 error = -ENOMEM;
945                 goto out_unlock;
946         }
947
948         hdr = (MPIHeader_t *) mf;
949         req = (SasIoUnitControlRequest_t *)mf;
950         memset(req, 0, sizeof(SasIoUnitControlRequest_t));
951         req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
952         req->MsgContext = hdr->MsgContext;
953         req->Operation = hard_reset ?
954                 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
955         req->PhyNum = phy->identify.phy_identifier;
956
957         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
958
959         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
960                         10 * HZ);
961         if (!timeleft) {
962                 /* On timeout reset the board */
963                 mpt_free_msg_frame(ioc, mf);
964                 mpt_HardResetHandler(ioc, CAN_SLEEP);
965                 error = -ETIMEDOUT;
966                 goto out_unlock;
967         }
968
969         /* a reply frame is expected */
970         if ((ioc->sas_mgmt.status &
971             MPT_IOCTL_STATUS_RF_VALID) == 0) {
972                 error = -ENXIO;
973                 goto out_unlock;
974         }
975
976         /* process the completed Reply Message Frame */
977         reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
978         if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
979                 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
980                     __FUNCTION__,
981                     reply->IOCStatus,
982                     reply->IOCLogInfo);
983                 error = -ENXIO;
984                 goto out_unlock;
985         }
986
987         error = 0;
988
989  out_unlock:
990         mutex_unlock(&ioc->sas_mgmt.mutex);
991  out:
992         return error;
993 }
994
995 static int
996 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
997 {
998         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
999         int i, error;
1000         struct mptsas_portinfo *p;
1001         struct mptsas_enclosure enclosure_info;
1002         u64 enclosure_handle;
1003
1004         mutex_lock(&ioc->sas_topology_mutex);
1005         list_for_each_entry(p, &ioc->sas_topology, list) {
1006                 for (i = 0; i < p->num_phys; i++) {
1007                         if (p->phy_info[i].attached.sas_address ==
1008                             rphy->identify.sas_address) {
1009                                 enclosure_handle = p->phy_info[i].
1010                                         attached.handle_enclosure;
1011                                 goto found_info;
1012                         }
1013                 }
1014         }
1015         mutex_unlock(&ioc->sas_topology_mutex);
1016         return -ENXIO;
1017
1018  found_info:
1019         mutex_unlock(&ioc->sas_topology_mutex);
1020         memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
1021         error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
1022                         (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
1023                          MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
1024         if (!error)
1025                 *identifier = enclosure_info.enclosure_logical_id;
1026         return error;
1027 }
1028
1029 static int
1030 mptsas_get_bay_identifier(struct sas_rphy *rphy)
1031 {
1032         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1033         struct mptsas_portinfo *p;
1034         int i, rc;
1035
1036         mutex_lock(&ioc->sas_topology_mutex);
1037         list_for_each_entry(p, &ioc->sas_topology, list) {
1038                 for (i = 0; i < p->num_phys; i++) {
1039                         if (p->phy_info[i].attached.sas_address ==
1040                             rphy->identify.sas_address) {
1041                                 rc = p->phy_info[i].attached.slot;
1042                                 goto out;
1043                         }
1044                 }
1045         }
1046         rc = -ENXIO;
1047  out:
1048         mutex_unlock(&ioc->sas_topology_mutex);
1049         return rc;
1050 }
1051
1052 static struct sas_function_template mptsas_transport_functions = {
1053         .get_linkerrors         = mptsas_get_linkerrors,
1054         .get_enclosure_identifier = mptsas_get_enclosure_identifier,
1055         .get_bay_identifier     = mptsas_get_bay_identifier,
1056         .phy_reset              = mptsas_phy_reset,
1057 };
1058
1059 static struct scsi_transport_template *mptsas_transport_template;
1060
1061 static int
1062 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
1063 {
1064         ConfigExtendedPageHeader_t hdr;
1065         CONFIGPARMS cfg;
1066         SasIOUnitPage0_t *buffer;
1067         dma_addr_t dma_handle;
1068         int error, i;
1069
1070         hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
1071         hdr.ExtPageLength = 0;
1072         hdr.PageNumber = 0;
1073         hdr.Reserved1 = 0;
1074         hdr.Reserved2 = 0;
1075         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1076         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1077
1078         cfg.cfghdr.ehdr = &hdr;
1079         cfg.physAddr = -1;
1080         cfg.pageAddr = 0;
1081         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1082         cfg.dir = 0;    /* read */
1083         cfg.timeout = 10;
1084
1085         error = mpt_config(ioc, &cfg);
1086         if (error)
1087                 goto out;
1088         if (!hdr.ExtPageLength) {
1089                 error = -ENXIO;
1090                 goto out;
1091         }
1092
1093         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1094                                             &dma_handle);
1095         if (!buffer) {
1096                 error = -ENOMEM;
1097                 goto out;
1098         }
1099
1100         cfg.physAddr = dma_handle;
1101         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1102
1103         error = mpt_config(ioc, &cfg);
1104         if (error)
1105                 goto out_free_consistent;
1106
1107         port_info->num_phys = buffer->NumPhys;
1108         port_info->phy_info = kcalloc(port_info->num_phys,
1109                 sizeof(*port_info->phy_info),GFP_KERNEL);
1110         if (!port_info->phy_info) {
1111                 error = -ENOMEM;
1112                 goto out_free_consistent;
1113         }
1114
1115         if (port_info->num_phys)
1116                 port_info->handle =
1117                     le16_to_cpu(buffer->PhyData[0].ControllerDevHandle);
1118         for (i = 0; i < port_info->num_phys; i++) {
1119                 mptsas_print_phy_data(&buffer->PhyData[i]);
1120                 port_info->phy_info[i].phy_id = i;
1121                 port_info->phy_info[i].port_id =
1122                     buffer->PhyData[i].Port;
1123                 port_info->phy_info[i].negotiated_link_rate =
1124                     buffer->PhyData[i].NegotiatedLinkRate;
1125                 port_info->phy_info[i].portinfo = port_info;
1126         }
1127
1128  out_free_consistent:
1129         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1130                             buffer, dma_handle);
1131  out:
1132         return error;
1133 }
1134
1135 static int
1136 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1137                 u32 form, u32 form_specific)
1138 {
1139         ConfigExtendedPageHeader_t hdr;
1140         CONFIGPARMS cfg;
1141         SasPhyPage0_t *buffer;
1142         dma_addr_t dma_handle;
1143         int error;
1144
1145         hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
1146         hdr.ExtPageLength = 0;
1147         hdr.PageNumber = 0;
1148         hdr.Reserved1 = 0;
1149         hdr.Reserved2 = 0;
1150         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1151         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1152
1153         cfg.cfghdr.ehdr = &hdr;
1154         cfg.dir = 0;    /* read */
1155         cfg.timeout = 10;
1156
1157         /* Get Phy Pg 0 for each Phy. */
1158         cfg.physAddr = -1;
1159         cfg.pageAddr = form + form_specific;
1160         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1161
1162         error = mpt_config(ioc, &cfg);
1163         if (error)
1164                 goto out;
1165
1166         if (!hdr.ExtPageLength) {
1167                 error = -ENXIO;
1168                 goto out;
1169         }
1170
1171         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1172                                       &dma_handle);
1173         if (!buffer) {
1174                 error = -ENOMEM;
1175                 goto out;
1176         }
1177
1178         cfg.physAddr = dma_handle;
1179         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1180
1181         error = mpt_config(ioc, &cfg);
1182         if (error)
1183                 goto out_free_consistent;
1184
1185         mptsas_print_phy_pg0(buffer);
1186
1187         phy_info->hw_link_rate = buffer->HwLinkRate;
1188         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1189         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1190         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1191
1192  out_free_consistent:
1193         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1194                             buffer, dma_handle);
1195  out:
1196         return error;
1197 }
1198
1199 static int
1200 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
1201                 u32 form, u32 form_specific)
1202 {
1203         ConfigExtendedPageHeader_t hdr;
1204         CONFIGPARMS cfg;
1205         SasDevicePage0_t *buffer;
1206         dma_addr_t dma_handle;
1207         __le64 sas_address;
1208         int error=0;
1209
1210         if (ioc->sas_discovery_runtime &&
1211                 mptsas_is_end_device(device_info))
1212                         goto out;
1213
1214         hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
1215         hdr.ExtPageLength = 0;
1216         hdr.PageNumber = 0;
1217         hdr.Reserved1 = 0;
1218         hdr.Reserved2 = 0;
1219         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1220         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1221
1222         cfg.cfghdr.ehdr = &hdr;
1223         cfg.pageAddr = form + form_specific;
1224         cfg.physAddr = -1;
1225         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1226         cfg.dir = 0;    /* read */
1227         cfg.timeout = 10;
1228
1229         memset(device_info, 0, sizeof(struct mptsas_devinfo));
1230         error = mpt_config(ioc, &cfg);
1231         if (error)
1232                 goto out;
1233         if (!hdr.ExtPageLength) {
1234                 error = -ENXIO;
1235                 goto out;
1236         }
1237
1238         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1239                                       &dma_handle);
1240         if (!buffer) {
1241                 error = -ENOMEM;
1242                 goto out;
1243         }
1244
1245         cfg.physAddr = dma_handle;
1246         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1247
1248         error = mpt_config(ioc, &cfg);
1249         if (error)
1250                 goto out_free_consistent;
1251
1252         mptsas_print_device_pg0(buffer);
1253
1254         device_info->handle = le16_to_cpu(buffer->DevHandle);
1255         device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
1256         device_info->handle_enclosure =
1257             le16_to_cpu(buffer->EnclosureHandle);
1258         device_info->slot = le16_to_cpu(buffer->Slot);
1259         device_info->phy_id = buffer->PhyNum;
1260         device_info->port_id = buffer->PhysicalPort;
1261         device_info->id = buffer->TargetID;
1262         device_info->channel = buffer->Bus;
1263         memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
1264         device_info->sas_address = le64_to_cpu(sas_address);
1265         device_info->device_info =
1266             le32_to_cpu(buffer->DeviceInfo);
1267
1268  out_free_consistent:
1269         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1270                             buffer, dma_handle);
1271  out:
1272         return error;
1273 }
1274
1275 static int
1276 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
1277                 u32 form, u32 form_specific)
1278 {
1279         ConfigExtendedPageHeader_t hdr;
1280         CONFIGPARMS cfg;
1281         SasExpanderPage0_t *buffer;
1282         dma_addr_t dma_handle;
1283         int i, error;
1284
1285         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1286         hdr.ExtPageLength = 0;
1287         hdr.PageNumber = 0;
1288         hdr.Reserved1 = 0;
1289         hdr.Reserved2 = 0;
1290         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1291         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1292
1293         cfg.cfghdr.ehdr = &hdr;
1294         cfg.physAddr = -1;
1295         cfg.pageAddr = form + form_specific;
1296         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1297         cfg.dir = 0;    /* read */
1298         cfg.timeout = 10;
1299
1300         memset(port_info, 0, sizeof(struct mptsas_portinfo));
1301         error = mpt_config(ioc, &cfg);
1302         if (error)
1303                 goto out;
1304
1305         if (!hdr.ExtPageLength) {
1306                 error = -ENXIO;
1307                 goto out;
1308         }
1309
1310         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1311                                       &dma_handle);
1312         if (!buffer) {
1313                 error = -ENOMEM;
1314                 goto out;
1315         }
1316
1317         cfg.physAddr = dma_handle;
1318         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1319
1320         error = mpt_config(ioc, &cfg);
1321         if (error)
1322                 goto out_free_consistent;
1323
1324         /* save config data */
1325         port_info->num_phys = buffer->NumPhys;
1326         port_info->handle = le16_to_cpu(buffer->DevHandle);
1327         port_info->phy_info = kcalloc(port_info->num_phys,
1328                 sizeof(*port_info->phy_info),GFP_KERNEL);
1329         if (!port_info->phy_info) {
1330                 error = -ENOMEM;
1331                 goto out_free_consistent;
1332         }
1333
1334         for (i = 0; i < port_info->num_phys; i++)
1335                 port_info->phy_info[i].portinfo = port_info;
1336
1337  out_free_consistent:
1338         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1339                             buffer, dma_handle);
1340  out:
1341         return error;
1342 }
1343
1344 static int
1345 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1346                 u32 form, u32 form_specific)
1347 {
1348         ConfigExtendedPageHeader_t hdr;
1349         CONFIGPARMS cfg;
1350         SasExpanderPage1_t *buffer;
1351         dma_addr_t dma_handle;
1352         int error=0;
1353
1354         if (ioc->sas_discovery_runtime &&
1355                 mptsas_is_end_device(&phy_info->attached))
1356                         goto out;
1357
1358         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1359         hdr.ExtPageLength = 0;
1360         hdr.PageNumber = 1;
1361         hdr.Reserved1 = 0;
1362         hdr.Reserved2 = 0;
1363         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1364         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1365
1366         cfg.cfghdr.ehdr = &hdr;
1367         cfg.physAddr = -1;
1368         cfg.pageAddr = form + form_specific;
1369         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1370         cfg.dir = 0;    /* read */
1371         cfg.timeout = 10;
1372
1373         error = mpt_config(ioc, &cfg);
1374         if (error)
1375                 goto out;
1376
1377         if (!hdr.ExtPageLength) {
1378                 error = -ENXIO;
1379                 goto out;
1380         }
1381
1382         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1383                                       &dma_handle);
1384         if (!buffer) {
1385                 error = -ENOMEM;
1386                 goto out;
1387         }
1388
1389         cfg.physAddr = dma_handle;
1390         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1391
1392         error = mpt_config(ioc, &cfg);
1393         if (error)
1394                 goto out_free_consistent;
1395
1396
1397         mptsas_print_expander_pg1(buffer);
1398
1399         /* save config data */
1400         phy_info->phy_id = buffer->PhyIdentifier;
1401         phy_info->port_id = buffer->PhysicalPort;
1402         phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
1403         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1404         phy_info->hw_link_rate = buffer->HwLinkRate;
1405         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1406         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1407
1408  out_free_consistent:
1409         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1410                             buffer, dma_handle);
1411  out:
1412         return error;
1413 }
1414
1415 static void
1416 mptsas_parse_device_info(struct sas_identify *identify,
1417                 struct mptsas_devinfo *device_info)
1418 {
1419         u16 protocols;
1420
1421         identify->sas_address = device_info->sas_address;
1422         identify->phy_identifier = device_info->phy_id;
1423
1424         /*
1425          * Fill in Phy Initiator Port Protocol.
1426          * Bits 6:3, more than one bit can be set, fall through cases.
1427          */
1428         protocols = device_info->device_info & 0x78;
1429         identify->initiator_port_protocols = 0;
1430         if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
1431                 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
1432         if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1433                 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
1434         if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
1435                 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
1436         if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
1437                 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
1438
1439         /*
1440          * Fill in Phy Target Port Protocol.
1441          * Bits 10:7, more than one bit can be set, fall through cases.
1442          */
1443         protocols = device_info->device_info & 0x780;
1444         identify->target_port_protocols = 0;
1445         if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1446                 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
1447         if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
1448                 identify->target_port_protocols |= SAS_PROTOCOL_STP;
1449         if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
1450                 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
1451         if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1452                 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
1453
1454         /*
1455          * Fill in Attached device type.
1456          */
1457         switch (device_info->device_info &
1458                         MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
1459         case MPI_SAS_DEVICE_INFO_NO_DEVICE:
1460                 identify->device_type = SAS_PHY_UNUSED;
1461                 break;
1462         case MPI_SAS_DEVICE_INFO_END_DEVICE:
1463                 identify->device_type = SAS_END_DEVICE;
1464                 break;
1465         case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
1466                 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
1467                 break;
1468         case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
1469                 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
1470                 break;
1471         }
1472 }
1473
1474 static int mptsas_probe_one_phy(struct device *dev,
1475                 struct mptsas_phyinfo *phy_info, int index, int local)
1476 {
1477         MPT_ADAPTER *ioc;
1478         struct sas_phy *phy;
1479         struct sas_port *port;
1480         int error = 0;
1481
1482         if (!dev) {
1483                 error = -ENODEV;
1484                 goto out;
1485         }
1486
1487         if (!phy_info->phy) {
1488                 phy = sas_phy_alloc(dev, index);
1489                 if (!phy) {
1490                         error = -ENOMEM;
1491                         goto out;
1492                 }
1493         } else
1494                 phy = phy_info->phy;
1495
1496         mptsas_parse_device_info(&phy->identify, &phy_info->identify);
1497
1498         /*
1499          * Set Negotiated link rate.
1500          */
1501         switch (phy_info->negotiated_link_rate) {
1502         case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
1503                 phy->negotiated_linkrate = SAS_PHY_DISABLED;
1504                 break;
1505         case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
1506                 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
1507                 break;
1508         case MPI_SAS_IOUNIT0_RATE_1_5:
1509                 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
1510                 break;
1511         case MPI_SAS_IOUNIT0_RATE_3_0:
1512                 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
1513                 break;
1514         case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
1515         case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
1516         default:
1517                 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
1518                 break;
1519         }
1520
1521         /*
1522          * Set Max hardware link rate.
1523          */
1524         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1525         case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
1526                 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1527                 break;
1528         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1529                 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1530                 break;
1531         default:
1532                 break;
1533         }
1534
1535         /*
1536          * Set Max programmed link rate.
1537          */
1538         switch (phy_info->programmed_link_rate &
1539                         MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1540         case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
1541                 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1542                 break;
1543         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1544                 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1545                 break;
1546         default:
1547                 break;
1548         }
1549
1550         /*
1551          * Set Min hardware link rate.
1552          */
1553         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
1554         case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
1555                 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1556                 break;
1557         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1558                 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1559                 break;
1560         default:
1561                 break;
1562         }
1563
1564         /*
1565          * Set Min programmed link rate.
1566          */
1567         switch (phy_info->programmed_link_rate &
1568                         MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
1569         case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
1570                 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1571                 break;
1572         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1573                 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1574                 break;
1575         default:
1576                 break;
1577         }
1578
1579         if (!phy_info->phy) {
1580
1581                 error = sas_phy_add(phy);
1582                 if (error) {
1583                         sas_phy_free(phy);
1584                         goto out;
1585                 }
1586                 phy_info->phy = phy;
1587         }
1588
1589         if (!phy_info->attached.handle ||
1590                         !phy_info->port_details)
1591                 goto out;
1592
1593         port = mptsas_get_port(phy_info);
1594         ioc = phy_to_ioc(phy_info->phy);
1595
1596         if (phy_info->sas_port_add_phy) {
1597
1598                 if (!port) {
1599                         port = sas_port_alloc_num(dev);
1600                         if (!port) {
1601                                 error = -ENOMEM;
1602                                 goto out;
1603                         }
1604                         error = sas_port_add(port);
1605                         if (error) {
1606                                 dfailprintk((MYIOC_s_ERR_FMT
1607                                         "%s: exit at line=%d\n", ioc->name,
1608                                         __FUNCTION__, __LINE__));
1609                                 goto out;
1610                         }
1611                         mptsas_set_port(phy_info, port);
1612                         dsaswideprintk((KERN_DEBUG
1613                             "sas_port_alloc: port=%p dev=%p port_id=%d\n",
1614                             port, dev, port->port_identifier));
1615                 }
1616                 dsaswideprintk((KERN_DEBUG "sas_port_add_phy: phy_id=%d\n",
1617                     phy_info->phy_id));
1618                 sas_port_add_phy(port, phy_info->phy);
1619                 phy_info->sas_port_add_phy = 0;
1620         }
1621
1622         if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
1623
1624                 struct sas_rphy *rphy;
1625                 struct device *parent;
1626                 struct sas_identify identify;
1627
1628                 parent = dev->parent->parent;
1629                 /*
1630                  * Let the hotplug_work thread handle processing
1631                  * the adding/removing of devices that occur
1632                  * after start of day.
1633                  */
1634                 if (ioc->sas_discovery_runtime &&
1635                         mptsas_is_end_device(&phy_info->attached))
1636                                 goto out;
1637
1638                 mptsas_parse_device_info(&identify, &phy_info->attached);
1639                 if (scsi_is_host_device(parent)) {
1640                         struct mptsas_portinfo *port_info;
1641                         int i;
1642
1643                         mutex_lock(&ioc->sas_topology_mutex);
1644                         port_info = mptsas_find_portinfo_by_handle(ioc,
1645                                                                    ioc->handle);
1646                         mutex_unlock(&ioc->sas_topology_mutex);
1647
1648                         for (i = 0; i < port_info->num_phys; i++)
1649                                 if (port_info->phy_info[i].identify.sas_address ==
1650                                     identify.sas_address) {
1651                                         sas_port_mark_backlink(port);
1652                                         goto out;
1653                                 }
1654
1655                 } else if (scsi_is_sas_rphy(parent)) {
1656                         struct sas_rphy *parent_rphy = dev_to_rphy(parent);
1657                         if (identify.sas_address ==
1658                             parent_rphy->identify.sas_address) {
1659                                 sas_port_mark_backlink(port);
1660                                 goto out;
1661                         }
1662                 }
1663
1664                 switch (identify.device_type) {
1665                 case SAS_END_DEVICE:
1666                         rphy = sas_end_device_alloc(port);
1667                         break;
1668                 case SAS_EDGE_EXPANDER_DEVICE:
1669                 case SAS_FANOUT_EXPANDER_DEVICE:
1670                         rphy = sas_expander_alloc(port, identify.device_type);
1671                         break;
1672                 default:
1673                         rphy = NULL;
1674                         break;
1675                 }
1676                 if (!rphy) {
1677                         dfailprintk((MYIOC_s_ERR_FMT
1678                                 "%s: exit at line=%d\n", ioc->name,
1679                                 __FUNCTION__, __LINE__));
1680                         goto out;
1681                 }
1682
1683                 rphy->identify = identify;
1684                 error = sas_rphy_add(rphy);
1685                 if (error) {
1686                         dfailprintk((MYIOC_s_ERR_FMT
1687                                 "%s: exit at line=%d\n", ioc->name,
1688                                 __FUNCTION__, __LINE__));
1689                         sas_rphy_free(rphy);
1690                         goto out;
1691                 }
1692                 mptsas_set_rphy(phy_info, rphy);
1693         }
1694
1695  out:
1696         return error;
1697 }
1698
1699 static int
1700 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
1701 {
1702         struct mptsas_portinfo *port_info, *hba;
1703         u32 handle = 0xFFFF;
1704         int error = -ENOMEM, i;
1705
1706         hba = kzalloc(sizeof(*port_info), GFP_KERNEL);
1707         if (! hba)
1708                 goto out;
1709
1710         error = mptsas_sas_io_unit_pg0(ioc, hba);
1711         if (error)
1712                 goto out_free_port_info;
1713
1714         mutex_lock(&ioc->sas_topology_mutex);
1715         ioc->handle = hba->handle;
1716         port_info = mptsas_find_portinfo_by_handle(ioc, hba->handle);
1717         if (!port_info) {
1718                 port_info = hba;
1719                 list_add_tail(&port_info->list, &ioc->sas_topology);
1720         } else {
1721                 port_info->handle = hba->handle;
1722                 for (i = 0; i < hba->num_phys; i++)
1723                         port_info->phy_info[i].negotiated_link_rate =
1724                                 hba->phy_info[i].negotiated_link_rate;
1725                 kfree(hba->phy_info);
1726                 kfree(hba);
1727                 hba = NULL;
1728         }
1729         mutex_unlock(&ioc->sas_topology_mutex);
1730
1731         for (i = 0; i < port_info->num_phys; i++) {
1732                 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
1733                         (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
1734                          MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
1735
1736                 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
1737                         (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
1738                          MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
1739                 port_info->phy_info[i].identify.phy_id =
1740                     port_info->phy_info[i].phy_id;
1741                 handle = port_info->phy_info[i].identify.handle;
1742
1743                 if (port_info->phy_info[i].attached.handle)
1744                         mptsas_sas_device_pg0(ioc,
1745                                 &port_info->phy_info[i].attached,
1746                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1747                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1748                                 port_info->phy_info[i].attached.handle);
1749         }
1750
1751         mptsas_setup_wide_ports(ioc, port_info);
1752
1753         for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
1754                 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
1755                     &port_info->phy_info[i], ioc->sas_index, 1);
1756
1757         return 0;
1758
1759  out_free_port_info:
1760         kfree(hba);
1761  out:
1762         return error;
1763 }
1764
1765 static int
1766 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
1767 {
1768         struct mptsas_portinfo *port_info, *p, *ex;
1769         struct device *parent;
1770         struct sas_rphy *rphy;
1771         int error = -ENOMEM, i, j;
1772
1773         ex = kzalloc(sizeof(*port_info), GFP_KERNEL);
1774         if (!ex)
1775                 goto out;
1776
1777         error = mptsas_sas_expander_pg0(ioc, ex,
1778                 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
1779                  MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
1780         if (error)
1781                 goto out_free_port_info;
1782
1783         *handle = ex->handle;
1784
1785         mutex_lock(&ioc->sas_topology_mutex);
1786         port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
1787         if (!port_info) {
1788                 port_info = ex;
1789                 list_add_tail(&port_info->list, &ioc->sas_topology);
1790         } else {
1791                 port_info->handle = ex->handle;
1792                 kfree(ex->phy_info);
1793                 kfree(ex);
1794                 ex = NULL;
1795         }
1796         mutex_unlock(&ioc->sas_topology_mutex);
1797
1798         for (i = 0; i < port_info->num_phys; i++) {
1799                 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
1800                         (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
1801                          MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
1802
1803                 if (port_info->phy_info[i].identify.handle) {
1804                         mptsas_sas_device_pg0(ioc,
1805                                 &port_info->phy_info[i].identify,
1806                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1807                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1808                                 port_info->phy_info[i].identify.handle);
1809                         port_info->phy_info[i].identify.phy_id =
1810                             port_info->phy_info[i].phy_id;
1811                 }
1812
1813                 if (port_info->phy_info[i].attached.handle) {
1814                         mptsas_sas_device_pg0(ioc,
1815                                 &port_info->phy_info[i].attached,
1816                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1817                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1818                                 port_info->phy_info[i].attached.handle);
1819                         port_info->phy_info[i].attached.phy_id =
1820                             port_info->phy_info[i].phy_id;
1821                 }
1822         }
1823
1824         parent = &ioc->sh->shost_gendev;
1825         for (i = 0; i < port_info->num_phys; i++) {
1826                 mutex_lock(&ioc->sas_topology_mutex);
1827                 list_for_each_entry(p, &ioc->sas_topology, list) {
1828                         for (j = 0; j < p->num_phys; j++) {
1829                                 if (port_info->phy_info[i].identify.handle !=
1830                                                 p->phy_info[j].attached.handle)
1831                                         continue;
1832                                 rphy = mptsas_get_rphy(&p->phy_info[j]);
1833                                 parent = &rphy->dev;
1834                         }
1835                 }
1836                 mutex_unlock(&ioc->sas_topology_mutex);
1837         }
1838
1839         mptsas_setup_wide_ports(ioc, port_info);
1840
1841         for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
1842                 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1843                     ioc->sas_index, 0);
1844
1845         return 0;
1846
1847  out_free_port_info:
1848         if (ex) {
1849                 kfree(ex->phy_info);
1850                 kfree(ex);
1851         }
1852  out:
1853         return error;
1854 }
1855
1856 /*
1857  * mptsas_delete_expander_phys
1858  *
1859  *
1860  * This will traverse topology, and remove expanders
1861  * that are no longer present
1862  */
1863 static void
1864 mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
1865 {
1866         struct mptsas_portinfo buffer;
1867         struct mptsas_portinfo *port_info, *n, *parent;
1868         struct mptsas_phyinfo *phy_info;
1869         struct scsi_target * starget;
1870         VirtTarget * vtarget;
1871         struct sas_port * port;
1872         int i;
1873         u64     expander_sas_address;
1874
1875         mutex_lock(&ioc->sas_topology_mutex);
1876         list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
1877
1878                 if (port_info->phy_info &&
1879                     (!(port_info->phy_info[0].identify.device_info &
1880                     MPI_SAS_DEVICE_INFO_SMP_TARGET)))
1881                         continue;
1882
1883                 if (mptsas_sas_expander_pg0(ioc, &buffer,
1884                      (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
1885                      MPI_SAS_EXPAND_PGAD_FORM_SHIFT), port_info->handle)) {
1886
1887                         /*
1888                          * Issue target reset to all child end devices
1889                          * then mark them deleted to prevent further
1890                          * IO going to them.
1891                          */
1892                         phy_info = port_info->phy_info;
1893                         for (i = 0; i < port_info->num_phys; i++, phy_info++) {
1894                                 starget = mptsas_get_starget(phy_info);
1895                                 if (!starget)
1896                                         continue;
1897                                 vtarget = starget->hostdata;
1898                                 if(vtarget->deleted)
1899                                         continue;
1900                                 vtarget->deleted = 1;
1901                                 mptsas_target_reset(ioc, vtarget);
1902                                 sas_port_delete(mptsas_get_port(phy_info));
1903                                 mptsas_port_delete(phy_info->port_details);
1904                         }
1905
1906                         /*
1907                          * Obtain the port_info instance to the parent port
1908                          */
1909                         parent = mptsas_find_portinfo_by_handle(ioc,
1910                             port_info->phy_info[0].identify.handle_parent);
1911
1912                         if (!parent)
1913                                 goto next_port;
1914
1915                         expander_sas_address =
1916                                 port_info->phy_info[0].identify.sas_address;
1917
1918                         /*
1919                          * Delete rphys in the parent that point
1920                          * to this expander.  The transport layer will
1921                          * cleanup all the children.
1922                          */
1923                         phy_info = parent->phy_info;
1924                         for (i = 0; i < parent->num_phys; i++, phy_info++) {
1925                                 port = mptsas_get_port(phy_info);
1926                                 if (!port)
1927                                         continue;
1928                                 if (phy_info->attached.sas_address !=
1929                                         expander_sas_address)
1930                                         continue;
1931 #ifdef MPT_DEBUG_SAS_WIDE
1932                                 dev_printk(KERN_DEBUG, &port->dev,
1933                                     "delete port (%d)\n", port->port_identifier);
1934 #endif
1935                                 sas_port_delete(port);
1936                                 mptsas_port_delete(phy_info->port_details);
1937                         }
1938  next_port:
1939
1940                         phy_info = port_info->phy_info;
1941                         for (i = 0; i < port_info->num_phys; i++, phy_info++)
1942                                 mptsas_port_delete(phy_info->port_details);
1943
1944                         list_del(&port_info->list);
1945                         kfree(port_info->phy_info);
1946                         kfree(port_info);
1947                 }
1948                 /*
1949                 * Free this memory allocated from inside
1950                 * mptsas_sas_expander_pg0
1951                 */
1952                 kfree(buffer.phy_info);
1953         }
1954         mutex_unlock(&ioc->sas_topology_mutex);
1955 }
1956
1957 /*
1958  * Start of day discovery
1959  */
1960 static void
1961 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1962 {
1963         u32 handle = 0xFFFF;
1964         int i;
1965
1966         mutex_lock(&ioc->sas_discovery_mutex);
1967         mptsas_probe_hba_phys(ioc);
1968         while (!mptsas_probe_expander_phys(ioc, &handle))
1969                 ;
1970         /*
1971           Reporting RAID volumes.
1972         */
1973         if (!ioc->raid_data.pIocPg2)
1974                 goto out;
1975         if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
1976                 goto out;
1977         for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
1978                 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
1979                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
1980         }
1981  out:
1982         mutex_unlock(&ioc->sas_discovery_mutex);
1983 }
1984
1985 /*
1986  * Work queue thread to handle Runtime discovery
1987  * Mere purpose is the hot add/delete of expanders
1988  *(Mutex UNLOCKED)
1989  */
1990 static void
1991 __mptsas_discovery_work(MPT_ADAPTER *ioc)
1992 {
1993         u32 handle = 0xFFFF;
1994
1995         ioc->sas_discovery_runtime=1;
1996         mptsas_delete_expander_phys(ioc);
1997         mptsas_probe_hba_phys(ioc);
1998         while (!mptsas_probe_expander_phys(ioc, &handle))
1999                 ;
2000         ioc->sas_discovery_runtime=0;
2001 }
2002
2003 /*
2004  * Work queue thread to handle Runtime discovery
2005  * Mere purpose is the hot add/delete of expanders
2006  *(Mutex LOCKED)
2007  */
2008 static void
2009 mptsas_discovery_work(void * arg)
2010 {
2011         struct mptsas_discovery_event *ev = arg;
2012         MPT_ADAPTER *ioc = ev->ioc;
2013
2014         mutex_lock(&ioc->sas_discovery_mutex);
2015         __mptsas_discovery_work(ioc);
2016         mutex_unlock(&ioc->sas_discovery_mutex);
2017         kfree(ev);
2018 }
2019
2020 static struct mptsas_phyinfo *
2021 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
2022 {
2023         struct mptsas_portinfo *port_info;
2024         struct mptsas_phyinfo *phy_info = NULL;
2025         int i;
2026
2027         mutex_lock(&ioc->sas_topology_mutex);
2028         list_for_each_entry(port_info, &ioc->sas_topology, list) {
2029                 for (i = 0; i < port_info->num_phys; i++) {
2030                         if (port_info->phy_info[i].attached.sas_address
2031                             != sas_address)
2032                                 continue;
2033                         if (!mptsas_is_end_device(
2034                                 &port_info->phy_info[i].attached))
2035                                 continue;
2036                         phy_info = &port_info->phy_info[i];
2037                         break;
2038                 }
2039         }
2040         mutex_unlock(&ioc->sas_topology_mutex);
2041         return phy_info;
2042 }
2043
2044 static struct mptsas_phyinfo *
2045 mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
2046 {
2047         struct mptsas_portinfo *port_info;
2048         struct mptsas_phyinfo *phy_info = NULL;
2049         int i;
2050
2051         mutex_lock(&ioc->sas_topology_mutex);
2052         list_for_each_entry(port_info, &ioc->sas_topology, list) {
2053                 for (i = 0; i < port_info->num_phys; i++) {
2054                         if (port_info->phy_info[i].attached.id != id)
2055                                 continue;
2056                         if (!mptsas_is_end_device(
2057                                 &port_info->phy_info[i].attached))
2058                                 continue;
2059                         phy_info = &port_info->phy_info[i];
2060                         break;
2061                 }
2062         }
2063         mutex_unlock(&ioc->sas_topology_mutex);
2064         return phy_info;
2065 }
2066
2067 /*
2068  * Work queue thread to clear the persitency table
2069  */
2070 static void
2071 mptsas_persist_clear_table(void * arg)
2072 {
2073         MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
2074
2075         mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2076 }
2077
2078 static void
2079 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
2080 {
2081         sdev->no_uld_attach = data ? 1 : 0;
2082         scsi_device_reprobe(sdev);
2083 }
2084
2085 static void
2086 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
2087 {
2088         starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
2089                         mptsas_reprobe_lun);
2090 }
2091
2092 /*
2093  * Work queue thread to handle SAS hotplug events
2094  */
2095 static void
2096 mptsas_hotplug_work(void *arg)
2097 {
2098         struct mptsas_hotplug_event *ev = arg;
2099         MPT_ADAPTER *ioc = ev->ioc;
2100         struct mptsas_phyinfo *phy_info;
2101         struct sas_rphy *rphy;
2102         struct sas_port *port;
2103         struct scsi_device *sdev;
2104         struct scsi_target * starget;
2105         struct sas_identify identify;
2106         char *ds = NULL;
2107         struct mptsas_devinfo sas_device;
2108         VirtTarget *vtarget;
2109         VirtDevice *vdevice;
2110
2111
2112         mutex_lock(&ioc->sas_discovery_mutex);
2113         switch (ev->event_type) {
2114         case MPTSAS_DEL_DEVICE:
2115
2116                 phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id);
2117
2118                 /*
2119                  * Sanity checks, for non-existing phys and remote rphys.
2120                  */
2121                 if (!phy_info || !phy_info->port_details) {
2122                         dfailprintk((MYIOC_s_ERR_FMT
2123                                 "%s: exit at line=%d\n", ioc->name,
2124                                 __FUNCTION__, __LINE__));
2125                         break;
2126                 }
2127                 rphy = mptsas_get_rphy(phy_info);
2128                 if (!rphy) {
2129                         dfailprintk((MYIOC_s_ERR_FMT
2130                                 "%s: exit at line=%d\n", ioc->name,
2131                                 __FUNCTION__, __LINE__));
2132                         break;
2133                 }
2134                 port = mptsas_get_port(phy_info);
2135                 if (!port) {
2136                         dfailprintk((MYIOC_s_ERR_FMT
2137                                 "%s: exit at line=%d\n", ioc->name,
2138                                 __FUNCTION__, __LINE__));
2139                         break;
2140                 }
2141
2142                 starget = mptsas_get_starget(phy_info);
2143                 if (starget) {
2144                         vtarget = starget->hostdata;
2145
2146                         if (!vtarget) {
2147                                 dfailprintk((MYIOC_s_ERR_FMT
2148                                         "%s: exit at line=%d\n", ioc->name,
2149                                         __FUNCTION__, __LINE__));
2150                                 break;
2151                         }
2152
2153                         /*
2154                          * Handling  RAID components
2155                          */
2156                         if (ev->phys_disk_num_valid) {
2157                                 vtarget->target_id = ev->phys_disk_num;
2158                                 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
2159                                 mptsas_reprobe_target(starget, 1);
2160                                 break;
2161                         }
2162
2163                         vtarget->deleted = 1;
2164                         mptsas_target_reset(ioc, vtarget);
2165                 }
2166
2167                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
2168                         ds = "ssp";
2169                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
2170                         ds = "stp";
2171                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2172                         ds = "sata";
2173
2174                 printk(MYIOC_s_INFO_FMT
2175                        "removing %s device, channel %d, id %d, phy %d\n",
2176                        ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
2177
2178 #ifdef MPT_DEBUG_SAS_WIDE
2179                 dev_printk(KERN_DEBUG, &port->dev,
2180                     "delete port (%d)\n", port->port_identifier);
2181 #endif
2182                 sas_port_delete(port);
2183                 mptsas_port_delete(phy_info->port_details);
2184                 break;
2185         case MPTSAS_ADD_DEVICE:
2186
2187                 if (ev->phys_disk_num_valid)
2188                         mpt_findImVolumes(ioc);
2189
2190                 /*
2191                  * Refresh sas device pg0 data
2192                  */
2193                 if (mptsas_sas_device_pg0(ioc, &sas_device,
2194                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2195                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id)) {
2196                                 dfailprintk((MYIOC_s_ERR_FMT
2197                                         "%s: exit at line=%d\n", ioc->name,
2198                                         __FUNCTION__, __LINE__));
2199                         break;
2200                 }
2201
2202                 ssleep(2);
2203                 __mptsas_discovery_work(ioc);
2204
2205                 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
2206                                 sas_device.sas_address);
2207
2208                 if (!phy_info || !phy_info->port_details) {
2209                         dfailprintk((MYIOC_s_ERR_FMT
2210                                 "%s: exit at line=%d\n", ioc->name,
2211                                 __FUNCTION__, __LINE__));
2212                         break;
2213                 }
2214
2215                 starget = mptsas_get_starget(phy_info);
2216                 if (starget) {
2217                         vtarget = starget->hostdata;
2218
2219                         if (!vtarget) {
2220                                 dfailprintk((MYIOC_s_ERR_FMT
2221                                         "%s: exit at line=%d\n", ioc->name,
2222                                         __FUNCTION__, __LINE__));
2223                                 break;
2224                         }
2225                         /*
2226                          * Handling  RAID components
2227                          */
2228                         if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
2229                                 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
2230                                 vtarget->target_id = ev->id;
2231                                 mptsas_reprobe_target(starget, 0);
2232                         }
2233                         break;
2234                 }
2235
2236                 if (mptsas_get_rphy(phy_info)) {
2237                         dfailprintk((MYIOC_s_ERR_FMT
2238                                 "%s: exit at line=%d\n", ioc->name,
2239                                 __FUNCTION__, __LINE__));
2240                         break;
2241                 }
2242                 port = mptsas_get_port(phy_info);
2243                 if (!port) {
2244                         dfailprintk((MYIOC_s_ERR_FMT
2245                                 "%s: exit at line=%d\n", ioc->name,
2246                                 __FUNCTION__, __LINE__));
2247                         break;
2248                 }
2249
2250                 memcpy(&phy_info->attached, &sas_device,
2251                     sizeof(struct mptsas_devinfo));
2252
2253                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
2254                         ds = "ssp";
2255                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
2256                         ds = "stp";
2257                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2258                         ds = "sata";
2259
2260                 printk(MYIOC_s_INFO_FMT
2261                        "attaching %s device, channel %d, id %d, phy %d\n",
2262                        ioc->name, ds, ev->channel, ev->id, ev->phy_id);
2263
2264                 mptsas_parse_device_info(&identify, &phy_info->attached);
2265                 rphy = sas_end_device_alloc(port);
2266                 if (!rphy) {
2267                         dfailprintk((MYIOC_s_ERR_FMT
2268                                 "%s: exit at line=%d\n", ioc->name,
2269                                 __FUNCTION__, __LINE__));
2270                         break; /* non-fatal: an rphy can be added later */
2271                 }
2272
2273                 rphy->identify = identify;
2274                 if (sas_rphy_add(rphy)) {
2275                         dfailprintk((MYIOC_s_ERR_FMT
2276                                 "%s: exit at line=%d\n", ioc->name,
2277                                 __FUNCTION__, __LINE__));
2278                         sas_rphy_free(rphy);
2279                         break;
2280                 }
2281                 mptsas_set_rphy(phy_info, rphy);
2282                 break;
2283         case MPTSAS_ADD_RAID:
2284                 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2285                     ev->id, 0);
2286                 if (sdev) {
2287                         scsi_device_put(sdev);
2288                         break;
2289                 }
2290                 printk(MYIOC_s_INFO_FMT
2291                        "attaching raid volume, channel %d, id %d\n",
2292                        ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2293                 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ev->id, 0);
2294                 mpt_findImVolumes(ioc);
2295                 break;
2296         case MPTSAS_DEL_RAID:
2297                 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2298                     ev->id, 0);
2299                 if (!sdev)
2300                         break;
2301                 printk(MYIOC_s_INFO_FMT
2302                        "removing raid volume, channel %d, id %d\n",
2303                        ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2304                 vdevice = sdev->hostdata;
2305                 vdevice->vtarget->deleted = 1;
2306                 mptsas_target_reset(ioc, vdevice->vtarget);
2307                 scsi_remove_device(sdev);
2308                 scsi_device_put(sdev);
2309                 mpt_findImVolumes(ioc);
2310                 break;
2311         case MPTSAS_IGNORE_EVENT:
2312         default:
2313                 break;
2314         }
2315
2316         mutex_unlock(&ioc->sas_discovery_mutex);
2317         kfree(ev);
2318
2319 }
2320
2321 static void
2322 mptsas_send_sas_event(MPT_ADAPTER *ioc,
2323                 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
2324 {
2325         struct mptsas_hotplug_event *ev;
2326         u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
2327         __le64 sas_address;
2328
2329         if ((device_info &
2330              (MPI_SAS_DEVICE_INFO_SSP_TARGET |
2331               MPI_SAS_DEVICE_INFO_STP_TARGET |
2332               MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
2333                 return;
2334
2335         switch (sas_event_data->ReasonCode) {
2336         case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
2337         case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
2338                 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2339                 if (!ev) {
2340                         printk(KERN_WARNING "mptsas: lost hotplug event\n");
2341                         break;
2342                 }
2343
2344                 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
2345                 ev->ioc = ioc;
2346                 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
2347                 ev->parent_handle =
2348                     le16_to_cpu(sas_event_data->ParentDevHandle);
2349                 ev->channel = sas_event_data->Bus;
2350                 ev->id = sas_event_data->TargetID;
2351                 ev->phy_id = sas_event_data->PhyNum;
2352                 memcpy(&sas_address, &sas_event_data->SASAddress,
2353                     sizeof(__le64));
2354                 ev->sas_address = le64_to_cpu(sas_address);
2355                 ev->device_info = device_info;
2356
2357                 if (sas_event_data->ReasonCode &
2358                     MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
2359                         ev->event_type = MPTSAS_ADD_DEVICE;
2360                 else
2361                         ev->event_type = MPTSAS_DEL_DEVICE;
2362                 schedule_work(&ev->work);
2363                 break;
2364         case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
2365         /*
2366          * Persistent table is full.
2367          */
2368                 INIT_WORK(&ioc->sas_persist_task,
2369                     mptsas_persist_clear_table, (void *)ioc);
2370                 schedule_work(&ioc->sas_persist_task);
2371                 break;
2372         case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
2373         /* TODO */
2374         case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
2375         /* TODO */
2376         default:
2377                 break;
2378         }
2379 }
2380
2381 static void
2382 mptsas_send_raid_event(MPT_ADAPTER *ioc,
2383                 EVENT_DATA_RAID *raid_event_data)
2384 {
2385         struct mptsas_hotplug_event *ev;
2386         int status = le32_to_cpu(raid_event_data->SettingsStatus);
2387         int state = (status >> 8) & 0xff;
2388
2389         if (ioc->bus_type != SAS)
2390                 return;
2391
2392         ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2393         if (!ev) {
2394                 printk(KERN_WARNING "mptsas: lost hotplug event\n");
2395                 return;
2396         }
2397
2398         INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
2399         ev->ioc = ioc;
2400         ev->id = raid_event_data->VolumeID;
2401         ev->event_type = MPTSAS_IGNORE_EVENT;
2402
2403         switch (raid_event_data->ReasonCode) {
2404         case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
2405                 ev->event_type = MPTSAS_ADD_DEVICE;
2406                 break;
2407         case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
2408                 ioc->raid_data.isRaid = 1;
2409                 ev->phys_disk_num_valid = 1;
2410                 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2411                 ev->event_type = MPTSAS_DEL_DEVICE;
2412                 break;
2413         case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
2414                 switch (state) {
2415                 case MPI_PD_STATE_ONLINE:
2416                         ioc->raid_data.isRaid = 1;
2417                         ev->phys_disk_num_valid = 1;
2418                         ev->phys_disk_num = raid_event_data->PhysDiskNum;
2419                         ev->event_type = MPTSAS_ADD_DEVICE;
2420                         break;
2421                 case MPI_PD_STATE_MISSING:
2422                 case MPI_PD_STATE_NOT_COMPATIBLE:
2423                 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
2424                 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
2425                 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
2426                         ev->event_type = MPTSAS_DEL_DEVICE;
2427                         break;
2428                 default:
2429                         break;
2430                 }
2431                 break;
2432         case MPI_EVENT_RAID_RC_VOLUME_DELETED:
2433                 ev->event_type = MPTSAS_DEL_RAID;
2434                 break;
2435         case MPI_EVENT_RAID_RC_VOLUME_CREATED:
2436                 ev->event_type = MPTSAS_ADD_RAID;
2437                 break;
2438         case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
2439                 switch (state) {
2440                 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
2441                 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
2442                         ev->event_type = MPTSAS_DEL_RAID;
2443                         break;
2444                 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
2445                 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
2446                         ev->event_type = MPTSAS_ADD_RAID;
2447                         break;
2448                 default:
2449                         break;
2450                 }
2451                 break;
2452         default:
2453                 break;
2454         }
2455         schedule_work(&ev->work);
2456 }
2457
2458 static void
2459 mptsas_send_discovery_event(MPT_ADAPTER *ioc,
2460         EVENT_DATA_SAS_DISCOVERY *discovery_data)
2461 {
2462         struct mptsas_discovery_event *ev;
2463
2464         /*
2465          * DiscoveryStatus
2466          *
2467          * This flag will be non-zero when firmware
2468          * kicks off discovery, and return to zero
2469          * once its completed.
2470          */
2471         if (discovery_data->DiscoveryStatus)
2472                 return;
2473
2474         ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2475         if (!ev)
2476                 return;
2477         INIT_WORK(&ev->work, mptsas_discovery_work, ev);
2478         ev->ioc = ioc;
2479         schedule_work(&ev->work);
2480 };
2481
2482
2483 static int
2484 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
2485 {
2486         int rc=1;
2487         u8 event = le32_to_cpu(reply->Event) & 0xFF;
2488
2489         if (!ioc->sh)
2490                 goto out;
2491
2492         /*
2493          * sas_discovery_ignore_events
2494          *
2495          * This flag is to prevent anymore processing of
2496          * sas events once mptsas_remove function is called.
2497          */
2498         if (ioc->sas_discovery_ignore_events) {
2499                 rc = mptscsih_event_process(ioc, reply);
2500                 goto out;
2501         }
2502
2503         switch (event) {
2504         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
2505                 mptsas_send_sas_event(ioc,
2506                         (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
2507                 break;
2508         case MPI_EVENT_INTEGRATED_RAID:
2509                 mptsas_send_raid_event(ioc,
2510                         (EVENT_DATA_RAID *)reply->Data);
2511                 break;
2512         case MPI_EVENT_PERSISTENT_TABLE_FULL:
2513                 INIT_WORK(&ioc->sas_persist_task,
2514                     mptsas_persist_clear_table,
2515                     (void *)ioc);
2516                 schedule_work(&ioc->sas_persist_task);
2517                 break;
2518          case MPI_EVENT_SAS_DISCOVERY:
2519                 mptsas_send_discovery_event(ioc,
2520                         (EVENT_DATA_SAS_DISCOVERY *)reply->Data);
2521                 break;
2522         default:
2523                 rc = mptscsih_event_process(ioc, reply);
2524                 break;
2525         }
2526  out:
2527
2528         return rc;
2529 }
2530
2531 static int
2532 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2533 {
2534         struct Scsi_Host        *sh;
2535         MPT_SCSI_HOST           *hd;
2536         MPT_ADAPTER             *ioc;
2537         unsigned long            flags;
2538         int                      ii;
2539         int                      numSGE = 0;
2540         int                      scale;
2541         int                      ioc_cap;
2542         int                     error=0;
2543         int                     r;
2544
2545         r = mpt_attach(pdev,id);
2546         if (r)
2547                 return r;
2548
2549         ioc = pci_get_drvdata(pdev);
2550         ioc->DoneCtx = mptsasDoneCtx;
2551         ioc->TaskCtx = mptsasTaskCtx;
2552         ioc->InternalCtx = mptsasInternalCtx;
2553
2554         /*  Added sanity check on readiness of the MPT adapter.
2555          */
2556         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
2557                 printk(MYIOC_s_WARN_FMT
2558                   "Skipping because it's not operational!\n",
2559                   ioc->name);
2560                 error = -ENODEV;
2561                 goto out_mptsas_probe;
2562         }
2563
2564         if (!ioc->active) {
2565                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
2566                   ioc->name);
2567                 error = -ENODEV;
2568                 goto out_mptsas_probe;
2569         }
2570
2571         /*  Sanity check - ensure at least 1 port is INITIATOR capable
2572          */
2573         ioc_cap = 0;
2574         for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
2575                 if (ioc->pfacts[ii].ProtocolFlags &
2576                                 MPI_PORTFACTS_PROTOCOL_INITIATOR)
2577                         ioc_cap++;
2578         }
2579
2580         if (!ioc_cap) {
2581                 printk(MYIOC_s_WARN_FMT
2582                         "Skipping ioc=%p because SCSI Initiator mode "
2583                         "is NOT enabled!\n", ioc->name, ioc);
2584                 return 0;
2585         }
2586
2587         sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
2588         if (!sh) {
2589                 printk(MYIOC_s_WARN_FMT
2590                         "Unable to register controller with SCSI subsystem\n",
2591                         ioc->name);
2592                 error = -1;
2593                 goto out_mptsas_probe;
2594         }
2595
2596         spin_lock_irqsave(&ioc->FreeQlock, flags);
2597
2598         /* Attach the SCSI Host to the IOC structure
2599          */
2600         ioc->sh = sh;
2601
2602         sh->io_port = 0;
2603         sh->n_io_port = 0;
2604         sh->irq = 0;
2605
2606         /* set 16 byte cdb's */
2607         sh->max_cmd_len = 16;
2608
2609         sh->max_id = ioc->pfacts->MaxDevices + 1;
2610
2611         sh->transportt = mptsas_transport_template;
2612
2613         sh->max_lun = MPT_LAST_LUN + 1;
2614         sh->max_channel = 0;
2615         sh->this_id = ioc->pfacts[0].PortSCSIID;
2616
2617         /* Required entry.
2618          */
2619         sh->unique_id = ioc->id;
2620
2621         INIT_LIST_HEAD(&ioc->sas_topology);
2622         mutex_init(&ioc->sas_topology_mutex);
2623         mutex_init(&ioc->sas_discovery_mutex);
2624         mutex_init(&ioc->sas_mgmt.mutex);
2625         init_completion(&ioc->sas_mgmt.done);
2626
2627         /* Verify that we won't exceed the maximum
2628          * number of chain buffers
2629          * We can optimize:  ZZ = req_sz/sizeof(SGE)
2630          * For 32bit SGE's:
2631          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
2632          *               + (req_sz - 64)/sizeof(SGE)
2633          * A slightly different algorithm is required for
2634          * 64bit SGEs.
2635          */
2636         scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
2637         if (sizeof(dma_addr_t) == sizeof(u64)) {
2638                 numSGE = (scale - 1) *
2639                   (ioc->facts.MaxChainDepth-1) + scale +
2640                   (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
2641                   sizeof(u32));
2642         } else {
2643                 numSGE = 1 + (scale - 1) *
2644                   (ioc->facts.MaxChainDepth-1) + scale +
2645                   (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
2646                   sizeof(u32));
2647         }
2648
2649         if (numSGE < sh->sg_tablesize) {
2650                 /* Reset this value */
2651                 dprintk((MYIOC_s_INFO_FMT
2652                   "Resetting sg_tablesize to %d from %d\n",
2653                   ioc->name, numSGE, sh->sg_tablesize));
2654                 sh->sg_tablesize = numSGE;
2655         }
2656
2657         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2658
2659         hd = (MPT_SCSI_HOST *) sh->hostdata;
2660         hd->ioc = ioc;
2661
2662         /* SCSI needs scsi_cmnd lookup table!
2663          * (with size equal to req_depth*PtrSz!)
2664          */
2665         hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
2666         if (!hd->ScsiLookup) {
2667                 error = -ENOMEM;
2668                 goto out_mptsas_probe;
2669         }
2670
2671         dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
2672                  ioc->name, hd->ScsiLookup));
2673
2674         /* Allocate memory for the device structures.
2675          * A non-Null pointer at an offset
2676          * indicates a device exists.
2677          * max_id = 1 + maximum id (hosts.h)
2678          */
2679         hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
2680         if (!hd->Targets) {
2681                 error = -ENOMEM;
2682                 goto out_mptsas_probe;
2683         }
2684
2685         dprintk((KERN_INFO "  vtarget @ %p\n", hd->Targets));
2686
2687         /* Clear the TM flags
2688          */
2689         hd->tmPending = 0;
2690         hd->tmState = TM_STATE_NONE;
2691         hd->resetPending = 0;
2692         hd->abortSCpnt = NULL;
2693
2694         /* Clear the pointer used to store
2695          * single-threaded commands, i.e., those
2696          * issued during a bus scan, dv and
2697          * configuration pages.
2698          */
2699         hd->cmdPtr = NULL;
2700
2701         /* Initialize this SCSI Hosts' timers
2702          * To use, set the timer expires field
2703          * and add_timer
2704          */
2705         init_timer(&hd->timer);
2706         hd->timer.data = (unsigned long) hd;
2707         hd->timer.function = mptscsih_timer_expired;
2708
2709         ioc->sas_data.ptClear = mpt_pt_clear;
2710
2711         if (ioc->sas_data.ptClear==1) {
2712                 mptbase_sas_persist_operation(
2713                     ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
2714         }
2715
2716         init_waitqueue_head(&hd->scandv_waitq);
2717         hd->scandv_wait_done = 0;
2718         hd->last_queue_full = 0;
2719
2720         error = scsi_add_host(sh, &ioc->pcidev->dev);
2721         if (error) {
2722                 dprintk((KERN_ERR MYNAM
2723                   "scsi_add_host failed\n"));
2724                 goto out_mptsas_probe;
2725         }
2726
2727         mptsas_scan_sas_topology(ioc);
2728
2729         return 0;
2730
2731  out_mptsas_probe:
2732
2733         mptscsih_remove(pdev);
2734         return error;
2735 }
2736
2737 static void __devexit mptsas_remove(struct pci_dev *pdev)
2738 {
2739         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2740         struct mptsas_portinfo *p, *n;
2741         int i;
2742
2743         ioc->sas_discovery_ignore_events=1;
2744         sas_remove_host(ioc->sh);
2745
2746         mutex_lock(&ioc->sas_topology_mutex);
2747         list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
2748                 list_del(&p->list);
2749                 for (i = 0 ; i < p->num_phys ; i++)
2750                         mptsas_port_delete(p->phy_info[i].port_details);
2751                 kfree(p->phy_info);
2752                 kfree(p);
2753         }
2754         mutex_unlock(&ioc->sas_topology_mutex);
2755
2756         mptscsih_remove(pdev);
2757 }
2758
2759 static struct pci_device_id mptsas_pci_table[] = {
2760         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
2761                 PCI_ANY_ID, PCI_ANY_ID },
2762         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
2763                 PCI_ANY_ID, PCI_ANY_ID },
2764         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
2765                 PCI_ANY_ID, PCI_ANY_ID },
2766         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
2767                 PCI_ANY_ID, PCI_ANY_ID },
2768         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
2769                 PCI_ANY_ID, PCI_ANY_ID },
2770         {0}     /* Terminating entry */
2771 };
2772 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
2773
2774
2775 static struct pci_driver mptsas_driver = {
2776         .name           = "mptsas",
2777         .id_table       = mptsas_pci_table,
2778         .probe          = mptsas_probe,
2779         .remove         = __devexit_p(mptsas_remove),
2780         .shutdown       = mptscsih_shutdown,
2781 #ifdef CONFIG_PM
2782         .suspend        = mptscsih_suspend,
2783         .resume         = mptscsih_resume,
2784 #endif
2785 };
2786
2787 static int __init
2788 mptsas_init(void)
2789 {
2790         show_mptmod_ver(my_NAME, my_VERSION);
2791
2792         mptsas_transport_template =
2793             sas_attach_transport(&mptsas_transport_functions);
2794         if (!mptsas_transport_template)
2795                 return -ENODEV;
2796
2797         mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
2798         mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
2799         mptsasInternalCtx =
2800                 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
2801         mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
2802
2803         if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) {
2804                 devtverboseprintk((KERN_INFO MYNAM
2805                   ": Registered for IOC event notifications\n"));
2806         }
2807
2808         if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
2809                 dprintk((KERN_INFO MYNAM
2810                   ": Registered for IOC reset notifications\n"));
2811         }
2812
2813         return pci_register_driver(&mptsas_driver);
2814 }
2815
2816 static void __exit
2817 mptsas_exit(void)
2818 {
2819         pci_unregister_driver(&mptsas_driver);
2820         sas_release_transport(mptsas_transport_template);
2821
2822         mpt_reset_deregister(mptsasDoneCtx);
2823         mpt_event_deregister(mptsasDoneCtx);
2824
2825         mpt_deregister(mptsasMgmtCtx);
2826         mpt_deregister(mptsasInternalCtx);
2827         mpt_deregister(mptsasTaskCtx);
2828         mpt_deregister(mptsasDoneCtx);
2829 }
2830
2831 module_init(mptsas_init);
2832 module_exit(mptsas_exit);