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