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