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