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