Pull trivial into release branch
[linux-2.6] / 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         if (hba)
1382                 kfree(hba);
1383  out:
1384         return error;
1385 }
1386
1387 static int
1388 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
1389 {
1390         struct mptsas_portinfo *port_info, *p, *ex;
1391         int error = -ENOMEM, i, j;
1392
1393         ex = kzalloc(sizeof(*port_info), GFP_KERNEL);
1394         if (!ex)
1395                 goto out;
1396
1397         error = mptsas_sas_expander_pg0(ioc, ex,
1398                 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
1399                  MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
1400         if (error)
1401                 goto out_free_port_info;
1402
1403         *handle = ex->handle;
1404
1405         mutex_lock(&ioc->sas_topology_mutex);
1406         port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
1407         if (!port_info) {
1408                 port_info = ex;
1409                 list_add_tail(&port_info->list, &ioc->sas_topology);
1410         } else {
1411                 port_info->handle = ex->handle;
1412                 if (ex->phy_info)
1413                         kfree(ex->phy_info);
1414                 kfree(ex);
1415                 ex = NULL;
1416         }
1417         mutex_unlock(&ioc->sas_topology_mutex);
1418
1419         for (i = 0; i < port_info->num_phys; i++) {
1420                 struct device *parent;
1421
1422                 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
1423                         (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
1424                          MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
1425
1426                 if (port_info->phy_info[i].identify.handle) {
1427                         mptsas_sas_device_pg0(ioc,
1428                                 &port_info->phy_info[i].identify,
1429                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1430                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1431                                 port_info->phy_info[i].identify.handle);
1432                         port_info->phy_info[i].identify.phy_id =
1433                             port_info->phy_info[i].phy_id;
1434                 }
1435
1436                 if (port_info->phy_info[i].attached.handle) {
1437                         mptsas_sas_device_pg0(ioc,
1438                                 &port_info->phy_info[i].attached,
1439                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1440                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1441                                 port_info->phy_info[i].attached.handle);
1442                         port_info->phy_info[i].attached.phy_id =
1443                             port_info->phy_info[i].phy_id;
1444                 }
1445
1446                 /*
1447                  * If we find a parent port handle this expander is
1448                  * attached to another expander, else it hangs of the
1449                  * HBA phys.
1450                  */
1451                 parent = &ioc->sh->shost_gendev;
1452                 mutex_lock(&ioc->sas_topology_mutex);
1453                 list_for_each_entry(p, &ioc->sas_topology, list) {
1454                         for (j = 0; j < p->num_phys; j++) {
1455                                 if (port_info->phy_info[i].identify.handle ==
1456                                                 p->phy_info[j].attached.handle)
1457                                         parent = &p->phy_info[j].rphy->dev;
1458                         }
1459                 }
1460                 mutex_unlock(&ioc->sas_topology_mutex);
1461
1462                 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1463                     ioc->sas_index, 0);
1464                 ioc->sas_index++;
1465         }
1466
1467         return 0;
1468
1469  out_free_port_info:
1470         if (ex) {
1471                 if (ex->phy_info)
1472                         kfree(ex->phy_info);
1473                 kfree(ex);
1474         }
1475  out:
1476         return error;
1477 }
1478
1479 /*
1480  * mptsas_delete_expander_phys
1481  *
1482  *
1483  * This will traverse topology, and remove expanders
1484  * that are no longer present
1485  */
1486 static void
1487 mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
1488 {
1489         struct mptsas_portinfo buffer;
1490         struct mptsas_portinfo *port_info, *n, *parent;
1491         int i;
1492
1493         mutex_lock(&ioc->sas_topology_mutex);
1494         list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
1495
1496                 if (port_info->phy_info &&
1497                     (!(port_info->phy_info[0].identify.device_info &
1498                     MPI_SAS_DEVICE_INFO_SMP_TARGET)))
1499                         continue;
1500
1501                 if (mptsas_sas_expander_pg0(ioc, &buffer,
1502                      (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
1503                      MPI_SAS_EXPAND_PGAD_FORM_SHIFT), port_info->handle)) {
1504
1505                         /*
1506                          * Obtain the port_info instance to the parent port
1507                          */
1508                         parent = mptsas_find_portinfo_by_handle(ioc,
1509                             port_info->phy_info[0].identify.handle_parent);
1510
1511                         if (!parent)
1512                                 goto next_port;
1513
1514                         /*
1515                          * Delete rphys in the parent that point
1516                          * to this expander.  The transport layer will
1517                          * cleanup all the children.
1518                          */
1519                         for (i = 0; i < parent->num_phys; i++) {
1520                                 if ((!parent->phy_info[i].rphy) ||
1521                                     (parent->phy_info[i].attached.sas_address !=
1522                                    port_info->phy_info[i].identify.sas_address))
1523                                         continue;
1524                                 sas_rphy_delete(parent->phy_info[i].rphy);
1525                                 memset(&parent->phy_info[i].attached, 0,
1526                                     sizeof(struct mptsas_devinfo));
1527                                 parent->phy_info[i].rphy = NULL;
1528                                 parent->phy_info[i].starget = NULL;
1529                         }
1530  next_port:
1531                         list_del(&port_info->list);
1532                         if (port_info->phy_info)
1533                                 kfree(port_info->phy_info);
1534                         kfree(port_info);
1535                 }
1536                 /*
1537                 * Free this memory allocated from inside
1538                 * mptsas_sas_expander_pg0
1539                 */
1540                 if (buffer.phy_info)
1541                         kfree(buffer.phy_info);
1542         }
1543         mutex_unlock(&ioc->sas_topology_mutex);
1544 }
1545
1546 /*
1547  * Start of day discovery
1548  */
1549 static void
1550 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1551 {
1552         u32 handle = 0xFFFF;
1553         int i;
1554
1555         mutex_lock(&ioc->sas_discovery_mutex);
1556         mptsas_probe_hba_phys(ioc);
1557         while (!mptsas_probe_expander_phys(ioc, &handle))
1558                 ;
1559         /*
1560           Reporting RAID volumes.
1561         */
1562         if (!ioc->raid_data.pIocPg2)
1563                 goto out;
1564         if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
1565                 goto out;
1566         for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
1567                 scsi_add_device(ioc->sh, ioc->num_ports,
1568                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
1569         }
1570  out:
1571         mutex_unlock(&ioc->sas_discovery_mutex);
1572 }
1573
1574 /*
1575  * Work queue thread to handle Runtime discovery
1576  * Mere purpose is the hot add/delete of expanders
1577  */
1578 static void
1579 mptscsih_discovery_work(void * arg)
1580 {
1581         struct mptsas_discovery_event *ev = arg;
1582         MPT_ADAPTER *ioc = ev->ioc;
1583         u32 handle = 0xFFFF;
1584
1585         mutex_lock(&ioc->sas_discovery_mutex);
1586         ioc->sas_discovery_runtime=1;
1587         mptsas_delete_expander_phys(ioc);
1588         mptsas_probe_hba_phys(ioc);
1589         while (!mptsas_probe_expander_phys(ioc, &handle))
1590                 ;
1591         kfree(ev);
1592         ioc->sas_discovery_runtime=0;
1593         mutex_unlock(&ioc->sas_discovery_mutex);
1594 }
1595
1596 static struct mptsas_phyinfo *
1597 mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id)
1598 {
1599         struct mptsas_portinfo *port_info;
1600         struct mptsas_devinfo device_info;
1601         struct mptsas_phyinfo *phy_info = NULL;
1602         int i, error;
1603
1604         /*
1605          * Retrieve the parent sas_address
1606          */
1607         error = mptsas_sas_device_pg0(ioc, &device_info,
1608                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1609                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1610                 parent_handle);
1611         if (error)
1612                 return NULL;
1613
1614         /*
1615          * The phy_info structures are never deallocated during lifetime of
1616          * a host, so the code below is safe without additional refcounting.
1617          */
1618         mutex_lock(&ioc->sas_topology_mutex);
1619         list_for_each_entry(port_info, &ioc->sas_topology, list) {
1620                 for (i = 0; i < port_info->num_phys; i++) {
1621                         if (port_info->phy_info[i].identify.sas_address ==
1622                             device_info.sas_address &&
1623                             port_info->phy_info[i].phy_id == phy_id) {
1624                                 phy_info = &port_info->phy_info[i];
1625                                 break;
1626                         }
1627                 }
1628         }
1629         mutex_unlock(&ioc->sas_topology_mutex);
1630
1631         return phy_info;
1632 }
1633
1634 static struct mptsas_phyinfo *
1635 mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
1636 {
1637         struct mptsas_portinfo *port_info;
1638         struct mptsas_phyinfo *phy_info = NULL;
1639         int i;
1640
1641         /*
1642          * The phy_info structures are never deallocated during lifetime of
1643          * a host, so the code below is safe without additional refcounting.
1644          */
1645         mutex_lock(&ioc->sas_topology_mutex);
1646         list_for_each_entry(port_info, &ioc->sas_topology, list) {
1647                 for (i = 0; i < port_info->num_phys; i++)
1648                         if (mptsas_is_end_device(&port_info->phy_info[i].attached))
1649                                 if (port_info->phy_info[i].attached.id == id) {
1650                                         phy_info = &port_info->phy_info[i];
1651                                         break;
1652                                 }
1653         }
1654         mutex_unlock(&ioc->sas_topology_mutex);
1655
1656         return phy_info;
1657 }
1658
1659 /*
1660  * Work queue thread to clear the persitency table
1661  */
1662 static void
1663 mptscsih_sas_persist_clear_table(void * arg)
1664 {
1665         MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
1666
1667         mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
1668 }
1669
1670 static void
1671 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
1672 {
1673         sdev->no_uld_attach = data ? 1 : 0;
1674         scsi_device_reprobe(sdev);
1675 }
1676
1677 static void
1678 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
1679 {
1680         starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
1681                         mptsas_reprobe_lun);
1682 }
1683
1684
1685 /*
1686  * Work queue thread to handle SAS hotplug events
1687  */
1688 static void
1689 mptsas_hotplug_work(void *arg)
1690 {
1691         struct mptsas_hotplug_event *ev = arg;
1692         MPT_ADAPTER *ioc = ev->ioc;
1693         struct mptsas_phyinfo *phy_info;
1694         struct sas_rphy *rphy;
1695         struct scsi_device *sdev;
1696         struct sas_identify identify;
1697         char *ds = NULL;
1698         struct mptsas_devinfo sas_device;
1699         VirtTarget *vtarget;
1700
1701         mutex_lock(&ioc->sas_discovery_mutex);
1702
1703         switch (ev->event_type) {
1704         case MPTSAS_DEL_DEVICE:
1705
1706                 phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id);
1707
1708                 /*
1709                  * Sanity checks, for non-existing phys and remote rphys.
1710                  */
1711                 if (!phy_info)
1712                         break;
1713                 if (!phy_info->rphy)
1714                         break;
1715                 if (phy_info->starget) {
1716                         vtarget = phy_info->starget->hostdata;
1717
1718                         if (!vtarget)
1719                                 break;
1720                         /*
1721                          * Handling  RAID components
1722                          */
1723                         if (ev->phys_disk_num_valid) {
1724                                 vtarget->target_id = ev->phys_disk_num;
1725                                 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
1726                                 mptsas_reprobe_target(vtarget->starget, 1);
1727                                 break;
1728                         }
1729                 }
1730
1731                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1732                         ds = "ssp";
1733                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
1734                         ds = "stp";
1735                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1736                         ds = "sata";
1737
1738                 printk(MYIOC_s_INFO_FMT
1739                        "removing %s device, channel %d, id %d, phy %d\n",
1740                        ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
1741
1742                 sas_rphy_delete(phy_info->rphy);
1743                 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
1744                 phy_info->rphy = NULL;
1745                 phy_info->starget = NULL;
1746                 break;
1747         case MPTSAS_ADD_DEVICE:
1748
1749                 if (ev->phys_disk_num_valid)
1750                         mpt_findImVolumes(ioc);
1751
1752                 /*
1753                  * Refresh sas device pg0 data
1754                  */
1755                 if (mptsas_sas_device_pg0(ioc, &sas_device,
1756                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
1757                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id))
1758                         break;
1759
1760                 phy_info = mptsas_find_phyinfo_by_parent(ioc,
1761                                 sas_device.handle_parent, sas_device.phy_id);
1762
1763                 if (!phy_info) {
1764                         u32 handle = 0xFFFF;
1765
1766                         /*
1767                         * Its possible when an expander has been hot added
1768                         * containing attached devices, the sas firmware
1769                         * may send a RC_ADDED event prior to the
1770                         * DISCOVERY STOP event. If that occurs, our
1771                         * view of the topology in the driver in respect to this
1772                         * expander might of not been setup, and we hit this
1773                         * condition.
1774                         * Therefore, this code kicks off discovery to
1775                         * refresh the data.
1776                         * Then again, we check whether the parent phy has
1777                         * been created.
1778                         */
1779                         ioc->sas_discovery_runtime=1;
1780                         mptsas_delete_expander_phys(ioc);
1781                         mptsas_probe_hba_phys(ioc);
1782                         while (!mptsas_probe_expander_phys(ioc, &handle))
1783                                 ;
1784                         ioc->sas_discovery_runtime=0;
1785
1786                         phy_info = mptsas_find_phyinfo_by_parent(ioc,
1787                                 sas_device.handle_parent, sas_device.phy_id);
1788                         if (!phy_info)
1789                                 break;
1790                 }
1791
1792                 if (phy_info->starget) {
1793                         vtarget = phy_info->starget->hostdata;
1794
1795                         if (!vtarget)
1796                                 break;
1797                         /*
1798                          * Handling  RAID components
1799                          */
1800                         if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1801                                 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
1802                                 vtarget->target_id = ev->id;
1803                                 mptsas_reprobe_target(phy_info->starget, 0);
1804                         }
1805                         break;
1806                 }
1807
1808                 if (phy_info->rphy)
1809                         break;
1810
1811                 memcpy(&phy_info->attached, &sas_device,
1812                     sizeof(struct mptsas_devinfo));
1813
1814                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1815                         ds = "ssp";
1816                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
1817                         ds = "stp";
1818                 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1819                         ds = "sata";
1820
1821                 printk(MYIOC_s_INFO_FMT
1822                        "attaching %s device, channel %d, id %d, phy %d\n",
1823                        ioc->name, ds, ev->channel, ev->id, ev->phy_id);
1824
1825                 mptsas_parse_device_info(&identify, &phy_info->attached);
1826                 switch (identify.device_type) {
1827                 case SAS_END_DEVICE:
1828                         rphy = sas_end_device_alloc(phy_info->phy);
1829                         break;
1830                 case SAS_EDGE_EXPANDER_DEVICE:
1831                 case SAS_FANOUT_EXPANDER_DEVICE:
1832                         rphy = sas_expander_alloc(phy_info->phy, identify.device_type);
1833                         break;
1834                 default:
1835                         rphy = NULL;
1836                         break;
1837                 }
1838                 if (!rphy)
1839                         break; /* non-fatal: an rphy can be added later */
1840
1841                 rphy->identify = identify;
1842                 if (sas_rphy_add(rphy)) {
1843                         sas_rphy_free(rphy);
1844                         break;
1845                 }
1846
1847                 phy_info->rphy = rphy;
1848                 break;
1849         case MPTSAS_ADD_RAID:
1850                 sdev = scsi_device_lookup(
1851                         ioc->sh,
1852                         ioc->num_ports,
1853                         ev->id,
1854                         0);
1855                 if (sdev) {
1856                         scsi_device_put(sdev);
1857                         break;
1858                 }
1859                 printk(MYIOC_s_INFO_FMT
1860                        "attaching raid volume, channel %d, id %d\n",
1861                        ioc->name, ioc->num_ports, ev->id);
1862                 scsi_add_device(ioc->sh,
1863                         ioc->num_ports,
1864                         ev->id,
1865                         0);
1866                 mpt_findImVolumes(ioc);
1867                 break;
1868         case MPTSAS_DEL_RAID:
1869                 sdev = scsi_device_lookup(
1870                         ioc->sh,
1871                         ioc->num_ports,
1872                         ev->id,
1873                         0);
1874                 if (!sdev)
1875                         break;
1876                 printk(MYIOC_s_INFO_FMT
1877                        "removing raid volume, channel %d, id %d\n",
1878                        ioc->name, ioc->num_ports, ev->id);
1879                 scsi_remove_device(sdev);
1880                 scsi_device_put(sdev);
1881                 mpt_findImVolumes(ioc);
1882                 break;
1883         case MPTSAS_IGNORE_EVENT:
1884         default:
1885                 break;
1886         }
1887
1888         kfree(ev);
1889         mutex_unlock(&ioc->sas_discovery_mutex);
1890 }
1891
1892 static void
1893 mptscsih_send_sas_event(MPT_ADAPTER *ioc,
1894                 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1895 {
1896         struct mptsas_hotplug_event *ev;
1897         u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
1898         __le64 sas_address;
1899
1900         if ((device_info &
1901              (MPI_SAS_DEVICE_INFO_SSP_TARGET |
1902               MPI_SAS_DEVICE_INFO_STP_TARGET |
1903               MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
1904                 return;
1905
1906         switch (sas_event_data->ReasonCode) {
1907         case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
1908         case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
1909                 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1910                 if (!ev) {
1911                         printk(KERN_WARNING "mptsas: lost hotplug event\n");
1912                         break;
1913                 }
1914
1915                 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1916                 ev->ioc = ioc;
1917                 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
1918                 ev->parent_handle =
1919                     le16_to_cpu(sas_event_data->ParentDevHandle);
1920                 ev->channel = sas_event_data->Bus;
1921                 ev->id = sas_event_data->TargetID;
1922                 ev->phy_id = sas_event_data->PhyNum;
1923                 memcpy(&sas_address, &sas_event_data->SASAddress,
1924                     sizeof(__le64));
1925                 ev->sas_address = le64_to_cpu(sas_address);
1926                 ev->device_info = device_info;
1927
1928                 if (sas_event_data->ReasonCode &
1929                     MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
1930                         ev->event_type = MPTSAS_ADD_DEVICE;
1931                 else
1932                         ev->event_type = MPTSAS_DEL_DEVICE;
1933                 schedule_work(&ev->work);
1934                 break;
1935         case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
1936         /*
1937          * Persistent table is full.
1938          */
1939                 INIT_WORK(&ioc->mptscsih_persistTask,
1940                     mptscsih_sas_persist_clear_table,
1941                     (void *)ioc);
1942                 schedule_work(&ioc->mptscsih_persistTask);
1943                 break;
1944         case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
1945         /* TODO */
1946         case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
1947         /* TODO */
1948         default:
1949                 break;
1950         }
1951 }
1952
1953 static void
1954 mptscsih_send_raid_event(MPT_ADAPTER *ioc,
1955                 EVENT_DATA_RAID *raid_event_data)
1956 {
1957         struct mptsas_hotplug_event *ev;
1958         int status = le32_to_cpu(raid_event_data->SettingsStatus);
1959         int state = (status >> 8) & 0xff;
1960
1961         if (ioc->bus_type != SAS)
1962                 return;
1963
1964         ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1965         if (!ev) {
1966                 printk(KERN_WARNING "mptsas: lost hotplug event\n");
1967                 return;
1968         }
1969
1970         memset(ev,0,sizeof(struct mptsas_hotplug_event));
1971         INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1972         ev->ioc = ioc;
1973         ev->id = raid_event_data->VolumeID;
1974         ev->event_type = MPTSAS_IGNORE_EVENT;
1975
1976         switch (raid_event_data->ReasonCode) {
1977         case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
1978                 ev->event_type = MPTSAS_ADD_DEVICE;
1979                 break;
1980         case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
1981                 ioc->raid_data.isRaid = 1;
1982                 ev->phys_disk_num_valid = 1;
1983                 ev->phys_disk_num = raid_event_data->PhysDiskNum;
1984                 ev->event_type = MPTSAS_DEL_DEVICE;
1985                 break;
1986         case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
1987                 switch (state) {
1988                 case MPI_PD_STATE_ONLINE:
1989                         ioc->raid_data.isRaid = 1;
1990                         ev->phys_disk_num_valid = 1;
1991                         ev->phys_disk_num = raid_event_data->PhysDiskNum;
1992                         ev->event_type = MPTSAS_ADD_DEVICE;
1993                         break;
1994                 case MPI_PD_STATE_MISSING:
1995                 case MPI_PD_STATE_NOT_COMPATIBLE:
1996                 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
1997                 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
1998                 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
1999                         ev->event_type = MPTSAS_DEL_DEVICE;
2000                         break;
2001                 default:
2002                         break;
2003                 }
2004                 break;
2005         case MPI_EVENT_RAID_RC_VOLUME_DELETED:
2006                 ev->event_type = MPTSAS_DEL_RAID;
2007                 break;
2008         case MPI_EVENT_RAID_RC_VOLUME_CREATED:
2009                 ev->event_type = MPTSAS_ADD_RAID;
2010                 break;
2011         case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
2012                 switch (state) {
2013                 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
2014                 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
2015                         ev->event_type = MPTSAS_DEL_RAID;
2016                         break;
2017                 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
2018                 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
2019                         ev->event_type = MPTSAS_ADD_RAID;
2020                         break;
2021                 default:
2022                         break;
2023                 }
2024                 break;
2025         default:
2026                 break;
2027         }
2028         schedule_work(&ev->work);
2029 }
2030
2031 static void
2032 mptscsih_send_discovery(MPT_ADAPTER *ioc,
2033         EVENT_DATA_SAS_DISCOVERY *discovery_data)
2034 {
2035         struct mptsas_discovery_event *ev;
2036
2037         /*
2038          * DiscoveryStatus
2039          *
2040          * This flag will be non-zero when firmware
2041          * kicks off discovery, and return to zero
2042          * once its completed.
2043          */
2044         if (discovery_data->DiscoveryStatus)
2045                 return;
2046
2047         ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
2048         if (!ev)
2049                 return;
2050         memset(ev,0,sizeof(struct mptsas_discovery_event));
2051         INIT_WORK(&ev->work, mptscsih_discovery_work, ev);
2052         ev->ioc = ioc;
2053         schedule_work(&ev->work);
2054 };
2055
2056
2057 static int
2058 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
2059 {
2060         int rc=1;
2061         u8 event = le32_to_cpu(reply->Event) & 0xFF;
2062
2063         if (!ioc->sh)
2064                 goto out;
2065
2066         /*
2067          * sas_discovery_ignore_events
2068          *
2069          * This flag is to prevent anymore processing of
2070          * sas events once mptsas_remove function is called.
2071          */
2072         if (ioc->sas_discovery_ignore_events) {
2073                 rc = mptscsih_event_process(ioc, reply);
2074                 goto out;
2075         }
2076
2077         switch (event) {
2078         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
2079                 mptscsih_send_sas_event(ioc,
2080                         (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
2081                 break;
2082         case MPI_EVENT_INTEGRATED_RAID:
2083                 mptscsih_send_raid_event(ioc,
2084                         (EVENT_DATA_RAID *)reply->Data);
2085                 break;
2086         case MPI_EVENT_PERSISTENT_TABLE_FULL:
2087                 INIT_WORK(&ioc->mptscsih_persistTask,
2088                     mptscsih_sas_persist_clear_table,
2089                     (void *)ioc);
2090                 schedule_work(&ioc->mptscsih_persistTask);
2091                 break;
2092          case MPI_EVENT_SAS_DISCOVERY:
2093                 mptscsih_send_discovery(ioc,
2094                         (EVENT_DATA_SAS_DISCOVERY *)reply->Data);
2095                 break;
2096         default:
2097                 rc = mptscsih_event_process(ioc, reply);
2098                 break;
2099         }
2100  out:
2101
2102         return rc;
2103 }
2104
2105 static int
2106 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2107 {
2108         struct Scsi_Host        *sh;
2109         MPT_SCSI_HOST           *hd;
2110         MPT_ADAPTER             *ioc;
2111         unsigned long            flags;
2112         int                      ii;
2113         int                      numSGE = 0;
2114         int                      scale;
2115         int                      ioc_cap;
2116         int                     error=0;
2117         int                     r;
2118
2119         r = mpt_attach(pdev,id);
2120         if (r)
2121                 return r;
2122
2123         ioc = pci_get_drvdata(pdev);
2124         ioc->DoneCtx = mptsasDoneCtx;
2125         ioc->TaskCtx = mptsasTaskCtx;
2126         ioc->InternalCtx = mptsasInternalCtx;
2127
2128         /*  Added sanity check on readiness of the MPT adapter.
2129          */
2130         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
2131                 printk(MYIOC_s_WARN_FMT
2132                   "Skipping because it's not operational!\n",
2133                   ioc->name);
2134                 error = -ENODEV;
2135                 goto out_mptsas_probe;
2136         }
2137
2138         if (!ioc->active) {
2139                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
2140                   ioc->name);
2141                 error = -ENODEV;
2142                 goto out_mptsas_probe;
2143         }
2144
2145         /*  Sanity check - ensure at least 1 port is INITIATOR capable
2146          */
2147         ioc_cap = 0;
2148         for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
2149                 if (ioc->pfacts[ii].ProtocolFlags &
2150                                 MPI_PORTFACTS_PROTOCOL_INITIATOR)
2151                         ioc_cap++;
2152         }
2153
2154         if (!ioc_cap) {
2155                 printk(MYIOC_s_WARN_FMT
2156                         "Skipping ioc=%p because SCSI Initiator mode "
2157                         "is NOT enabled!\n", ioc->name, ioc);
2158                 return 0;
2159         }
2160
2161         sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
2162         if (!sh) {
2163                 printk(MYIOC_s_WARN_FMT
2164                         "Unable to register controller with SCSI subsystem\n",
2165                         ioc->name);
2166                 error = -1;
2167                 goto out_mptsas_probe;
2168         }
2169
2170         spin_lock_irqsave(&ioc->FreeQlock, flags);
2171
2172         /* Attach the SCSI Host to the IOC structure
2173          */
2174         ioc->sh = sh;
2175
2176         sh->io_port = 0;
2177         sh->n_io_port = 0;
2178         sh->irq = 0;
2179
2180         /* set 16 byte cdb's */
2181         sh->max_cmd_len = 16;
2182
2183         sh->max_id = ioc->pfacts->MaxDevices + 1;
2184
2185         sh->transportt = mptsas_transport_template;
2186
2187         sh->max_lun = MPT_LAST_LUN + 1;
2188         sh->max_channel = 0;
2189         sh->this_id = ioc->pfacts[0].PortSCSIID;
2190
2191         /* Required entry.
2192          */
2193         sh->unique_id = ioc->id;
2194
2195         INIT_LIST_HEAD(&ioc->sas_topology);
2196         mutex_init(&ioc->sas_topology_mutex);
2197         mutex_init(&ioc->sas_discovery_mutex);
2198         mutex_init(&ioc->sas_mgmt.mutex);
2199         init_completion(&ioc->sas_mgmt.done);
2200
2201         /* Verify that we won't exceed the maximum
2202          * number of chain buffers
2203          * We can optimize:  ZZ = req_sz/sizeof(SGE)
2204          * For 32bit SGE's:
2205          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
2206          *               + (req_sz - 64)/sizeof(SGE)
2207          * A slightly different algorithm is required for
2208          * 64bit SGEs.
2209          */
2210         scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
2211         if (sizeof(dma_addr_t) == sizeof(u64)) {
2212                 numSGE = (scale - 1) *
2213                   (ioc->facts.MaxChainDepth-1) + scale +
2214                   (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
2215                   sizeof(u32));
2216         } else {
2217                 numSGE = 1 + (scale - 1) *
2218                   (ioc->facts.MaxChainDepth-1) + scale +
2219                   (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
2220                   sizeof(u32));
2221         }
2222
2223         if (numSGE < sh->sg_tablesize) {
2224                 /* Reset this value */
2225                 dprintk((MYIOC_s_INFO_FMT
2226                   "Resetting sg_tablesize to %d from %d\n",
2227                   ioc->name, numSGE, sh->sg_tablesize));
2228                 sh->sg_tablesize = numSGE;
2229         }
2230
2231         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2232
2233         hd = (MPT_SCSI_HOST *) sh->hostdata;
2234         hd->ioc = ioc;
2235
2236         /* SCSI needs scsi_cmnd lookup table!
2237          * (with size equal to req_depth*PtrSz!)
2238          */
2239         hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
2240         if (!hd->ScsiLookup) {
2241                 error = -ENOMEM;
2242                 goto out_mptsas_probe;
2243         }
2244
2245         dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
2246                  ioc->name, hd->ScsiLookup));
2247
2248         /* Allocate memory for the device structures.
2249          * A non-Null pointer at an offset
2250          * indicates a device exists.
2251          * max_id = 1 + maximum id (hosts.h)
2252          */
2253         hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
2254         if (!hd->Targets) {
2255                 error = -ENOMEM;
2256                 goto out_mptsas_probe;
2257         }
2258
2259         dprintk((KERN_INFO "  vtarget @ %p\n", hd->Targets));
2260
2261         /* Clear the TM flags
2262          */
2263         hd->tmPending = 0;
2264         hd->tmState = TM_STATE_NONE;
2265         hd->resetPending = 0;
2266         hd->abortSCpnt = NULL;
2267
2268         /* Clear the pointer used to store
2269          * single-threaded commands, i.e., those
2270          * issued during a bus scan, dv and
2271          * configuration pages.
2272          */
2273         hd->cmdPtr = NULL;
2274
2275         /* Initialize this SCSI Hosts' timers
2276          * To use, set the timer expires field
2277          * and add_timer
2278          */
2279         init_timer(&hd->timer);
2280         hd->timer.data = (unsigned long) hd;
2281         hd->timer.function = mptscsih_timer_expired;
2282
2283         hd->mpt_pq_filter = mpt_pq_filter;
2284         ioc->sas_data.ptClear = mpt_pt_clear;
2285
2286         if (ioc->sas_data.ptClear==1) {
2287                 mptbase_sas_persist_operation(
2288                     ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
2289         }
2290
2291         ddvprintk((MYIOC_s_INFO_FMT
2292                 "mpt_pq_filter %x mpt_pq_filter %x\n",
2293                 ioc->name,
2294                 mpt_pq_filter,
2295                 mpt_pq_filter));
2296
2297         init_waitqueue_head(&hd->scandv_waitq);
2298         hd->scandv_wait_done = 0;
2299         hd->last_queue_full = 0;
2300
2301         error = scsi_add_host(sh, &ioc->pcidev->dev);
2302         if (error) {
2303                 dprintk((KERN_ERR MYNAM
2304                   "scsi_add_host failed\n"));
2305                 goto out_mptsas_probe;
2306         }
2307
2308         mptsas_scan_sas_topology(ioc);
2309
2310         return 0;
2311
2312 out_mptsas_probe:
2313
2314         mptscsih_remove(pdev);
2315         return error;
2316 }
2317
2318 static void __devexit mptsas_remove(struct pci_dev *pdev)
2319 {
2320         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2321         struct mptsas_portinfo *p, *n;
2322
2323         ioc->sas_discovery_ignore_events=1;
2324         sas_remove_host(ioc->sh);
2325
2326         mutex_lock(&ioc->sas_topology_mutex);
2327         list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
2328                 list_del(&p->list);
2329                 if (p->phy_info)
2330                         kfree(p->phy_info);
2331                 kfree(p);
2332         }
2333         mutex_unlock(&ioc->sas_topology_mutex);
2334
2335         mptscsih_remove(pdev);
2336 }
2337
2338 static struct pci_device_id mptsas_pci_table[] = {
2339         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
2340                 PCI_ANY_ID, PCI_ANY_ID },
2341         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
2342                 PCI_ANY_ID, PCI_ANY_ID },
2343         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
2344                 PCI_ANY_ID, PCI_ANY_ID },
2345         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
2346                 PCI_ANY_ID, PCI_ANY_ID },
2347         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
2348                 PCI_ANY_ID, PCI_ANY_ID },
2349         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
2350                 PCI_ANY_ID, PCI_ANY_ID },
2351         {0}     /* Terminating entry */
2352 };
2353 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
2354
2355
2356 static struct pci_driver mptsas_driver = {
2357         .name           = "mptsas",
2358         .id_table       = mptsas_pci_table,
2359         .probe          = mptsas_probe,
2360         .remove         = __devexit_p(mptsas_remove),
2361         .shutdown       = mptscsih_shutdown,
2362 #ifdef CONFIG_PM
2363         .suspend        = mptscsih_suspend,
2364         .resume         = mptscsih_resume,
2365 #endif
2366 };
2367
2368 static int __init
2369 mptsas_init(void)
2370 {
2371         show_mptmod_ver(my_NAME, my_VERSION);
2372
2373         mptsas_transport_template =
2374             sas_attach_transport(&mptsas_transport_functions);
2375         if (!mptsas_transport_template)
2376                 return -ENODEV;
2377
2378         mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
2379         mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
2380         mptsasInternalCtx =
2381                 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
2382         mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
2383
2384         if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) {
2385                 devtverboseprintk((KERN_INFO MYNAM
2386                   ": Registered for IOC event notifications\n"));
2387         }
2388
2389         if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
2390                 dprintk((KERN_INFO MYNAM
2391                   ": Registered for IOC reset notifications\n"));
2392         }
2393
2394         return pci_register_driver(&mptsas_driver);
2395 }
2396
2397 static void __exit
2398 mptsas_exit(void)
2399 {
2400         pci_unregister_driver(&mptsas_driver);
2401         sas_release_transport(mptsas_transport_template);
2402
2403         mpt_reset_deregister(mptsasDoneCtx);
2404         mpt_event_deregister(mptsasDoneCtx);
2405
2406         mpt_deregister(mptsasMgmtCtx);
2407         mpt_deregister(mptsasInternalCtx);
2408         mpt_deregister(mptsasTaskCtx);
2409         mpt_deregister(mptsasDoneCtx);
2410 }
2411
2412 module_init(mptsas_init);
2413 module_exit(mptsas_exit);