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