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