]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/message/fusion/mptsas.c
[ACPI] merge 3549 4320 4485 4588 4980 5483 5651 acpica asus fops pnpacpi branches...
[linux-2.6-omap-h63xx.git] / drivers / message / fusion / mptsas.c
1 /*
2  *  linux/drivers/message/fusion/mptsas.c
3  *      For use with LSI Logic PCI chip/adapter(s)
4  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5  *
6  *  Copyright (c) 1999-2005 LSI Logic Corporation
7  *  (mailto:mpt_linux_developer@lsil.com)
8  *  Copyright (c) 2005-2006 Dell
9  */
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11 /*
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; version 2 of the License.
15
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20
21     NO WARRANTY
22     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26     solely responsible for determining the appropriateness of using and
27     distributing the Program and assumes all risks associated with its
28     exercise of rights under this Agreement, including but not limited to
29     the risks and costs of program errors, damage to or loss of data,
30     programs or equipment, and unavailability or interruption of operations.
31
32     DISCLAIMER OF LIABILITY
33     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40
41     You should have received a copy of the GNU General Public License
42     along with this program; if not, write to the Free Software
43     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
44 */
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46
47 #include <linux/module.h>
48 #include <linux/kernel.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/sched.h>
52 #include <linux/workqueue.h>
53
54 #include <scsi/scsi_cmnd.h>
55 #include <scsi/scsi_device.h>
56 #include <scsi/scsi_host.h>
57 #include <scsi/scsi_transport_sas.h>
58
59 #include "mptbase.h"
60 #include "mptscsih.h"
61
62
63 #define my_NAME         "Fusion MPT SAS Host driver"
64 #define my_VERSION      MPT_LINUX_VERSION_COMMON
65 #define MYNAM           "mptsas"
66
67 MODULE_AUTHOR(MODULEAUTHOR);
68 MODULE_DESCRIPTION(my_NAME);
69 MODULE_LICENSE("GPL");
70
71 static int mpt_pq_filter;
72 module_param(mpt_pq_filter, int, 0);
73 MODULE_PARM_DESC(mpt_pq_filter,
74                 "Enable peripheral qualifier filter: enable=1  "
75                 "(default=0)");
76
77 static int mpt_pt_clear;
78 module_param(mpt_pt_clear, int, 0);
79 MODULE_PARM_DESC(mpt_pt_clear,
80                 "Clear persistency table: enable=1  "
81                 "(default=MPTSCSIH_PT_CLEAR=0)");
82
83 static int      mptsasDoneCtx = -1;
84 static int      mptsasTaskCtx = -1;
85 static int      mptsasInternalCtx = -1; /* Used only for internal commands */
86 static int      mptsasMgmtCtx = -1;
87
88
89 enum mptsas_hotplug_action {
90         MPTSAS_ADD_DEVICE,
91         MPTSAS_DEL_DEVICE,
92 };
93
94 struct mptsas_hotplug_event {
95         struct work_struct      work;
96         MPT_ADAPTER             *ioc;
97         enum mptsas_hotplug_action event_type;
98         u64                     sas_address;
99         u32                     channel;
100         u32                     id;
101         u32                     device_info;
102         u16                     handle;
103         u16                     parent_handle;
104         u8                      phy_id;
105 };
106
107 /*
108  * SAS topology structures
109  *
110  * The MPT Fusion firmware interface spreads information about the
111  * SAS topology over many manufacture pages, thus we need some data
112  * structure to collect it and process it for the SAS transport class.
113  */
114
115 struct mptsas_devinfo {
116         u16     handle;         /* unique id to address this device */
117         u8      phy_id;         /* phy number of parent device */
118         u8      port_id;        /* sas physical port this device
119                                    is assoc'd with */
120         u8      id;             /* logical target id of this device */
121         u8      channel;        /* logical bus number of this device */
122         u64     sas_address;    /* WWN of this device,
123                                    SATA is assigned by HBA,expander */
124         u32     device_info;    /* bitfield detailed info about this device */
125 };
126
127 struct mptsas_phyinfo {
128         u8      phy_id;                 /* phy index */
129         u8      port_id;                /* port number this phy is part of */
130         u8      negotiated_link_rate;   /* nego'd link rate for this phy */
131         u8      hw_link_rate;           /* hardware max/min phys link rate */
132         u8      programmed_link_rate;   /* programmed max/min phy link rate */
133         struct mptsas_devinfo identify; /* point to phy device info */
134         struct mptsas_devinfo attached; /* point to attached device info */
135         struct sas_phy *phy;
136         struct sas_rphy *rphy;
137 };
138
139 struct mptsas_portinfo {
140         struct list_head list;
141         u16             handle;         /* unique id to address this */
142         u8              num_phys;       /* number of phys */
143         struct mptsas_phyinfo *phy_info;
144 };
145
146
147 #ifdef SASDEBUG
148 static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
149 {
150         printk("---- IO UNIT PAGE 0 ------------\n");
151         printk("Handle=0x%X\n",
152                 le16_to_cpu(phy_data->AttachedDeviceHandle));
153         printk("Controller Handle=0x%X\n",
154                 le16_to_cpu(phy_data->ControllerDevHandle));
155         printk("Port=0x%X\n", phy_data->Port);
156         printk("Port Flags=0x%X\n", phy_data->PortFlags);
157         printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
158         printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
159         printk("Controller PHY Device Info=0x%X\n",
160                 le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
161         printk("DiscoveryStatus=0x%X\n",
162                 le32_to_cpu(phy_data->DiscoveryStatus));
163         printk("\n");
164 }
165
166 static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
167 {
168         __le64 sas_address;
169
170         memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
171
172         printk("---- SAS PHY PAGE 0 ------------\n");
173         printk("Attached Device Handle=0x%X\n",
174                         le16_to_cpu(pg0->AttachedDevHandle));
175         printk("SAS Address=0x%llX\n",
176                         (unsigned long long)le64_to_cpu(sas_address));
177         printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
178         printk("Attached Device Info=0x%X\n",
179                         le32_to_cpu(pg0->AttachedDeviceInfo));
180         printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
181         printk("Change Count=0x%X\n", pg0->ChangeCount);
182         printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
183         printk("\n");
184 }
185
186 static void mptsas_print_phy_pg1(SasPhyPage1_t *pg1)
187 {
188         printk("---- SAS PHY PAGE 1 ------------\n");
189         printk("Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount);
190         printk("Running Disparity Error Count=0x%x\n",
191                         pg1->RunningDisparityErrorCount);
192         printk("Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount);
193         printk("PHY Reset Problem Count=0x%x\n", pg1->PhyResetProblemCount);
194         printk("\n");
195 }
196
197 static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
198 {
199         __le64 sas_address;
200
201         memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
202
203         printk("---- SAS DEVICE PAGE 0 ---------\n");
204         printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
205         printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
206         printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
207         printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
208         printk("Target ID=0x%X\n", pg0->TargetID);
209         printk("Bus=0x%X\n", pg0->Bus);
210         /* The PhyNum field specifies the PHY number of the parent
211          * device this device is linked to
212          */
213         printk("Parent Phy Num=0x%X\n", pg0->PhyNum);
214         printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus));
215         printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
216         printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
217         printk("Physical Port=0x%X\n", pg0->PhysicalPort);
218         printk("\n");
219 }
220
221 static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
222 {
223         printk("---- SAS EXPANDER PAGE 1 ------------\n");
224
225         printk("Physical Port=0x%X\n", pg1->PhysicalPort);
226         printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier);
227         printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
228         printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
229         printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
230         printk("Owner Device Handle=0x%X\n",
231                         le16_to_cpu(pg1->OwnerDevHandle));
232         printk("Attached Device Handle=0x%X\n",
233                         le16_to_cpu(pg1->AttachedDevHandle));
234 }
235 #else
236 #define mptsas_print_phy_data(phy_data)         do { } while (0)
237 #define mptsas_print_phy_pg0(pg0)               do { } while (0)
238 #define mptsas_print_phy_pg1(pg1)               do { } while (0)
239 #define mptsas_print_device_pg0(pg0)            do { } while (0)
240 #define mptsas_print_expander_pg1(pg1)          do { } while (0)
241 #endif
242
243
244 /*
245  * This is pretty ugly.  We will be able to seriously clean it up
246  * once the DV code in mptscsih goes away and we can properly
247  * implement ->target_alloc.
248  */
249 static int
250 mptsas_slave_alloc(struct scsi_device *sdev)
251 {
252         struct Scsi_Host        *host = sdev->host;
253         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
254         struct sas_rphy         *rphy;
255         struct mptsas_portinfo  *p;
256         VirtTarget              *vtarget;
257         VirtDevice              *vdev;
258         struct scsi_target      *starget;
259         int i;
260
261         vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
262         if (!vdev) {
263                 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
264                                 hd->ioc->name, sizeof(VirtDevice));
265                 return -ENOMEM;
266         }
267         vdev->ioc_id = hd->ioc->id;
268         sdev->hostdata = vdev;
269         starget = scsi_target(sdev);
270         vtarget = starget->hostdata;
271         vdev->vtarget = vtarget;
272         if (vtarget->num_luns == 0) {
273                 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
274                 hd->Targets[sdev->id] = vtarget;
275         }
276
277         /*
278           RAID volumes placed beyond the last expected port.
279         */
280         if (sdev->channel == hd->ioc->num_ports) {
281                 vdev->target_id = sdev->id;
282                 vdev->bus_id = 0;
283                 vdev->lun = 0;
284                 goto out;
285         }
286
287         rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
288         mutex_lock(&hd->ioc->sas_topology_mutex);
289         list_for_each_entry(p, &hd->ioc->sas_topology, list) {
290                 for (i = 0; i < p->num_phys; i++) {
291                         if (p->phy_info[i].attached.sas_address ==
292                                         rphy->identify.sas_address) {
293                                 vdev->target_id =
294                                         p->phy_info[i].attached.id;
295                                 vdev->bus_id = p->phy_info[i].attached.channel;
296                                 vdev->lun = sdev->lun;
297         mutex_unlock(&hd->ioc->sas_topology_mutex);
298                                 goto out;
299                         }
300                 }
301         }
302         mutex_unlock(&hd->ioc->sas_topology_mutex);
303
304         printk("No matching SAS device found!!\n");
305         kfree(vdev);
306         return -ENODEV;
307
308  out:
309         vtarget->ioc_id = vdev->ioc_id;
310         vtarget->target_id = vdev->target_id;
311         vtarget->bus_id = vdev->bus_id;
312         vtarget->num_luns++;
313         return 0;
314 }
315
316 static void
317 mptsas_slave_destroy(struct scsi_device *sdev)
318 {
319         struct Scsi_Host *host = sdev->host;
320         MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
321         struct sas_rphy *rphy;
322         struct mptsas_portinfo *p;
323         int i;
324
325         /*
326          * Handle hotplug removal case.
327          * We need to clear out attached data structure.
328          */
329         rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
330
331         mutex_lock(&hd->ioc->sas_topology_mutex);
332         list_for_each_entry(p, &hd->ioc->sas_topology, list) {
333                 for (i = 0; i < p->num_phys; i++) {
334                         if (p->phy_info[i].attached.sas_address ==
335                                         rphy->identify.sas_address) {
336                                 memset(&p->phy_info[i].attached, 0,
337                                     sizeof(struct mptsas_devinfo));
338                                 p->phy_info[i].rphy = NULL;
339                                 goto out;
340                         }
341                 }
342         }
343
344  out:
345         mutex_unlock(&hd->ioc->sas_topology_mutex);
346         /*
347          * TODO: Issue target reset to flush firmware outstanding commands.
348          */
349         mptscsih_slave_destroy(sdev);
350 }
351
352 static struct scsi_host_template mptsas_driver_template = {
353         .module                         = THIS_MODULE,
354         .proc_name                      = "mptsas",
355         .proc_info                      = mptscsih_proc_info,
356         .name                           = "MPT SPI Host",
357         .info                           = mptscsih_info,
358         .queuecommand                   = mptscsih_qcmd,
359         .target_alloc                   = mptscsih_target_alloc,
360         .slave_alloc                    = mptsas_slave_alloc,
361         .slave_configure                = mptscsih_slave_configure,
362         .target_destroy                 = mptscsih_target_destroy,
363         .slave_destroy                  = mptsas_slave_destroy,
364         .change_queue_depth             = mptscsih_change_queue_depth,
365         .eh_abort_handler               = mptscsih_abort,
366         .eh_device_reset_handler        = mptscsih_dev_reset,
367         .eh_bus_reset_handler           = mptscsih_bus_reset,
368         .eh_host_reset_handler          = mptscsih_host_reset,
369         .bios_param                     = mptscsih_bios_param,
370         .can_queue                      = MPT_FC_CAN_QUEUE,
371         .this_id                        = -1,
372         .sg_tablesize                   = MPT_SCSI_SG_DEPTH,
373         .max_sectors                    = 8192,
374         .cmd_per_lun                    = 7,
375         .use_clustering                 = ENABLE_CLUSTERING,
376 };
377
378 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
379 {
380         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
381         return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
382 }
383
384 static int mptsas_get_linkerrors(struct sas_phy *phy)
385 {
386         MPT_ADAPTER *ioc = phy_to_ioc(phy);
387         ConfigExtendedPageHeader_t hdr;
388         CONFIGPARMS cfg;
389         SasPhyPage1_t *buffer;
390         dma_addr_t dma_handle;
391         int error;
392
393         hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
394         hdr.ExtPageLength = 0;
395         hdr.PageNumber = 1 /* page number 1*/;
396         hdr.Reserved1 = 0;
397         hdr.Reserved2 = 0;
398         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
399         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
400
401         cfg.cfghdr.ehdr = &hdr;
402         cfg.physAddr = -1;
403         cfg.pageAddr = phy->identify.phy_identifier;
404         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
405         cfg.dir = 0;    /* read */
406         cfg.timeout = 10;
407
408         error = mpt_config(ioc, &cfg);
409         if (error)
410                 return error;
411         if (!hdr.ExtPageLength)
412                 return -ENXIO;
413
414         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
415                                       &dma_handle);
416         if (!buffer)
417                 return -ENOMEM;
418
419         cfg.physAddr = dma_handle;
420         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
421
422         error = mpt_config(ioc, &cfg);
423         if (error)
424                 goto out_free_consistent;
425
426         mptsas_print_phy_pg1(buffer);
427
428         phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
429         phy->running_disparity_error_count =
430                 le32_to_cpu(buffer->RunningDisparityErrorCount);
431         phy->loss_of_dword_sync_count =
432                 le32_to_cpu(buffer->LossDwordSynchCount);
433         phy->phy_reset_problem_count =
434                 le32_to_cpu(buffer->PhyResetProblemCount);
435
436  out_free_consistent:
437         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
438                             buffer, dma_handle);
439         return error;
440 }
441
442 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
443                 MPT_FRAME_HDR *reply)
444 {
445         ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
446         if (reply != NULL) {
447                 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
448                 memcpy(ioc->sas_mgmt.reply, reply,
449                     min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
450         }
451         complete(&ioc->sas_mgmt.done);
452         return 1;
453 }
454
455 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
456 {
457         MPT_ADAPTER *ioc = phy_to_ioc(phy);
458         SasIoUnitControlRequest_t *req;
459         SasIoUnitControlReply_t *reply;
460         MPT_FRAME_HDR *mf;
461         MPIHeader_t *hdr;
462         unsigned long timeleft;
463         int error = -ERESTARTSYS;
464
465         /* not implemented for expanders */
466         if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
467                 return -ENXIO;
468
469         if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
470                 goto out;
471
472         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
473         if (!mf) {
474                 error = -ENOMEM;
475                 goto out_unlock;
476         }
477
478         hdr = (MPIHeader_t *) mf;
479         req = (SasIoUnitControlRequest_t *)mf;
480         memset(req, 0, sizeof(SasIoUnitControlRequest_t));
481         req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
482         req->MsgContext = hdr->MsgContext;
483         req->Operation = hard_reset ?
484                 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
485         req->PhyNum = phy->identify.phy_identifier;
486
487         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
488
489         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
490                         10 * HZ);
491         if (!timeleft) {
492                 /* On timeout reset the board */
493                 mpt_free_msg_frame(ioc, mf);
494                 mpt_HardResetHandler(ioc, CAN_SLEEP);
495                 error = -ETIMEDOUT;
496                 goto out_unlock;
497         }
498
499         /* a reply frame is expected */
500         if ((ioc->sas_mgmt.status &
501             MPT_IOCTL_STATUS_RF_VALID) == 0) {
502                 error = -ENXIO;
503                 goto out_unlock;
504         }
505
506         /* process the completed Reply Message Frame */
507         reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
508         if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
509                 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
510                     __FUNCTION__,
511                     reply->IOCStatus,
512                     reply->IOCLogInfo);
513                 error = -ENXIO;
514                 goto out_unlock;
515         }
516
517         error = 0;
518
519  out_unlock:
520         mutex_unlock(&ioc->sas_mgmt.mutex);
521  out:
522         return error;
523 }
524
525 static struct sas_function_template mptsas_transport_functions = {
526         .get_linkerrors         = mptsas_get_linkerrors,
527         .phy_reset              = mptsas_phy_reset,
528 };
529
530 static struct scsi_transport_template *mptsas_transport_template;
531
532 static int
533 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
534 {
535         ConfigExtendedPageHeader_t hdr;
536         CONFIGPARMS cfg;
537         SasIOUnitPage0_t *buffer;
538         dma_addr_t dma_handle;
539         int error, i;
540
541         hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
542         hdr.ExtPageLength = 0;
543         hdr.PageNumber = 0;
544         hdr.Reserved1 = 0;
545         hdr.Reserved2 = 0;
546         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
547         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
548
549         cfg.cfghdr.ehdr = &hdr;
550         cfg.physAddr = -1;
551         cfg.pageAddr = 0;
552         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
553         cfg.dir = 0;    /* read */
554         cfg.timeout = 10;
555
556         error = mpt_config(ioc, &cfg);
557         if (error)
558                 goto out;
559         if (!hdr.ExtPageLength) {
560                 error = -ENXIO;
561                 goto out;
562         }
563
564         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
565                                             &dma_handle);
566         if (!buffer) {
567                 error = -ENOMEM;
568                 goto out;
569         }
570
571         cfg.physAddr = dma_handle;
572         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
573
574         error = mpt_config(ioc, &cfg);
575         if (error)
576                 goto out_free_consistent;
577
578         port_info->num_phys = buffer->NumPhys;
579         port_info->phy_info = kcalloc(port_info->num_phys,
580                 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
581         if (!port_info->phy_info) {
582                 error = -ENOMEM;
583                 goto out_free_consistent;
584         }
585
586         for (i = 0; i < port_info->num_phys; i++) {
587                 mptsas_print_phy_data(&buffer->PhyData[i]);
588                 port_info->phy_info[i].phy_id = i;
589                 port_info->phy_info[i].port_id =
590                     buffer->PhyData[i].Port;
591                 port_info->phy_info[i].negotiated_link_rate =
592                     buffer->PhyData[i].NegotiatedLinkRate;
593         }
594
595  out_free_consistent:
596         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
597                             buffer, dma_handle);
598  out:
599         return error;
600 }
601
602 static int
603 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
604                 u32 form, u32 form_specific)
605 {
606         ConfigExtendedPageHeader_t hdr;
607         CONFIGPARMS cfg;
608         SasPhyPage0_t *buffer;
609         dma_addr_t dma_handle;
610         int error;
611
612         hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
613         hdr.ExtPageLength = 0;
614         hdr.PageNumber = 0;
615         hdr.Reserved1 = 0;
616         hdr.Reserved2 = 0;
617         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
618         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
619
620         cfg.cfghdr.ehdr = &hdr;
621         cfg.dir = 0;    /* read */
622         cfg.timeout = 10;
623
624         /* Get Phy Pg 0 for each Phy. */
625         cfg.physAddr = -1;
626         cfg.pageAddr = form + form_specific;
627         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
628
629         error = mpt_config(ioc, &cfg);
630         if (error)
631                 goto out;
632
633         if (!hdr.ExtPageLength) {
634                 error = -ENXIO;
635                 goto out;
636         }
637
638         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
639                                       &dma_handle);
640         if (!buffer) {
641                 error = -ENOMEM;
642                 goto out;
643         }
644
645         cfg.physAddr = dma_handle;
646         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
647
648         error = mpt_config(ioc, &cfg);
649         if (error)
650                 goto out_free_consistent;
651
652         mptsas_print_phy_pg0(buffer);
653
654         phy_info->hw_link_rate = buffer->HwLinkRate;
655         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
656         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
657         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
658
659  out_free_consistent:
660         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
661                             buffer, dma_handle);
662  out:
663         return error;
664 }
665
666 static int
667 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
668                 u32 form, u32 form_specific)
669 {
670         ConfigExtendedPageHeader_t hdr;
671         CONFIGPARMS cfg;
672         SasDevicePage0_t *buffer;
673         dma_addr_t dma_handle;
674         __le64 sas_address;
675         int error;
676
677         hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
678         hdr.ExtPageLength = 0;
679         hdr.PageNumber = 0;
680         hdr.Reserved1 = 0;
681         hdr.Reserved2 = 0;
682         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
683         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
684
685         cfg.cfghdr.ehdr = &hdr;
686         cfg.pageAddr = form + form_specific;
687         cfg.physAddr = -1;
688         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
689         cfg.dir = 0;    /* read */
690         cfg.timeout = 10;
691
692         error = mpt_config(ioc, &cfg);
693         if (error)
694                 goto out;
695         if (!hdr.ExtPageLength) {
696                 error = -ENXIO;
697                 goto out;
698         }
699
700         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
701                                       &dma_handle);
702         if (!buffer) {
703                 error = -ENOMEM;
704                 goto out;
705         }
706
707         cfg.physAddr = dma_handle;
708         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
709
710         error = mpt_config(ioc, &cfg);
711         if (error)
712                 goto out_free_consistent;
713
714         mptsas_print_device_pg0(buffer);
715
716         device_info->handle = le16_to_cpu(buffer->DevHandle);
717         device_info->phy_id = buffer->PhyNum;
718         device_info->port_id = buffer->PhysicalPort;
719         device_info->id = buffer->TargetID;
720         device_info->channel = buffer->Bus;
721         memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
722         device_info->sas_address = le64_to_cpu(sas_address);
723         device_info->device_info =
724             le32_to_cpu(buffer->DeviceInfo);
725
726  out_free_consistent:
727         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
728                             buffer, dma_handle);
729  out:
730         return error;
731 }
732
733 static int
734 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
735                 u32 form, u32 form_specific)
736 {
737         ConfigExtendedPageHeader_t hdr;
738         CONFIGPARMS cfg;
739         SasExpanderPage0_t *buffer;
740         dma_addr_t dma_handle;
741         int error;
742
743         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
744         hdr.ExtPageLength = 0;
745         hdr.PageNumber = 0;
746         hdr.Reserved1 = 0;
747         hdr.Reserved2 = 0;
748         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
749         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
750
751         cfg.cfghdr.ehdr = &hdr;
752         cfg.physAddr = -1;
753         cfg.pageAddr = form + form_specific;
754         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
755         cfg.dir = 0;    /* read */
756         cfg.timeout = 10;
757
758         error = mpt_config(ioc, &cfg);
759         if (error)
760                 goto out;
761
762         if (!hdr.ExtPageLength) {
763                 error = -ENXIO;
764                 goto out;
765         }
766
767         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
768                                       &dma_handle);
769         if (!buffer) {
770                 error = -ENOMEM;
771                 goto out;
772         }
773
774         cfg.physAddr = dma_handle;
775         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
776
777         error = mpt_config(ioc, &cfg);
778         if (error)
779                 goto out_free_consistent;
780
781         /* save config data */
782         port_info->num_phys = buffer->NumPhys;
783         port_info->handle = le16_to_cpu(buffer->DevHandle);
784         port_info->phy_info = kcalloc(port_info->num_phys,
785                 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
786         if (!port_info->phy_info) {
787                 error = -ENOMEM;
788                 goto out_free_consistent;
789         }
790
791  out_free_consistent:
792         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
793                             buffer, dma_handle);
794  out:
795         return error;
796 }
797
798 static int
799 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
800                 u32 form, u32 form_specific)
801 {
802         ConfigExtendedPageHeader_t hdr;
803         CONFIGPARMS cfg;
804         SasExpanderPage1_t *buffer;
805         dma_addr_t dma_handle;
806         int error;
807
808         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
809         hdr.ExtPageLength = 0;
810         hdr.PageNumber = 1;
811         hdr.Reserved1 = 0;
812         hdr.Reserved2 = 0;
813         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
814         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
815
816         cfg.cfghdr.ehdr = &hdr;
817         cfg.physAddr = -1;
818         cfg.pageAddr = form + form_specific;
819         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
820         cfg.dir = 0;    /* read */
821         cfg.timeout = 10;
822
823         error = mpt_config(ioc, &cfg);
824         if (error)
825                 goto out;
826
827         if (!hdr.ExtPageLength) {
828                 error = -ENXIO;
829                 goto out;
830         }
831
832         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
833                                       &dma_handle);
834         if (!buffer) {
835                 error = -ENOMEM;
836                 goto out;
837         }
838
839         cfg.physAddr = dma_handle;
840         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
841
842         error = mpt_config(ioc, &cfg);
843         if (error)
844                 goto out_free_consistent;
845
846
847         mptsas_print_expander_pg1(buffer);
848
849         /* save config data */
850         phy_info->phy_id = buffer->PhyIdentifier;
851         phy_info->port_id = buffer->PhysicalPort;
852         phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
853         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
854         phy_info->hw_link_rate = buffer->HwLinkRate;
855         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
856         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
857
858
859  out_free_consistent:
860         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
861                             buffer, dma_handle);
862  out:
863         return error;
864 }
865
866 static void
867 mptsas_parse_device_info(struct sas_identify *identify,
868                 struct mptsas_devinfo *device_info)
869 {
870         u16 protocols;
871
872         identify->sas_address = device_info->sas_address;
873         identify->phy_identifier = device_info->phy_id;
874
875         /*
876          * Fill in Phy Initiator Port Protocol.
877          * Bits 6:3, more than one bit can be set, fall through cases.
878          */
879         protocols = device_info->device_info & 0x78;
880         identify->initiator_port_protocols = 0;
881         if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
882                 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
883         if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
884                 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
885         if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
886                 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
887         if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
888                 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
889
890         /*
891          * Fill in Phy Target Port Protocol.
892          * Bits 10:7, more than one bit can be set, fall through cases.
893          */
894         protocols = device_info->device_info & 0x780;
895         identify->target_port_protocols = 0;
896         if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
897                 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
898         if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
899                 identify->target_port_protocols |= SAS_PROTOCOL_STP;
900         if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
901                 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
902         if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
903                 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
904
905         /*
906          * Fill in Attached device type.
907          */
908         switch (device_info->device_info &
909                         MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
910         case MPI_SAS_DEVICE_INFO_NO_DEVICE:
911                 identify->device_type = SAS_PHY_UNUSED;
912                 break;
913         case MPI_SAS_DEVICE_INFO_END_DEVICE:
914                 identify->device_type = SAS_END_DEVICE;
915                 break;
916         case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
917                 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
918                 break;
919         case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
920                 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
921                 break;
922         }
923 }
924
925 static int mptsas_probe_one_phy(struct device *dev,
926                 struct mptsas_phyinfo *phy_info, int index, int local)
927 {
928         struct sas_phy *phy;
929         int error;
930
931         phy = sas_phy_alloc(dev, index);
932         if (!phy)
933                 return -ENOMEM;
934
935         phy->port_identifier = phy_info->port_id;
936         mptsas_parse_device_info(&phy->identify, &phy_info->identify);
937
938         /*
939          * Set Negotiated link rate.
940          */
941         switch (phy_info->negotiated_link_rate) {
942         case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
943                 phy->negotiated_linkrate = SAS_PHY_DISABLED;
944                 break;
945         case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
946                 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
947                 break;
948         case MPI_SAS_IOUNIT0_RATE_1_5:
949                 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
950                 break;
951         case MPI_SAS_IOUNIT0_RATE_3_0:
952                 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
953                 break;
954         case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
955         case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
956         default:
957                 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
958                 break;
959         }
960
961         /*
962          * Set Max hardware link rate.
963          */
964         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
965         case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
966                 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
967                 break;
968         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
969                 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
970                 break;
971         default:
972                 break;
973         }
974
975         /*
976          * Set Max programmed link rate.
977          */
978         switch (phy_info->programmed_link_rate &
979                         MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
980         case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
981                 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
982                 break;
983         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
984                 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
985                 break;
986         default:
987                 break;
988         }
989
990         /*
991          * Set Min hardware link rate.
992          */
993         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
994         case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
995                 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
996                 break;
997         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
998                 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
999                 break;
1000         default:
1001                 break;
1002         }
1003
1004         /*
1005          * Set Min programmed link rate.
1006          */
1007         switch (phy_info->programmed_link_rate &
1008                         MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
1009         case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
1010                 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1011                 break;
1012         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1013                 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1014                 break;
1015         default:
1016                 break;
1017         }
1018
1019         if (local)
1020                 phy->local_attached = 1;
1021
1022         error = sas_phy_add(phy);
1023         if (error) {
1024                 sas_phy_free(phy);
1025                 return error;
1026         }
1027         phy_info->phy = phy;
1028
1029         if (phy_info->attached.handle) {
1030                 struct sas_rphy *rphy;
1031
1032                 rphy = sas_rphy_alloc(phy);
1033                 if (!rphy)
1034                         return 0; /* non-fatal: an rphy can be added later */
1035
1036                 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
1037                 error = sas_rphy_add(rphy);
1038                 if (error) {
1039                         sas_rphy_free(rphy);
1040                         return error;
1041                 }
1042
1043                 phy_info->rphy = rphy;
1044         }
1045
1046         return 0;
1047 }
1048
1049 static int
1050 mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
1051 {
1052         struct mptsas_portinfo *port_info;
1053         u32 handle = 0xFFFF;
1054         int error = -ENOMEM, i;
1055
1056         port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);
1057         if (!port_info)
1058                 goto out;
1059
1060         error = mptsas_sas_io_unit_pg0(ioc, port_info);
1061         if (error)
1062                 goto out_free_port_info;
1063
1064         ioc->num_ports = port_info->num_phys;
1065         mutex_lock(&ioc->sas_topology_mutex);
1066         list_add_tail(&port_info->list, &ioc->sas_topology);
1067         mutex_unlock(&ioc->sas_topology_mutex);
1068
1069         for (i = 0; i < port_info->num_phys; i++) {
1070                 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
1071                         (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
1072                          MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
1073
1074                 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
1075                         (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
1076                          MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
1077                 port_info->phy_info[i].identify.phy_id =
1078                     port_info->phy_info[i].phy_id;
1079                 handle = port_info->phy_info[i].identify.handle;
1080
1081                 if (port_info->phy_info[i].attached.handle) {
1082                         mptsas_sas_device_pg0(ioc,
1083                                 &port_info->phy_info[i].attached,
1084                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1085                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1086                                 port_info->phy_info[i].attached.handle);
1087                 }
1088
1089                 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
1090                                      &port_info->phy_info[i], *index, 1);
1091                 (*index)++;
1092         }
1093
1094         return 0;
1095
1096  out_free_port_info:
1097         kfree(port_info);
1098  out:
1099         return error;
1100 }
1101
1102 static int
1103 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1104 {
1105         struct mptsas_portinfo *port_info, *p;
1106         int error = -ENOMEM, i, j;
1107
1108         port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);
1109         if (!port_info)
1110                 goto out;
1111
1112         error = mptsas_sas_expander_pg0(ioc, port_info,
1113                 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
1114                  MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
1115         if (error)
1116                 goto out_free_port_info;
1117
1118         *handle = port_info->handle;
1119
1120         mutex_lock(&ioc->sas_topology_mutex);
1121         list_add_tail(&port_info->list, &ioc->sas_topology);
1122         mutex_unlock(&ioc->sas_topology_mutex);
1123
1124         for (i = 0; i < port_info->num_phys; i++) {
1125                 struct device *parent;
1126
1127                 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
1128                         (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
1129                          MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
1130
1131                 if (port_info->phy_info[i].identify.handle) {
1132                         mptsas_sas_device_pg0(ioc,
1133                                 &port_info->phy_info[i].identify,
1134                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1135                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1136                                 port_info->phy_info[i].identify.handle);
1137                         port_info->phy_info[i].identify.phy_id =
1138                             port_info->phy_info[i].phy_id;
1139                 }
1140
1141                 if (port_info->phy_info[i].attached.handle) {
1142                         mptsas_sas_device_pg0(ioc,
1143                                 &port_info->phy_info[i].attached,
1144                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1145                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1146                                 port_info->phy_info[i].attached.handle);
1147                 }
1148
1149                 /*
1150                  * If we find a parent port handle this expander is
1151                  * attached to another expander, else it hangs of the
1152                  * HBA phys.
1153                  */
1154                 parent = &ioc->sh->shost_gendev;
1155                 mutex_lock(&ioc->sas_topology_mutex);
1156                 list_for_each_entry(p, &ioc->sas_topology, list) {
1157                         for (j = 0; j < p->num_phys; j++) {
1158                                 if (port_info->phy_info[i].identify.handle ==
1159                                                 p->phy_info[j].attached.handle)
1160                                         parent = &p->phy_info[j].rphy->dev;
1161                         }
1162                 }
1163                 mutex_unlock(&ioc->sas_topology_mutex);
1164
1165                 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1166                                      *index, 0);
1167                 (*index)++;
1168         }
1169
1170         return 0;
1171
1172  out_free_port_info:
1173         kfree(port_info);
1174  out:
1175         return error;
1176 }
1177
1178 static void
1179 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1180 {
1181         u32 handle = 0xFFFF;
1182         int index = 0;
1183
1184         mptsas_probe_hba_phys(ioc, &index);
1185         while (!mptsas_probe_expander_phys(ioc, &handle, &index))
1186                 ;
1187 }
1188
1189 static struct mptsas_phyinfo *
1190 mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id)
1191 {
1192         struct mptsas_portinfo *port_info;
1193         struct mptsas_devinfo device_info;
1194         struct mptsas_phyinfo *phy_info = NULL;
1195         int i, error;
1196
1197         /*
1198          * Retrieve the parent sas_address
1199          */
1200         error = mptsas_sas_device_pg0(ioc, &device_info,
1201                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1202                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1203                 parent_handle);
1204         if (error) {
1205                 printk("mptsas: failed to retrieve device page\n");
1206                 return NULL;
1207         }
1208
1209         /*
1210          * The phy_info structures are never deallocated during lifetime of
1211          * a host, so the code below is safe without additional refcounting.
1212          */
1213         mutex_lock(&ioc->sas_topology_mutex);
1214         list_for_each_entry(port_info, &ioc->sas_topology, list) {
1215                 for (i = 0; i < port_info->num_phys; i++) {
1216                         if (port_info->phy_info[i].identify.sas_address ==
1217                             device_info.sas_address &&
1218                             port_info->phy_info[i].phy_id == phy_id) {
1219                                 phy_info = &port_info->phy_info[i];
1220                                 break;
1221                         }
1222                 }
1223         }
1224         mutex_unlock(&ioc->sas_topology_mutex);
1225
1226         return phy_info;
1227 }
1228
1229 static struct mptsas_phyinfo *
1230 mptsas_find_phyinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
1231 {
1232         struct mptsas_portinfo *port_info;
1233         struct mptsas_phyinfo *phy_info = NULL;
1234         int i;
1235
1236         /*
1237          * The phy_info structures are never deallocated during lifetime of
1238          * a host, so the code below is safe without additional refcounting.
1239          */
1240         mutex_lock(&ioc->sas_topology_mutex);
1241         list_for_each_entry(port_info, &ioc->sas_topology, list) {
1242                 for (i = 0; i < port_info->num_phys; i++) {
1243                         if (port_info->phy_info[i].attached.handle == handle) {
1244                                 phy_info = &port_info->phy_info[i];
1245                                 break;
1246                         }
1247                 }
1248         }
1249         mutex_unlock(&ioc->sas_topology_mutex);
1250
1251         return phy_info;
1252 }
1253
1254 static void
1255 mptsas_hotplug_work(void *arg)
1256 {
1257         struct mptsas_hotplug_event *ev = arg;
1258         MPT_ADAPTER *ioc = ev->ioc;
1259         struct mptsas_phyinfo *phy_info;
1260         struct sas_rphy *rphy;
1261         char *ds = NULL;
1262
1263         if (ev->device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1264                 ds = "ssp";
1265         if (ev->device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
1266                 ds = "stp";
1267         if (ev->device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1268                 ds = "sata";
1269
1270         switch (ev->event_type) {
1271         case MPTSAS_DEL_DEVICE:
1272                 printk(MYIOC_s_INFO_FMT
1273                        "removing %s device, channel %d, id %d, phy %d\n",
1274                        ioc->name, ds, ev->channel, ev->id, ev->phy_id);
1275
1276                 phy_info = mptsas_find_phyinfo_by_handle(ioc, ev->handle);
1277                 if (!phy_info) {
1278                         printk("mptsas: remove event for non-existant PHY.\n");
1279                         break;
1280                 }
1281
1282                 if (phy_info->rphy) {
1283                         sas_rphy_delete(phy_info->rphy);
1284                         phy_info->rphy = NULL;
1285                 }
1286                 break;
1287         case MPTSAS_ADD_DEVICE:
1288                 printk(MYIOC_s_INFO_FMT
1289                        "attaching %s device, channel %d, id %d, phy %d\n",
1290                        ioc->name, ds, ev->channel, ev->id, ev->phy_id);
1291
1292                 phy_info = mptsas_find_phyinfo_by_parent(ioc,
1293                                 ev->parent_handle, ev->phy_id);
1294                 if (!phy_info) {
1295                         printk("mptsas: add event for non-existant PHY.\n");
1296                         break;
1297                 }
1298
1299                 if (phy_info->rphy) {
1300                         printk("mptsas: trying to add existing device.\n");
1301                         break;
1302                 }
1303
1304                 /* fill attached info */
1305                 phy_info->attached.handle = ev->handle;
1306                 phy_info->attached.phy_id = ev->phy_id;
1307                 phy_info->attached.port_id = phy_info->identify.port_id;
1308                 phy_info->attached.id = ev->id;
1309                 phy_info->attached.channel = ev->channel;
1310                 phy_info->attached.sas_address = ev->sas_address;
1311                 phy_info->attached.device_info = ev->device_info;
1312
1313                 rphy = sas_rphy_alloc(phy_info->phy);
1314                 if (!rphy)
1315                         break; /* non-fatal: an rphy can be added later */
1316
1317                 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
1318                 if (sas_rphy_add(rphy)) {
1319                         sas_rphy_free(rphy);
1320                         break;
1321                 }
1322
1323                 phy_info->rphy = rphy;
1324                 break;
1325         }
1326
1327         kfree(ev);
1328 }
1329
1330 static void
1331 mptscsih_send_sas_event(MPT_ADAPTER *ioc,
1332                 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1333 {
1334         struct mptsas_hotplug_event *ev;
1335         u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
1336         __le64 sas_address;
1337
1338         if ((device_info &
1339              (MPI_SAS_DEVICE_INFO_SSP_TARGET |
1340               MPI_SAS_DEVICE_INFO_STP_TARGET |
1341               MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
1342                 return;
1343
1344         if ((sas_event_data->ReasonCode &
1345              (MPI_EVENT_SAS_DEV_STAT_RC_ADDED |
1346               MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING)) == 0)
1347                 return;
1348
1349         ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1350         if (!ev) {
1351                 printk(KERN_WARNING "mptsas: lost hotplug event\n");
1352                 return;
1353         }
1354
1355
1356         INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1357         ev->ioc = ioc;
1358         ev->handle = le16_to_cpu(sas_event_data->DevHandle);
1359         ev->parent_handle = le16_to_cpu(sas_event_data->ParentDevHandle);
1360         ev->channel = sas_event_data->Bus;
1361         ev->id = sas_event_data->TargetID;
1362         ev->phy_id = sas_event_data->PhyNum;
1363         memcpy(&sas_address, &sas_event_data->SASAddress, sizeof(__le64));
1364         ev->sas_address = le64_to_cpu(sas_address);
1365         ev->device_info = device_info;
1366
1367         if (sas_event_data->ReasonCode & MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
1368                 ev->event_type = MPTSAS_ADD_DEVICE;
1369         else
1370                 ev->event_type = MPTSAS_DEL_DEVICE;
1371
1372         schedule_work(&ev->work);
1373 }
1374
1375 static int
1376 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
1377 {
1378         u8 event = le32_to_cpu(reply->Event) & 0xFF;
1379
1380         if (!ioc->sh)
1381                 return 1;
1382
1383         switch (event) {
1384         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1385                 mptscsih_send_sas_event(ioc,
1386                         (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
1387                 return 1;               /* currently means nothing really */
1388
1389         default:
1390                 return mptscsih_event_process(ioc, reply);
1391         }
1392 }
1393
1394 static int
1395 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1396 {
1397         struct Scsi_Host        *sh;
1398         MPT_SCSI_HOST           *hd;
1399         MPT_ADAPTER             *ioc;
1400         unsigned long            flags;
1401         int                      ii;
1402         int                      numSGE = 0;
1403         int                      scale;
1404         int                      ioc_cap;
1405         int                     error=0;
1406         int                     r;
1407
1408         r = mpt_attach(pdev,id);
1409         if (r)
1410                 return r;
1411
1412         ioc = pci_get_drvdata(pdev);
1413         ioc->DoneCtx = mptsasDoneCtx;
1414         ioc->TaskCtx = mptsasTaskCtx;
1415         ioc->InternalCtx = mptsasInternalCtx;
1416
1417         /*  Added sanity check on readiness of the MPT adapter.
1418          */
1419         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1420                 printk(MYIOC_s_WARN_FMT
1421                   "Skipping because it's not operational!\n",
1422                   ioc->name);
1423                 error = -ENODEV;
1424                 goto out_mptsas_probe;
1425         }
1426
1427         if (!ioc->active) {
1428                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1429                   ioc->name);
1430                 error = -ENODEV;
1431                 goto out_mptsas_probe;
1432         }
1433
1434         /*  Sanity check - ensure at least 1 port is INITIATOR capable
1435          */
1436         ioc_cap = 0;
1437         for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
1438                 if (ioc->pfacts[ii].ProtocolFlags &
1439                                 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1440                         ioc_cap++;
1441         }
1442
1443         if (!ioc_cap) {
1444                 printk(MYIOC_s_WARN_FMT
1445                         "Skipping ioc=%p because SCSI Initiator mode "
1446                         "is NOT enabled!\n", ioc->name, ioc);
1447                 return 0;
1448         }
1449
1450         sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
1451         if (!sh) {
1452                 printk(MYIOC_s_WARN_FMT
1453                         "Unable to register controller with SCSI subsystem\n",
1454                         ioc->name);
1455                 error = -1;
1456                 goto out_mptsas_probe;
1457         }
1458
1459         spin_lock_irqsave(&ioc->FreeQlock, flags);
1460
1461         /* Attach the SCSI Host to the IOC structure
1462          */
1463         ioc->sh = sh;
1464
1465         sh->io_port = 0;
1466         sh->n_io_port = 0;
1467         sh->irq = 0;
1468
1469         /* set 16 byte cdb's */
1470         sh->max_cmd_len = 16;
1471
1472         sh->max_id = ioc->pfacts->MaxDevices + 1;
1473
1474         sh->transportt = mptsas_transport_template;
1475
1476         sh->max_lun = MPT_LAST_LUN + 1;
1477         sh->max_channel = 0;
1478         sh->this_id = ioc->pfacts[0].PortSCSIID;
1479
1480         /* Required entry.
1481          */
1482         sh->unique_id = ioc->id;
1483
1484         INIT_LIST_HEAD(&ioc->sas_topology);
1485         mutex_init(&ioc->sas_topology_mutex);
1486
1487         mutex_init(&ioc->sas_mgmt.mutex);
1488         init_completion(&ioc->sas_mgmt.done);
1489
1490         /* Verify that we won't exceed the maximum
1491          * number of chain buffers
1492          * We can optimize:  ZZ = req_sz/sizeof(SGE)
1493          * For 32bit SGE's:
1494          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1495          *               + (req_sz - 64)/sizeof(SGE)
1496          * A slightly different algorithm is required for
1497          * 64bit SGEs.
1498          */
1499         scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1500         if (sizeof(dma_addr_t) == sizeof(u64)) {
1501                 numSGE = (scale - 1) *
1502                   (ioc->facts.MaxChainDepth-1) + scale +
1503                   (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1504                   sizeof(u32));
1505         } else {
1506                 numSGE = 1 + (scale - 1) *
1507                   (ioc->facts.MaxChainDepth-1) + scale +
1508                   (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1509                   sizeof(u32));
1510         }
1511
1512         if (numSGE < sh->sg_tablesize) {
1513                 /* Reset this value */
1514                 dprintk((MYIOC_s_INFO_FMT
1515                   "Resetting sg_tablesize to %d from %d\n",
1516                   ioc->name, numSGE, sh->sg_tablesize));
1517                 sh->sg_tablesize = numSGE;
1518         }
1519
1520         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1521
1522         hd = (MPT_SCSI_HOST *) sh->hostdata;
1523         hd->ioc = ioc;
1524
1525         /* SCSI needs scsi_cmnd lookup table!
1526          * (with size equal to req_depth*PtrSz!)
1527          */
1528         hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
1529         if (!hd->ScsiLookup) {
1530                 error = -ENOMEM;
1531                 goto out_mptsas_probe;
1532         }
1533
1534         dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
1535                  ioc->name, hd->ScsiLookup));
1536
1537         /* Allocate memory for the device structures.
1538          * A non-Null pointer at an offset
1539          * indicates a device exists.
1540          * max_id = 1 + maximum id (hosts.h)
1541          */
1542         hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
1543         if (!hd->Targets) {
1544                 error = -ENOMEM;
1545                 goto out_mptsas_probe;
1546         }
1547
1548         dprintk((KERN_INFO "  vtarget @ %p\n", hd->Targets));
1549
1550         /* Clear the TM flags
1551          */
1552         hd->tmPending = 0;
1553         hd->tmState = TM_STATE_NONE;
1554         hd->resetPending = 0;
1555         hd->abortSCpnt = NULL;
1556
1557         /* Clear the pointer used to store
1558          * single-threaded commands, i.e., those
1559          * issued during a bus scan, dv and
1560          * configuration pages.
1561          */
1562         hd->cmdPtr = NULL;
1563
1564         /* Initialize this SCSI Hosts' timers
1565          * To use, set the timer expires field
1566          * and add_timer
1567          */
1568         init_timer(&hd->timer);
1569         hd->timer.data = (unsigned long) hd;
1570         hd->timer.function = mptscsih_timer_expired;
1571
1572         hd->mpt_pq_filter = mpt_pq_filter;
1573         ioc->sas_data.ptClear = mpt_pt_clear;
1574
1575         if (ioc->sas_data.ptClear==1) {
1576                 mptbase_sas_persist_operation(
1577                     ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
1578         }
1579
1580         ddvprintk((MYIOC_s_INFO_FMT
1581                 "mpt_pq_filter %x mpt_pq_filter %x\n",
1582                 ioc->name,
1583                 mpt_pq_filter,
1584                 mpt_pq_filter));
1585
1586         init_waitqueue_head(&hd->scandv_waitq);
1587         hd->scandv_wait_done = 0;
1588         hd->last_queue_full = 0;
1589
1590         error = scsi_add_host(sh, &ioc->pcidev->dev);
1591         if (error) {
1592                 dprintk((KERN_ERR MYNAM
1593                   "scsi_add_host failed\n"));
1594                 goto out_mptsas_probe;
1595         }
1596
1597         mptsas_scan_sas_topology(ioc);
1598
1599         /*
1600           Reporting RAID volumes.
1601         */
1602         if (!ioc->raid_data.pIocPg2)
1603                 return 0;
1604         if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
1605                 return 0;
1606         for (ii=0;ii<ioc->raid_data.pIocPg2->NumActiveVolumes;ii++) {
1607                 scsi_add_device(sh,
1608                         ioc->num_ports,
1609                         ioc->raid_data.pIocPg2->RaidVolume[ii].VolumeID,
1610                         0);
1611         }
1612
1613         return 0;
1614
1615 out_mptsas_probe:
1616
1617         mptscsih_remove(pdev);
1618         return error;
1619 }
1620
1621 static void __devexit mptsas_remove(struct pci_dev *pdev)
1622 {
1623         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1624         struct mptsas_portinfo *p, *n;
1625
1626         sas_remove_host(ioc->sh);
1627
1628         mutex_lock(&ioc->sas_topology_mutex);
1629         list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1630                 list_del(&p->list);
1631                 kfree(p);
1632         }
1633         mutex_unlock(&ioc->sas_topology_mutex);
1634
1635         mptscsih_remove(pdev);
1636 }
1637
1638 static struct pci_device_id mptsas_pci_table[] = {
1639         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
1640                 PCI_ANY_ID, PCI_ANY_ID },
1641         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
1642                 PCI_ANY_ID, PCI_ANY_ID },
1643         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
1644                 PCI_ANY_ID, PCI_ANY_ID },
1645         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
1646                 PCI_ANY_ID, PCI_ANY_ID },
1647         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
1648                 PCI_ANY_ID, PCI_ANY_ID },
1649         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
1650                 PCI_ANY_ID, PCI_ANY_ID },
1651         {0}     /* Terminating entry */
1652 };
1653 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
1654
1655
1656 static struct pci_driver mptsas_driver = {
1657         .name           = "mptsas",
1658         .id_table       = mptsas_pci_table,
1659         .probe          = mptsas_probe,
1660         .remove         = __devexit_p(mptsas_remove),
1661         .shutdown       = mptscsih_shutdown,
1662 #ifdef CONFIG_PM
1663         .suspend        = mptscsih_suspend,
1664         .resume         = mptscsih_resume,
1665 #endif
1666 };
1667
1668 static int __init
1669 mptsas_init(void)
1670 {
1671         show_mptmod_ver(my_NAME, my_VERSION);
1672
1673         mptsas_transport_template =
1674             sas_attach_transport(&mptsas_transport_functions);
1675         if (!mptsas_transport_template)
1676                 return -ENODEV;
1677
1678         mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
1679         mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
1680         mptsasInternalCtx =
1681                 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
1682         mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
1683
1684         if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) {
1685                 devtprintk((KERN_INFO MYNAM
1686                   ": Registered for IOC event notifications\n"));
1687         }
1688
1689         if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
1690                 dprintk((KERN_INFO MYNAM
1691                   ": Registered for IOC reset notifications\n"));
1692         }
1693
1694         return pci_register_driver(&mptsas_driver);
1695 }
1696
1697 static void __exit
1698 mptsas_exit(void)
1699 {
1700         pci_unregister_driver(&mptsas_driver);
1701         sas_release_transport(mptsas_transport_template);
1702
1703         mpt_reset_deregister(mptsasDoneCtx);
1704         mpt_event_deregister(mptsasDoneCtx);
1705
1706         mpt_deregister(mptsasMgmtCtx);
1707         mpt_deregister(mptsasInternalCtx);
1708         mpt_deregister(mptsasTaskCtx);
1709         mpt_deregister(mptsasDoneCtx);
1710 }
1711
1712 module_init(mptsas_init);
1713 module_exit(mptsas_exit);