[SCSI] fusion SAS support (mptsas driver) updates
[linux-2.6.git] / drivers / message / fusion / mptsas.c
1 /*
2  *  linux/drivers/message/fusion/mptsas.c
3  *      For use with LSI Logic PCI chip/adapter(s)
4  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5  *
6  *  Copyright (c) 1999-2005 LSI Logic Corporation
7  *  (mailto:mpt_linux_developer@lsil.com)
8  *  Copyright (c) 2005 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
87
88 /*
89  * SAS topology structures
90  *
91  * The MPT Fusion firmware interface spreads information about the
92  * SAS topology over many manufacture pages, thus we need some data
93  * structure to collect it and process it for the SAS transport class.
94  */
95
96 struct mptsas_devinfo {
97         u16     handle;         /* unique id to address this device */
98         u8      phy_id;         /* phy number of parent device */
99         u8      port_id;        /* sas physical port this device
100                                    is assoc'd with */
101         u8      target;         /* logical target id of this device */
102         u8      bus;            /* logical bus number of this device */
103         u64     sas_address;    /* WWN of this device,
104                                    SATA is assigned by HBA,expander */
105         u32     device_info;    /* bitfield detailed info about this device */
106 };
107
108 struct mptsas_phyinfo {
109         u8      phy_id;                 /* phy index */
110         u8      port_id;                /* port number this phy is part of */
111         u8      negotiated_link_rate;   /* nego'd link rate for this phy */
112         u8      hw_link_rate;           /* hardware max/min phys link rate */
113         u8      programmed_link_rate;   /* programmed max/min phy link rate */
114         struct mptsas_devinfo identify; /* point to phy device info */
115         struct mptsas_devinfo attached; /* point to attached device info */
116         struct sas_rphy *rphy;
117 };
118
119 struct mptsas_portinfo {
120         struct list_head list;
121         u16             handle;         /* unique id to address this */
122         u8              num_phys;       /* number of phys */
123         struct mptsas_phyinfo *phy_info;
124 };
125
126 /*
127  * This is pretty ugly.  We will be able to seriously clean it up
128  * once the DV code in mptscsih goes away and we can properly
129  * implement ->target_alloc.
130  */
131 static int
132 mptsas_slave_alloc(struct scsi_device *device)
133 {
134         struct Scsi_Host        *host = device->host;
135         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
136         struct sas_rphy         *rphy;
137         struct mptsas_portinfo  *p;
138         VirtDevice              *vdev;
139         uint                    target = device->id;
140         int i;
141
142         if ((vdev = hd->Targets[target]) != NULL)
143                 goto out;
144
145         vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
146         if (!vdev) {
147                 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
148                                 hd->ioc->name, sizeof(VirtDevice));
149                 return -ENOMEM;
150         }
151
152         memset(vdev, 0, sizeof(VirtDevice));
153         vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
154         vdev->ioc_id = hd->ioc->id;
155
156         rphy = dev_to_rphy(device->sdev_target->dev.parent);
157         list_for_each_entry(p, &hd->ioc->sas_topology, list) {
158                 for (i = 0; i < p->num_phys; i++) {
159                         if (p->phy_info[i].attached.sas_address ==
160                                         rphy->identify.sas_address) {
161                                 vdev->target_id =
162                                         p->phy_info[i].attached.target;
163                                 vdev->bus_id = p->phy_info[i].attached.bus;
164                                 hd->Targets[device->id] = vdev;
165                                 goto out;
166                         }
167                 }
168         }
169
170         printk("No matching SAS device found!!\n");
171         kfree(vdev);
172         return -ENODEV;
173
174  out:
175         vdev->num_luns++;
176         device->hostdata = vdev;
177         return 0;
178 }
179
180 static struct scsi_host_template mptsas_driver_template = {
181         .proc_name                      = "mptsas",
182         .proc_info                      = mptscsih_proc_info,
183         .name                           = "MPT SPI Host",
184         .info                           = mptscsih_info,
185         .queuecommand                   = mptscsih_qcmd,
186         .slave_alloc                    = mptsas_slave_alloc,
187         .slave_configure                = mptscsih_slave_configure,
188         .slave_destroy                  = mptscsih_slave_destroy,
189         .change_queue_depth             = mptscsih_change_queue_depth,
190         .eh_abort_handler               = mptscsih_abort,
191         .eh_device_reset_handler        = mptscsih_dev_reset,
192         .eh_bus_reset_handler           = mptscsih_bus_reset,
193         .eh_host_reset_handler          = mptscsih_host_reset,
194         .bios_param                     = mptscsih_bios_param,
195         .can_queue                      = MPT_FC_CAN_QUEUE,
196         .this_id                        = -1,
197         .sg_tablesize                   = MPT_SCSI_SG_DEPTH,
198         .max_sectors                    = 8192,
199         .cmd_per_lun                    = 7,
200         .use_clustering                 = ENABLE_CLUSTERING,
201 };
202
203 static struct sas_function_template mptsas_transport_functions = {
204 };
205
206 static struct scsi_transport_template *mptsas_transport_template;
207
208 #ifdef SASDEBUG
209 static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
210 {
211         printk("---- IO UNIT PAGE 0 ------------\n");
212         printk("Handle=0x%X\n",
213                 le16_to_cpu(phy_data->AttachedDeviceHandle));
214         printk("Controller Handle=0x%X\n",
215                 le16_to_cpu(phy_data->ControllerDevHandle));
216         printk("Port=0x%X\n", phy_data->Port);
217         printk("Port Flags=0x%X\n", phy_data->PortFlags);
218         printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
219         printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
220         printk("Controller PHY Device Info=0x%X\n",
221                 le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
222         printk("DiscoveryStatus=0x%X\n",
223                 le32_to_cpu(phy_data->DiscoveryStatus));
224         printk("\n");
225 }
226
227 static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
228 {
229         __le64 sas_address;
230
231         memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
232
233         printk("---- SAS PHY PAGE 0 ------------\n");
234         printk("Attached Device Handle=0x%X\n",
235                         le16_to_cpu(pg0->AttachedDevHandle));
236         printk("SAS Address=0x%llX\n",
237                         (unsigned long long)le64_to_cpu(sas_address));
238         printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
239         printk("Attached Device Info=0x%X\n",
240                         le32_to_cpu(pg0->AttachedDeviceInfo));
241         printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
242         printk("Change Count=0x%X\n", pg0->ChangeCount);
243         printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
244         printk("\n");
245 }
246
247 static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
248 {
249         __le64 sas_address;
250
251         memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
252
253         printk("---- SAS DEVICE PAGE 0 ---------\n");
254         printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
255         printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
256         printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
257         printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
258         printk("Target ID=0x%X\n", pg0->TargetID);
259         printk("Bus=0x%X\n", pg0->Bus);
260         printk("PhyNum=0x%X\n", pg0->PhyNum);
261         printk("AccessStatus=0x%X\n", le16_to_cpu(pg0->AccessStatus));
262         printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
263         printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
264         printk("Physical Port=0x%X\n", pg0->PhysicalPort);
265         printk("\n");
266 }
267
268 static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
269 {
270         printk("---- SAS EXPANDER PAGE 1 ------------\n");
271
272         printk("Physical Port=0x%X\n", pg1->PhysicalPort);
273         printk("PHY Identifier=0x%X\n", pg1->Phy);
274         printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
275         printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
276         printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
277         printk("Owner Device Handle=0x%X\n",
278                         le16_to_cpu(pg1->OwnerDevHandle));
279         printk("Attached Device Handle=0x%X\n",
280                         le16_to_cpu(pg1->AttachedDevHandle));
281 }
282 #else
283 #define mptsas_print_phy_data(phy_data)         do { } while (0)
284 #define mptsas_print_phy_pg0(pg0)               do { } while (0)
285 #define mptsas_print_device_pg0(pg0)            do { } while (0)
286 #define mptsas_print_expander_pg1(pg1)          do { } while (0)
287 #endif
288
289 static int
290 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
291 {
292         ConfigExtendedPageHeader_t hdr;
293         CONFIGPARMS cfg;
294         SasIOUnitPage0_t *buffer;
295         dma_addr_t dma_handle;
296         int error, i;
297
298         hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
299         hdr.ExtPageLength = 0;
300         hdr.PageNumber = 0;
301         hdr.Reserved1 = 0;
302         hdr.Reserved2 = 0;
303         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
304         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
305
306         cfg.cfghdr.ehdr = &hdr;
307         cfg.physAddr = -1;
308         cfg.pageAddr = 0;
309         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
310         cfg.dir = 0;    /* read */
311         cfg.timeout = 10;
312
313         error = mpt_config(ioc, &cfg);
314         if (error)
315                 goto out;
316         if (!hdr.ExtPageLength) {
317                 error = -ENXIO;
318                 goto out;
319         }
320
321         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
322                                             &dma_handle);
323         if (!buffer) {
324                 error = -ENOMEM;
325                 goto out;
326         }
327
328         cfg.physAddr = dma_handle;
329         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
330
331         error = mpt_config(ioc, &cfg);
332         if (error)
333                 goto out_free_consistent;
334
335         port_info->num_phys = buffer->NumPhys;
336         port_info->phy_info = kcalloc(port_info->num_phys,
337                 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
338         if (!port_info->phy_info) {
339                 error = -ENOMEM;
340                 goto out_free_consistent;
341         }
342
343         for (i = 0; i < port_info->num_phys; i++) {
344                 mptsas_print_phy_data(&buffer->PhyData[i]);
345                 port_info->phy_info[i].phy_id = i;
346                 port_info->phy_info[i].port_id =
347                     buffer->PhyData[i].Port;
348                 port_info->phy_info[i].negotiated_link_rate =
349                     buffer->PhyData[i].NegotiatedLinkRate;
350         }
351
352  out_free_consistent:
353         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
354                             buffer, dma_handle);
355  out:
356         return error;
357 }
358
359 static int
360 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
361                 u32 form, u32 form_specific)
362 {
363         ConfigExtendedPageHeader_t hdr;
364         CONFIGPARMS cfg;
365         SasPhyPage0_t *buffer;
366         dma_addr_t dma_handle;
367         int error;
368
369         hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
370         hdr.ExtPageLength = 0;
371         hdr.PageNumber = 0;
372         hdr.Reserved1 = 0;
373         hdr.Reserved2 = 0;
374         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
375         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
376
377         cfg.cfghdr.ehdr = &hdr;
378         cfg.dir = 0;    /* read */
379         cfg.timeout = 10;
380
381         /* Get Phy Pg 0 for each Phy. */
382         cfg.physAddr = -1;
383         cfg.pageAddr = form + form_specific;
384         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
385
386         error = mpt_config(ioc, &cfg);
387         if (error)
388                 goto out;
389
390         if (!hdr.ExtPageLength) {
391                 error = -ENXIO;
392                 goto out;
393         }
394
395         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
396                                       &dma_handle);
397         if (!buffer) {
398                 error = -ENOMEM;
399                 goto out;
400         }
401
402         cfg.physAddr = dma_handle;
403         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
404
405         error = mpt_config(ioc, &cfg);
406         if (error)
407                 goto out_free_consistent;
408
409         mptsas_print_phy_pg0(buffer);
410
411         phy_info->hw_link_rate = buffer->HwLinkRate;
412         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
413         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
414         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
415
416  out_free_consistent:
417         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
418                             buffer, dma_handle);
419  out:
420         return error;
421 }
422
423 static int
424 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
425                 u32 form, u32 form_specific)
426 {
427         ConfigExtendedPageHeader_t hdr;
428         CONFIGPARMS cfg;
429         SasDevicePage0_t *buffer;
430         dma_addr_t dma_handle;
431         __le64 sas_address;
432         int error;
433
434         hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
435         hdr.ExtPageLength = 0;
436         hdr.PageNumber = 0;
437         hdr.Reserved1 = 0;
438         hdr.Reserved2 = 0;
439         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
440         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
441
442         cfg.cfghdr.ehdr = &hdr;
443         cfg.pageAddr = form + form_specific;
444         cfg.physAddr = -1;
445         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
446         cfg.dir = 0;    /* read */
447         cfg.timeout = 10;
448
449         error = mpt_config(ioc, &cfg);
450         if (error)
451                 goto out;
452         if (!hdr.ExtPageLength) {
453                 error = -ENXIO;
454                 goto out;
455         }
456
457         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
458                                       &dma_handle);
459         if (!buffer) {
460                 error = -ENOMEM;
461                 goto out;
462         }
463
464         cfg.physAddr = dma_handle;
465         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
466
467         error = mpt_config(ioc, &cfg);
468         if (error)
469                 goto out_free_consistent;
470
471         mptsas_print_device_pg0(buffer);
472
473         device_info->handle = le16_to_cpu(buffer->DevHandle);
474         device_info->phy_id = buffer->PhyNum;
475         device_info->port_id = buffer->PhysicalPort;
476         device_info->target = buffer->TargetID;
477         device_info->bus = buffer->Bus;
478         memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
479         device_info->sas_address = le64_to_cpu(sas_address);
480         device_info->device_info =
481             le32_to_cpu(buffer->DeviceInfo);
482
483  out_free_consistent:
484         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
485                             buffer, dma_handle);
486  out:
487         return error;
488 }
489
490 static int
491 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
492                 u32 form, u32 form_specific)
493 {
494         ConfigExtendedPageHeader_t hdr;
495         CONFIGPARMS cfg;
496         SasExpanderPage0_t *buffer;
497         dma_addr_t dma_handle;
498         int error;
499
500         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
501         hdr.ExtPageLength = 0;
502         hdr.PageNumber = 0;
503         hdr.Reserved1 = 0;
504         hdr.Reserved2 = 0;
505         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
506         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
507
508         cfg.cfghdr.ehdr = &hdr;
509         cfg.physAddr = -1;
510         cfg.pageAddr = form + form_specific;
511         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
512         cfg.dir = 0;    /* read */
513         cfg.timeout = 10;
514
515         error = mpt_config(ioc, &cfg);
516         if (error)
517                 goto out;
518
519         if (!hdr.ExtPageLength) {
520                 error = -ENXIO;
521                 goto out;
522         }
523
524         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
525                                       &dma_handle);
526         if (!buffer) {
527                 error = -ENOMEM;
528                 goto out;
529         }
530
531         cfg.physAddr = dma_handle;
532         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
533
534         error = mpt_config(ioc, &cfg);
535         if (error)
536                 goto out_free_consistent;
537
538         /* save config data */
539         port_info->num_phys = buffer->NumPhys;
540         port_info->handle = le16_to_cpu(buffer->DevHandle);
541         port_info->phy_info = kcalloc(port_info->num_phys,
542                 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
543         if (!port_info->phy_info) {
544                 error = -ENOMEM;
545                 goto out_free_consistent;
546         }
547
548  out_free_consistent:
549         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
550                             buffer, dma_handle);
551  out:
552         return error;
553 }
554
555 static int
556 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
557                 u32 form, u32 form_specific)
558 {
559         ConfigExtendedPageHeader_t hdr;
560         CONFIGPARMS cfg;
561         SasExpanderPage1_t *buffer;
562         dma_addr_t dma_handle;
563         int error;
564
565         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
566         hdr.ExtPageLength = 0;
567         hdr.PageNumber = 1;
568         hdr.Reserved1 = 0;
569         hdr.Reserved2 = 0;
570         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
571         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
572
573         cfg.cfghdr.ehdr = &hdr;
574         cfg.physAddr = -1;
575         cfg.pageAddr = form + form_specific;
576         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
577         cfg.dir = 0;    /* read */
578         cfg.timeout = 10;
579
580         error = mpt_config(ioc, &cfg);
581         if (error)
582                 goto out;
583
584         if (!hdr.ExtPageLength) {
585                 error = -ENXIO;
586                 goto out;
587         }
588
589         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
590                                       &dma_handle);
591         if (!buffer) {
592                 error = -ENOMEM;
593                 goto out;
594         }
595
596         cfg.physAddr = dma_handle;
597         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
598
599         error = mpt_config(ioc, &cfg);
600         if (error)
601                 goto out_free_consistent;
602
603
604         mptsas_print_expander_pg1(buffer);
605
606         /* save config data */
607         phy_info->phy_id = buffer->Phy;
608         phy_info->port_id = buffer->PhysicalPort;
609         phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
610         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
611         phy_info->hw_link_rate = buffer->HwLinkRate;
612         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
613         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
614
615
616  out_free_consistent:
617         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
618                             buffer, dma_handle);
619  out:
620         return error;
621 }
622
623 static void
624 mptsas_parse_device_info(struct sas_identify *identify,
625                 struct mptsas_devinfo *device_info)
626 {
627         u16 protocols;
628
629         identify->sas_address = device_info->sas_address;
630         identify->phy_identifier = device_info->phy_id;
631
632         /*
633          * Fill in Phy Initiator Port Protocol.
634          * Bits 6:3, more than one bit can be set, fall through cases.
635          */
636         protocols = device_info->device_info & 0x78;
637         identify->initiator_port_protocols = 0;
638         if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
639                 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
640         if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
641                 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
642         if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
643                 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
644         if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
645                 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
646
647         /*
648          * Fill in Phy Target Port Protocol.
649          * Bits 10:7, more than one bit can be set, fall through cases.
650          */
651         protocols = device_info->device_info & 0x780;
652         identify->target_port_protocols = 0;
653         if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
654                 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
655         if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
656                 identify->target_port_protocols |= SAS_PROTOCOL_STP;
657         if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
658                 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
659         if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
660                 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
661
662         /*
663          * Fill in Attached device type.
664          */
665         switch (device_info->device_info &
666                         MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
667         case MPI_SAS_DEVICE_INFO_NO_DEVICE:
668                 identify->device_type = SAS_PHY_UNUSED;
669                 break;
670         case MPI_SAS_DEVICE_INFO_END_DEVICE:
671                 identify->device_type = SAS_END_DEVICE;
672                 break;
673         case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
674                 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
675                 break;
676         case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
677                 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
678                 break;
679         }
680 }
681
682 static int mptsas_probe_one_phy(struct device *dev,
683                 struct mptsas_phyinfo *phy_info, int index)
684 {
685         struct sas_phy *port;
686         int error;
687
688         port = sas_phy_alloc(dev, index);
689         if (!port)
690                 return -ENOMEM;
691
692         port->port_identifier = phy_info->port_id;
693         mptsas_parse_device_info(&port->identify, &phy_info->identify);
694
695         /*
696          * Set Negotiated link rate.
697          */
698         switch (phy_info->negotiated_link_rate) {
699         case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
700                 port->negotiated_linkrate = SAS_PHY_DISABLED;
701                 break;
702         case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
703                 port->negotiated_linkrate = SAS_LINK_RATE_FAILED;
704                 break;
705         case MPI_SAS_IOUNIT0_RATE_1_5:
706                 port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
707                 break;
708         case MPI_SAS_IOUNIT0_RATE_3_0:
709                 port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
710                 break;
711         case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
712         case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
713         default:
714                 port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
715                 break;
716         }
717
718         /*
719          * Set Max hardware link rate.
720          */
721         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
722         case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
723                 port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
724                 break;
725         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
726                 port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
727                 break;
728         default:
729                 break;
730         }
731
732         /*
733          * Set Max programmed link rate.
734          */
735         switch (phy_info->programmed_link_rate &
736                         MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
737         case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
738                 port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
739                 break;
740         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
741                 port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
742                 break;
743         default:
744                 break;
745         }
746
747         /*
748          * Set Min hardware link rate.
749          */
750         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
751         case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
752                 port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
753                 break;
754         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
755                 port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
756                 break;
757         default:
758                 break;
759         }
760
761         /*
762          * Set Min programmed link rate.
763          */
764         switch (phy_info->programmed_link_rate &
765                         MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
766         case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
767                 port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
768                 break;
769         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
770                 port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
771                 break;
772         default:
773                 break;
774         }
775
776         error = sas_phy_add(port);
777         if (error) {
778                 sas_phy_free(port);
779                 return error;
780         }
781
782         if (phy_info->attached.handle) {
783                 struct sas_rphy *rphy;
784
785                 rphy = sas_rphy_alloc(port);
786                 if (!rphy)
787                         return 0; /* non-fatal: an rphy can be added later */
788
789                 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
790                 error = sas_rphy_add(rphy);
791                 if (error) {
792                         sas_rphy_free(rphy);
793                         return error;
794                 }
795
796                 phy_info->rphy = rphy;
797         }
798
799         return 0;
800 }
801
802 static int
803 mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
804 {
805         struct mptsas_portinfo *port_info;
806         u32 handle = 0xFFFF;
807         int error = -ENOMEM, i;
808
809         port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
810         if (!port_info)
811                 goto out;
812         memset(port_info, 0, sizeof(*port_info));
813
814         error = mptsas_sas_io_unit_pg0(ioc, port_info);
815         if (error)
816                 goto out_free_port_info;
817
818         list_add_tail(&port_info->list, &ioc->sas_topology);
819
820         for (i = 0; i < port_info->num_phys; i++) {
821                 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
822                         (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
823                          MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
824
825                 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
826                         (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
827                          MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
828                 handle = port_info->phy_info[i].identify.handle;
829
830                 if (port_info->phy_info[i].attached.handle) {
831                         mptsas_sas_device_pg0(ioc,
832                                 &port_info->phy_info[i].attached,
833                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
834                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
835                                 port_info->phy_info[i].attached.handle);
836                 }
837
838                 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
839                                      &port_info->phy_info[i], *index);
840                 (*index)++;
841         }
842
843         return 0;
844
845  out_free_port_info:
846         kfree(port_info);
847  out:
848         return error;
849 }
850
851 static int
852 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
853 {
854         struct mptsas_portinfo *port_info, *p;
855         int error = -ENOMEM, i, j;
856
857         port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
858         if (!port_info)
859                 goto out;
860         memset(port_info, 0, sizeof(*port_info));
861
862         error = mptsas_sas_expander_pg0(ioc, port_info,
863                 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
864                  MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
865         if (error)
866                 goto out_free_port_info;
867
868         *handle = port_info->handle;
869
870         list_add_tail(&port_info->list, &ioc->sas_topology);
871         for (i = 0; i < port_info->num_phys; i++) {
872                 struct device *parent;
873
874                 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
875                         (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
876                          MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
877
878                 if (port_info->phy_info[i].identify.handle) {
879                         mptsas_sas_device_pg0(ioc,
880                                 &port_info->phy_info[i].identify,
881                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
882                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
883                                 port_info->phy_info[i].identify.handle);
884                 }
885
886                 if (port_info->phy_info[i].attached.handle) {
887                         mptsas_sas_device_pg0(ioc,
888                                 &port_info->phy_info[i].attached,
889                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
890                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
891                                 port_info->phy_info[i].attached.handle);
892                 }
893
894                 /*
895                  * If we find a parent port handle this expander is
896                  * attached to another expander, else it hangs of the
897                  * HBA phys.
898                  */
899                 parent = &ioc->sh->shost_gendev;
900                 list_for_each_entry(p, &ioc->sas_topology, list) {
901                         for (j = 0; j < p->num_phys; j++) {
902                                 if (port_info->phy_info[i].identify.handle ==
903                                                 p->phy_info[j].attached.handle)
904                                         parent = &p->phy_info[j].rphy->dev;
905                         }
906                 }
907
908                 mptsas_probe_one_phy(parent, &port_info->phy_info[i], *index);
909                 (*index)++;
910         }
911
912         return 0;
913
914  out_free_port_info:
915         kfree(port_info);
916  out:
917         return error;
918 }
919
920 static void
921 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
922 {
923         u32 handle = 0xFFFF;
924         int index = 0;
925
926         mptsas_probe_hba_phys(ioc, &index);
927         while (!mptsas_probe_expander_phys(ioc, &handle, &index))
928                 ;
929 }
930
931 static int
932 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
933 {
934         struct Scsi_Host        *sh;
935         MPT_SCSI_HOST           *hd;
936         MPT_ADAPTER             *ioc;
937         unsigned long            flags;
938         int                      sz, ii;
939         int                      numSGE = 0;
940         int                      scale;
941         int                      ioc_cap;
942         u8                      *mem;
943         int                     error=0;
944         int                     r;
945
946         r = mpt_attach(pdev,id);
947         if (r)
948                 return r;
949
950         ioc = pci_get_drvdata(pdev);
951         ioc->DoneCtx = mptsasDoneCtx;
952         ioc->TaskCtx = mptsasTaskCtx;
953         ioc->InternalCtx = mptsasInternalCtx;
954
955         /*  Added sanity check on readiness of the MPT adapter.
956          */
957         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
958                 printk(MYIOC_s_WARN_FMT
959                   "Skipping because it's not operational!\n",
960                   ioc->name);
961                 return -ENODEV;
962         }
963
964         if (!ioc->active) {
965                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
966                   ioc->name);
967                 return -ENODEV;
968         }
969
970         /*  Sanity check - ensure at least 1 port is INITIATOR capable
971          */
972         ioc_cap = 0;
973         for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
974                 if (ioc->pfacts[ii].ProtocolFlags &
975                                 MPI_PORTFACTS_PROTOCOL_INITIATOR)
976                         ioc_cap++;
977         }
978
979         if (!ioc_cap) {
980                 printk(MYIOC_s_WARN_FMT
981                         "Skipping ioc=%p because SCSI Initiator mode "
982                         "is NOT enabled!\n", ioc->name, ioc);
983                 return 0;
984         }
985
986         sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
987         if (!sh) {
988                 printk(MYIOC_s_WARN_FMT
989                         "Unable to register controller with SCSI subsystem\n",
990                         ioc->name);
991                 return -1;
992         }
993
994         spin_lock_irqsave(&ioc->FreeQlock, flags);
995
996         /* Attach the SCSI Host to the IOC structure
997          */
998         ioc->sh = sh;
999
1000         sh->io_port = 0;
1001         sh->n_io_port = 0;
1002         sh->irq = 0;
1003
1004         /* set 16 byte cdb's */
1005         sh->max_cmd_len = 16;
1006
1007         sh->max_id = ioc->pfacts->MaxDevices + 1;
1008
1009         sh->transportt = mptsas_transport_template;
1010
1011         sh->max_lun = MPT_LAST_LUN + 1;
1012         sh->max_channel = 0;
1013         sh->this_id = ioc->pfacts[0].PortSCSIID;
1014
1015         /* Required entry.
1016          */
1017         sh->unique_id = ioc->id;
1018
1019         INIT_LIST_HEAD(&ioc->sas_topology);
1020
1021         /* Verify that we won't exceed the maximum
1022          * number of chain buffers
1023          * We can optimize:  ZZ = req_sz/sizeof(SGE)
1024          * For 32bit SGE's:
1025          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1026          *               + (req_sz - 64)/sizeof(SGE)
1027          * A slightly different algorithm is required for
1028          * 64bit SGEs.
1029          */
1030         scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1031         if (sizeof(dma_addr_t) == sizeof(u64)) {
1032                 numSGE = (scale - 1) *
1033                   (ioc->facts.MaxChainDepth-1) + scale +
1034                   (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1035                   sizeof(u32));
1036         } else {
1037                 numSGE = 1 + (scale - 1) *
1038                   (ioc->facts.MaxChainDepth-1) + scale +
1039                   (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1040                   sizeof(u32));
1041         }
1042
1043         if (numSGE < sh->sg_tablesize) {
1044                 /* Reset this value */
1045                 dprintk((MYIOC_s_INFO_FMT
1046                   "Resetting sg_tablesize to %d from %d\n",
1047                   ioc->name, numSGE, sh->sg_tablesize));
1048                 sh->sg_tablesize = numSGE;
1049         }
1050
1051         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1052
1053         hd = (MPT_SCSI_HOST *) sh->hostdata;
1054         hd->ioc = ioc;
1055
1056         /* SCSI needs scsi_cmnd lookup table!
1057          * (with size equal to req_depth*PtrSz!)
1058          */
1059         sz = ioc->req_depth * sizeof(void *);
1060         mem = kmalloc(sz, GFP_ATOMIC);
1061         if (mem == NULL) {
1062                 error = -ENOMEM;
1063                 goto mptsas_probe_failed;
1064         }
1065
1066         memset(mem, 0, sz);
1067         hd->ScsiLookup = (struct scsi_cmnd **) mem;
1068
1069         dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1070                  ioc->name, hd->ScsiLookup, sz));
1071
1072         /* Allocate memory for the device structures.
1073          * A non-Null pointer at an offset
1074          * indicates a device exists.
1075          * max_id = 1 + maximum id (hosts.h)
1076          */
1077         sz = sh->max_id * sizeof(void *);
1078         mem = kmalloc(sz, GFP_ATOMIC);
1079         if (mem == NULL) {
1080                 error = -ENOMEM;
1081                 goto mptsas_probe_failed;
1082         }
1083
1084         memset(mem, 0, sz);
1085         hd->Targets = (VirtDevice **) mem;
1086
1087         dprintk((KERN_INFO
1088           "  Targets @ %p, sz=%d\n", hd->Targets, sz));
1089
1090         /* Clear the TM flags
1091          */
1092         hd->tmPending = 0;
1093         hd->tmState = TM_STATE_NONE;
1094         hd->resetPending = 0;
1095         hd->abortSCpnt = NULL;
1096
1097         /* Clear the pointer used to store
1098          * single-threaded commands, i.e., those
1099          * issued during a bus scan, dv and
1100          * configuration pages.
1101          */
1102         hd->cmdPtr = NULL;
1103
1104         /* Initialize this SCSI Hosts' timers
1105          * To use, set the timer expires field
1106          * and add_timer
1107          */
1108         init_timer(&hd->timer);
1109         hd->timer.data = (unsigned long) hd;
1110         hd->timer.function = mptscsih_timer_expired;
1111
1112         hd->mpt_pq_filter = mpt_pq_filter;
1113         ioc->sas_data.ptClear = mpt_pt_clear;
1114
1115         if (ioc->sas_data.ptClear==1) {
1116                 mptbase_sas_persist_operation(
1117                     ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
1118         }
1119
1120         ddvprintk((MYIOC_s_INFO_FMT
1121                 "mpt_pq_filter %x mpt_pq_filter %x\n",
1122                 ioc->name,
1123                 mpt_pq_filter,
1124                 mpt_pq_filter));
1125
1126         init_waitqueue_head(&hd->scandv_waitq);
1127         hd->scandv_wait_done = 0;
1128         hd->last_queue_full = 0;
1129
1130         error = scsi_add_host(sh, &ioc->pcidev->dev);
1131         if (error) {
1132                 dprintk((KERN_ERR MYNAM
1133                   "scsi_add_host failed\n"));
1134                 goto mptsas_probe_failed;
1135         }
1136
1137         mptsas_scan_sas_topology(ioc);
1138
1139         return 0;
1140
1141 mptsas_probe_failed:
1142
1143         mptscsih_remove(pdev);
1144         return error;
1145 }
1146
1147 static void __devexit mptsas_remove(struct pci_dev *pdev)
1148 {
1149         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1150         struct mptsas_portinfo *p, *n;
1151
1152         sas_remove_host(ioc->sh);
1153
1154         list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1155                 list_del(&p->list);
1156                 kfree(p);
1157         }
1158
1159         mptscsih_remove(pdev);
1160 }
1161
1162 static struct pci_device_id mptsas_pci_table[] = {
1163         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
1164                 PCI_ANY_ID, PCI_ANY_ID },
1165         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
1166                 PCI_ANY_ID, PCI_ANY_ID },
1167         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
1168                 PCI_ANY_ID, PCI_ANY_ID },
1169         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
1170                 PCI_ANY_ID, PCI_ANY_ID },
1171         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
1172                 PCI_ANY_ID, PCI_ANY_ID },
1173         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
1174                 PCI_ANY_ID, PCI_ANY_ID },
1175         {0}     /* Terminating entry */
1176 };
1177 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
1178
1179
1180 static struct pci_driver mptsas_driver = {
1181         .name           = "mptsas",
1182         .id_table       = mptsas_pci_table,
1183         .probe          = mptsas_probe,
1184         .remove         = __devexit_p(mptsas_remove),
1185         .shutdown       = mptscsih_shutdown,
1186 #ifdef CONFIG_PM
1187         .suspend        = mptscsih_suspend,
1188         .resume         = mptscsih_resume,
1189 #endif
1190 };
1191
1192 static int __init
1193 mptsas_init(void)
1194 {
1195         show_mptmod_ver(my_NAME, my_VERSION);
1196
1197         mptsas_transport_template =
1198             sas_attach_transport(&mptsas_transport_functions);
1199         if (!mptsas_transport_template)
1200                 return -ENODEV;
1201
1202         mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
1203         mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
1204         mptsasInternalCtx =
1205                 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
1206
1207         if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
1208                 devtprintk((KERN_INFO MYNAM
1209                   ": Registered for IOC event notifications\n"));
1210         }
1211
1212         if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
1213                 dprintk((KERN_INFO MYNAM
1214                   ": Registered for IOC reset notifications\n"));
1215         }
1216
1217         return pci_register_driver(&mptsas_driver);
1218 }
1219
1220 static void __exit
1221 mptsas_exit(void)
1222 {
1223         pci_unregister_driver(&mptsas_driver);
1224         sas_release_transport(mptsas_transport_template);
1225
1226         mpt_reset_deregister(mptsasDoneCtx);
1227         mpt_event_deregister(mptsasDoneCtx);
1228
1229         mpt_deregister(mptsasInternalCtx);
1230         mpt_deregister(mptsasTaskCtx);
1231         mpt_deregister(mptsasDoneCtx);
1232 }
1233
1234 module_init(mptsas_init);
1235 module_exit(mptsas_exit);