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