Merge master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
[pandora-kernel.git] / drivers / message / fusion / mptsas.c
1 /*
2  *  linux/drivers/message/fusion/mptsas.c
3  *      For use with LSI Logic PCI chip/adapter(s)
4  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5  *
6  *  Copyright (c) 1999-2005 LSI Logic Corporation
7  *  (mailto:mpt_linux_developer@lsil.com)
8  *  Copyright (c) 2005-2006 Dell
9  */
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11 /*
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; version 2 of the License.
15
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20
21     NO WARRANTY
22     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26     solely responsible for determining the appropriateness of using and
27     distributing the Program and assumes all risks associated with its
28     exercise of rights under this Agreement, including but not limited to
29     the risks and costs of program errors, damage to or loss of data,
30     programs or equipment, and unavailability or interruption of operations.
31
32     DISCLAIMER OF LIABILITY
33     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40
41     You should have received a copy of the GNU General Public License
42     along with this program; if not, write to the Free Software
43     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
44 */
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46
47 #include <linux/module.h>
48 #include <linux/kernel.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/sched.h>
52 #include <linux/workqueue.h>
53
54 #include <scsi/scsi_cmnd.h>
55 #include <scsi/scsi_device.h>
56 #include <scsi/scsi_host.h>
57 #include <scsi/scsi_transport_sas.h>
58
59 #include "mptbase.h"
60 #include "mptscsih.h"
61
62
63 #define my_NAME         "Fusion MPT SAS Host driver"
64 #define my_VERSION      MPT_LINUX_VERSION_COMMON
65 #define MYNAM           "mptsas"
66
67 MODULE_AUTHOR(MODULEAUTHOR);
68 MODULE_DESCRIPTION(my_NAME);
69 MODULE_LICENSE("GPL");
70
71 static int mpt_pq_filter;
72 module_param(mpt_pq_filter, int, 0);
73 MODULE_PARM_DESC(mpt_pq_filter,
74                 "Enable peripheral qualifier filter: enable=1  "
75                 "(default=0)");
76
77 static int mpt_pt_clear;
78 module_param(mpt_pt_clear, int, 0);
79 MODULE_PARM_DESC(mpt_pt_clear,
80                 "Clear persistency table: enable=1  "
81                 "(default=MPTSCSIH_PT_CLEAR=0)");
82
83 static int      mptsasDoneCtx = -1;
84 static int      mptsasTaskCtx = -1;
85 static int      mptsasInternalCtx = -1; /* Used only for internal commands */
86 static int      mptsasMgmtCtx = -1;
87
88
89 enum mptsas_hotplug_action {
90         MPTSAS_ADD_DEVICE,
91         MPTSAS_DEL_DEVICE,
92         MPTSAS_ADD_RAID,
93         MPTSAS_DEL_RAID,
94         MPTSAS_IGNORE_EVENT,
95 };
96
97 struct mptsas_hotplug_event {
98         struct work_struct      work;
99         MPT_ADAPTER             *ioc;
100         enum mptsas_hotplug_action event_type;
101         u64                     sas_address;
102         u32                     channel;
103         u32                     id;
104         u32                     device_info;
105         u16                     handle;
106         u16                     parent_handle;
107         u8                      phy_id;
108         u8                      phys_disk_num;
109         u8                      phys_disk_num_valid;
110 };
111
112 struct mptsas_discovery_event {
113         struct work_struct      work;
114         MPT_ADAPTER             *ioc;
115 };
116
117 /*
118  * SAS topology structures
119  *
120  * The MPT Fusion firmware interface spreads information about the
121  * SAS topology over many manufacture pages, thus we need some data
122  * structure to collect it and process it for the SAS transport class.
123  */
124
125 struct mptsas_devinfo {
126         u16     handle;         /* unique id to address this device */
127         u16     handle_parent;  /* unique id to address parent device */
128         u16     handle_enclosure; /* enclosure identifier of the enclosure */
129         u16     slot;           /* physical slot in enclosure */
130         u8      phy_id;         /* phy number of parent device */
131         u8      port_id;        /* sas physical port this device
132                                    is assoc'd with */
133         u8      id;             /* logical target id of this device */
134         u8      channel;        /* logical bus number of this device */
135         u64     sas_address;    /* WWN of this device,
136                                    SATA is assigned by HBA,expander */
137         u32     device_info;    /* bitfield detailed info about this device */
138 };
139
140 struct mptsas_phyinfo {
141         u8      phy_id;                 /* phy index */
142         u8      port_id;                /* port number this phy is part of */
143         u8      negotiated_link_rate;   /* nego'd link rate for this phy */
144         u8      hw_link_rate;           /* hardware max/min phys link rate */
145         u8      programmed_link_rate;   /* programmed max/min phy link rate */
146         struct mptsas_devinfo identify; /* point to phy device info */
147         struct mptsas_devinfo attached; /* point to attached device info */
148         struct sas_phy *phy;
149         struct sas_rphy *rphy;
150         struct scsi_target *starget;
151 };
152
153 struct mptsas_portinfo {
154         struct list_head list;
155         u16             handle;         /* unique id to address this */
156         u8              num_phys;       /* number of phys */
157         struct mptsas_phyinfo *phy_info;
158 };
159
160 struct mptsas_enclosure {
161         u64     enclosure_logical_id;   /* The WWN for the enclosure */
162         u16     enclosure_handle;       /* unique id to address this */
163         u16     flags;                  /* details enclosure management */
164         u16     num_slot;               /* num slots */
165         u16     start_slot;             /* first slot */
166         u8      start_id;               /* starting logical target id */
167         u8      start_channel;          /* starting logical channel id */
168         u8      sep_id;                 /* SEP device logical target id */
169         u8      sep_channel;            /* SEP channel logical channel id */
170 };
171
172 #ifdef SASDEBUG
173 static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
174 {
175         printk("---- IO UNIT PAGE 0 ------------\n");
176         printk("Handle=0x%X\n",
177                 le16_to_cpu(phy_data->AttachedDeviceHandle));
178         printk("Controller Handle=0x%X\n",
179                 le16_to_cpu(phy_data->ControllerDevHandle));
180         printk("Port=0x%X\n", phy_data->Port);
181         printk("Port Flags=0x%X\n", phy_data->PortFlags);
182         printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
183         printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
184         printk("Controller PHY Device Info=0x%X\n",
185                 le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
186         printk("DiscoveryStatus=0x%X\n",
187                 le32_to_cpu(phy_data->DiscoveryStatus));
188         printk("\n");
189 }
190
191 static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
192 {
193         __le64 sas_address;
194
195         memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
196
197         printk("---- SAS PHY PAGE 0 ------------\n");
198         printk("Attached Device Handle=0x%X\n",
199                         le16_to_cpu(pg0->AttachedDevHandle));
200         printk("SAS Address=0x%llX\n",
201                         (unsigned long long)le64_to_cpu(sas_address));
202         printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
203         printk("Attached Device Info=0x%X\n",
204                         le32_to_cpu(pg0->AttachedDeviceInfo));
205         printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
206         printk("Change Count=0x%X\n", pg0->ChangeCount);
207         printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
208         printk("\n");
209 }
210
211 static void mptsas_print_phy_pg1(SasPhyPage1_t *pg1)
212 {
213         printk("---- SAS PHY PAGE 1 ------------\n");
214         printk("Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount);
215         printk("Running Disparity Error Count=0x%x\n",
216                         pg1->RunningDisparityErrorCount);
217         printk("Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount);
218         printk("PHY Reset Problem Count=0x%x\n", pg1->PhyResetProblemCount);
219         printk("\n");
220 }
221
222 static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
223 {
224         __le64 sas_address;
225
226         memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
227
228         printk("---- SAS DEVICE PAGE 0 ---------\n");
229         printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
230         printk("Parent Handle=0x%X\n" ,le16_to_cpu(pg0->ParentDevHandle));
231         printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
232         printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
233         printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
234         printk("Target ID=0x%X\n", pg0->TargetID);
235         printk("Bus=0x%X\n", pg0->Bus);
236         /* The PhyNum field specifies the PHY number of the parent
237          * device this device is linked to
238          */
239         printk("Parent Phy Num=0x%X\n", pg0->PhyNum);
240         printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus));
241         printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
242         printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
243         printk("Physical Port=0x%X\n", pg0->PhysicalPort);
244         printk("\n");
245 }
246
247 static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
248 {
249         printk("---- SAS EXPANDER PAGE 1 ------------\n");
250
251         printk("Physical Port=0x%X\n", pg1->PhysicalPort);
252         printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier);
253         printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
254         printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
255         printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
256         printk("Owner Device Handle=0x%X\n",
257                         le16_to_cpu(pg1->OwnerDevHandle));
258         printk("Attached Device Handle=0x%X\n",
259                         le16_to_cpu(pg1->AttachedDevHandle));
260 }
261 #else
262 #define mptsas_print_phy_data(phy_data)         do { } while (0)
263 #define mptsas_print_phy_pg0(pg0)               do { } while (0)
264 #define mptsas_print_phy_pg1(pg1)               do { } while (0)
265 #define mptsas_print_device_pg0(pg0)            do { } while (0)
266 #define mptsas_print_expander_pg1(pg1)          do { } while (0)
267 #endif
268
269 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
270 {
271         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
272         return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
273 }
274
275 static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
276 {
277         struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
278         return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
279 }
280
281 /*
282  * mptsas_find_portinfo_by_handle
283  *
284  * This function should be called with the sas_topology_mutex already held
285  */
286 static struct mptsas_portinfo *
287 mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
288 {
289         struct mptsas_portinfo *port_info, *rc=NULL;
290         int i;
291
292         list_for_each_entry(port_info, &ioc->sas_topology, list)
293                 for (i = 0; i < port_info->num_phys; i++)
294                         if (port_info->phy_info[i].identify.handle == handle) {
295                                 rc = port_info;
296                                 goto out;
297                         }
298  out:
299         return rc;
300 }
301
302 /*
303  * Returns true if there is a scsi end device
304  */
305 static inline int
306 mptsas_is_end_device(struct mptsas_devinfo * attached)
307 {
308         if ((attached->handle) &&
309             (attached->device_info &
310             MPI_SAS_DEVICE_INFO_END_DEVICE) &&
311             ((attached->device_info &
312             MPI_SAS_DEVICE_INFO_SSP_TARGET) |
313             (attached->device_info &
314             MPI_SAS_DEVICE_INFO_STP_TARGET) |
315             (attached->device_info &
316             MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
317                 return 1;
318         else
319                 return 0;
320 }
321
322 static int
323 mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
324                 u32 form, u32 form_specific)
325 {
326         ConfigExtendedPageHeader_t hdr;
327         CONFIGPARMS cfg;
328         SasEnclosurePage0_t *buffer;
329         dma_addr_t dma_handle;
330         int error;
331         __le64 le_identifier;
332
333         memset(&hdr, 0, sizeof(hdr));
334         hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
335         hdr.PageNumber = 0;
336         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
337         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
338
339         cfg.cfghdr.ehdr = &hdr;
340         cfg.physAddr = -1;
341         cfg.pageAddr = form + form_specific;
342         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
343         cfg.dir = 0;    /* read */
344         cfg.timeout = 10;
345
346         error = mpt_config(ioc, &cfg);
347         if (error)
348                 goto out;
349         if (!hdr.ExtPageLength) {
350                 error = -ENXIO;
351                 goto out;
352         }
353
354         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
355                         &dma_handle);
356         if (!buffer) {
357                 error = -ENOMEM;
358                 goto out;
359         }
360
361         cfg.physAddr = dma_handle;
362         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
363
364         error = mpt_config(ioc, &cfg);
365         if (error)
366                 goto out_free_consistent;
367
368         /* save config data */
369         memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
370         enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
371         enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
372         enclosure->flags = le16_to_cpu(buffer->Flags);
373         enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
374         enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
375         enclosure->start_id = buffer->StartTargetID;
376         enclosure->start_channel = buffer->StartBus;
377         enclosure->sep_id = buffer->SEPTargetID;
378         enclosure->sep_channel = buffer->SEPBus;
379
380  out_free_consistent:
381         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
382                             buffer, dma_handle);
383  out:
384         return error;
385 }
386
387 static int
388 mptsas_slave_configure(struct scsi_device *sdev)
389 {
390         struct Scsi_Host        *host = sdev->host;
391         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
392
393         /*
394          * RAID volumes placed beyond the last expected port.
395          * Ignore sending sas mode pages in that case..
396          */
397         if (sdev->channel < hd->ioc->num_ports)
398                 sas_read_port_mode_page(sdev);
399
400         return mptscsih_slave_configure(sdev);
401 }
402
403 /*
404  * This is pretty ugly.  We will be able to seriously clean it up
405  * once the DV code in mptscsih goes away and we can properly
406  * implement ->target_alloc.
407  */
408 static int
409 mptsas_slave_alloc(struct scsi_device *sdev)
410 {
411         struct Scsi_Host        *host = sdev->host;
412         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
413         struct sas_rphy         *rphy;
414         struct mptsas_portinfo  *p;
415         VirtTarget              *vtarget;
416         VirtDevice              *vdev;
417         struct scsi_target      *starget;
418         u32                     target_id;
419         int i;
420
421         vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
422         if (!vdev) {
423                 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
424                                 hd->ioc->name, sizeof(VirtDevice));
425                 return -ENOMEM;
426         }
427         sdev->hostdata = vdev;
428         starget = scsi_target(sdev);
429         vtarget = starget->hostdata;
430         vtarget->ioc_id = hd->ioc->id;
431         vdev->vtarget = vtarget;
432         if (vtarget->num_luns == 0) {
433                 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
434                 hd->Targets[sdev->id] = vtarget;
435         }
436
437         /*
438           RAID volumes placed beyond the last expected port.
439         */
440         if (sdev->channel == hd->ioc->num_ports) {
441                 target_id = sdev->id;
442                 vtarget->bus_id = 0;
443                 vdev->lun = 0;
444                 goto out;
445         }
446
447         rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
448         mutex_lock(&hd->ioc->sas_topology_mutex);
449         list_for_each_entry(p, &hd->ioc->sas_topology, list) {
450                 for (i = 0; i < p->num_phys; i++) {
451                         if (p->phy_info[i].attached.sas_address ==
452                                         rphy->identify.sas_address) {
453                                 target_id = p->phy_info[i].attached.id;
454                                 vtarget->bus_id = p->phy_info[i].attached.channel;
455                                 vdev->lun = sdev->lun;
456                                 p->phy_info[i].starget = sdev->sdev_target;
457                                 /*
458                                  * Exposing hidden disk (RAID)
459                                  */
460                                 if (mptscsih_is_phys_disk(hd->ioc, target_id)) {
461                                         target_id = mptscsih_raid_id_to_num(hd,
462                                                         target_id);
463                                         vdev->vtarget->tflags |=
464                                             MPT_TARGET_FLAGS_RAID_COMPONENT;
465                                         sdev->no_uld_attach = 1;
466                                 }
467                                 mutex_unlock(&hd->ioc->sas_topology_mutex);
468                                 goto out;
469                         }
470                 }
471         }
472         mutex_unlock(&hd->ioc->sas_topology_mutex);
473
474         kfree(vdev);
475         return -ENXIO;
476
477  out:
478         vtarget->target_id = target_id;
479         vtarget->num_luns++;
480         return 0;
481 }
482
483 static void
484 mptsas_slave_destroy(struct scsi_device *sdev)
485 {
486         struct Scsi_Host *host = sdev->host;
487         MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
488         VirtDevice *vdev;
489
490         /*
491          * Issue target reset to flush firmware outstanding commands.
492          */
493         vdev = sdev->hostdata;
494         if (vdev->configured_lun){
495                 if (mptscsih_TMHandler(hd,
496                      MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
497                      vdev->vtarget->bus_id,
498                      vdev->vtarget->target_id,
499                      0, 0, 5 /* 5 second timeout */)
500                      < 0){
501
502                         /* The TM request failed!
503                          * Fatal error case.
504                          */
505                         printk(MYIOC_s_WARN_FMT
506                        "Error processing TaskMgmt id=%d TARGET_RESET\n",
507                                 hd->ioc->name,
508                                 vdev->vtarget->target_id);
509
510                         hd->tmPending = 0;
511                         hd->tmState = TM_STATE_NONE;
512                 }
513         }
514         mptscsih_slave_destroy(sdev);
515 }
516
517 static struct scsi_host_template mptsas_driver_template = {
518         .module                         = THIS_MODULE,
519         .proc_name                      = "mptsas",
520         .proc_info                      = mptscsih_proc_info,
521         .name                           = "MPT SPI Host",
522         .info                           = mptscsih_info,
523         .queuecommand                   = mptscsih_qcmd,
524         .target_alloc                   = mptscsih_target_alloc,
525         .slave_alloc                    = mptsas_slave_alloc,
526         .slave_configure                = mptsas_slave_configure,
527         .target_destroy                 = mptscsih_target_destroy,
528         .slave_destroy                  = mptsas_slave_destroy,
529         .change_queue_depth             = mptscsih_change_queue_depth,
530         .eh_abort_handler               = mptscsih_abort,
531         .eh_device_reset_handler        = mptscsih_dev_reset,
532         .eh_bus_reset_handler           = mptscsih_bus_reset,
533         .eh_host_reset_handler          = mptscsih_host_reset,
534         .bios_param                     = mptscsih_bios_param,
535         .can_queue                      = MPT_FC_CAN_QUEUE,
536         .this_id                        = -1,
537         .sg_tablesize                   = MPT_SCSI_SG_DEPTH,
538         .max_sectors                    = 8192,
539         .cmd_per_lun                    = 7,
540         .use_clustering                 = ENABLE_CLUSTERING,
541 };
542
543 static int mptsas_get_linkerrors(struct sas_phy *phy)
544 {
545         MPT_ADAPTER *ioc = phy_to_ioc(phy);
546         ConfigExtendedPageHeader_t hdr;
547         CONFIGPARMS cfg;
548         SasPhyPage1_t *buffer;
549         dma_addr_t dma_handle;
550         int error;
551
552         hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
553         hdr.ExtPageLength = 0;
554         hdr.PageNumber = 1 /* page number 1*/;
555         hdr.Reserved1 = 0;
556         hdr.Reserved2 = 0;
557         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
558         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
559
560         cfg.cfghdr.ehdr = &hdr;
561         cfg.physAddr = -1;
562         cfg.pageAddr = phy->identify.phy_identifier;
563         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
564         cfg.dir = 0;    /* read */
565         cfg.timeout = 10;
566
567         error = mpt_config(ioc, &cfg);
568         if (error)
569                 return error;
570         if (!hdr.ExtPageLength)
571                 return -ENXIO;
572
573         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
574                                       &dma_handle);
575         if (!buffer)
576                 return -ENOMEM;
577
578         cfg.physAddr = dma_handle;
579         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
580
581         error = mpt_config(ioc, &cfg);
582         if (error)
583                 goto out_free_consistent;
584
585         mptsas_print_phy_pg1(buffer);
586
587         phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
588         phy->running_disparity_error_count =
589                 le32_to_cpu(buffer->RunningDisparityErrorCount);
590         phy->loss_of_dword_sync_count =
591                 le32_to_cpu(buffer->LossDwordSynchCount);
592         phy->phy_reset_problem_count =
593                 le32_to_cpu(buffer->PhyResetProblemCount);
594
595  out_free_consistent:
596         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
597                             buffer, dma_handle);
598         return error;
599 }
600
601 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
602                 MPT_FRAME_HDR *reply)
603 {
604         ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
605         if (reply != NULL) {
606                 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
607                 memcpy(ioc->sas_mgmt.reply, reply,
608                     min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
609         }
610         complete(&ioc->sas_mgmt.done);
611         return 1;
612 }
613
614 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
615 {
616         MPT_ADAPTER *ioc = phy_to_ioc(phy);
617         SasIoUnitControlRequest_t *req;
618         SasIoUnitControlReply_t *reply;
619         MPT_FRAME_HDR *mf;
620         MPIHeader_t *hdr;
621         unsigned long timeleft;
622         int error = -ERESTARTSYS;
623
624         /* not implemented for expanders */
625         if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
626                 return -ENXIO;
627
628         if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
629                 goto out;
630
631         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
632         if (!mf) {
633                 error = -ENOMEM;
634                 goto out_unlock;
635         }
636
637         hdr = (MPIHeader_t *) mf;
638         req = (SasIoUnitControlRequest_t *)mf;
639         memset(req, 0, sizeof(SasIoUnitControlRequest_t));
640         req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
641         req->MsgContext = hdr->MsgContext;
642         req->Operation = hard_reset ?
643                 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
644         req->PhyNum = phy->identify.phy_identifier;
645
646         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
647
648         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
649                         10 * HZ);
650         if (!timeleft) {
651                 /* On timeout reset the board */
652                 mpt_free_msg_frame(ioc, mf);
653                 mpt_HardResetHandler(ioc, CAN_SLEEP);
654                 error = -ETIMEDOUT;
655                 goto out_unlock;
656         }
657
658         /* a reply frame is expected */
659         if ((ioc->sas_mgmt.status &
660             MPT_IOCTL_STATUS_RF_VALID) == 0) {
661                 error = -ENXIO;
662                 goto out_unlock;
663         }
664
665         /* process the completed Reply Message Frame */
666         reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
667         if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
668                 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
669                     __FUNCTION__,
670                     reply->IOCStatus,
671                     reply->IOCLogInfo);
672                 error = -ENXIO;
673                 goto out_unlock;
674         }
675
676         error = 0;
677
678  out_unlock:
679         mutex_unlock(&ioc->sas_mgmt.mutex);
680  out:
681         return error;
682 }
683
684 static int
685 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
686 {
687         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
688         int i, error;
689         struct mptsas_portinfo *p;
690         struct mptsas_enclosure enclosure_info;
691         u64 enclosure_handle;
692
693         mutex_lock(&ioc->sas_topology_mutex);
694         list_for_each_entry(p, &ioc->sas_topology, list) {
695                 for (i = 0; i < p->num_phys; i++) {
696                         if (p->phy_info[i].attached.sas_address ==
697                             rphy->identify.sas_address) {
698                                 enclosure_handle = p->phy_info[i].
699                                         attached.handle_enclosure;
700                                 goto found_info;
701                         }
702                 }
703         }
704         mutex_unlock(&ioc->sas_topology_mutex);
705         return -ENXIO;
706
707  found_info:
708         mutex_unlock(&ioc->sas_topology_mutex);
709         memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
710         error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
711                         (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
712                          MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
713         if (!error)
714                 *identifier = enclosure_info.enclosure_logical_id;
715         return error;
716 }
717
718 static int
719 mptsas_get_bay_identifier(struct sas_rphy *rphy)
720 {
721         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
722         struct mptsas_portinfo *p;
723         int i, rc;
724
725         mutex_lock(&ioc->sas_topology_mutex);
726         list_for_each_entry(p, &ioc->sas_topology, list) {
727                 for (i = 0; i < p->num_phys; i++) {
728                         if (p->phy_info[i].attached.sas_address ==
729                             rphy->identify.sas_address) {
730                                 rc = p->phy_info[i].attached.slot;
731                                 goto out;
732                         }
733                 }
734         }
735         rc = -ENXIO;
736  out:
737         mutex_unlock(&ioc->sas_topology_mutex);
738         return rc;
739 }
740
741 static struct sas_function_template mptsas_transport_functions = {
742         .get_linkerrors         = mptsas_get_linkerrors,
743         .get_enclosure_identifier = mptsas_get_enclosure_identifier,
744         .get_bay_identifier     = mptsas_get_bay_identifier,
745         .phy_reset              = mptsas_phy_reset,
746 };
747
748 static struct scsi_transport_template *mptsas_transport_template;
749
750 static int
751 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
752 {
753         ConfigExtendedPageHeader_t hdr;
754         CONFIGPARMS cfg;
755         SasIOUnitPage0_t *buffer;
756         dma_addr_t dma_handle;
757         int error, i;
758
759         hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
760         hdr.ExtPageLength = 0;
761         hdr.PageNumber = 0;
762         hdr.Reserved1 = 0;
763         hdr.Reserved2 = 0;
764         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
765         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
766
767         cfg.cfghdr.ehdr = &hdr;
768         cfg.physAddr = -1;
769         cfg.pageAddr = 0;
770         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
771         cfg.dir = 0;    /* read */
772         cfg.timeout = 10;
773
774         error = mpt_config(ioc, &cfg);
775         if (error)
776                 goto out;
777         if (!hdr.ExtPageLength) {
778                 error = -ENXIO;
779                 goto out;
780         }
781
782         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
783                                             &dma_handle);
784         if (!buffer) {
785                 error = -ENOMEM;
786                 goto out;
787         }
788
789         cfg.physAddr = dma_handle;
790         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
791
792         error = mpt_config(ioc, &cfg);
793         if (error)
794                 goto out_free_consistent;
795
796         port_info->num_phys = buffer->NumPhys;
797         port_info->phy_info = kcalloc(port_info->num_phys,
798                 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
799         if (!port_info->phy_info) {
800                 error = -ENOMEM;
801                 goto out_free_consistent;
802         }
803
804         if (port_info->num_phys)
805                 port_info->handle =
806                     le16_to_cpu(buffer->PhyData[0].ControllerDevHandle);
807         for (i = 0; i < port_info->num_phys; i++) {
808                 mptsas_print_phy_data(&buffer->PhyData[i]);
809                 port_info->phy_info[i].phy_id = i;
810                 port_info->phy_info[i].port_id =
811                     buffer->PhyData[i].Port;
812                 port_info->phy_info[i].negotiated_link_rate =
813                     buffer->PhyData[i].NegotiatedLinkRate;
814         }
815
816  out_free_consistent:
817         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
818                             buffer, dma_handle);
819  out:
820         return error;
821 }
822
823 static int
824 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
825                 u32 form, u32 form_specific)
826 {
827         ConfigExtendedPageHeader_t hdr;
828         CONFIGPARMS cfg;
829         SasPhyPage0_t *buffer;
830         dma_addr_t dma_handle;
831         int error;
832
833         hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
834         hdr.ExtPageLength = 0;
835         hdr.PageNumber = 0;
836         hdr.Reserved1 = 0;
837         hdr.Reserved2 = 0;
838         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
839         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
840
841         cfg.cfghdr.ehdr = &hdr;
842         cfg.dir = 0;    /* read */
843         cfg.timeout = 10;
844
845         /* Get Phy Pg 0 for each Phy. */
846         cfg.physAddr = -1;
847         cfg.pageAddr = form + form_specific;
848         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
849
850         error = mpt_config(ioc, &cfg);
851         if (error)
852                 goto out;
853
854         if (!hdr.ExtPageLength) {
855                 error = -ENXIO;
856                 goto out;
857         }
858
859         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
860                                       &dma_handle);
861         if (!buffer) {
862                 error = -ENOMEM;
863                 goto out;
864         }
865
866         cfg.physAddr = dma_handle;
867         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
868
869         error = mpt_config(ioc, &cfg);
870         if (error)
871                 goto out_free_consistent;
872
873         mptsas_print_phy_pg0(buffer);
874
875         phy_info->hw_link_rate = buffer->HwLinkRate;
876         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
877         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
878         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
879
880  out_free_consistent:
881         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
882                             buffer, dma_handle);
883  out:
884         return error;
885 }
886
887 static int
888 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
889                 u32 form, u32 form_specific)
890 {
891         ConfigExtendedPageHeader_t hdr;
892         CONFIGPARMS cfg;
893         SasDevicePage0_t *buffer;
894         dma_addr_t dma_handle;
895         __le64 sas_address;
896         int error=0;
897
898         if (ioc->sas_discovery_runtime &&
899                 mptsas_is_end_device(device_info))
900                         goto out;
901
902         hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
903         hdr.ExtPageLength = 0;
904         hdr.PageNumber = 0;
905         hdr.Reserved1 = 0;
906         hdr.Reserved2 = 0;
907         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
908         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
909
910         cfg.cfghdr.ehdr = &hdr;
911         cfg.pageAddr = form + form_specific;
912         cfg.physAddr = -1;
913         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
914         cfg.dir = 0;    /* read */
915         cfg.timeout = 10;
916
917         memset(device_info, 0, sizeof(struct mptsas_devinfo));
918         error = mpt_config(ioc, &cfg);
919         if (error)
920                 goto out;
921         if (!hdr.ExtPageLength) {
922                 error = -ENXIO;
923                 goto out;
924         }
925
926         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
927                                       &dma_handle);
928         if (!buffer) {
929                 error = -ENOMEM;
930                 goto out;
931         }
932
933         cfg.physAddr = dma_handle;
934         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
935
936         error = mpt_config(ioc, &cfg);
937         if (error)
938                 goto out_free_consistent;
939
940         mptsas_print_device_pg0(buffer);
941
942         device_info->handle = le16_to_cpu(buffer->DevHandle);
943         device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
944         device_info->handle_enclosure =
945             le16_to_cpu(buffer->EnclosureHandle);
946         device_info->slot = le16_to_cpu(buffer->Slot);
947         device_info->phy_id = buffer->PhyNum;
948         device_info->port_id = buffer->PhysicalPort;
949         device_info->id = buffer->TargetID;
950         device_info->channel = buffer->Bus;
951         memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
952         device_info->sas_address = le64_to_cpu(sas_address);
953         device_info->device_info =
954             le32_to_cpu(buffer->DeviceInfo);
955
956  out_free_consistent:
957         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
958                             buffer, dma_handle);
959  out:
960         return error;
961 }
962
963 static int
964 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
965                 u32 form, u32 form_specific)
966 {
967         ConfigExtendedPageHeader_t hdr;
968         CONFIGPARMS cfg;
969         SasExpanderPage0_t *buffer;
970         dma_addr_t dma_handle;
971         int error;
972
973         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
974         hdr.ExtPageLength = 0;
975         hdr.PageNumber = 0;
976         hdr.Reserved1 = 0;
977         hdr.Reserved2 = 0;
978         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
979         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
980
981         cfg.cfghdr.ehdr = &hdr;
982         cfg.physAddr = -1;
983         cfg.pageAddr = form + form_specific;
984         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
985         cfg.dir = 0;    /* read */
986         cfg.timeout = 10;
987
988         memset(port_info, 0, sizeof(struct mptsas_portinfo));
989         error = mpt_config(ioc, &cfg);
990         if (error)
991                 goto out;
992
993         if (!hdr.ExtPageLength) {
994                 error = -ENXIO;
995                 goto out;
996         }
997
998         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
999                                       &dma_handle);
1000         if (!buffer) {
1001                 error = -ENOMEM;
1002                 goto out;
1003         }
1004
1005         cfg.physAddr = dma_handle;
1006         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1007
1008         error = mpt_config(ioc, &cfg);
1009         if (error)
1010                 goto out_free_consistent;
1011
1012         /* save config data */
1013         port_info->num_phys = buffer->NumPhys;
1014         port_info->handle = le16_to_cpu(buffer->DevHandle);
1015         port_info->phy_info = kcalloc(port_info->num_phys,
1016                 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
1017         if (!port_info->phy_info) {
1018                 error = -ENOMEM;
1019                 goto out_free_consistent;
1020         }
1021
1022  out_free_consistent:
1023         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1024                             buffer, dma_handle);
1025  out:
1026         return error;
1027 }
1028
1029 static int
1030 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1031                 u32 form, u32 form_specific)
1032 {
1033         ConfigExtendedPageHeader_t hdr;
1034         CONFIGPARMS cfg;
1035         SasExpanderPage1_t *buffer;
1036         dma_addr_t dma_handle;
1037         int error=0;
1038
1039         if (ioc->sas_discovery_runtime &&
1040                 mptsas_is_end_device(&phy_info->attached))
1041                         goto out;
1042
1043         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1044         hdr.ExtPageLength = 0;
1045         hdr.PageNumber = 1;
1046         hdr.Reserved1 = 0;
1047         hdr.Reserved2 = 0;
1048         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1049         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1050
1051         cfg.cfghdr.ehdr = &hdr;
1052         cfg.physAddr = -1;
1053         cfg.pageAddr = form + form_specific;
1054         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1055         cfg.dir = 0;    /* read */
1056         cfg.timeout = 10;
1057
1058         error = mpt_config(ioc, &cfg);
1059         if (error)
1060                 goto out;
1061
1062         if (!hdr.ExtPageLength) {
1063                 error = -ENXIO;
1064                 goto out;
1065         }
1066
1067         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1068                                       &dma_handle);
1069         if (!buffer) {
1070                 error = -ENOMEM;
1071                 goto out;
1072         }
1073
1074         cfg.physAddr = dma_handle;
1075         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1076
1077         error = mpt_config(ioc, &cfg);
1078         if (error)
1079                 goto out_free_consistent;
1080
1081
1082         mptsas_print_expander_pg1(buffer);
1083
1084         /* save config data */
1085         phy_info->phy_id = buffer->PhyIdentifier;
1086         phy_info->port_id = buffer->PhysicalPort;
1087         phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
1088         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1089         phy_info->hw_link_rate = buffer->HwLinkRate;
1090         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1091         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1092
1093  out_free_consistent:
1094         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1095                             buffer, dma_handle);
1096  out:
1097         return error;
1098 }
1099
1100 static void
1101 mptsas_parse_device_info(struct sas_identify *identify,
1102                 struct mptsas_devinfo *device_info)
1103 {
1104         u16 protocols;
1105
1106         identify->sas_address = device_info->sas_address;
1107         identify->phy_identifier = device_info->phy_id;
1108
1109         /*
1110          * Fill in Phy Initiator Port Protocol.
1111          * Bits 6:3, more than one bit can be set, fall through cases.
1112          */
1113         protocols = device_info->device_info & 0x78;
1114         identify->initiator_port_protocols = 0;
1115         if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
1116                 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
1117         if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1118                 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
1119         if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
1120                 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
1121         if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
1122                 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
1123
1124         /*
1125          * Fill in Phy Target Port Protocol.
1126          * Bits 10:7, more than one bit can be set, fall through cases.
1127          */
1128         protocols = device_info->device_info & 0x780;
1129         identify->target_port_protocols = 0;
1130         if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1131                 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
1132         if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
1133                 identify->target_port_protocols |= SAS_PROTOCOL_STP;
1134         if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
1135                 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
1136         if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1137                 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
1138
1139         /*
1140          * Fill in Attached device type.
1141          */
1142         switch (device_info->device_info &
1143                         MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
1144         case MPI_SAS_DEVICE_INFO_NO_DEVICE:
1145                 identify->device_type = SAS_PHY_UNUSED;
1146                 break;
1147         case MPI_SAS_DEVICE_INFO_END_DEVICE:
1148                 identify->device_type = SAS_END_DEVICE;
1149                 break;
1150         case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
1151                 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
1152                 break;
1153         case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
1154                 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
1155                 break;
1156         }
1157 }
1158
1159 static int mptsas_probe_one_phy(struct device *dev,
1160                 struct mptsas_phyinfo *phy_info, int index, int local)
1161 {
1162         MPT_ADAPTER *ioc;
1163         struct sas_phy *phy;
1164         int error;
1165
1166         if (!dev)
1167                 return -ENODEV;
1168
1169         if (!phy_info->phy) {
1170                 phy = sas_phy_alloc(dev, index);
1171                 if (!phy)
1172                         return -ENOMEM;
1173         } else
1174                 phy = phy_info->phy;
1175
1176         phy->port_identifier = phy_info->port_id;
1177         mptsas_parse_device_info(&phy->identify, &phy_info->identify);
1178
1179         /*
1180          * Set Negotiated link rate.
1181          */
1182         switch (phy_info->negotiated_link_rate) {
1183         case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
1184                 phy->negotiated_linkrate = SAS_PHY_DISABLED;
1185                 break;
1186         case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
1187                 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
1188                 break;
1189         case MPI_SAS_IOUNIT0_RATE_1_5:
1190                 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
1191                 break;
1192         case MPI_SAS_IOUNIT0_RATE_3_0:
1193                 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
1194                 break;
1195         case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
1196         case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
1197         default:
1198                 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
1199                 break;
1200         }
1201
1202         /*
1203          * Set Max hardware link rate.
1204          */
1205         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1206         case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
1207                 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1208                 break;
1209         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1210                 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1211                 break;
1212         default:
1213                 break;
1214         }
1215
1216         /*
1217          * Set Max programmed link rate.
1218          */
1219         switch (phy_info->programmed_link_rate &
1220                         MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1221         case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
1222                 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1223                 break;
1224         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1225                 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1226                 break;
1227         default:
1228                 break;
1229         }
1230
1231         /*
1232          * Set Min hardware link rate.
1233          */
1234         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
1235         case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
1236                 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1237                 break;
1238         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1239                 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1240                 break;
1241         default:
1242                 break;
1243         }
1244
1245         /*
1246          * Set Min programmed link rate.
1247          */
1248         switch (phy_info->programmed_link_rate &
1249                         MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
1250         case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
1251                 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1252                 break;
1253         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1254                 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1255                 break;
1256         default:
1257                 break;
1258         }
1259
1260         if (!phy_info->phy) {
1261
1262                 if (local)
1263                         phy->local_attached = 1;
1264
1265                 error = sas_phy_add(phy);
1266                 if (error) {
1267                         sas_phy_free(phy);
1268                         return error;
1269                 }
1270                 phy_info->phy = phy;
1271         }
1272
1273         if ((phy_info->attached.handle) &&
1274             (!phy_info->rphy)) {
1275
1276                 struct sas_rphy *rphy;
1277                 struct sas_identify identify;
1278
1279                 ioc = phy_to_ioc(phy_info->phy);
1280
1281                 /*
1282                  * Let the hotplug_work thread handle processing
1283                  * the adding/removing of devices that occur
1284                  * after start of day.
1285                  */
1286                 if (ioc->sas_discovery_runtime &&
1287                         mptsas_is_end_device(&phy_info->attached))
1288                         return 0;
1289
1290                 mptsas_parse_device_info(&identify, &phy_info->attached);
1291                 switch (identify.device_type) {
1292                 case SAS_END_DEVICE:
1293                         rphy = sas_end_device_alloc(phy);
1294                         break;
1295                 case SAS_EDGE_EXPANDER_DEVICE:
1296                 case SAS_FANOUT_EXPANDER_DEVICE:
1297                         rphy = sas_expander_alloc(phy, identify.device_type);
1298                         break;
1299                 default:
1300                         rphy = NULL;
1301                         break;
1302                 }
1303                 if (!rphy)
1304                         return 0; /* non-fatal: an rphy can be added later */
1305
1306                 rphy->identify = identify;
1307
1308                 error = sas_rphy_add(rphy);
1309                 if (error) {
1310                         sas_rphy_free(rphy);
1311                         return error;
1312                 }
1313
1314                 phy_info->rphy = rphy;
1315         }
1316
1317         return 0;
1318 }
1319
1320 static int
1321 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
1322 {
1323         struct mptsas_portinfo *port_info, *hba;
1324         u32 handle = 0xFFFF;
1325         int error = -ENOMEM, i;
1326
1327         hba = kzalloc(sizeof(*port_info), GFP_KERNEL);
1328         if (! hba)
1329                 goto out;
1330
1331         error = mptsas_sas_io_unit_pg0(ioc, hba);
1332         if (error)
1333                 goto out_free_port_info;
1334
1335         mutex_lock(&ioc->sas_topology_mutex);
1336         port_info = mptsas_find_portinfo_by_handle(ioc, hba->handle);
1337         if (!port_info) {
1338                 port_info = hba;
1339                 list_add_tail(&port_info->list, &ioc->sas_topology);
1340         } else {
1341                 port_info->handle = hba->handle;
1342                 for (i = 0; i < hba->num_phys; i++)
1343                         port_info->phy_info[i].negotiated_link_rate =
1344                                 hba->phy_info[i].negotiated_link_rate;
1345                 if (hba->phy_info)
1346                         kfree(hba->phy_info);
1347                 kfree(hba);
1348                 hba = NULL;
1349         }
1350         mutex_unlock(&ioc->sas_topology_mutex);
1351         ioc->num_ports = port_info->num_phys;
1352
1353         for (i = 0; i < port_info->num_phys; i++) {
1354                 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
1355                         (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
1356                          MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
1357
1358                 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
1359                         (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
1360                          MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
1361                 port_info->phy_info[i].identify.phy_id =
1362                     port_info->phy_info[i].phy_id;
1363                 handle = port_info->phy_info[i].identify.handle;
1364
1365                 if (port_info->phy_info[i].attached.handle) {
1366                         mptsas_sas_device_pg0(ioc,
1367                                 &port_info->phy_info[i].attached,
1368                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1369                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1370                                 port_info->phy_info[i].attached.handle);
1371                 }
1372
1373                 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
1374                     &port_info->phy_info[i], ioc->sas_index, 1);
1375                 ioc->sas_index++;
1376         }
1377
1378         return 0;
1379
1380  out_free_port_info:
1381         kfree(hba);
1382  out:
1383         return error;
1384 }
1385
1386 static int
1387 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
1388 {
1389         struct mptsas_portinfo *port_info, *p, *ex;
1390         int error = -ENOMEM, i, j;
1391
1392         ex = kzalloc(sizeof(*port_info), GFP_KERNEL);
1393         if (!ex)
1394                 goto out;
1395
1396         error = mptsas_sas_expander_pg0(ioc, ex,
1397                 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
1398                  MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
1399         if (error)
1400                 goto out_free_port_info;
1401
1402         *handle = ex->handle;
1403
1404         mutex_lock(&ioc->sas_topology_mutex);
1405         port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
1406         if (!port_info) {
1407                 port_info = ex;
1408                 list_add_tail(&port_info->list, &ioc->sas_topology);
1409         } else {
1410                 port_info->handle = ex->handle;
1411                 if (ex->phy_info)
1412                         kfree(ex->phy_info);
1413                 kfree(ex);
1414                 ex = NULL;
1415         }
1416         mutex_unlock(&ioc->sas_topology_mutex);
1417
1418         for (i = 0; i < port_info->num_phys; i++) {
1419                 struct device *parent;
1420
1421                 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
1422                         (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
1423                          MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
1424
1425                 if (port_info->phy_info[i].identify.handle) {
1426                         mptsas_sas_device_pg0(ioc,
1427                                 &port_info->phy_info[i].identify,
1428                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1429                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1430                                 port_info->phy_info[i].identify.handle);
1431                         port_info->phy_info[i].identify.phy_id =
1432                             port_info->phy_info[i].phy_id;
1433                 }
1434
1435                 if (port_info->phy_info[i].attached.handle) {
1436                         mptsas_sas_device_pg0(ioc,
1437                                 &port_info->phy_info[i].attached,
1438                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1439                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1440                                 port_info->phy_info[i].attached.handle);
1441                         port_info->phy_info[i].attached.phy_id =
1442                             port_info->phy_info[i].phy_id;
1443                 }
1444
1445                 /*
1446                  * If we find a parent port handle this expander is
1447                  * attached to another expander, else it hangs of the
1448                  * HBA phys.
1449                  */
1450                 parent = &ioc->sh->shost_gendev;
1451                 mutex_lock(&ioc->sas_topology_mutex);
1452                 list_for_each_entry(p, &ioc->sas_topology, list) {
1453                         for (j = 0; j < p->num_phys; j++) {
1454                                 if (port_info->phy_info[i].identify.handle ==
1455                                                 p->phy_info[j].attached.handle)
1456                                         parent = &p->phy_info[j].rphy->dev;
1457                         }
1458                 }
1459                 mutex_unlock(&ioc->sas_topology_mutex);
1460
1461                 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1462                     ioc->sas_index, 0);
1463                 ioc->sas_index++;
1464         }
1465
1466         return 0;
1467
1468  out_free_port_info:
1469         if (ex) {
1470                 if (ex->phy_info)
1471                         kfree(ex->phy_info);
1472                 kfree(ex);
1473         }
1474  out:
1475         return error;
1476 }
1477
1478 /*
1479  * mptsas_delete_expander_phys
1480  *
1481  *
1482  * This will traverse topology, and remove expanders
1483  * that are no longer present
1484  */
1485 static void
1486 mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
1487 {
1488         struct mptsas_portinfo buffer;
1489         struct mptsas_portinfo *port_info, *n, *parent;
1490         int i;
1491
1492         mutex_lock(&ioc->sas_topology_mutex);
1493         list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
1494
1495                 if (port_info->phy_info &&
1496                     (!(port_info->phy_info[0].identify.device_info &
1497                     MPI_SAS_DEVICE_INFO_SMP_TARGET)))
1498                         continue;
1499
1500                 if (mptsas_sas_expander_pg0(ioc, &buffer,
1501                      (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
1502                      MPI_SAS_EXPAND_PGAD_FORM_SHIFT), port_info->handle)) {
1503
1504                         /*
1505                          * Obtain the port_info instance to the parent port
1506                          */
1507                         parent = mptsas_find_portinfo_by_handle(ioc,
1508                             port_info->phy_info[0].identify.handle_parent);
1509
1510                         if (!parent)
1511                                 goto next_port;
1512
1513                         /*
1514                          * Delete rphys in the parent that point
1515                          * to this expander.  The transport layer will
1516                          * cleanup all the children.
1517                          */
1518                         for (i = 0; i < parent->num_phys; i++) {
1519                                 if ((!parent->phy_info[i].rphy) ||
1520                                     (parent->phy_info[i].attached.sas_address !=
1521                                    port_info->phy_info[i].identify.sas_address))
1522                                         continue;
1523                                 sas_rphy_delete(parent->phy_info[i].rphy);
1524                                 memset(&parent->phy_info[i].attached, 0,
1525                                     sizeof(struct mptsas_devinfo));
1526                                 parent->phy_info[i].rphy = NULL;
1527                                 parent->phy_info[i].starget = NULL;
1528                         }
1529  next_port:
1530                         list_del(&port_info->list);
1531                         if (port_info->phy_info)
1532                                 kfree(port_info->phy_info);
1533                         kfree(port_info);
1534                 }
1535                 /*
1536                 * Free this memory allocated from inside
1537                 * mptsas_sas_expander_pg0
1538                 */
1539                 if (buffer.phy_info)
1540                         kfree(buffer.phy_info);
1541         }
1542         mutex_unlock(&ioc->sas_topology_mutex);
1543 }
1544
1545 /*
1546  * Start of day discovery
1547  */
1548 static void
1549 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1550 {
1551         u32 handle = 0xFFFF;
1552         int i;
1553
1554         mutex_lock(&ioc->sas_discovery_mutex);
1555         mptsas_probe_hba_phys(ioc);
1556         while (!mptsas_probe_expander_phys(ioc, &handle))
1557                 ;
1558         /*
1559           Reporting RAID volumes.
1560         */
1561         if (!ioc->raid_data.pIocPg2)
1562                 goto out;
1563         if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
1564                 goto out;
1565         for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
1566                 scsi_add_device(ioc->sh, ioc->num_ports,
1567                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
1568         }
1569  out:
1570         mutex_unlock(&ioc->sas_discovery_mutex);
1571 }
1572
1573 /*
1574  * Work queue thread to handle Runtime discovery
1575  * Mere purpose is the hot add/delete of expanders
1576  */
1577 static void
1578 mptscsih_discovery_work(void * arg)
1579 {
1580         struct mptsas_discovery_event *ev = arg;
1581         MPT_ADAPTER *ioc = ev->ioc;
1582         u32 handle = 0xFFFF;
1583
1584         mutex_lock(&ioc->sas_discovery_mutex);
1585         ioc->sas_discovery_runtime=1;
1586         mptsas_delete_expander_phys(ioc);
1587         mptsas_probe_hba_phys(ioc);
1588         while (!mptsas_probe_expander_phys(ioc, &handle))
1589                 ;
1590         kfree(ev);
1591         ioc->sas_discovery_runtime=0;
1592         mutex_unlock(&ioc->sas_discovery_mutex);
1593 }
1594
1595 static struct mptsas_phyinfo *
1596 mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id)
1597 {
1598         struct mptsas_portinfo *port_info;
1599         struct mptsas_devinfo device_info;
1600         struct mptsas_phyinfo *phy_info = NULL;
1601         int i, error;
1602
1603         /*
1604          * Retrieve the parent sas_address
1605          */
1606         error = mptsas_sas_device_pg0(ioc, &device_info,
1607                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1608                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1609                 parent_handle);
1610         if (error)
1611                 return NULL;
1612
1613         /*
1614          * The phy_info structures are never deallocated during lifetime of
1615          * a host, so the code below is safe without additional refcounting.
1616          */
1617         mutex_lock(&ioc->sas_topology_mutex);
1618         list_for_each_entry(port_info, &ioc->sas_topology, list) {
1619                 for (i = 0; i < port_info->num_phys; i++) {
1620                         if (port_info->phy_info[i].identify.sas_address ==
1621                             device_info.sas_address &&
1622                             port_info->phy_info[i].phy_id == phy_id) {
1623                                 phy_info = &port_info->phy_info[i];
1624                                 break;
1625                         }
1626                 }
1627         }
1628         mutex_unlock(&ioc->sas_topology_mutex);
1629
1630         return phy_info;
1631 }
1632
1633 static struct mptsas_phyinfo *
1634 mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
1635 {
1636         struct mptsas_portinfo *port_info;
1637         struct mptsas_phyinfo *phy_info = NULL;
1638         int i;
1639
1640         /*
1641          * The phy_info structures are never deallocated during lifetime of
1642          * a host, so the code below is safe without additional refcounting.
1643          */
1644         mutex_lock(&ioc->sas_topology_mutex);
1645         list_for_each_entry(port_info, &ioc->sas_topology, list) {
1646                 for (i = 0; i < port_info->num_phys; i++)
1647                         if (mptsas_is_end_device(&port_info->phy_info[i].attached))
1648                                 if (port_info->phy_info[i].attached.id == id) {
1649                                         phy_info = &port_info->phy_info[i];
1650                                         break;
1651                                 }
1652         }
1653         mutex_unlock(&ioc->sas_topology_mutex);
1654
1655         return phy_info;
1656 }
1657
1658 /*
1659  * Work queue thread to clear the persitency table
1660  */
1661 static void
1662 mptscsih_sas_persist_clear_table(void * arg)
1663 {
1664         MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
1665
1666         mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
1667 }
1668
1669 static void
1670 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
1671 {
1672         sdev->no_uld_attach = data ? 1 : 0;
1673         scsi_device_reprobe(sdev);
1674 }
1675
1676 static void
1677 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
1678 {
1679         starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
1680                         mptsas_reprobe_lun);
1681 }
1682
1683
1684 /*
1685  * Work queue thread to handle SAS hotplug events
1686  */
1687 static void
1688 mptsas_hotplug_work(void *arg)
1689 {
1690         struct mptsas_hotplug_event *ev = arg;
1691         MPT_ADAPTER *ioc = ev->ioc;
1692         struct mptsas_phyinfo *phy_info;
1693         struct sas_rphy *rphy;
1694         struct scsi_device *sdev;
1695         struct sas_identify identify;
1696         char *ds = NULL;
1697         struct mptsas_devinfo sas_device;
1698         VirtTarget *vtarget;
1699
1700         mutex_lock(&ioc->sas_discovery_mutex);
1701
1702         switch (ev->event_type) {
1703         case MPTSAS_DEL_DEVICE:
1704
1705                 phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id);
1706
1707                 /*
1708                  * Sanity checks, for non-existing phys and remote rphys.
1709                  */
1710                 if (!phy_info)
1711                         break;
1712                 if (!phy_info->rphy)
1713                         break;
1714                 if (phy_info->starget) {
1715                         vtarget = phy_info->starget->hostdata;
1716
1717                         if (!vtarget)
1718                                 break;
1719                         /*
1720                          * Handling  RAID components
1721                          */
1722                         if (ev->phys_disk_num_valid) {
1723                                 vtarget->target_id = ev->phys_disk_num;
1724                                 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
1725                                 mptsas_reprobe_target(vtarget->starget, 1);
1726                                 break;
1727                         }
1728                 }
1729
1730                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1731                         ds = "ssp";
1732                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
1733                         ds = "stp";
1734                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1735                         ds = "sata";
1736
1737                 printk(MYIOC_s_INFO_FMT
1738                        "removing %s device, channel %d, id %d, phy %d\n",
1739                        ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
1740
1741                 sas_rphy_delete(phy_info->rphy);
1742                 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
1743                 phy_info->rphy = NULL;
1744                 phy_info->starget = NULL;
1745                 break;
1746         case MPTSAS_ADD_DEVICE:
1747
1748                 if (ev->phys_disk_num_valid)
1749                         mpt_findImVolumes(ioc);
1750
1751                 /*
1752                  * Refresh sas device pg0 data
1753                  */
1754                 if (mptsas_sas_device_pg0(ioc, &sas_device,
1755                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
1756                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id))
1757                         break;
1758
1759                 phy_info = mptsas_find_phyinfo_by_parent(ioc,
1760                                 sas_device.handle_parent, sas_device.phy_id);
1761
1762                 if (!phy_info) {
1763                         u32 handle = 0xFFFF;
1764
1765                         /*
1766                         * Its possible when an expander has been hot added
1767                         * containing attached devices, the sas firmware
1768                         * may send a RC_ADDED event prior to the
1769                         * DISCOVERY STOP event. If that occurs, our
1770                         * view of the topology in the driver in respect to this
1771                         * expander might of not been setup, and we hit this
1772                         * condition.
1773                         * Therefore, this code kicks off discovery to
1774                         * refresh the data.
1775                         * Then again, we check whether the parent phy has
1776                         * been created.
1777                         */
1778                         ioc->sas_discovery_runtime=1;
1779                         mptsas_delete_expander_phys(ioc);
1780                         mptsas_probe_hba_phys(ioc);
1781                         while (!mptsas_probe_expander_phys(ioc, &handle))
1782                                 ;
1783                         ioc->sas_discovery_runtime=0;
1784
1785                         phy_info = mptsas_find_phyinfo_by_parent(ioc,
1786                                 sas_device.handle_parent, sas_device.phy_id);
1787                         if (!phy_info)
1788                                 break;
1789                 }
1790
1791                 if (phy_info->starget) {
1792                         vtarget = phy_info->starget->hostdata;
1793
1794                         if (!vtarget)
1795                                 break;
1796                         /*
1797                          * Handling  RAID components
1798                          */
1799                         if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1800                                 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
1801                                 vtarget->target_id = ev->id;
1802                                 mptsas_reprobe_target(phy_info->starget, 0);
1803                         }
1804                         break;
1805                 }
1806
1807                 if (phy_info->rphy)
1808                         break;
1809
1810                 memcpy(&phy_info->attached, &sas_device,
1811                     sizeof(struct mptsas_devinfo));
1812
1813                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1814                         ds = "ssp";
1815                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
1816                         ds = "stp";
1817                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1818                         ds = "sata";
1819
1820                 printk(MYIOC_s_INFO_FMT
1821                        "attaching %s device, channel %d, id %d, phy %d\n",
1822                        ioc->name, ds, ev->channel, ev->id, ev->phy_id);
1823
1824                 mptsas_parse_device_info(&identify, &phy_info->attached);
1825                 switch (identify.device_type) {
1826                 case SAS_END_DEVICE:
1827                         rphy = sas_end_device_alloc(phy_info->phy);
1828                         break;
1829                 case SAS_EDGE_EXPANDER_DEVICE:
1830                 case SAS_FANOUT_EXPANDER_DEVICE:
1831                         rphy = sas_expander_alloc(phy_info->phy, identify.device_type);
1832                         break;
1833                 default:
1834                         rphy = NULL;
1835                         break;
1836                 }
1837                 if (!rphy)
1838                         break; /* non-fatal: an rphy can be added later */
1839
1840                 rphy->identify = identify;
1841                 if (sas_rphy_add(rphy)) {
1842                         sas_rphy_free(rphy);
1843                         break;
1844                 }
1845
1846                 phy_info->rphy = rphy;
1847                 break;
1848         case MPTSAS_ADD_RAID:
1849                 sdev = scsi_device_lookup(
1850                         ioc->sh,
1851                         ioc->num_ports,
1852                         ev->id,
1853                         0);
1854                 if (sdev) {
1855                         scsi_device_put(sdev);
1856                         break;
1857                 }
1858                 printk(MYIOC_s_INFO_FMT
1859                        "attaching raid volume, channel %d, id %d\n",
1860                        ioc->name, ioc->num_ports, ev->id);
1861                 scsi_add_device(ioc->sh,
1862                         ioc->num_ports,
1863                         ev->id,
1864                         0);
1865                 mpt_findImVolumes(ioc);
1866                 break;
1867         case MPTSAS_DEL_RAID:
1868                 sdev = scsi_device_lookup(
1869                         ioc->sh,
1870                         ioc->num_ports,
1871                         ev->id,
1872                         0);
1873                 if (!sdev)
1874                         break;
1875                 printk(MYIOC_s_INFO_FMT
1876                        "removing raid volume, channel %d, id %d\n",
1877                        ioc->name, ioc->num_ports, ev->id);
1878                 scsi_remove_device(sdev);
1879                 scsi_device_put(sdev);
1880                 mpt_findImVolumes(ioc);
1881                 break;
1882         case MPTSAS_IGNORE_EVENT:
1883         default:
1884                 break;
1885         }
1886
1887         kfree(ev);
1888         mutex_unlock(&ioc->sas_discovery_mutex);
1889 }
1890
1891 static void
1892 mptscsih_send_sas_event(MPT_ADAPTER *ioc,
1893                 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1894 {
1895         struct mptsas_hotplug_event *ev;
1896         u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
1897         __le64 sas_address;
1898
1899         if ((device_info &
1900              (MPI_SAS_DEVICE_INFO_SSP_TARGET |
1901               MPI_SAS_DEVICE_INFO_STP_TARGET |
1902               MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
1903                 return;
1904
1905         switch (sas_event_data->ReasonCode) {
1906         case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
1907         case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
1908                 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1909                 if (!ev) {
1910                         printk(KERN_WARNING "mptsas: lost hotplug event\n");
1911                         break;
1912                 }
1913
1914                 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1915                 ev->ioc = ioc;
1916                 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
1917                 ev->parent_handle =
1918                     le16_to_cpu(sas_event_data->ParentDevHandle);
1919                 ev->channel = sas_event_data->Bus;
1920                 ev->id = sas_event_data->TargetID;
1921                 ev->phy_id = sas_event_data->PhyNum;
1922                 memcpy(&sas_address, &sas_event_data->SASAddress,
1923                     sizeof(__le64));
1924                 ev->sas_address = le64_to_cpu(sas_address);
1925                 ev->device_info = device_info;
1926
1927                 if (sas_event_data->ReasonCode &
1928                     MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
1929                         ev->event_type = MPTSAS_ADD_DEVICE;
1930                 else
1931                         ev->event_type = MPTSAS_DEL_DEVICE;
1932                 schedule_work(&ev->work);
1933                 break;
1934         case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
1935         /*
1936          * Persistent table is full.
1937          */
1938                 INIT_WORK(&ioc->mptscsih_persistTask,
1939                     mptscsih_sas_persist_clear_table,
1940                     (void *)ioc);
1941                 schedule_work(&ioc->mptscsih_persistTask);
1942                 break;
1943         case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
1944         /* TODO */
1945         case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
1946         /* TODO */
1947         default:
1948                 break;
1949         }
1950 }
1951
1952 static void
1953 mptscsih_send_raid_event(MPT_ADAPTER *ioc,
1954                 EVENT_DATA_RAID *raid_event_data)
1955 {
1956         struct mptsas_hotplug_event *ev;
1957         int status = le32_to_cpu(raid_event_data->SettingsStatus);
1958         int state = (status >> 8) & 0xff;
1959
1960         if (ioc->bus_type != SAS)
1961                 return;
1962
1963         ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1964         if (!ev) {
1965                 printk(KERN_WARNING "mptsas: lost hotplug event\n");
1966                 return;
1967         }
1968
1969         memset(ev,0,sizeof(struct mptsas_hotplug_event));
1970         INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1971         ev->ioc = ioc;
1972         ev->id = raid_event_data->VolumeID;
1973         ev->event_type = MPTSAS_IGNORE_EVENT;
1974
1975         switch (raid_event_data->ReasonCode) {
1976         case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
1977                 ev->event_type = MPTSAS_ADD_DEVICE;
1978                 break;
1979         case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
1980                 ioc->raid_data.isRaid = 1;
1981                 ev->phys_disk_num_valid = 1;
1982                 ev->phys_disk_num = raid_event_data->PhysDiskNum;
1983                 ev->event_type = MPTSAS_DEL_DEVICE;
1984                 break;
1985         case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
1986                 switch (state) {
1987                 case MPI_PD_STATE_ONLINE:
1988                         ioc->raid_data.isRaid = 1;
1989                         ev->phys_disk_num_valid = 1;
1990                         ev->phys_disk_num = raid_event_data->PhysDiskNum;
1991                         ev->event_type = MPTSAS_ADD_DEVICE;
1992                         break;
1993                 case MPI_PD_STATE_MISSING:
1994                 case MPI_PD_STATE_NOT_COMPATIBLE:
1995                 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
1996                 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
1997                 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
1998                         ev->event_type = MPTSAS_DEL_DEVICE;
1999                         break;
2000                 default:
2001                         break;
2002                 }
2003                 break;
2004         case MPI_EVENT_RAID_RC_VOLUME_DELETED:
2005                 ev->event_type = MPTSAS_DEL_RAID;
2006                 break;
2007         case MPI_EVENT_RAID_RC_VOLUME_CREATED:
2008                 ev->event_type = MPTSAS_ADD_RAID;
2009                 break;
2010         case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
2011                 switch (state) {
2012                 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
2013                 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
2014                         ev->event_type = MPTSAS_DEL_RAID;
2015                         break;
2016                 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
2017                 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
2018                         ev->event_type = MPTSAS_ADD_RAID;
2019                         break;
2020                 default:
2021                         break;
2022                 }
2023                 break;
2024         default:
2025                 break;
2026         }
2027         schedule_work(&ev->work);
2028 }
2029
2030 static void
2031 mptscsih_send_discovery(MPT_ADAPTER *ioc,
2032         EVENT_DATA_SAS_DISCOVERY *discovery_data)
2033 {
2034         struct mptsas_discovery_event *ev;
2035
2036         /*
2037          * DiscoveryStatus
2038          *
2039          * This flag will be non-zero when firmware
2040          * kicks off discovery, and return to zero
2041          * once its completed.
2042          */
2043         if (discovery_data->DiscoveryStatus)
2044                 return;
2045
2046         ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
2047         if (!ev)
2048                 return;
2049         memset(ev,0,sizeof(struct mptsas_discovery_event));
2050         INIT_WORK(&ev->work, mptscsih_discovery_work, ev);
2051         ev->ioc = ioc;
2052         schedule_work(&ev->work);
2053 };
2054
2055
2056 static int
2057 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
2058 {
2059         int rc=1;
2060         u8 event = le32_to_cpu(reply->Event) & 0xFF;
2061
2062         if (!ioc->sh)
2063                 goto out;
2064
2065         /*
2066          * sas_discovery_ignore_events
2067          *
2068          * This flag is to prevent anymore processing of
2069          * sas events once mptsas_remove function is called.
2070          */
2071         if (ioc->sas_discovery_ignore_events) {
2072                 rc = mptscsih_event_process(ioc, reply);
2073                 goto out;
2074         }
2075
2076         switch (event) {
2077         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
2078                 mptscsih_send_sas_event(ioc,
2079                         (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
2080                 break;
2081         case MPI_EVENT_INTEGRATED_RAID:
2082                 mptscsih_send_raid_event(ioc,
2083                         (EVENT_DATA_RAID *)reply->Data);
2084                 break;
2085         case MPI_EVENT_PERSISTENT_TABLE_FULL:
2086                 INIT_WORK(&ioc->mptscsih_persistTask,
2087                     mptscsih_sas_persist_clear_table,
2088                     (void *)ioc);
2089                 schedule_work(&ioc->mptscsih_persistTask);
2090                 break;
2091          case MPI_EVENT_SAS_DISCOVERY:
2092                 mptscsih_send_discovery(ioc,
2093                         (EVENT_DATA_SAS_DISCOVERY *)reply->Data);
2094                 break;
2095         default:
2096                 rc = mptscsih_event_process(ioc, reply);
2097                 break;
2098         }
2099  out:
2100
2101         return rc;
2102 }
2103
2104 static int
2105 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2106 {
2107         struct Scsi_Host        *sh;
2108         MPT_SCSI_HOST           *hd;
2109         MPT_ADAPTER             *ioc;
2110         unsigned long            flags;
2111         int                      ii;
2112         int                      numSGE = 0;
2113         int                      scale;
2114         int                      ioc_cap;
2115         int                     error=0;
2116         int                     r;
2117
2118         r = mpt_attach(pdev,id);
2119         if (r)
2120                 return r;
2121
2122         ioc = pci_get_drvdata(pdev);
2123         ioc->DoneCtx = mptsasDoneCtx;
2124         ioc->TaskCtx = mptsasTaskCtx;
2125         ioc->InternalCtx = mptsasInternalCtx;
2126
2127         /*  Added sanity check on readiness of the MPT adapter.
2128          */
2129         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
2130                 printk(MYIOC_s_WARN_FMT
2131                   "Skipping because it's not operational!\n",
2132                   ioc->name);
2133                 error = -ENODEV;
2134                 goto out_mptsas_probe;
2135         }
2136
2137         if (!ioc->active) {
2138                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
2139                   ioc->name);
2140                 error = -ENODEV;
2141                 goto out_mptsas_probe;
2142         }
2143
2144         /*  Sanity check - ensure at least 1 port is INITIATOR capable
2145          */
2146         ioc_cap = 0;
2147         for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
2148                 if (ioc->pfacts[ii].ProtocolFlags &
2149                                 MPI_PORTFACTS_PROTOCOL_INITIATOR)
2150                         ioc_cap++;
2151         }
2152
2153         if (!ioc_cap) {
2154                 printk(MYIOC_s_WARN_FMT
2155                         "Skipping ioc=%p because SCSI Initiator mode "
2156                         "is NOT enabled!\n", ioc->name, ioc);
2157                 return 0;
2158         }
2159
2160         sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
2161         if (!sh) {
2162                 printk(MYIOC_s_WARN_FMT
2163                         "Unable to register controller with SCSI subsystem\n",
2164                         ioc->name);
2165                 error = -1;
2166                 goto out_mptsas_probe;
2167         }
2168
2169         spin_lock_irqsave(&ioc->FreeQlock, flags);
2170
2171         /* Attach the SCSI Host to the IOC structure
2172          */
2173         ioc->sh = sh;
2174
2175         sh->io_port = 0;
2176         sh->n_io_port = 0;
2177         sh->irq = 0;
2178
2179         /* set 16 byte cdb's */
2180         sh->max_cmd_len = 16;
2181
2182         sh->max_id = ioc->pfacts->MaxDevices + 1;
2183
2184         sh->transportt = mptsas_transport_template;
2185
2186         sh->max_lun = MPT_LAST_LUN + 1;
2187         sh->max_channel = 0;
2188         sh->this_id = ioc->pfacts[0].PortSCSIID;
2189
2190         /* Required entry.
2191          */
2192         sh->unique_id = ioc->id;
2193
2194         INIT_LIST_HEAD(&ioc->sas_topology);
2195         mutex_init(&ioc->sas_topology_mutex);
2196         mutex_init(&ioc->sas_discovery_mutex);
2197         mutex_init(&ioc->sas_mgmt.mutex);
2198         init_completion(&ioc->sas_mgmt.done);
2199
2200         /* Verify that we won't exceed the maximum
2201          * number of chain buffers
2202          * We can optimize:  ZZ = req_sz/sizeof(SGE)
2203          * For 32bit SGE's:
2204          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
2205          *               + (req_sz - 64)/sizeof(SGE)
2206          * A slightly different algorithm is required for
2207          * 64bit SGEs.
2208          */
2209         scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
2210         if (sizeof(dma_addr_t) == sizeof(u64)) {
2211                 numSGE = (scale - 1) *
2212                   (ioc->facts.MaxChainDepth-1) + scale +
2213                   (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
2214                   sizeof(u32));
2215         } else {
2216                 numSGE = 1 + (scale - 1) *
2217                   (ioc->facts.MaxChainDepth-1) + scale +
2218                   (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
2219                   sizeof(u32));
2220         }
2221
2222         if (numSGE < sh->sg_tablesize) {
2223                 /* Reset this value */
2224                 dprintk((MYIOC_s_INFO_FMT
2225                   "Resetting sg_tablesize to %d from %d\n",
2226                   ioc->name, numSGE, sh->sg_tablesize));
2227                 sh->sg_tablesize = numSGE;
2228         }
2229
2230         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2231
2232         hd = (MPT_SCSI_HOST *) sh->hostdata;
2233         hd->ioc = ioc;
2234
2235         /* SCSI needs scsi_cmnd lookup table!
2236          * (with size equal to req_depth*PtrSz!)
2237          */
2238         hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
2239         if (!hd->ScsiLookup) {
2240                 error = -ENOMEM;
2241                 goto out_mptsas_probe;
2242         }
2243
2244         dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
2245                  ioc->name, hd->ScsiLookup));
2246
2247         /* Allocate memory for the device structures.
2248          * A non-Null pointer at an offset
2249          * indicates a device exists.
2250          * max_id = 1 + maximum id (hosts.h)
2251          */
2252         hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
2253         if (!hd->Targets) {
2254                 error = -ENOMEM;
2255                 goto out_mptsas_probe;
2256         }
2257
2258         dprintk((KERN_INFO "  vtarget @ %p\n", hd->Targets));
2259
2260         /* Clear the TM flags
2261          */
2262         hd->tmPending = 0;
2263         hd->tmState = TM_STATE_NONE;
2264         hd->resetPending = 0;
2265         hd->abortSCpnt = NULL;
2266
2267         /* Clear the pointer used to store
2268          * single-threaded commands, i.e., those
2269          * issued during a bus scan, dv and
2270          * configuration pages.
2271          */
2272         hd->cmdPtr = NULL;
2273
2274         /* Initialize this SCSI Hosts' timers
2275          * To use, set the timer expires field
2276          * and add_timer
2277          */
2278         init_timer(&hd->timer);
2279         hd->timer.data = (unsigned long) hd;
2280         hd->timer.function = mptscsih_timer_expired;
2281
2282         hd->mpt_pq_filter = mpt_pq_filter;
2283         ioc->sas_data.ptClear = mpt_pt_clear;
2284
2285         if (ioc->sas_data.ptClear==1) {
2286                 mptbase_sas_persist_operation(
2287                     ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
2288         }
2289
2290         ddvprintk((MYIOC_s_INFO_FMT
2291                 "mpt_pq_filter %x mpt_pq_filter %x\n",
2292                 ioc->name,
2293                 mpt_pq_filter,
2294                 mpt_pq_filter));
2295
2296         init_waitqueue_head(&hd->scandv_waitq);
2297         hd->scandv_wait_done = 0;
2298         hd->last_queue_full = 0;
2299
2300         error = scsi_add_host(sh, &ioc->pcidev->dev);
2301         if (error) {
2302                 dprintk((KERN_ERR MYNAM
2303                   "scsi_add_host failed\n"));
2304                 goto out_mptsas_probe;
2305         }
2306
2307         mptsas_scan_sas_topology(ioc);
2308
2309         return 0;
2310
2311 out_mptsas_probe:
2312
2313         mptscsih_remove(pdev);
2314         return error;
2315 }
2316
2317 static void __devexit mptsas_remove(struct pci_dev *pdev)
2318 {
2319         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2320         struct mptsas_portinfo *p, *n;
2321
2322         ioc->sas_discovery_ignore_events=1;
2323         sas_remove_host(ioc->sh);
2324
2325         mutex_lock(&ioc->sas_topology_mutex);
2326         list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
2327                 list_del(&p->list);
2328                 if (p->phy_info)
2329                         kfree(p->phy_info);
2330                 kfree(p);
2331         }
2332         mutex_unlock(&ioc->sas_topology_mutex);
2333
2334         mptscsih_remove(pdev);
2335 }
2336
2337 static struct pci_device_id mptsas_pci_table[] = {
2338         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
2339                 PCI_ANY_ID, PCI_ANY_ID },
2340         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
2341                 PCI_ANY_ID, PCI_ANY_ID },
2342         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
2343                 PCI_ANY_ID, PCI_ANY_ID },
2344         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
2345                 PCI_ANY_ID, PCI_ANY_ID },
2346         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
2347                 PCI_ANY_ID, PCI_ANY_ID },
2348         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
2349                 PCI_ANY_ID, PCI_ANY_ID },
2350         {0}     /* Terminating entry */
2351 };
2352 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
2353
2354
2355 static struct pci_driver mptsas_driver = {
2356         .name           = "mptsas",
2357         .id_table       = mptsas_pci_table,
2358         .probe          = mptsas_probe,
2359         .remove         = __devexit_p(mptsas_remove),
2360         .shutdown       = mptscsih_shutdown,
2361 #ifdef CONFIG_PM
2362         .suspend        = mptscsih_suspend,
2363         .resume         = mptscsih_resume,
2364 #endif
2365 };
2366
2367 static int __init
2368 mptsas_init(void)
2369 {
2370         show_mptmod_ver(my_NAME, my_VERSION);
2371
2372         mptsas_transport_template =
2373             sas_attach_transport(&mptsas_transport_functions);
2374         if (!mptsas_transport_template)
2375                 return -ENODEV;
2376
2377         mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
2378         mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
2379         mptsasInternalCtx =
2380                 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
2381         mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
2382
2383         if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) {
2384                 devtverboseprintk((KERN_INFO MYNAM
2385                   ": Registered for IOC event notifications\n"));
2386         }
2387
2388         if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
2389                 dprintk((KERN_INFO MYNAM
2390                   ": Registered for IOC reset notifications\n"));
2391         }
2392
2393         return pci_register_driver(&mptsas_driver);
2394 }
2395
2396 static void __exit
2397 mptsas_exit(void)
2398 {
2399         pci_unregister_driver(&mptsas_driver);
2400         sas_release_transport(mptsas_transport_template);
2401
2402         mpt_reset_deregister(mptsasDoneCtx);
2403         mpt_event_deregister(mptsasDoneCtx);
2404
2405         mpt_deregister(mptsasMgmtCtx);
2406         mpt_deregister(mptsasInternalCtx);
2407         mpt_deregister(mptsasTaskCtx);
2408         mpt_deregister(mptsasDoneCtx);
2409 }
2410
2411 module_init(mptsas_init);
2412 module_exit(mptsas_exit);