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