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