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