[SCSI] mpt fusion: removing references to hd->ioc
[linux-2.6] / 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         MPT_ADAPTER             *ioc = hd->ioc;
850
851         vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
852         if (!vtarget)
853                 return -ENOMEM;
854
855         vtarget->starget = starget;
856         vtarget->ioc_id = ioc->id;
857         vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
858         id = starget->id;
859         channel = 0;
860
861         /*
862          * RAID volumes placed beyond the last expected port.
863          */
864         if (starget->channel == MPTSAS_RAID_CHANNEL) {
865                 for (i=0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
866                         if (id == ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID)
867                                 channel = ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus;
868                 goto out;
869         }
870
871         rphy = dev_to_rphy(starget->dev.parent);
872         mutex_lock(&ioc->sas_topology_mutex);
873         list_for_each_entry(p, &ioc->sas_topology, list) {
874                 for (i = 0; i < p->num_phys; i++) {
875                         if (p->phy_info[i].attached.sas_address !=
876                                         rphy->identify.sas_address)
877                                 continue;
878                         id = p->phy_info[i].attached.id;
879                         channel = p->phy_info[i].attached.channel;
880                         mptsas_set_starget(&p->phy_info[i], starget);
881
882                         /*
883                          * Exposing hidden raid components
884                          */
885                         if (mptscsih_is_phys_disk(ioc, channel, id)) {
886                                 id = mptscsih_raid_id_to_num(ioc,
887                                                 channel, id);
888                                 vtarget->tflags |=
889                                     MPT_TARGET_FLAGS_RAID_COMPONENT;
890                                 p->phy_info[i].attached.phys_disk_num = id;
891                         }
892                         mutex_unlock(&ioc->sas_topology_mutex);
893                         goto out;
894                 }
895         }
896         mutex_unlock(&ioc->sas_topology_mutex);
897
898         kfree(vtarget);
899         return -ENXIO;
900
901  out:
902         vtarget->id = id;
903         vtarget->channel = channel;
904         starget->hostdata = vtarget;
905         return 0;
906 }
907
908 static void
909 mptsas_target_destroy(struct scsi_target *starget)
910 {
911         struct Scsi_Host *host = dev_to_shost(&starget->dev);
912         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
913         struct sas_rphy         *rphy;
914         struct mptsas_portinfo  *p;
915         int                      i;
916         MPT_ADAPTER *ioc = hd->ioc;
917
918         if (!starget->hostdata)
919                 return;
920
921         if (starget->channel == MPTSAS_RAID_CHANNEL)
922                 goto out;
923
924         rphy = dev_to_rphy(starget->dev.parent);
925         list_for_each_entry(p, &ioc->sas_topology, list) {
926                 for (i = 0; i < p->num_phys; i++) {
927                         if (p->phy_info[i].attached.sas_address !=
928                                         rphy->identify.sas_address)
929                                 continue;
930                         mptsas_set_starget(&p->phy_info[i], NULL);
931                         goto out;
932                 }
933         }
934
935  out:
936         kfree(starget->hostdata);
937         starget->hostdata = NULL;
938 }
939
940
941 static int
942 mptsas_slave_alloc(struct scsi_device *sdev)
943 {
944         struct Scsi_Host        *host = sdev->host;
945         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
946         struct sas_rphy         *rphy;
947         struct mptsas_portinfo  *p;
948         VirtDevice              *vdevice;
949         struct scsi_target      *starget;
950         int                     i;
951         MPT_ADAPTER *ioc = hd->ioc;
952
953         vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
954         if (!vdevice) {
955                 printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
956                                 ioc->name, sizeof(VirtDevice));
957                 return -ENOMEM;
958         }
959         starget = scsi_target(sdev);
960         vdevice->vtarget = starget->hostdata;
961
962         if (sdev->channel == MPTSAS_RAID_CHANNEL)
963                 goto out;
964
965         rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
966         mutex_lock(&ioc->sas_topology_mutex);
967         list_for_each_entry(p, &ioc->sas_topology, list) {
968                 for (i = 0; i < p->num_phys; i++) {
969                         if (p->phy_info[i].attached.sas_address !=
970                                         rphy->identify.sas_address)
971                                 continue;
972                         vdevice->lun = sdev->lun;
973                         /*
974                          * Exposing hidden raid components
975                          */
976                         if (mptscsih_is_phys_disk(ioc,
977                             p->phy_info[i].attached.channel,
978                             p->phy_info[i].attached.id))
979                                 sdev->no_uld_attach = 1;
980                         mutex_unlock(&ioc->sas_topology_mutex);
981                         goto out;
982                 }
983         }
984         mutex_unlock(&ioc->sas_topology_mutex);
985
986         kfree(vdevice);
987         return -ENXIO;
988
989  out:
990         vdevice->vtarget->num_luns++;
991         sdev->hostdata = vdevice;
992         return 0;
993 }
994
995 static int
996 mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
997 {
998         VirtDevice      *vdevice = SCpnt->device->hostdata;
999
1000         if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
1001                 SCpnt->result = DID_NO_CONNECT << 16;
1002                 done(SCpnt);
1003                 return 0;
1004         }
1005
1006 //      scsi_print_command(SCpnt);
1007
1008         return mptscsih_qcmd(SCpnt,done);
1009 }
1010
1011
1012 static struct scsi_host_template mptsas_driver_template = {
1013         .module                         = THIS_MODULE,
1014         .proc_name                      = "mptsas",
1015         .proc_info                      = mptscsih_proc_info,
1016         .name                           = "MPT SPI Host",
1017         .info                           = mptscsih_info,
1018         .queuecommand                   = mptsas_qcmd,
1019         .target_alloc                   = mptsas_target_alloc,
1020         .slave_alloc                    = mptsas_slave_alloc,
1021         .slave_configure                = mptsas_slave_configure,
1022         .target_destroy                 = mptsas_target_destroy,
1023         .slave_destroy                  = mptscsih_slave_destroy,
1024         .change_queue_depth             = mptscsih_change_queue_depth,
1025         .eh_abort_handler               = mptscsih_abort,
1026         .eh_device_reset_handler        = mptscsih_dev_reset,
1027         .eh_bus_reset_handler           = mptscsih_bus_reset,
1028         .eh_host_reset_handler          = mptscsih_host_reset,
1029         .bios_param                     = mptscsih_bios_param,
1030         .can_queue                      = MPT_FC_CAN_QUEUE,
1031         .this_id                        = -1,
1032         .sg_tablesize                   = MPT_SCSI_SG_DEPTH,
1033         .max_sectors                    = 8192,
1034         .cmd_per_lun                    = 7,
1035         .use_clustering                 = ENABLE_CLUSTERING,
1036         .shost_attrs                    = mptscsih_host_attrs,
1037 };
1038
1039 static int mptsas_get_linkerrors(struct sas_phy *phy)
1040 {
1041         MPT_ADAPTER *ioc = phy_to_ioc(phy);
1042         ConfigExtendedPageHeader_t hdr;
1043         CONFIGPARMS cfg;
1044         SasPhyPage1_t *buffer;
1045         dma_addr_t dma_handle;
1046         int error;
1047
1048         /* FIXME: only have link errors on local phys */
1049         if (!scsi_is_sas_phy_local(phy))
1050                 return -EINVAL;
1051
1052         hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
1053         hdr.ExtPageLength = 0;
1054         hdr.PageNumber = 1 /* page number 1*/;
1055         hdr.Reserved1 = 0;
1056         hdr.Reserved2 = 0;
1057         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1058         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1059
1060         cfg.cfghdr.ehdr = &hdr;
1061         cfg.physAddr = -1;
1062         cfg.pageAddr = phy->identify.phy_identifier;
1063         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1064         cfg.dir = 0;    /* read */
1065         cfg.timeout = 10;
1066
1067         error = mpt_config(ioc, &cfg);
1068         if (error)
1069                 return error;
1070         if (!hdr.ExtPageLength)
1071                 return -ENXIO;
1072
1073         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1074                                       &dma_handle);
1075         if (!buffer)
1076                 return -ENOMEM;
1077
1078         cfg.physAddr = dma_handle;
1079         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1080
1081         error = mpt_config(ioc, &cfg);
1082         if (error)
1083                 goto out_free_consistent;
1084
1085         mptsas_print_phy_pg1(ioc, buffer);
1086
1087         phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
1088         phy->running_disparity_error_count =
1089                 le32_to_cpu(buffer->RunningDisparityErrorCount);
1090         phy->loss_of_dword_sync_count =
1091                 le32_to_cpu(buffer->LossDwordSynchCount);
1092         phy->phy_reset_problem_count =
1093                 le32_to_cpu(buffer->PhyResetProblemCount);
1094
1095  out_free_consistent:
1096         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1097                             buffer, dma_handle);
1098         return error;
1099 }
1100
1101 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
1102                 MPT_FRAME_HDR *reply)
1103 {
1104         ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
1105         if (reply != NULL) {
1106                 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
1107                 memcpy(ioc->sas_mgmt.reply, reply,
1108                     min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
1109         }
1110         complete(&ioc->sas_mgmt.done);
1111         return 1;
1112 }
1113
1114 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
1115 {
1116         MPT_ADAPTER *ioc = phy_to_ioc(phy);
1117         SasIoUnitControlRequest_t *req;
1118         SasIoUnitControlReply_t *reply;
1119         MPT_FRAME_HDR *mf;
1120         MPIHeader_t *hdr;
1121         unsigned long timeleft;
1122         int error = -ERESTARTSYS;
1123
1124         /* FIXME: fusion doesn't allow non-local phy reset */
1125         if (!scsi_is_sas_phy_local(phy))
1126                 return -EINVAL;
1127
1128         /* not implemented for expanders */
1129         if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
1130                 return -ENXIO;
1131
1132         if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
1133                 goto out;
1134
1135         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
1136         if (!mf) {
1137                 error = -ENOMEM;
1138                 goto out_unlock;
1139         }
1140
1141         hdr = (MPIHeader_t *) mf;
1142         req = (SasIoUnitControlRequest_t *)mf;
1143         memset(req, 0, sizeof(SasIoUnitControlRequest_t));
1144         req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
1145         req->MsgContext = hdr->MsgContext;
1146         req->Operation = hard_reset ?
1147                 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
1148         req->PhyNum = phy->identify.phy_identifier;
1149
1150         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1151
1152         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
1153                         10 * HZ);
1154         if (!timeleft) {
1155                 /* On timeout reset the board */
1156                 mpt_free_msg_frame(ioc, mf);
1157                 mpt_HardResetHandler(ioc, CAN_SLEEP);
1158                 error = -ETIMEDOUT;
1159                 goto out_unlock;
1160         }
1161
1162         /* a reply frame is expected */
1163         if ((ioc->sas_mgmt.status &
1164             MPT_IOCTL_STATUS_RF_VALID) == 0) {
1165                 error = -ENXIO;
1166                 goto out_unlock;
1167         }
1168
1169         /* process the completed Reply Message Frame */
1170         reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
1171         if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
1172                 printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
1173                     ioc->name, __FUNCTION__, reply->IOCStatus, reply->IOCLogInfo);
1174                 error = -ENXIO;
1175                 goto out_unlock;
1176         }
1177
1178         error = 0;
1179
1180  out_unlock:
1181         mutex_unlock(&ioc->sas_mgmt.mutex);
1182  out:
1183         return error;
1184 }
1185
1186 static int
1187 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
1188 {
1189         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1190         int i, error;
1191         struct mptsas_portinfo *p;
1192         struct mptsas_enclosure enclosure_info;
1193         u64 enclosure_handle;
1194
1195         mutex_lock(&ioc->sas_topology_mutex);
1196         list_for_each_entry(p, &ioc->sas_topology, list) {
1197                 for (i = 0; i < p->num_phys; i++) {
1198                         if (p->phy_info[i].attached.sas_address ==
1199                             rphy->identify.sas_address) {
1200                                 enclosure_handle = p->phy_info[i].
1201                                         attached.handle_enclosure;
1202                                 goto found_info;
1203                         }
1204                 }
1205         }
1206         mutex_unlock(&ioc->sas_topology_mutex);
1207         return -ENXIO;
1208
1209  found_info:
1210         mutex_unlock(&ioc->sas_topology_mutex);
1211         memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
1212         error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
1213                         (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
1214                          MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
1215         if (!error)
1216                 *identifier = enclosure_info.enclosure_logical_id;
1217         return error;
1218 }
1219
1220 static int
1221 mptsas_get_bay_identifier(struct sas_rphy *rphy)
1222 {
1223         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1224         struct mptsas_portinfo *p;
1225         int i, rc;
1226
1227         mutex_lock(&ioc->sas_topology_mutex);
1228         list_for_each_entry(p, &ioc->sas_topology, list) {
1229                 for (i = 0; i < p->num_phys; i++) {
1230                         if (p->phy_info[i].attached.sas_address ==
1231                             rphy->identify.sas_address) {
1232                                 rc = p->phy_info[i].attached.slot;
1233                                 goto out;
1234                         }
1235                 }
1236         }
1237         rc = -ENXIO;
1238  out:
1239         mutex_unlock(&ioc->sas_topology_mutex);
1240         return rc;
1241 }
1242
1243 static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1244                               struct request *req)
1245 {
1246         MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
1247         MPT_FRAME_HDR *mf;
1248         SmpPassthroughRequest_t *smpreq;
1249         struct request *rsp = req->next_rq;
1250         int ret;
1251         int flagsLength;
1252         unsigned long timeleft;
1253         char *psge;
1254         dma_addr_t dma_addr_in = 0;
1255         dma_addr_t dma_addr_out = 0;
1256         u64 sas_address = 0;
1257
1258         if (!rsp) {
1259                 printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n",
1260                     ioc->name, __FUNCTION__);
1261                 return -EINVAL;
1262         }
1263
1264         /* do we need to support multiple segments? */
1265         if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
1266                 printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
1267                     ioc->name, __FUNCTION__, req->bio->bi_vcnt, req->data_len,
1268                     rsp->bio->bi_vcnt, rsp->data_len);
1269                 return -EINVAL;
1270         }
1271
1272         ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
1273         if (ret)
1274                 goto out;
1275
1276         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
1277         if (!mf) {
1278                 ret = -ENOMEM;
1279                 goto out_unlock;
1280         }
1281
1282         smpreq = (SmpPassthroughRequest_t *)mf;
1283         memset(smpreq, 0, sizeof(*smpreq));
1284
1285         smpreq->RequestDataLength = cpu_to_le16(req->data_len - 4);
1286         smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
1287
1288         if (rphy)
1289                 sas_address = rphy->identify.sas_address;
1290         else {
1291                 struct mptsas_portinfo *port_info;
1292
1293                 mutex_lock(&ioc->sas_topology_mutex);
1294                 port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
1295                 if (port_info && port_info->phy_info)
1296                         sas_address =
1297                                 port_info->phy_info[0].phy->identify.sas_address;
1298                 mutex_unlock(&ioc->sas_topology_mutex);
1299         }
1300
1301         *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
1302
1303         psge = (char *)
1304                 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
1305
1306         /* request */
1307         flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1308                        MPI_SGE_FLAGS_END_OF_BUFFER |
1309                        MPI_SGE_FLAGS_DIRECTION |
1310                        mpt_addr_size()) << MPI_SGE_FLAGS_SHIFT;
1311         flagsLength |= (req->data_len - 4);
1312
1313         dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
1314                                       req->data_len, PCI_DMA_BIDIRECTIONAL);
1315         if (!dma_addr_out)
1316                 goto put_mf;
1317         mpt_add_sge(psge, flagsLength, dma_addr_out);
1318         psge += (sizeof(u32) + sizeof(dma_addr_t));
1319
1320         /* response */
1321         flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
1322         flagsLength |= rsp->data_len + 4;
1323         dma_addr_in =  pci_map_single(ioc->pcidev, bio_data(rsp->bio),
1324                                       rsp->data_len, PCI_DMA_BIDIRECTIONAL);
1325         if (!dma_addr_in)
1326                 goto unmap;
1327         mpt_add_sge(psge, flagsLength, dma_addr_in);
1328
1329         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1330
1331         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
1332         if (!timeleft) {
1333                 printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __FUNCTION__);
1334                 /* On timeout reset the board */
1335                 mpt_HardResetHandler(ioc, CAN_SLEEP);
1336                 ret = -ETIMEDOUT;
1337                 goto unmap;
1338         }
1339         mf = NULL;
1340
1341         if (ioc->sas_mgmt.status & MPT_IOCTL_STATUS_RF_VALID) {
1342                 SmpPassthroughReply_t *smprep;
1343
1344                 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
1345                 memcpy(req->sense, smprep, sizeof(*smprep));
1346                 req->sense_len = sizeof(*smprep);
1347         } else {
1348                 printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n",
1349                     ioc->name, __FUNCTION__);
1350                 ret = -ENXIO;
1351         }
1352 unmap:
1353         if (dma_addr_out)
1354                 pci_unmap_single(ioc->pcidev, dma_addr_out, req->data_len,
1355                                  PCI_DMA_BIDIRECTIONAL);
1356         if (dma_addr_in)
1357                 pci_unmap_single(ioc->pcidev, dma_addr_in, rsp->data_len,
1358                                  PCI_DMA_BIDIRECTIONAL);
1359 put_mf:
1360         if (mf)
1361                 mpt_free_msg_frame(ioc, mf);
1362 out_unlock:
1363         mutex_unlock(&ioc->sas_mgmt.mutex);
1364 out:
1365         return ret;
1366 }
1367
1368 static struct sas_function_template mptsas_transport_functions = {
1369         .get_linkerrors         = mptsas_get_linkerrors,
1370         .get_enclosure_identifier = mptsas_get_enclosure_identifier,
1371         .get_bay_identifier     = mptsas_get_bay_identifier,
1372         .phy_reset              = mptsas_phy_reset,
1373         .smp_handler            = mptsas_smp_handler,
1374 };
1375
1376 static struct scsi_transport_template *mptsas_transport_template;
1377
1378 static int
1379 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
1380 {
1381         ConfigExtendedPageHeader_t hdr;
1382         CONFIGPARMS cfg;
1383         SasIOUnitPage0_t *buffer;
1384         dma_addr_t dma_handle;
1385         int error, i;
1386
1387         hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
1388         hdr.ExtPageLength = 0;
1389         hdr.PageNumber = 0;
1390         hdr.Reserved1 = 0;
1391         hdr.Reserved2 = 0;
1392         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1393         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1394
1395         cfg.cfghdr.ehdr = &hdr;
1396         cfg.physAddr = -1;
1397         cfg.pageAddr = 0;
1398         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1399         cfg.dir = 0;    /* read */
1400         cfg.timeout = 10;
1401
1402         error = mpt_config(ioc, &cfg);
1403         if (error)
1404                 goto out;
1405         if (!hdr.ExtPageLength) {
1406                 error = -ENXIO;
1407                 goto out;
1408         }
1409
1410         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1411                                             &dma_handle);
1412         if (!buffer) {
1413                 error = -ENOMEM;
1414                 goto out;
1415         }
1416
1417         cfg.physAddr = dma_handle;
1418         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1419
1420         error = mpt_config(ioc, &cfg);
1421         if (error)
1422                 goto out_free_consistent;
1423
1424         port_info->num_phys = buffer->NumPhys;
1425         port_info->phy_info = kcalloc(port_info->num_phys,
1426                 sizeof(*port_info->phy_info),GFP_KERNEL);
1427         if (!port_info->phy_info) {
1428                 error = -ENOMEM;
1429                 goto out_free_consistent;
1430         }
1431
1432         ioc->nvdata_version_persistent =
1433             le16_to_cpu(buffer->NvdataVersionPersistent);
1434         ioc->nvdata_version_default =
1435             le16_to_cpu(buffer->NvdataVersionDefault);
1436
1437         for (i = 0; i < port_info->num_phys; i++) {
1438                 mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
1439                 port_info->phy_info[i].phy_id = i;
1440                 port_info->phy_info[i].port_id =
1441                     buffer->PhyData[i].Port;
1442                 port_info->phy_info[i].negotiated_link_rate =
1443                     buffer->PhyData[i].NegotiatedLinkRate;
1444                 port_info->phy_info[i].portinfo = port_info;
1445                 port_info->phy_info[i].handle =
1446                     le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
1447         }
1448
1449  out_free_consistent:
1450         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1451                             buffer, dma_handle);
1452  out:
1453         return error;
1454 }
1455
1456 static int
1457 mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
1458 {
1459         ConfigExtendedPageHeader_t hdr;
1460         CONFIGPARMS cfg;
1461         SasIOUnitPage1_t *buffer;
1462         dma_addr_t dma_handle;
1463         int error;
1464         u16 device_missing_delay;
1465
1466         memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
1467         memset(&cfg, 0, sizeof(CONFIGPARMS));
1468
1469         cfg.cfghdr.ehdr = &hdr;
1470         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1471         cfg.timeout = 10;
1472         cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1473         cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1474         cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
1475         cfg.cfghdr.ehdr->PageNumber = 1;
1476
1477         error = mpt_config(ioc, &cfg);
1478         if (error)
1479                 goto out;
1480         if (!hdr.ExtPageLength) {
1481                 error = -ENXIO;
1482                 goto out;
1483         }
1484
1485         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1486                                             &dma_handle);
1487         if (!buffer) {
1488                 error = -ENOMEM;
1489                 goto out;
1490         }
1491
1492         cfg.physAddr = dma_handle;
1493         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1494
1495         error = mpt_config(ioc, &cfg);
1496         if (error)
1497                 goto out_free_consistent;
1498
1499         ioc->io_missing_delay  =
1500             le16_to_cpu(buffer->IODeviceMissingDelay);
1501         device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay);
1502         ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
1503             (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
1504             device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
1505
1506  out_free_consistent:
1507         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1508                             buffer, dma_handle);
1509  out:
1510         return error;
1511 }
1512
1513 static int
1514 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1515                 u32 form, u32 form_specific)
1516 {
1517         ConfigExtendedPageHeader_t hdr;
1518         CONFIGPARMS cfg;
1519         SasPhyPage0_t *buffer;
1520         dma_addr_t dma_handle;
1521         int error;
1522
1523         hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
1524         hdr.ExtPageLength = 0;
1525         hdr.PageNumber = 0;
1526         hdr.Reserved1 = 0;
1527         hdr.Reserved2 = 0;
1528         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1529         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1530
1531         cfg.cfghdr.ehdr = &hdr;
1532         cfg.dir = 0;    /* read */
1533         cfg.timeout = 10;
1534
1535         /* Get Phy Pg 0 for each Phy. */
1536         cfg.physAddr = -1;
1537         cfg.pageAddr = form + form_specific;
1538         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1539
1540         error = mpt_config(ioc, &cfg);
1541         if (error)
1542                 goto out;
1543
1544         if (!hdr.ExtPageLength) {
1545                 error = -ENXIO;
1546                 goto out;
1547         }
1548
1549         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1550                                       &dma_handle);
1551         if (!buffer) {
1552                 error = -ENOMEM;
1553                 goto out;
1554         }
1555
1556         cfg.physAddr = dma_handle;
1557         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1558
1559         error = mpt_config(ioc, &cfg);
1560         if (error)
1561                 goto out_free_consistent;
1562
1563         mptsas_print_phy_pg0(ioc, buffer);
1564
1565         phy_info->hw_link_rate = buffer->HwLinkRate;
1566         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1567         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1568         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1569
1570  out_free_consistent:
1571         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1572                             buffer, dma_handle);
1573  out:
1574         return error;
1575 }
1576
1577 static int
1578 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
1579                 u32 form, u32 form_specific)
1580 {
1581         ConfigExtendedPageHeader_t hdr;
1582         CONFIGPARMS cfg;
1583         SasDevicePage0_t *buffer;
1584         dma_addr_t dma_handle;
1585         __le64 sas_address;
1586         int error=0;
1587
1588         if (ioc->sas_discovery_runtime &&
1589                 mptsas_is_end_device(device_info))
1590                         goto out;
1591
1592         hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
1593         hdr.ExtPageLength = 0;
1594         hdr.PageNumber = 0;
1595         hdr.Reserved1 = 0;
1596         hdr.Reserved2 = 0;
1597         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1598         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1599
1600         cfg.cfghdr.ehdr = &hdr;
1601         cfg.pageAddr = form + form_specific;
1602         cfg.physAddr = -1;
1603         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1604         cfg.dir = 0;    /* read */
1605         cfg.timeout = 10;
1606
1607         memset(device_info, 0, sizeof(struct mptsas_devinfo));
1608         error = mpt_config(ioc, &cfg);
1609         if (error)
1610                 goto out;
1611         if (!hdr.ExtPageLength) {
1612                 error = -ENXIO;
1613                 goto out;
1614         }
1615
1616         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1617                                       &dma_handle);
1618         if (!buffer) {
1619                 error = -ENOMEM;
1620                 goto out;
1621         }
1622
1623         cfg.physAddr = dma_handle;
1624         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1625
1626         error = mpt_config(ioc, &cfg);
1627         if (error)
1628                 goto out_free_consistent;
1629
1630         mptsas_print_device_pg0(ioc, buffer);
1631
1632         device_info->handle = le16_to_cpu(buffer->DevHandle);
1633         device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
1634         device_info->handle_enclosure =
1635             le16_to_cpu(buffer->EnclosureHandle);
1636         device_info->slot = le16_to_cpu(buffer->Slot);
1637         device_info->phy_id = buffer->PhyNum;
1638         device_info->port_id = buffer->PhysicalPort;
1639         device_info->id = buffer->TargetID;
1640         device_info->phys_disk_num = ~0;
1641         device_info->channel = buffer->Bus;
1642         memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
1643         device_info->sas_address = le64_to_cpu(sas_address);
1644         device_info->device_info =
1645             le32_to_cpu(buffer->DeviceInfo);
1646
1647  out_free_consistent:
1648         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1649                             buffer, dma_handle);
1650  out:
1651         return error;
1652 }
1653
1654 static int
1655 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
1656                 u32 form, u32 form_specific)
1657 {
1658         ConfigExtendedPageHeader_t hdr;
1659         CONFIGPARMS cfg;
1660         SasExpanderPage0_t *buffer;
1661         dma_addr_t dma_handle;
1662         int i, error;
1663
1664         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1665         hdr.ExtPageLength = 0;
1666         hdr.PageNumber = 0;
1667         hdr.Reserved1 = 0;
1668         hdr.Reserved2 = 0;
1669         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1670         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1671
1672         cfg.cfghdr.ehdr = &hdr;
1673         cfg.physAddr = -1;
1674         cfg.pageAddr = form + form_specific;
1675         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1676         cfg.dir = 0;    /* read */
1677         cfg.timeout = 10;
1678
1679         memset(port_info, 0, sizeof(struct mptsas_portinfo));
1680         error = mpt_config(ioc, &cfg);
1681         if (error)
1682                 goto out;
1683
1684         if (!hdr.ExtPageLength) {
1685                 error = -ENXIO;
1686                 goto out;
1687         }
1688
1689         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1690                                       &dma_handle);
1691         if (!buffer) {
1692                 error = -ENOMEM;
1693                 goto out;
1694         }
1695
1696         cfg.physAddr = dma_handle;
1697         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1698
1699         error = mpt_config(ioc, &cfg);
1700         if (error)
1701                 goto out_free_consistent;
1702
1703         /* save config data */
1704         port_info->num_phys = buffer->NumPhys;
1705         port_info->phy_info = kcalloc(port_info->num_phys,
1706                 sizeof(*port_info->phy_info),GFP_KERNEL);
1707         if (!port_info->phy_info) {
1708                 error = -ENOMEM;
1709                 goto out_free_consistent;
1710         }
1711
1712         for (i = 0; i < port_info->num_phys; i++) {
1713                 port_info->phy_info[i].portinfo = port_info;
1714                 port_info->phy_info[i].handle =
1715                     le16_to_cpu(buffer->DevHandle);
1716         }
1717
1718  out_free_consistent:
1719         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1720                             buffer, dma_handle);
1721  out:
1722         return error;
1723 }
1724
1725 static int
1726 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1727                 u32 form, u32 form_specific)
1728 {
1729         ConfigExtendedPageHeader_t hdr;
1730         CONFIGPARMS cfg;
1731         SasExpanderPage1_t *buffer;
1732         dma_addr_t dma_handle;
1733         int error=0;
1734
1735         if (ioc->sas_discovery_runtime &&
1736                 mptsas_is_end_device(&phy_info->attached))
1737                         goto out;
1738
1739         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1740         hdr.ExtPageLength = 0;
1741         hdr.PageNumber = 1;
1742         hdr.Reserved1 = 0;
1743         hdr.Reserved2 = 0;
1744         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1745         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1746
1747         cfg.cfghdr.ehdr = &hdr;
1748         cfg.physAddr = -1;
1749         cfg.pageAddr = form + form_specific;
1750         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1751         cfg.dir = 0;    /* read */
1752         cfg.timeout = 10;
1753
1754         error = mpt_config(ioc, &cfg);
1755         if (error)
1756                 goto out;
1757
1758         if (!hdr.ExtPageLength) {
1759                 error = -ENXIO;
1760                 goto out;
1761         }
1762
1763         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1764                                       &dma_handle);
1765         if (!buffer) {
1766                 error = -ENOMEM;
1767                 goto out;
1768         }
1769
1770         cfg.physAddr = dma_handle;
1771         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1772
1773         error = mpt_config(ioc, &cfg);
1774         if (error)
1775                 goto out_free_consistent;
1776
1777
1778         mptsas_print_expander_pg1(ioc, buffer);
1779
1780         /* save config data */
1781         phy_info->phy_id = buffer->PhyIdentifier;
1782         phy_info->port_id = buffer->PhysicalPort;
1783         phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
1784         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1785         phy_info->hw_link_rate = buffer->HwLinkRate;
1786         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1787         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1788
1789  out_free_consistent:
1790         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1791                             buffer, dma_handle);
1792  out:
1793         return error;
1794 }
1795
1796 static void
1797 mptsas_parse_device_info(struct sas_identify *identify,
1798                 struct mptsas_devinfo *device_info)
1799 {
1800         u16 protocols;
1801
1802         identify->sas_address = device_info->sas_address;
1803         identify->phy_identifier = device_info->phy_id;
1804
1805         /*
1806          * Fill in Phy Initiator Port Protocol.
1807          * Bits 6:3, more than one bit can be set, fall through cases.
1808          */
1809         protocols = device_info->device_info & 0x78;
1810         identify->initiator_port_protocols = 0;
1811         if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
1812                 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
1813         if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1814                 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
1815         if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
1816                 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
1817         if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
1818                 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
1819
1820         /*
1821          * Fill in Phy Target Port Protocol.
1822          * Bits 10:7, more than one bit can be set, fall through cases.
1823          */
1824         protocols = device_info->device_info & 0x780;
1825         identify->target_port_protocols = 0;
1826         if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1827                 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
1828         if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
1829                 identify->target_port_protocols |= SAS_PROTOCOL_STP;
1830         if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
1831                 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
1832         if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1833                 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
1834
1835         /*
1836          * Fill in Attached device type.
1837          */
1838         switch (device_info->device_info &
1839                         MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
1840         case MPI_SAS_DEVICE_INFO_NO_DEVICE:
1841                 identify->device_type = SAS_PHY_UNUSED;
1842                 break;
1843         case MPI_SAS_DEVICE_INFO_END_DEVICE:
1844                 identify->device_type = SAS_END_DEVICE;
1845                 break;
1846         case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
1847                 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
1848                 break;
1849         case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
1850                 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
1851                 break;
1852         }
1853 }
1854
1855 static int mptsas_probe_one_phy(struct device *dev,
1856                 struct mptsas_phyinfo *phy_info, int index, int local)
1857 {
1858         MPT_ADAPTER *ioc;
1859         struct sas_phy *phy;
1860         struct sas_port *port;
1861         int error = 0;
1862
1863         if (!dev) {
1864                 error = -ENODEV;
1865                 goto out;
1866         }
1867
1868         if (!phy_info->phy) {
1869                 phy = sas_phy_alloc(dev, index);
1870                 if (!phy) {
1871                         error = -ENOMEM;
1872                         goto out;
1873                 }
1874         } else
1875                 phy = phy_info->phy;
1876
1877         mptsas_parse_device_info(&phy->identify, &phy_info->identify);
1878
1879         /*
1880          * Set Negotiated link rate.
1881          */
1882         switch (phy_info->negotiated_link_rate) {
1883         case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
1884                 phy->negotiated_linkrate = SAS_PHY_DISABLED;
1885                 break;
1886         case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
1887                 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
1888                 break;
1889         case MPI_SAS_IOUNIT0_RATE_1_5:
1890                 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
1891                 break;
1892         case MPI_SAS_IOUNIT0_RATE_3_0:
1893                 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
1894                 break;
1895         case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
1896         case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
1897         default:
1898                 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
1899                 break;
1900         }
1901
1902         /*
1903          * Set Max hardware link rate.
1904          */
1905         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1906         case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
1907                 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1908                 break;
1909         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1910                 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1911                 break;
1912         default:
1913                 break;
1914         }
1915
1916         /*
1917          * Set Max programmed link rate.
1918          */
1919         switch (phy_info->programmed_link_rate &
1920                         MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1921         case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
1922                 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1923                 break;
1924         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1925                 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1926                 break;
1927         default:
1928                 break;
1929         }
1930
1931         /*
1932          * Set Min hardware link rate.
1933          */
1934         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
1935         case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
1936                 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1937                 break;
1938         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1939                 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1940                 break;
1941         default:
1942                 break;
1943         }
1944
1945         /*
1946          * Set Min programmed link rate.
1947          */
1948         switch (phy_info->programmed_link_rate &
1949                         MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
1950         case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
1951                 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1952                 break;
1953         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1954                 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1955                 break;
1956         default:
1957                 break;
1958         }
1959
1960         if (!phy_info->phy) {
1961
1962                 error = sas_phy_add(phy);
1963                 if (error) {
1964                         sas_phy_free(phy);
1965                         goto out;
1966                 }
1967                 phy_info->phy = phy;
1968         }
1969
1970         if (!phy_info->attached.handle ||
1971                         !phy_info->port_details)
1972                 goto out;
1973
1974         port = mptsas_get_port(phy_info);
1975         ioc = phy_to_ioc(phy_info->phy);
1976
1977         if (phy_info->sas_port_add_phy) {
1978
1979                 if (!port) {
1980                         port = sas_port_alloc_num(dev);
1981                         if (!port) {
1982                                 error = -ENOMEM;
1983                                 goto out;
1984                         }
1985                         error = sas_port_add(port);
1986                         if (error) {
1987                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1988                                         "%s: exit at line=%d\n", ioc->name,
1989                                         __FUNCTION__, __LINE__));
1990                                 goto out;
1991                         }
1992                         mptsas_set_port(ioc, phy_info, port);
1993                         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1994                             "sas_port_alloc: port=%p dev=%p port_id=%d\n",
1995                             ioc->name, port, dev, port->port_identifier));
1996                 }
1997                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_port_add_phy: phy_id=%d\n",
1998                     ioc->name, phy_info->phy_id));
1999                 sas_port_add_phy(port, phy_info->phy);
2000                 phy_info->sas_port_add_phy = 0;
2001         }
2002
2003         if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
2004
2005                 struct sas_rphy *rphy;
2006                 struct device *parent;
2007                 struct sas_identify identify;
2008
2009                 parent = dev->parent->parent;
2010                 /*
2011                  * Let the hotplug_work thread handle processing
2012                  * the adding/removing of devices that occur
2013                  * after start of day.
2014                  */
2015                 if (ioc->sas_discovery_runtime &&
2016                         mptsas_is_end_device(&phy_info->attached))
2017                                 goto out;
2018
2019                 mptsas_parse_device_info(&identify, &phy_info->attached);
2020                 if (scsi_is_host_device(parent)) {
2021                         struct mptsas_portinfo *port_info;
2022                         int i;
2023
2024                         mutex_lock(&ioc->sas_topology_mutex);
2025                         port_info = mptsas_find_portinfo_by_handle(ioc,
2026                                                                    ioc->handle);
2027                         mutex_unlock(&ioc->sas_topology_mutex);
2028
2029                         for (i = 0; i < port_info->num_phys; i++)
2030                                 if (port_info->phy_info[i].identify.sas_address ==
2031                                     identify.sas_address) {
2032                                         sas_port_mark_backlink(port);
2033                                         goto out;
2034                                 }
2035
2036                 } else if (scsi_is_sas_rphy(parent)) {
2037                         struct sas_rphy *parent_rphy = dev_to_rphy(parent);
2038                         if (identify.sas_address ==
2039                             parent_rphy->identify.sas_address) {
2040                                 sas_port_mark_backlink(port);
2041                                 goto out;
2042                         }
2043                 }
2044
2045                 switch (identify.device_type) {
2046                 case SAS_END_DEVICE:
2047                         rphy = sas_end_device_alloc(port);
2048                         break;
2049                 case SAS_EDGE_EXPANDER_DEVICE:
2050                 case SAS_FANOUT_EXPANDER_DEVICE:
2051                         rphy = sas_expander_alloc(port, identify.device_type);
2052                         break;
2053                 default:
2054                         rphy = NULL;
2055                         break;
2056                 }
2057                 if (!rphy) {
2058                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2059                                 "%s: exit at line=%d\n", ioc->name,
2060                                 __FUNCTION__, __LINE__));
2061                         goto out;
2062                 }
2063
2064                 rphy->identify = identify;
2065                 error = sas_rphy_add(rphy);
2066                 if (error) {
2067                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2068                                 "%s: exit at line=%d\n", ioc->name,
2069                                 __FUNCTION__, __LINE__));
2070                         sas_rphy_free(rphy);
2071                         goto out;
2072                 }
2073                 mptsas_set_rphy(ioc, phy_info, rphy);
2074         }
2075
2076  out:
2077         return error;
2078 }
2079
2080 static int
2081 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
2082 {
2083         struct mptsas_portinfo *port_info, *hba;
2084         int error = -ENOMEM, i;
2085
2086         hba = kzalloc(sizeof(*port_info), GFP_KERNEL);
2087         if (! hba)
2088                 goto out;
2089
2090         error = mptsas_sas_io_unit_pg0(ioc, hba);
2091         if (error)
2092                 goto out_free_port_info;
2093
2094         mptsas_sas_io_unit_pg1(ioc);
2095         mutex_lock(&ioc->sas_topology_mutex);
2096         ioc->handle = hba->phy_info[0].handle;
2097         port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
2098         if (!port_info) {
2099                 port_info = hba;
2100                 list_add_tail(&port_info->list, &ioc->sas_topology);
2101         } else {
2102                 for (i = 0; i < hba->num_phys; i++) {
2103                         port_info->phy_info[i].negotiated_link_rate =
2104                                 hba->phy_info[i].negotiated_link_rate;
2105                         port_info->phy_info[i].handle =
2106                                 hba->phy_info[i].handle;
2107                         port_info->phy_info[i].port_id =
2108                                 hba->phy_info[i].port_id;
2109                 }
2110                 kfree(hba->phy_info);
2111                 kfree(hba);
2112                 hba = NULL;
2113         }
2114         mutex_unlock(&ioc->sas_topology_mutex);
2115         for (i = 0; i < port_info->num_phys; i++) {
2116                 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
2117                         (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
2118                          MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
2119
2120                 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
2121                         (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2122                          MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2123                          port_info->phy_info[i].handle);
2124                 port_info->phy_info[i].identify.phy_id =
2125                     port_info->phy_info[i].phy_id = i;
2126                 if (port_info->phy_info[i].attached.handle)
2127                         mptsas_sas_device_pg0(ioc,
2128                                 &port_info->phy_info[i].attached,
2129                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2130                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2131                                 port_info->phy_info[i].attached.handle);
2132         }
2133
2134         mptsas_setup_wide_ports(ioc, port_info);
2135
2136         for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
2137                 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
2138                     &port_info->phy_info[i], ioc->sas_index, 1);
2139
2140         return 0;
2141
2142  out_free_port_info:
2143         kfree(hba);
2144  out:
2145         return error;
2146 }
2147
2148 static int
2149 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
2150 {
2151         struct mptsas_portinfo *port_info, *p, *ex;
2152         struct device *parent;
2153         struct sas_rphy *rphy;
2154         int error = -ENOMEM, i, j;
2155
2156         ex = kzalloc(sizeof(*port_info), GFP_KERNEL);
2157         if (!ex)
2158                 goto out;
2159
2160         error = mptsas_sas_expander_pg0(ioc, ex,
2161             (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
2162              MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
2163         if (error)
2164                 goto out_free_port_info;
2165
2166         *handle = ex->phy_info[0].handle;
2167
2168         mutex_lock(&ioc->sas_topology_mutex);
2169         port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
2170         if (!port_info) {
2171                 port_info = ex;
2172                 list_add_tail(&port_info->list, &ioc->sas_topology);
2173         } else {
2174                 for (i = 0; i < ex->num_phys; i++) {
2175                         port_info->phy_info[i].handle =
2176                                 ex->phy_info[i].handle;
2177                         port_info->phy_info[i].port_id =
2178                                 ex->phy_info[i].port_id;
2179                 }
2180                 kfree(ex->phy_info);
2181                 kfree(ex);
2182                 ex = NULL;
2183         }
2184         mutex_unlock(&ioc->sas_topology_mutex);
2185
2186         for (i = 0; i < port_info->num_phys; i++) {
2187                 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
2188                         (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
2189                          MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
2190
2191                 if (port_info->phy_info[i].identify.handle) {
2192                         mptsas_sas_device_pg0(ioc,
2193                                 &port_info->phy_info[i].identify,
2194                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2195                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2196                                 port_info->phy_info[i].identify.handle);
2197                         port_info->phy_info[i].identify.phy_id =
2198                             port_info->phy_info[i].phy_id;
2199                 }
2200
2201                 if (port_info->phy_info[i].attached.handle) {
2202                         mptsas_sas_device_pg0(ioc,
2203                                 &port_info->phy_info[i].attached,
2204                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2205                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2206                                 port_info->phy_info[i].attached.handle);
2207                         port_info->phy_info[i].attached.phy_id =
2208                             port_info->phy_info[i].phy_id;
2209                 }
2210         }
2211
2212         parent = &ioc->sh->shost_gendev;
2213         for (i = 0; i < port_info->num_phys; i++) {
2214                 mutex_lock(&ioc->sas_topology_mutex);
2215                 list_for_each_entry(p, &ioc->sas_topology, list) {
2216                         for (j = 0; j < p->num_phys; j++) {
2217                                 if (port_info->phy_info[i].identify.handle !=
2218                                                 p->phy_info[j].attached.handle)
2219                                         continue;
2220                                 rphy = mptsas_get_rphy(&p->phy_info[j]);
2221                                 parent = &rphy->dev;
2222                         }
2223                 }
2224                 mutex_unlock(&ioc->sas_topology_mutex);
2225         }
2226
2227         mptsas_setup_wide_ports(ioc, port_info);
2228
2229         for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
2230                 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
2231                     ioc->sas_index, 0);
2232
2233         return 0;
2234
2235  out_free_port_info:
2236         if (ex) {
2237                 kfree(ex->phy_info);
2238                 kfree(ex);
2239         }
2240  out:
2241         return error;
2242 }
2243
2244 /*
2245  * mptsas_delete_expander_phys
2246  *
2247  *
2248  * This will traverse topology, and remove expanders
2249  * that are no longer present
2250  */
2251 static void
2252 mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
2253 {
2254         struct mptsas_portinfo buffer;
2255         struct mptsas_portinfo *port_info, *n, *parent;
2256         struct mptsas_phyinfo *phy_info;
2257         struct sas_port * port;
2258         int i;
2259         u64     expander_sas_address;
2260
2261         mutex_lock(&ioc->sas_topology_mutex);
2262         list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
2263
2264                 if (port_info->phy_info &&
2265                     (!(port_info->phy_info[0].identify.device_info &
2266                     MPI_SAS_DEVICE_INFO_SMP_TARGET)))
2267                         continue;
2268
2269                 if (mptsas_sas_expander_pg0(ioc, &buffer,
2270                      (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
2271                      MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
2272                      port_info->phy_info[0].handle)) {
2273
2274                         /*
2275                          * Obtain the port_info instance to the parent port
2276                          */
2277                         parent = mptsas_find_portinfo_by_handle(ioc,
2278                             port_info->phy_info[0].identify.handle_parent);
2279
2280                         if (!parent)
2281                                 goto next_port;
2282
2283                         expander_sas_address =
2284                                 port_info->phy_info[0].identify.sas_address;
2285
2286                         /*
2287                          * Delete rphys in the parent that point
2288                          * to this expander.  The transport layer will
2289                          * cleanup all the children.
2290                          */
2291                         phy_info = parent->phy_info;
2292                         for (i = 0; i < parent->num_phys; i++, phy_info++) {
2293                                 port = mptsas_get_port(phy_info);
2294                                 if (!port)
2295                                         continue;
2296                                 if (phy_info->attached.sas_address !=
2297                                         expander_sas_address)
2298                                         continue;
2299                                 dsaswideprintk(ioc,
2300                                     dev_printk(MYIOC_s_DEBUG_FMT, &port->dev,
2301                                     "delete port (%d)\n", ioc->name, port->port_identifier));
2302                                 sas_port_delete(port);
2303                                 mptsas_port_delete(ioc, phy_info->port_details);
2304                         }
2305  next_port:
2306
2307                         phy_info = port_info->phy_info;
2308                         for (i = 0; i < port_info->num_phys; i++, phy_info++)
2309                                 mptsas_port_delete(ioc, phy_info->port_details);
2310
2311                         list_del(&port_info->list);
2312                         kfree(port_info->phy_info);
2313                         kfree(port_info);
2314                 }
2315                 /*
2316                 * Free this memory allocated from inside
2317                 * mptsas_sas_expander_pg0
2318                 */
2319                 kfree(buffer.phy_info);
2320         }
2321         mutex_unlock(&ioc->sas_topology_mutex);
2322 }
2323
2324 /*
2325  * Start of day discovery
2326  */
2327 static void
2328 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
2329 {
2330         u32 handle = 0xFFFF;
2331         int i;
2332
2333         mutex_lock(&ioc->sas_discovery_mutex);
2334         mptsas_probe_hba_phys(ioc);
2335         while (!mptsas_probe_expander_phys(ioc, &handle))
2336                 ;
2337         /*
2338           Reporting RAID volumes.
2339         */
2340         if (!ioc->ir_firmware)
2341                 goto out;
2342         if (!ioc->raid_data.pIocPg2)
2343                 goto out;
2344         if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
2345                 goto out;
2346         for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
2347                 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
2348                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
2349         }
2350  out:
2351         mutex_unlock(&ioc->sas_discovery_mutex);
2352 }
2353
2354 /*
2355  * Work queue thread to handle Runtime discovery
2356  * Mere purpose is the hot add/delete of expanders
2357  *(Mutex UNLOCKED)
2358  */
2359 static void
2360 __mptsas_discovery_work(MPT_ADAPTER *ioc)
2361 {
2362         u32 handle = 0xFFFF;
2363
2364         ioc->sas_discovery_runtime=1;
2365         mptsas_delete_expander_phys(ioc);
2366         mptsas_probe_hba_phys(ioc);
2367         while (!mptsas_probe_expander_phys(ioc, &handle))
2368                 ;
2369         ioc->sas_discovery_runtime=0;
2370 }
2371
2372 /*
2373  * Work queue thread to handle Runtime discovery
2374  * Mere purpose is the hot add/delete of expanders
2375  *(Mutex LOCKED)
2376  */
2377 static void
2378 mptsas_discovery_work(struct work_struct *work)
2379 {
2380         struct mptsas_discovery_event *ev =
2381                 container_of(work, struct mptsas_discovery_event, work);
2382         MPT_ADAPTER *ioc = ev->ioc;
2383
2384         mutex_lock(&ioc->sas_discovery_mutex);
2385         __mptsas_discovery_work(ioc);
2386         mutex_unlock(&ioc->sas_discovery_mutex);
2387         kfree(ev);
2388 }
2389
2390 static struct mptsas_phyinfo *
2391 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
2392 {
2393         struct mptsas_portinfo *port_info;
2394         struct mptsas_phyinfo *phy_info = NULL;
2395         int i;
2396
2397         mutex_lock(&ioc->sas_topology_mutex);
2398         list_for_each_entry(port_info, &ioc->sas_topology, list) {
2399                 for (i = 0; i < port_info->num_phys; i++) {
2400                         if (!mptsas_is_end_device(
2401                                 &port_info->phy_info[i].attached))
2402                                 continue;
2403                         if (port_info->phy_info[i].attached.sas_address
2404                             != sas_address)
2405                                 continue;
2406                         phy_info = &port_info->phy_info[i];
2407                         break;
2408                 }
2409         }
2410         mutex_unlock(&ioc->sas_topology_mutex);
2411         return phy_info;
2412 }
2413
2414 static struct mptsas_phyinfo *
2415 mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u8 channel, u8 id)
2416 {
2417         struct mptsas_portinfo *port_info;
2418         struct mptsas_phyinfo *phy_info = NULL;
2419         int i;
2420
2421         mutex_lock(&ioc->sas_topology_mutex);
2422         list_for_each_entry(port_info, &ioc->sas_topology, list) {
2423                 for (i = 0; i < port_info->num_phys; i++) {
2424                         if (!mptsas_is_end_device(
2425                                 &port_info->phy_info[i].attached))
2426                                 continue;
2427                         if (port_info->phy_info[i].attached.id != id)
2428                                 continue;
2429                         if (port_info->phy_info[i].attached.channel != channel)
2430                                 continue;
2431                         phy_info = &port_info->phy_info[i];
2432                         break;
2433                 }
2434         }
2435         mutex_unlock(&ioc->sas_topology_mutex);
2436         return phy_info;
2437 }
2438
2439 static struct mptsas_phyinfo *
2440 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2441 {
2442         struct mptsas_portinfo *port_info;
2443         struct mptsas_phyinfo *phy_info = NULL;
2444         int i;
2445
2446         mutex_lock(&ioc->sas_topology_mutex);
2447         list_for_each_entry(port_info, &ioc->sas_topology, list) {
2448                 for (i = 0; i < port_info->num_phys; i++) {
2449                         if (!mptsas_is_end_device(
2450                                 &port_info->phy_info[i].attached))
2451                                 continue;
2452                         if (port_info->phy_info[i].attached.phys_disk_num == ~0)
2453                                 continue;
2454                         if (port_info->phy_info[i].attached.phys_disk_num != id)
2455                                 continue;
2456                         if (port_info->phy_info[i].attached.channel != channel)
2457                                 continue;
2458                         phy_info = &port_info->phy_info[i];
2459                         break;
2460                 }
2461         }
2462         mutex_unlock(&ioc->sas_topology_mutex);
2463         return phy_info;
2464 }
2465
2466 /*
2467  * Work queue thread to clear the persitency table
2468  */
2469 static void
2470 mptsas_persist_clear_table(struct work_struct *work)
2471 {
2472         MPT_ADAPTER *ioc = container_of(work, MPT_ADAPTER, sas_persist_task);
2473
2474         mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2475 }
2476
2477 static void
2478 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
2479 {
2480         int rc;
2481
2482         sdev->no_uld_attach = data ? 1 : 0;
2483         rc = scsi_device_reprobe(sdev);
2484 }
2485
2486 static void
2487 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
2488 {
2489         starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
2490                         mptsas_reprobe_lun);
2491 }
2492
2493 static void
2494 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
2495 {
2496         CONFIGPARMS                     cfg;
2497         ConfigPageHeader_t              hdr;
2498         dma_addr_t                      dma_handle;
2499         pRaidVolumePage0_t              buffer = NULL;
2500         RaidPhysDiskPage0_t             phys_disk;
2501         int                             i;
2502         struct mptsas_hotplug_event     *ev;
2503
2504         memset(&cfg, 0 , sizeof(CONFIGPARMS));
2505         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
2506         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
2507         cfg.pageAddr = (channel << 8) + id;
2508         cfg.cfghdr.hdr = &hdr;
2509         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2510
2511         if (mpt_config(ioc, &cfg) != 0)
2512                 goto out;
2513
2514         if (!hdr.PageLength)
2515                 goto out;
2516
2517         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
2518             &dma_handle);
2519
2520         if (!buffer)
2521                 goto out;
2522
2523         cfg.physAddr = dma_handle;
2524         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2525
2526         if (mpt_config(ioc, &cfg) != 0)
2527                 goto out;
2528
2529         if (!(buffer->VolumeStatus.Flags &
2530             MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
2531                 goto out;
2532
2533         if (!buffer->NumPhysDisks)
2534                 goto out;
2535
2536         for (i = 0; i < buffer->NumPhysDisks; i++) {
2537
2538                 if (mpt_raid_phys_disk_pg0(ioc,
2539                     buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
2540                         continue;
2541
2542                 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2543                 if (!ev) {
2544                         printk(MYIOC_s_WARN_FMT "mptsas: lost hotplug event\n", ioc->name);
2545                         goto out;
2546                 }
2547
2548                 INIT_WORK(&ev->work, mptsas_hotplug_work);
2549                 ev->ioc = ioc;
2550                 ev->id = phys_disk.PhysDiskID;
2551                 ev->channel = phys_disk.PhysDiskBus;
2552                 ev->phys_disk_num_valid = 1;
2553                 ev->phys_disk_num = phys_disk.PhysDiskNum;
2554                 ev->event_type = MPTSAS_ADD_DEVICE;
2555                 schedule_work(&ev->work);
2556         }
2557
2558  out:
2559         if (buffer)
2560                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
2561                     dma_handle);
2562 }
2563 /*
2564  * Work queue thread to handle SAS hotplug events
2565  */
2566 static void
2567 mptsas_hotplug_work(struct work_struct *work)
2568 {
2569         struct mptsas_hotplug_event *ev =
2570                 container_of(work, struct mptsas_hotplug_event, work);
2571
2572         MPT_ADAPTER *ioc = ev->ioc;
2573         struct mptsas_phyinfo *phy_info;
2574         struct sas_rphy *rphy;
2575         struct sas_port *port;
2576         struct scsi_device *sdev;
2577         struct scsi_target * starget;
2578         struct sas_identify identify;
2579         char *ds = NULL;
2580         struct mptsas_devinfo sas_device;
2581         VirtTarget *vtarget;
2582         VirtDevice *vdevice;
2583
2584         mutex_lock(&ioc->sas_discovery_mutex);
2585         switch (ev->event_type) {
2586         case MPTSAS_DEL_DEVICE:
2587
2588                 phy_info = NULL;
2589                 if (ev->phys_disk_num_valid) {
2590                         if (ev->hidden_raid_component){
2591                                 if (mptsas_sas_device_pg0(ioc, &sas_device,
2592                                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2593                                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2594                                     (ev->channel << 8) + ev->id)) {
2595                                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2596                                         "%s: exit at line=%d\n", ioc->name,
2597                                                 __FUNCTION__, __LINE__));
2598                                         break;
2599                                 }
2600                                 phy_info = mptsas_find_phyinfo_by_sas_address(
2601                                     ioc, sas_device.sas_address);
2602                         }else
2603                                 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
2604                                     ioc, ev->channel, ev->phys_disk_num);
2605                 }
2606
2607                 if (!phy_info)
2608                         phy_info = mptsas_find_phyinfo_by_target(ioc,
2609                             ev->channel, ev->id);
2610
2611                 /*
2612                  * Sanity checks, for non-existing phys and remote rphys.
2613                  */
2614                 if (!phy_info){
2615                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2616                                 "%s: exit at line=%d\n", ioc->name,
2617                                 __FUNCTION__, __LINE__));
2618                         break;
2619                 }
2620                 if (!phy_info->port_details) {
2621                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2622                                 "%s: exit at line=%d\n", ioc->name,
2623                                 __FUNCTION__, __LINE__));
2624                         break;
2625                 }
2626                 rphy = mptsas_get_rphy(phy_info);
2627                 if (!rphy) {
2628                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2629                                 "%s: exit at line=%d\n", ioc->name,
2630                                 __FUNCTION__, __LINE__));
2631                         break;
2632                 }
2633
2634                 port = mptsas_get_port(phy_info);
2635                 if (!port) {
2636                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2637                                 "%s: exit at line=%d\n", ioc->name,
2638                                 __FUNCTION__, __LINE__));
2639                         break;
2640                 }
2641
2642                 starget = mptsas_get_starget(phy_info);
2643                 if (starget) {
2644                         vtarget = starget->hostdata;
2645
2646                         if (!vtarget) {
2647                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2648                                         "%s: exit at line=%d\n", ioc->name,
2649                                         __FUNCTION__, __LINE__));
2650                                 break;
2651                         }
2652
2653                         /*
2654                          * Handling  RAID components
2655                          */
2656                         if (ev->phys_disk_num_valid &&
2657                             ev->hidden_raid_component) {
2658                                 printk(MYIOC_s_INFO_FMT
2659                                     "RAID Hidding: channel=%d, id=%d, "
2660                                     "physdsk %d \n", ioc->name, ev->channel,
2661                                     ev->id, ev->phys_disk_num);
2662                                 vtarget->id = ev->phys_disk_num;
2663                                 vtarget->tflags |=
2664                                     MPT_TARGET_FLAGS_RAID_COMPONENT;
2665                                 mptsas_reprobe_target(starget, 1);
2666                                 phy_info->attached.phys_disk_num =
2667                                     ev->phys_disk_num;
2668                         break;
2669                         }
2670                 }
2671
2672                 if (phy_info->attached.device_info &
2673                     MPI_SAS_DEVICE_INFO_SSP_TARGET)
2674                         ds = "ssp";
2675                 if (phy_info->attached.device_info &
2676                     MPI_SAS_DEVICE_INFO_STP_TARGET)
2677                         ds = "stp";
2678                 if (phy_info->attached.device_info &
2679                     MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2680                         ds = "sata";
2681
2682                 printk(MYIOC_s_INFO_FMT
2683                        "removing %s device, channel %d, id %d, phy %d\n",
2684                        ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
2685                 dev_printk(MYIOC_s_DEBUG_FMT, &port->dev,
2686                     "delete port (%d)\n", ioc->name, port->port_identifier);
2687                 sas_port_delete(port);
2688                 mptsas_port_delete(ioc, phy_info->port_details);
2689                 break;
2690         case MPTSAS_ADD_DEVICE:
2691
2692                 if (ev->phys_disk_num_valid)
2693                         mpt_findImVolumes(ioc);
2694
2695                 /*
2696                  * Refresh sas device pg0 data
2697                  */
2698                 if (mptsas_sas_device_pg0(ioc, &sas_device,
2699                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2700                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2701                         (ev->channel << 8) + ev->id)) {
2702                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2703                                         "%s: exit at line=%d\n", ioc->name,
2704                                         __FUNCTION__, __LINE__));
2705                         break;
2706                 }
2707
2708                 __mptsas_discovery_work(ioc);
2709
2710                 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
2711                                 sas_device.sas_address);
2712
2713                 if (!phy_info || !phy_info->port_details) {
2714                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2715                                 "%s: exit at line=%d\n", ioc->name,
2716                                 __FUNCTION__, __LINE__));
2717                         break;
2718                 }
2719
2720                 starget = mptsas_get_starget(phy_info);
2721                 if (starget && (!ev->hidden_raid_component)){
2722
2723                         vtarget = starget->hostdata;
2724
2725                         if (!vtarget) {
2726                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2727                                     "%s: exit at line=%d\n", ioc->name,
2728                                     __FUNCTION__, __LINE__));
2729                                 break;
2730                         }
2731                         /*
2732                          * Handling  RAID components
2733                          */
2734                         if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
2735                                 printk(MYIOC_s_INFO_FMT
2736                                     "RAID Exposing: channel=%d, id=%d, "
2737                                     "physdsk %d \n", ioc->name, ev->channel,
2738                                     ev->id, ev->phys_disk_num);
2739                                 vtarget->tflags &=
2740                                     ~MPT_TARGET_FLAGS_RAID_COMPONENT;
2741                                 vtarget->id = ev->id;
2742                                 mptsas_reprobe_target(starget, 0);
2743                                 phy_info->attached.phys_disk_num = ~0;
2744                         }
2745                         break;
2746                 }
2747
2748                 if (mptsas_get_rphy(phy_info)) {
2749                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2750                                 "%s: exit at line=%d\n", ioc->name,
2751                                 __FUNCTION__, __LINE__));
2752                         if (ev->channel) printk("%d\n", __LINE__);
2753                         break;
2754                 }
2755
2756                 port = mptsas_get_port(phy_info);
2757                 if (!port) {
2758                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2759                                 "%s: exit at line=%d\n", ioc->name,
2760                                 __FUNCTION__, __LINE__));
2761                         break;
2762                 }
2763                 memcpy(&phy_info->attached, &sas_device,
2764                     sizeof(struct mptsas_devinfo));
2765
2766                 if (phy_info->attached.device_info &
2767                     MPI_SAS_DEVICE_INFO_SSP_TARGET)
2768                         ds = "ssp";
2769                 if (phy_info->attached.device_info &
2770                     MPI_SAS_DEVICE_INFO_STP_TARGET)
2771                         ds = "stp";
2772                 if (phy_info->attached.device_info &
2773                     MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2774                         ds = "sata";
2775
2776                 printk(MYIOC_s_INFO_FMT
2777                        "attaching %s device, channel %d, id %d, phy %d\n",
2778                        ioc->name, ds, ev->channel, ev->id, ev->phy_id);
2779
2780                 mptsas_parse_device_info(&identify, &phy_info->attached);
2781                 rphy = sas_end_device_alloc(port);
2782                 if (!rphy) {
2783                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2784                                 "%s: exit at line=%d\n", ioc->name,
2785                                 __FUNCTION__, __LINE__));
2786                         break; /* non-fatal: an rphy can be added later */
2787                 }
2788
2789                 rphy->identify = identify;
2790                 if (sas_rphy_add(rphy)) {
2791                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2792                                 "%s: exit at line=%d\n", ioc->name,
2793                                 __FUNCTION__, __LINE__));
2794                         sas_rphy_free(rphy);
2795                         break;
2796                 }
2797                 mptsas_set_rphy(ioc, phy_info, rphy);
2798                 break;
2799         case MPTSAS_ADD_RAID:
2800                 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2801                     ev->id, 0);
2802                 if (sdev) {
2803                         scsi_device_put(sdev);
2804                         break;
2805                 }
2806                 printk(MYIOC_s_INFO_FMT
2807                        "attaching raid volume, channel %d, id %d\n",
2808                        ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2809                 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ev->id, 0);
2810                 mpt_findImVolumes(ioc);
2811                 break;
2812         case MPTSAS_DEL_RAID:
2813                 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2814                     ev->id, 0);
2815                 if (!sdev)
2816                         break;
2817                 printk(MYIOC_s_INFO_FMT
2818                        "removing raid volume, channel %d, id %d\n",
2819                        ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2820                 vdevice = sdev->hostdata;
2821                 scsi_remove_device(sdev);
2822                 scsi_device_put(sdev);
2823                 mpt_findImVolumes(ioc);
2824                 break;
2825         case MPTSAS_ADD_INACTIVE_VOLUME:
2826                 mptsas_adding_inactive_raid_components(ioc,
2827                     ev->channel, ev->id);
2828                 break;
2829         case MPTSAS_IGNORE_EVENT:
2830         default:
2831                 break;
2832         }
2833
2834         mutex_unlock(&ioc->sas_discovery_mutex);
2835         kfree(ev);
2836 }
2837
2838 static void
2839 mptsas_send_sas_event(MPT_ADAPTER *ioc,
2840                 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
2841 {
2842         struct mptsas_hotplug_event *ev;
2843         u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
2844         __le64 sas_address;
2845
2846         if ((device_info &
2847              (MPI_SAS_DEVICE_INFO_SSP_TARGET |
2848               MPI_SAS_DEVICE_INFO_STP_TARGET |
2849               MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
2850                 return;
2851
2852         switch (sas_event_data->ReasonCode) {
2853         case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
2854
2855                 mptsas_target_reset_queue(ioc, sas_event_data);
2856                 break;
2857
2858         case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
2859                 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2860                 if (!ev) {
2861                         printk(MYIOC_s_WARN_FMT "lost hotplug event\n", ioc->name);
2862                         break;
2863                 }
2864
2865                 INIT_WORK(&ev->work, mptsas_hotplug_work);
2866                 ev->ioc = ioc;
2867                 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
2868                 ev->parent_handle =
2869                     le16_to_cpu(sas_event_data->ParentDevHandle);
2870                 ev->channel = sas_event_data->Bus;
2871                 ev->id = sas_event_data->TargetID;
2872                 ev->phy_id = sas_event_data->PhyNum;
2873                 memcpy(&sas_address, &sas_event_data->SASAddress,
2874                     sizeof(__le64));
2875                 ev->sas_address = le64_to_cpu(sas_address);
2876                 ev->device_info = device_info;
2877
2878                 if (sas_event_data->ReasonCode &
2879                     MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
2880                         ev->event_type = MPTSAS_ADD_DEVICE;
2881                 else
2882                         ev->event_type = MPTSAS_DEL_DEVICE;
2883                 schedule_work(&ev->work);
2884                 break;
2885         case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
2886         /*
2887          * Persistent table is full.
2888          */
2889                 INIT_WORK(&ioc->sas_persist_task,
2890                     mptsas_persist_clear_table);
2891                 schedule_work(&ioc->sas_persist_task);
2892                 break;
2893         /*
2894          * TODO, handle other events
2895          */
2896         case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
2897         case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
2898         case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
2899         case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
2900         case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
2901         case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
2902         case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
2903         default:
2904                 break;
2905         }
2906 }
2907 static void
2908 mptsas_send_raid_event(MPT_ADAPTER *ioc,
2909                 EVENT_DATA_RAID *raid_event_data)
2910 {
2911         struct mptsas_hotplug_event *ev;
2912         int status = le32_to_cpu(raid_event_data->SettingsStatus);
2913         int state = (status >> 8) & 0xff;
2914
2915         if (ioc->bus_type != SAS)
2916                 return;
2917
2918         ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2919         if (!ev) {
2920                 printk(MYIOC_s_WARN_FMT "lost hotplug event\n", ioc->name);
2921                 return;
2922         }
2923
2924         INIT_WORK(&ev->work, mptsas_hotplug_work);
2925         ev->ioc = ioc;
2926         ev->id = raid_event_data->VolumeID;
2927         ev->channel = raid_event_data->VolumeBus;
2928         ev->event_type = MPTSAS_IGNORE_EVENT;
2929
2930         switch (raid_event_data->ReasonCode) {
2931         case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
2932                 ev->phys_disk_num_valid = 1;
2933                 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2934                 ev->event_type = MPTSAS_ADD_DEVICE;
2935                 break;
2936         case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
2937                 ev->phys_disk_num_valid = 1;
2938                 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2939                 ev->hidden_raid_component = 1;
2940                 ev->event_type = MPTSAS_DEL_DEVICE;
2941                 break;
2942         case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
2943                 switch (state) {
2944                 case MPI_PD_STATE_ONLINE:
2945                 case MPI_PD_STATE_NOT_COMPATIBLE:
2946                         ev->phys_disk_num_valid = 1;
2947                         ev->phys_disk_num = raid_event_data->PhysDiskNum;
2948                         ev->hidden_raid_component = 1;
2949                         ev->event_type = MPTSAS_ADD_DEVICE;
2950                         break;
2951                 case MPI_PD_STATE_MISSING:
2952                 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
2953                 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
2954                 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
2955                         ev->phys_disk_num_valid = 1;
2956                         ev->phys_disk_num = raid_event_data->PhysDiskNum;
2957                         ev->event_type = MPTSAS_DEL_DEVICE;
2958                         break;
2959                 default:
2960                         break;
2961                 }
2962                 break;
2963         case MPI_EVENT_RAID_RC_VOLUME_DELETED:
2964                 ev->event_type = MPTSAS_DEL_RAID;
2965                 break;
2966         case MPI_EVENT_RAID_RC_VOLUME_CREATED:
2967                 ev->event_type = MPTSAS_ADD_RAID;
2968                 break;
2969         case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
2970                 switch (state) {
2971                 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
2972                 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
2973                         ev->event_type = MPTSAS_DEL_RAID;
2974                         break;
2975                 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
2976                 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
2977                         ev->event_type = MPTSAS_ADD_RAID;
2978                         break;
2979                 default:
2980                         break;
2981                 }
2982                 break;
2983         default:
2984                 break;
2985         }
2986         schedule_work(&ev->work);
2987 }
2988
2989 static void
2990 mptsas_send_discovery_event(MPT_ADAPTER *ioc,
2991         EVENT_DATA_SAS_DISCOVERY *discovery_data)
2992 {
2993         struct mptsas_discovery_event *ev;
2994
2995         /*
2996          * DiscoveryStatus
2997          *
2998          * This flag will be non-zero when firmware
2999          * kicks off discovery, and return to zero
3000          * once its completed.
3001          */
3002         if (discovery_data->DiscoveryStatus)
3003                 return;
3004
3005         ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
3006         if (!ev)
3007                 return;
3008         INIT_WORK(&ev->work, mptsas_discovery_work);
3009         ev->ioc = ioc;
3010         schedule_work(&ev->work);
3011 };
3012
3013 /*
3014  * mptsas_send_ir2_event - handle exposing hidden disk when
3015  * an inactive raid volume is added
3016  *
3017  * @ioc: Pointer to MPT_ADAPTER structure
3018  * @ir2_data
3019  *
3020  */
3021 static void
3022 mptsas_send_ir2_event(MPT_ADAPTER *ioc, PTR_MPI_EVENT_DATA_IR2 ir2_data)
3023 {
3024         struct mptsas_hotplug_event *ev;
3025
3026         if (ir2_data->ReasonCode !=
3027             MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED)
3028                 return;
3029
3030         ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
3031         if (!ev)
3032                 return;
3033
3034         INIT_WORK(&ev->work, mptsas_hotplug_work);
3035         ev->ioc = ioc;
3036         ev->id = ir2_data->TargetID;
3037         ev->channel = ir2_data->Bus;
3038         ev->event_type = MPTSAS_ADD_INACTIVE_VOLUME;
3039
3040         schedule_work(&ev->work);
3041 };
3042
3043 static int
3044 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
3045 {
3046         int rc=1;
3047         u8 event = le32_to_cpu(reply->Event) & 0xFF;
3048
3049         if (!ioc->sh)
3050                 goto out;
3051
3052         /*
3053          * sas_discovery_ignore_events
3054          *
3055          * This flag is to prevent anymore processing of
3056          * sas events once mptsas_remove function is called.
3057          */
3058         if (ioc->sas_discovery_ignore_events) {
3059                 rc = mptscsih_event_process(ioc, reply);
3060                 goto out;
3061         }
3062
3063         switch (event) {
3064         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
3065                 mptsas_send_sas_event(ioc,
3066                         (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
3067                 break;
3068         case MPI_EVENT_INTEGRATED_RAID:
3069                 mptsas_send_raid_event(ioc,
3070                         (EVENT_DATA_RAID *)reply->Data);
3071                 break;
3072         case MPI_EVENT_PERSISTENT_TABLE_FULL:
3073                 INIT_WORK(&ioc->sas_persist_task,
3074                     mptsas_persist_clear_table);
3075                 schedule_work(&ioc->sas_persist_task);
3076                 break;
3077          case MPI_EVENT_SAS_DISCOVERY:
3078                 mptsas_send_discovery_event(ioc,
3079                         (EVENT_DATA_SAS_DISCOVERY *)reply->Data);
3080                 break;
3081         case MPI_EVENT_IR2:
3082                 mptsas_send_ir2_event(ioc,
3083                     (PTR_MPI_EVENT_DATA_IR2)reply->Data);
3084                 break;
3085         default:
3086                 rc = mptscsih_event_process(ioc, reply);
3087                 break;
3088         }
3089  out:
3090
3091         return rc;
3092 }
3093
3094 static int
3095 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3096 {
3097         struct Scsi_Host        *sh;
3098         MPT_SCSI_HOST           *hd;
3099         MPT_ADAPTER             *ioc;
3100         unsigned long            flags;
3101         int                      ii;
3102         int                      numSGE = 0;
3103         int                      scale;
3104         int                      ioc_cap;
3105         int                     error=0;
3106         int                     r;
3107
3108         r = mpt_attach(pdev,id);
3109         if (r)
3110                 return r;
3111
3112         ioc = pci_get_drvdata(pdev);
3113         ioc->DoneCtx = mptsasDoneCtx;
3114         ioc->TaskCtx = mptsasTaskCtx;
3115         ioc->InternalCtx = mptsasInternalCtx;
3116
3117         /*  Added sanity check on readiness of the MPT adapter.
3118          */
3119         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
3120                 printk(MYIOC_s_WARN_FMT
3121                   "Skipping because it's not operational!\n",
3122                   ioc->name);
3123                 error = -ENODEV;
3124                 goto out_mptsas_probe;
3125         }
3126
3127         if (!ioc->active) {
3128                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
3129                   ioc->name);
3130                 error = -ENODEV;
3131                 goto out_mptsas_probe;
3132         }
3133
3134         /*  Sanity check - ensure at least 1 port is INITIATOR capable
3135          */
3136         ioc_cap = 0;
3137         for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
3138                 if (ioc->pfacts[ii].ProtocolFlags &
3139                                 MPI_PORTFACTS_PROTOCOL_INITIATOR)
3140                         ioc_cap++;
3141         }
3142
3143         if (!ioc_cap) {
3144                 printk(MYIOC_s_WARN_FMT
3145                         "Skipping ioc=%p because SCSI Initiator mode "
3146                         "is NOT enabled!\n", ioc->name, ioc);
3147                 return 0;
3148         }
3149
3150         sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
3151         if (!sh) {
3152                 printk(MYIOC_s_WARN_FMT
3153                         "Unable to register controller with SCSI subsystem\n",
3154                         ioc->name);
3155                 error = -1;
3156                 goto out_mptsas_probe;
3157         }
3158
3159         spin_lock_irqsave(&ioc->FreeQlock, flags);
3160
3161         /* Attach the SCSI Host to the IOC structure
3162          */
3163         ioc->sh = sh;
3164
3165         sh->io_port = 0;
3166         sh->n_io_port = 0;
3167         sh->irq = 0;
3168
3169         /* set 16 byte cdb's */
3170         sh->max_cmd_len = 16;
3171
3172         sh->max_id = ioc->pfacts[0].PortSCSIID;
3173         sh->max_lun = max_lun;
3174
3175         sh->transportt = mptsas_transport_template;
3176
3177         sh->this_id = ioc->pfacts[0].PortSCSIID;
3178
3179         /* Required entry.
3180          */
3181         sh->unique_id = ioc->id;
3182
3183         INIT_LIST_HEAD(&ioc->sas_topology);
3184         mutex_init(&ioc->sas_topology_mutex);
3185         mutex_init(&ioc->sas_discovery_mutex);
3186         mutex_init(&ioc->sas_mgmt.mutex);
3187         init_completion(&ioc->sas_mgmt.done);
3188
3189         /* Verify that we won't exceed the maximum
3190          * number of chain buffers
3191          * We can optimize:  ZZ = req_sz/sizeof(SGE)
3192          * For 32bit SGE's:
3193          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
3194          *               + (req_sz - 64)/sizeof(SGE)
3195          * A slightly different algorithm is required for
3196          * 64bit SGEs.
3197          */
3198         scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3199         if (sizeof(dma_addr_t) == sizeof(u64)) {
3200                 numSGE = (scale - 1) *
3201                   (ioc->facts.MaxChainDepth-1) + scale +
3202                   (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
3203                   sizeof(u32));
3204         } else {
3205                 numSGE = 1 + (scale - 1) *
3206                   (ioc->facts.MaxChainDepth-1) + scale +
3207                   (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
3208                   sizeof(u32));
3209         }
3210
3211         if (numSGE < sh->sg_tablesize) {
3212                 /* Reset this value */
3213                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3214                   "Resetting sg_tablesize to %d from %d\n",
3215                   ioc->name, numSGE, sh->sg_tablesize));
3216                 sh->sg_tablesize = numSGE;
3217         }
3218
3219         hd = (MPT_SCSI_HOST *) sh->hostdata;
3220         hd->ioc = ioc;
3221
3222         /* SCSI needs scsi_cmnd lookup table!
3223          * (with size equal to req_depth*PtrSz!)
3224          */
3225         hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
3226         if (!hd->ScsiLookup) {
3227                 error = -ENOMEM;
3228                 goto out_mptsas_probe;
3229         }
3230
3231         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
3232                  ioc->name, hd->ScsiLookup));
3233
3234         /* Clear the TM flags
3235          */
3236         hd->tmPending = 0;
3237         hd->tmState = TM_STATE_NONE;
3238         hd->resetPending = 0;
3239         hd->abortSCpnt = NULL;
3240
3241         /* Clear the pointer used to store
3242          * single-threaded commands, i.e., those
3243          * issued during a bus scan, dv and
3244          * configuration pages.
3245          */
3246         hd->cmdPtr = NULL;
3247
3248         /* Initialize this SCSI Hosts' timers
3249          * To use, set the timer expires field
3250          * and add_timer
3251          */
3252         init_timer(&hd->timer);
3253         hd->timer.data = (unsigned long) hd;
3254         hd->timer.function = mptscsih_timer_expired;
3255
3256         ioc->sas_data.ptClear = mpt_pt_clear;
3257
3258         init_waitqueue_head(&hd->scandv_waitq);
3259         hd->scandv_wait_done = 0;
3260         hd->last_queue_full = 0;
3261         INIT_LIST_HEAD(&hd->target_reset_list);
3262         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3263
3264         if (ioc->sas_data.ptClear==1) {
3265                 mptbase_sas_persist_operation(
3266                     ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
3267         }
3268
3269         error = scsi_add_host(sh, &ioc->pcidev->dev);
3270         if (error) {
3271                 dprintk(ioc, printk(MYIOC_s_ERR_FMT
3272                   "scsi_add_host failed\n", ioc->name));
3273                 goto out_mptsas_probe;
3274         }
3275
3276         mptsas_scan_sas_topology(ioc);
3277
3278         return 0;
3279
3280  out_mptsas_probe:
3281
3282         mptscsih_remove(pdev);
3283         return error;
3284 }
3285
3286 static void __devexit mptsas_remove(struct pci_dev *pdev)
3287 {
3288         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
3289         struct mptsas_portinfo *p, *n;
3290         int i;
3291
3292         ioc->sas_discovery_ignore_events = 1;
3293         sas_remove_host(ioc->sh);
3294
3295         mutex_lock(&ioc->sas_topology_mutex);
3296         list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
3297                 list_del(&p->list);
3298                 for (i = 0 ; i < p->num_phys ; i++)
3299                         mptsas_port_delete(ioc, p->phy_info[i].port_details);
3300                 kfree(p->phy_info);
3301                 kfree(p);
3302         }
3303         mutex_unlock(&ioc->sas_topology_mutex);
3304
3305         mptscsih_remove(pdev);
3306 }
3307
3308 static struct pci_device_id mptsas_pci_table[] = {
3309         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
3310                 PCI_ANY_ID, PCI_ANY_ID },
3311         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
3312                 PCI_ANY_ID, PCI_ANY_ID },
3313         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
3314                 PCI_ANY_ID, PCI_ANY_ID },
3315         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
3316                 PCI_ANY_ID, PCI_ANY_ID },
3317         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
3318                 PCI_ANY_ID, PCI_ANY_ID },
3319         {0}     /* Terminating entry */
3320 };
3321 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
3322
3323
3324 static struct pci_driver mptsas_driver = {
3325         .name           = "mptsas",
3326         .id_table       = mptsas_pci_table,
3327         .probe          = mptsas_probe,
3328         .remove         = __devexit_p(mptsas_remove),
3329         .shutdown       = mptscsih_shutdown,
3330 #ifdef CONFIG_PM
3331         .suspend        = mptscsih_suspend,
3332         .resume         = mptscsih_resume,
3333 #endif
3334 };
3335
3336 static int __init
3337 mptsas_init(void)
3338 {
3339         int error;
3340
3341         show_mptmod_ver(my_NAME, my_VERSION);
3342
3343         mptsas_transport_template =
3344             sas_attach_transport(&mptsas_transport_functions);
3345         if (!mptsas_transport_template)
3346                 return -ENODEV;
3347
3348         mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
3349         mptsasTaskCtx = mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
3350         mptsasInternalCtx =
3351                 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
3352         mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
3353
3354         mpt_event_register(mptsasDoneCtx, mptsas_event_process);
3355         mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
3356
3357         error = pci_register_driver(&mptsas_driver);
3358         if (error)
3359                 sas_release_transport(mptsas_transport_template);
3360
3361         return error;
3362 }
3363
3364 static void __exit
3365 mptsas_exit(void)
3366 {
3367         pci_unregister_driver(&mptsas_driver);
3368         sas_release_transport(mptsas_transport_template);
3369
3370         mpt_reset_deregister(mptsasDoneCtx);
3371         mpt_event_deregister(mptsasDoneCtx);
3372
3373         mpt_deregister(mptsasMgmtCtx);
3374         mpt_deregister(mptsasInternalCtx);
3375         mpt_deregister(mptsasTaskCtx);
3376         mpt_deregister(mptsasDoneCtx);
3377 }
3378
3379 module_init(mptsas_init);
3380 module_exit(mptsas_exit);