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