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