[SCSI] mpt fusion: Use menuconfig objects
[linux-2.6] / drivers / message / fusion / mptsas.c
1 /*
2  *  linux/drivers/message/fusion/mptsas.c
3  *      For use with LSI PCI chip/adapter(s)
4  *      running LSI Fusion MPT (Message Passing Technology) firmware.
5  *
6  *  Copyright (c) 1999-2007 LSI Corporation
7  *  (mailto:DL-MPTFusionLinux@lsi.com)
8  *  Copyright (c) 2005-2007 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/jiffies.h>
52 #include <linux/workqueue.h>
53 #include <linux/delay.h>        /* for mdelay */
54
55 #include <scsi/scsi.h>
56 #include <scsi/scsi_cmnd.h>
57 #include <scsi/scsi_device.h>
58 #include <scsi/scsi_host.h>
59 #include <scsi/scsi_transport_sas.h>
60 #include <scsi/scsi_dbg.h>
61
62 #include "mptbase.h"
63 #include "mptscsih.h"
64 #include "mptsas.h"
65
66
67 #define my_NAME         "Fusion MPT SAS Host driver"
68 #define my_VERSION      MPT_LINUX_VERSION_COMMON
69 #define MYNAM           "mptsas"
70
71 /*
72  * Reserved channel for integrated raid
73  */
74 #define MPTSAS_RAID_CHANNEL     1
75
76 MODULE_AUTHOR(MODULEAUTHOR);
77 MODULE_DESCRIPTION(my_NAME);
78 MODULE_LICENSE("GPL");
79 MODULE_VERSION(my_VERSION);
80
81 static int mpt_pt_clear;
82 module_param(mpt_pt_clear, int, 0);
83 MODULE_PARM_DESC(mpt_pt_clear,
84                 " Clear persistency table: enable=1  "
85                 "(default=MPTSCSIH_PT_CLEAR=0)");
86
87 /* scsi-mid layer global parmeter is max_report_luns, which is 511 */
88 #define MPTSAS_MAX_LUN (16895)
89 static int max_lun = MPTSAS_MAX_LUN;
90 module_param(max_lun, int, 0);
91 MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
92
93 static u8       mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
94 static u8       mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
95 static u8       mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */
96 static u8       mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS;
97
98 static void mptsas_hotplug_work(struct work_struct *work);
99
100 static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
101                                         MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
102 {
103         dsasprintk(ioc, printk(KERN_DEBUG "---- IO UNIT PAGE 0 ------------\n"));
104         dsasprintk(ioc, printk(KERN_DEBUG "Handle=0x%X\n",
105                 le16_to_cpu(phy_data->AttachedDeviceHandle)));
106         dsasprintk(ioc, printk(KERN_DEBUG "Controller Handle=0x%X\n",
107                 le16_to_cpu(phy_data->ControllerDevHandle)));
108         dsasprintk(ioc, printk(KERN_DEBUG "Port=0x%X\n", phy_data->Port));
109         dsasprintk(ioc, printk(KERN_DEBUG "Port Flags=0x%X\n", phy_data->PortFlags));
110         dsasprintk(ioc, printk(KERN_DEBUG "PHY Flags=0x%X\n", phy_data->PhyFlags));
111         dsasprintk(ioc, printk(KERN_DEBUG "Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate));
112         dsasprintk(ioc, printk(KERN_DEBUG "Controller PHY Device Info=0x%X\n",
113                 le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
114         dsasprintk(ioc, printk(KERN_DEBUG "DiscoveryStatus=0x%X\n\n",
115                 le32_to_cpu(phy_data->DiscoveryStatus)));
116 }
117
118 static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
119 {
120         __le64 sas_address;
121
122         memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
123
124         dsasprintk(ioc, printk(KERN_DEBUG "---- SAS PHY PAGE 0 ------------\n"));
125         dsasprintk(ioc, printk(KERN_DEBUG "Attached Device Handle=0x%X\n",
126                         le16_to_cpu(pg0->AttachedDevHandle)));
127         dsasprintk(ioc, printk(KERN_DEBUG "SAS Address=0x%llX\n",
128                         (unsigned long long)le64_to_cpu(sas_address)));
129         dsasprintk(ioc, printk(KERN_DEBUG "Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier));
130         dsasprintk(ioc, printk(KERN_DEBUG "Attached Device Info=0x%X\n",
131                         le32_to_cpu(pg0->AttachedDeviceInfo)));
132         dsasprintk(ioc, printk(KERN_DEBUG "Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate));
133         dsasprintk(ioc, printk(KERN_DEBUG "Change Count=0x%X\n", pg0->ChangeCount));
134         dsasprintk(ioc, printk(KERN_DEBUG "PHY Info=0x%X\n\n", le32_to_cpu(pg0->PhyInfo)));
135 }
136
137 static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
138 {
139         dsasprintk(ioc, printk(KERN_DEBUG "---- SAS PHY PAGE 1 ------------\n"));
140         dsasprintk(ioc, printk(KERN_DEBUG "Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount));
141         dsasprintk(ioc, printk(KERN_DEBUG "Running Disparity Error Count=0x%x\n",
142                         pg1->RunningDisparityErrorCount));
143         dsasprintk(ioc, printk(KERN_DEBUG "Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount));
144         dsasprintk(ioc, printk(KERN_DEBUG "PHY Reset Problem Count=0x%x\n\n", pg1->PhyResetProblemCount));
145 }
146
147 static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
148 {
149         __le64 sas_address;
150
151         memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
152
153         dsasprintk(ioc, printk(KERN_DEBUG "---- SAS DEVICE PAGE 0 ---------\n"));
154         dsasprintk(ioc, printk(KERN_DEBUG "Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle)));
155         dsasprintk(ioc, printk(KERN_DEBUG "Parent Handle=0x%X\n" ,le16_to_cpu(pg0->ParentDevHandle)));
156         dsasprintk(ioc, printk(KERN_DEBUG "Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle)));
157         dsasprintk(ioc, printk(KERN_DEBUG "Slot=0x%X\n", le16_to_cpu(pg0->Slot)));
158         dsasprintk(ioc, printk(KERN_DEBUG "SAS Address=0x%llX\n", (unsigned long long)
159             le64_to_cpu(sas_address)));
160         dsasprintk(ioc, printk(KERN_DEBUG "Target ID=0x%X\n", pg0->TargetID));
161         dsasprintk(ioc, printk(KERN_DEBUG "Bus=0x%X\n", pg0->Bus));
162         /* The PhyNum field specifies the PHY number of the parent
163          * device this device is linked to
164          */
165         dsasprintk(ioc, printk(KERN_DEBUG "Parent Phy Num=0x%X\n", pg0->PhyNum));
166         dsasprintk(ioc, printk(KERN_DEBUG "Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus)));
167         dsasprintk(ioc, printk(KERN_DEBUG "Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo)));
168         dsasprintk(ioc, printk(KERN_DEBUG "Flags=0x%X\n", le16_to_cpu(pg0->Flags)));
169         dsasprintk(ioc, printk(KERN_DEBUG "Physical Port=0x%X\n\n", pg0->PhysicalPort));
170 }
171
172 static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
173 {
174         dsasprintk(ioc, printk(KERN_DEBUG "---- SAS EXPANDER PAGE 1 ------------\n"));
175         dsasprintk(ioc, printk(KERN_DEBUG "Physical Port=0x%X\n", pg1->PhysicalPort));
176         dsasprintk(ioc, printk(KERN_DEBUG "PHY Identifier=0x%X\n", pg1->PhyIdentifier));
177         dsasprintk(ioc, printk(KERN_DEBUG "Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate));
178         dsasprintk(ioc, printk(KERN_DEBUG "Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate));
179         dsasprintk(ioc, printk(KERN_DEBUG "Hardware Link Rate=0x%X\n", pg1->HwLinkRate));
180         dsasprintk(ioc, printk(KERN_DEBUG "Owner Device Handle=0x%X\n",
181                         le16_to_cpu(pg1->OwnerDevHandle)));
182         dsasprintk(ioc, printk(KERN_DEBUG "Attached Device Handle=0x%X\n\n",
183                         le16_to_cpu(pg1->AttachedDevHandle)));
184 }
185
186 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
187 {
188         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
189         return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
190 }
191
192 static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
193 {
194         struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
195         return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
196 }
197
198 /*
199  * mptsas_find_portinfo_by_handle
200  *
201  * This function should be called with the sas_topology_mutex already held
202  */
203 static struct mptsas_portinfo *
204 mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
205 {
206         struct mptsas_portinfo *port_info, *rc=NULL;
207         int i;
208
209         list_for_each_entry(port_info, &ioc->sas_topology, list)
210                 for (i = 0; i < port_info->num_phys; i++)
211                         if (port_info->phy_info[i].identify.handle == handle) {
212                                 rc = port_info;
213                                 goto out;
214                         }
215  out:
216         return rc;
217 }
218
219 /*
220  * Returns true if there is a scsi end device
221  */
222 static inline int
223 mptsas_is_end_device(struct mptsas_devinfo * attached)
224 {
225         if ((attached->sas_address) &&
226             (attached->device_info &
227             MPI_SAS_DEVICE_INFO_END_DEVICE) &&
228             ((attached->device_info &
229             MPI_SAS_DEVICE_INFO_SSP_TARGET) |
230             (attached->device_info &
231             MPI_SAS_DEVICE_INFO_STP_TARGET) |
232             (attached->device_info &
233             MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
234                 return 1;
235         else
236                 return 0;
237 }
238
239 /* no mutex */
240 static void
241 mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
242 {
243         struct mptsas_portinfo *port_info;
244         struct mptsas_phyinfo *phy_info;
245         u8      i;
246
247         if (!port_details)
248                 return;
249
250         port_info = port_details->port_info;
251         phy_info = port_info->phy_info;
252
253         dsaswideprintk(ioc, printk(KERN_DEBUG "%s: [%p]: num_phys=%02d "
254             "bitmask=0x%016llX\n", __FUNCTION__, port_details,
255             port_details->num_phys, (unsigned long long)
256             port_details->phy_bitmask));
257
258         for (i = 0; i < port_info->num_phys; i++, phy_info++) {
259                 if(phy_info->port_details != port_details)
260                         continue;
261                 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
262                 phy_info->port_details = NULL;
263         }
264         kfree(port_details);
265 }
266
267 static inline struct sas_rphy *
268 mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
269 {
270         if (phy_info->port_details)
271                 return phy_info->port_details->rphy;
272         else
273                 return NULL;
274 }
275
276 static inline void
277 mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
278 {
279         if (phy_info->port_details) {
280                 phy_info->port_details->rphy = rphy;
281                 dsaswideprintk(ioc, printk(KERN_DEBUG "sas_rphy_add: rphy=%p\n", rphy));
282         }
283
284         if (rphy) {
285                 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
286                     &rphy->dev, "add:"));
287                 dsaswideprintk(ioc, printk(KERN_DEBUG "rphy=%p release=%p\n",
288                         rphy, rphy->dev.release));
289         }
290 }
291
292 static inline struct sas_port *
293 mptsas_get_port(struct mptsas_phyinfo *phy_info)
294 {
295         if (phy_info->port_details)
296                 return phy_info->port_details->port;
297         else
298                 return NULL;
299 }
300
301 static inline void
302 mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_port *port)
303 {
304         if (phy_info->port_details)
305                 phy_info->port_details->port = port;
306
307         if (port) {
308                 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
309                     &port->dev, "add:"));
310                 dsaswideprintk(ioc, printk(KERN_DEBUG "port=%p release=%p\n",
311                         port, port->dev.release));
312         }
313 }
314
315 static inline struct scsi_target *
316 mptsas_get_starget(struct mptsas_phyinfo *phy_info)
317 {
318         if (phy_info->port_details)
319                 return phy_info->port_details->starget;
320         else
321                 return NULL;
322 }
323
324 static inline void
325 mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
326 starget)
327 {
328         if (phy_info->port_details)
329                 phy_info->port_details->starget = starget;
330 }
331
332
333 /*
334  * mptsas_setup_wide_ports
335  *
336  * Updates for new and existing narrow/wide port configuration
337  * in the sas_topology
338  */
339 static void
340 mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
341 {
342         struct mptsas_portinfo_details * port_details;
343         struct mptsas_phyinfo *phy_info, *phy_info_cmp;
344         u64     sas_address;
345         int     i, j;
346
347         mutex_lock(&ioc->sas_topology_mutex);
348
349         phy_info = port_info->phy_info;
350         for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
351                 if (phy_info->attached.handle)
352                         continue;
353                 port_details = phy_info->port_details;
354                 if (!port_details)
355                         continue;
356                 if (port_details->num_phys < 2)
357                         continue;
358                 /*
359                  * Removing a phy from a port, letting the last
360                  * phy be removed by firmware events.
361                  */
362                 dsaswideprintk(ioc, printk(KERN_DEBUG
363                         "%s: [%p]: deleting phy = %d\n",
364                         __FUNCTION__, port_details, i));
365                 port_details->num_phys--;
366                 port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
367                 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
368                 sas_port_delete_phy(port_details->port, phy_info->phy);
369                 phy_info->port_details = NULL;
370         }
371
372         /*
373          * Populate and refresh the tree
374          */
375         phy_info = port_info->phy_info;
376         for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
377                 sas_address = phy_info->attached.sas_address;
378                 dsaswideprintk(ioc, printk(KERN_DEBUG "phy_id=%d sas_address=0x%018llX\n",
379                     i, (unsigned long long)sas_address));
380                 if (!sas_address)
381                         continue;
382                 port_details = phy_info->port_details;
383                 /*
384                  * Forming a port
385                  */
386                 if (!port_details) {
387                         port_details = kzalloc(sizeof(*port_details),
388                                 GFP_KERNEL);
389                         if (!port_details)
390                                 goto out;
391                         port_details->num_phys = 1;
392                         port_details->port_info = port_info;
393                         if (phy_info->phy_id < 64 )
394                                 port_details->phy_bitmask |=
395                                     (1 << phy_info->phy_id);
396                         phy_info->sas_port_add_phy=1;
397                         dsaswideprintk(ioc, printk(KERN_DEBUG "\t\tForming port\n\t\t"
398                             "phy_id=%d sas_address=0x%018llX\n",
399                             i, (unsigned long long)sas_address));
400                         phy_info->port_details = port_details;
401                 }
402
403                 if (i == port_info->num_phys - 1)
404                         continue;
405                 phy_info_cmp = &port_info->phy_info[i + 1];
406                 for (j = i + 1 ; j < port_info->num_phys ; j++,
407                     phy_info_cmp++) {
408                         if (!phy_info_cmp->attached.sas_address)
409                                 continue;
410                         if (sas_address != phy_info_cmp->attached.sas_address)
411                                 continue;
412                         if (phy_info_cmp->port_details == port_details )
413                                 continue;
414                         dsaswideprintk(ioc, printk(KERN_DEBUG
415                             "\t\tphy_id=%d sas_address=0x%018llX\n",
416                             j, (unsigned long long)
417                             phy_info_cmp->attached.sas_address));
418                         if (phy_info_cmp->port_details) {
419                                 port_details->rphy =
420                                     mptsas_get_rphy(phy_info_cmp);
421                                 port_details->port =
422                                     mptsas_get_port(phy_info_cmp);
423                                 port_details->starget =
424                                     mptsas_get_starget(phy_info_cmp);
425                                 port_details->num_phys =
426                                         phy_info_cmp->port_details->num_phys;
427                                 if (!phy_info_cmp->port_details->num_phys)
428                                         kfree(phy_info_cmp->port_details);
429                         } else
430                                 phy_info_cmp->sas_port_add_phy=1;
431                         /*
432                          * Adding a phy to a port
433                          */
434                         phy_info_cmp->port_details = port_details;
435                         if (phy_info_cmp->phy_id < 64 )
436                                 port_details->phy_bitmask |=
437                                 (1 << phy_info_cmp->phy_id);
438                         port_details->num_phys++;
439                 }
440         }
441
442  out:
443
444         for (i = 0; i < port_info->num_phys; i++) {
445                 port_details = port_info->phy_info[i].port_details;
446                 if (!port_details)
447                         continue;
448                 dsaswideprintk(ioc, printk(KERN_DEBUG
449                     "%s: [%p]: phy_id=%02d num_phys=%02d "
450                     "bitmask=0x%016llX\n", __FUNCTION__,
451                     port_details, i, port_details->num_phys,
452                     (unsigned long long)port_details->phy_bitmask));
453                 dsaswideprintk(ioc, printk(KERN_DEBUG"\t\tport = %p rphy=%p\n",
454                         port_details->port, port_details->rphy));
455         }
456         dsaswideprintk(ioc, printk(KERN_DEBUG"\n"));
457         mutex_unlock(&ioc->sas_topology_mutex);
458 }
459
460 /**
461  * csmisas_find_vtarget
462  *
463  * @ioc
464  * @volume_id
465  * @volume_bus
466  *
467  **/
468 static VirtTarget *
469 mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
470 {
471         struct scsi_device              *sdev;
472         VirtDevice                      *vdev;
473         VirtTarget                      *vtarget = NULL;
474
475         shost_for_each_device(sdev, ioc->sh) {
476                 if ((vdev = sdev->hostdata) == NULL)
477                         continue;
478                 if (vdev->vtarget->id == id &&
479                     vdev->vtarget->channel == channel)
480                         vtarget = vdev->vtarget;
481         }
482         return vtarget;
483 }
484
485 /**
486  * mptsas_target_reset
487  *
488  * Issues TARGET_RESET to end device using handshaking method
489  *
490  * @ioc
491  * @channel
492  * @id
493  *
494  * Returns (1) success
495  *         (0) failure
496  *
497  **/
498 static int
499 mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
500 {
501         MPT_FRAME_HDR   *mf;
502         SCSITaskMgmt_t  *pScsiTm;
503
504         if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
505                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames @%d!!\n",
506                     ioc->name,__FUNCTION__, __LINE__));
507                 return 0;
508         }
509
510         /* Format the Request
511          */
512         pScsiTm = (SCSITaskMgmt_t *) mf;
513         memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
514         pScsiTm->TargetID = id;
515         pScsiTm->Bus = channel;
516         pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
517         pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
518         pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
519
520         DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
521
522         mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
523
524         return 1;
525 }
526
527 /**
528  * mptsas_target_reset_queue
529  *
530  * Receive request for TARGET_RESET after recieving an firmware
531  * event NOT_RESPONDING_EVENT, then put command in link list
532  * and queue if task_queue already in use.
533  *
534  * @ioc
535  * @sas_event_data
536  *
537  **/
538 static void
539 mptsas_target_reset_queue(MPT_ADAPTER *ioc,
540     EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
541 {
542         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
543         VirtTarget *vtarget = NULL;
544         struct mptsas_target_reset_event *target_reset_list;
545         u8              id, channel;
546
547         id = sas_event_data->TargetID;
548         channel = sas_event_data->Bus;
549
550         if (!(vtarget = mptsas_find_vtarget(ioc, channel, id)))
551                 return;
552
553         vtarget->deleted = 1; /* block IO */
554
555         target_reset_list = kzalloc(sizeof(*target_reset_list),
556             GFP_ATOMIC);
557         if (!target_reset_list) {
558                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",
559                     ioc->name,__FUNCTION__, __LINE__));
560                 return;
561         }
562
563         memcpy(&target_reset_list->sas_event_data, sas_event_data,
564                 sizeof(*sas_event_data));
565         list_add_tail(&target_reset_list->list, &hd->target_reset_list);
566
567         if (hd->resetPending)
568                 return;
569
570         if (mptsas_target_reset(ioc, channel, id)) {
571                 target_reset_list->target_reset_issued = 1;
572                 hd->resetPending = 1;
573         }
574 }
575
576 /**
577  * mptsas_dev_reset_complete
578  *
579  * Completion for TARGET_RESET after NOT_RESPONDING_EVENT,
580  * enable work queue to finish off removing device from upper layers.
581  * then send next TARGET_RESET in the queue.
582  *
583  * @ioc
584  *
585  **/
586 static void
587 mptsas_dev_reset_complete(MPT_ADAPTER *ioc)
588 {
589         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
590         struct list_head *head = &hd->target_reset_list;
591         struct mptsas_target_reset_event *target_reset_list;
592         struct mptsas_hotplug_event *ev;
593         EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
594         u8              id, channel;
595         __le64          sas_address;
596
597         if (list_empty(head))
598                 return;
599
600         target_reset_list = list_entry(head->next, struct mptsas_target_reset_event, list);
601
602         sas_event_data = &target_reset_list->sas_event_data;
603         id = sas_event_data->TargetID;
604         channel = sas_event_data->Bus;
605         hd->resetPending = 0;
606
607         /*
608          * retry target reset
609          */
610         if (!target_reset_list->target_reset_issued) {
611                 if (mptsas_target_reset(ioc, channel, id)) {
612                         target_reset_list->target_reset_issued = 1;
613                         hd->resetPending = 1;
614                 }
615                 return;
616         }
617
618         /*
619          * enable work queue to remove device from upper layers
620          */
621         list_del(&target_reset_list->list);
622
623         ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
624         if (!ev) {
625                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",
626                     ioc->name,__FUNCTION__, __LINE__));
627                 return;
628         }
629
630         INIT_WORK(&ev->work, mptsas_hotplug_work);
631         ev->ioc = ioc;
632         ev->handle = le16_to_cpu(sas_event_data->DevHandle);
633         ev->parent_handle =
634             le16_to_cpu(sas_event_data->ParentDevHandle);
635         ev->channel = channel;
636         ev->id =id;
637         ev->phy_id = sas_event_data->PhyNum;
638         memcpy(&sas_address, &sas_event_data->SASAddress,
639             sizeof(__le64));
640         ev->sas_address = le64_to_cpu(sas_address);
641         ev->device_info = le32_to_cpu(sas_event_data->DeviceInfo);
642         ev->event_type = MPTSAS_DEL_DEVICE;
643         schedule_work(&ev->work);
644         kfree(target_reset_list);
645
646         /*
647          * issue target reset to next device in the queue
648          */
649
650         head = &hd->target_reset_list;
651         if (list_empty(head))
652                 return;
653
654         target_reset_list = list_entry(head->next, struct mptsas_target_reset_event,
655             list);
656
657         sas_event_data = &target_reset_list->sas_event_data;
658         id = sas_event_data->TargetID;
659         channel = sas_event_data->Bus;
660
661         if (mptsas_target_reset(ioc, channel, id)) {
662                 target_reset_list->target_reset_issued = 1;
663                 hd->resetPending = 1;
664         }
665 }
666
667 /**
668  * mptsas_taskmgmt_complete
669  *
670  * @ioc
671  * @mf
672  * @mr
673  *
674  **/
675 static int
676 mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
677 {
678         mptsas_dev_reset_complete(ioc);
679         return mptscsih_taskmgmt_complete(ioc, mf, mr);
680 }
681
682 /**
683  * mptscsih_ioc_reset
684  *
685  * @ioc
686  * @reset_phase
687  *
688  **/
689 static int
690 mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
691 {
692         MPT_SCSI_HOST   *hd;
693         struct mptsas_target_reset_event *target_reset_list, *n;
694         int rc;
695
696         rc = mptscsih_ioc_reset(ioc, reset_phase);
697
698         if (ioc->bus_type != SAS)
699                 goto out;
700
701         if (reset_phase != MPT_IOC_POST_RESET)
702                 goto out;
703
704         if (!ioc->sh || !ioc->sh->hostdata)
705                 goto out;
706         hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
707         if (!hd->ioc)
708                 goto out;
709
710         if (list_empty(&hd->target_reset_list))
711                 goto out;
712
713         /* flush the target_reset_list */
714         list_for_each_entry_safe(target_reset_list, n,
715             &hd->target_reset_list, list) {
716                 list_del(&target_reset_list->list);
717                 kfree(target_reset_list);
718         }
719
720  out:
721         return rc;
722 }
723
724 static int
725 mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
726                 u32 form, u32 form_specific)
727 {
728         ConfigExtendedPageHeader_t hdr;
729         CONFIGPARMS cfg;
730         SasEnclosurePage0_t *buffer;
731         dma_addr_t dma_handle;
732         int error;
733         __le64 le_identifier;
734
735         memset(&hdr, 0, sizeof(hdr));
736         hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
737         hdr.PageNumber = 0;
738         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
739         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
740
741         cfg.cfghdr.ehdr = &hdr;
742         cfg.physAddr = -1;
743         cfg.pageAddr = form + form_specific;
744         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
745         cfg.dir = 0;    /* read */
746         cfg.timeout = 10;
747
748         error = mpt_config(ioc, &cfg);
749         if (error)
750                 goto out;
751         if (!hdr.ExtPageLength) {
752                 error = -ENXIO;
753                 goto out;
754         }
755
756         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
757                         &dma_handle);
758         if (!buffer) {
759                 error = -ENOMEM;
760                 goto out;
761         }
762
763         cfg.physAddr = dma_handle;
764         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
765
766         error = mpt_config(ioc, &cfg);
767         if (error)
768                 goto out_free_consistent;
769
770         /* save config data */
771         memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
772         enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
773         enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
774         enclosure->flags = le16_to_cpu(buffer->Flags);
775         enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
776         enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
777         enclosure->start_id = buffer->StartTargetID;
778         enclosure->start_channel = buffer->StartBus;
779         enclosure->sep_id = buffer->SEPTargetID;
780         enclosure->sep_channel = buffer->SEPBus;
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_slave_configure(struct scsi_device *sdev)
791 {
792
793         if (sdev->channel == MPTSAS_RAID_CHANNEL)
794                 goto out;
795
796         sas_read_port_mode_page(sdev);
797
798  out:
799         return mptscsih_slave_configure(sdev);
800 }
801
802 static int
803 mptsas_target_alloc(struct scsi_target *starget)
804 {
805         struct Scsi_Host *host = dev_to_shost(&starget->dev);
806         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
807         VirtTarget              *vtarget;
808         u8                      id, channel;
809         struct sas_rphy         *rphy;
810         struct mptsas_portinfo  *p;
811         int                      i;
812
813         vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
814         if (!vtarget)
815                 return -ENOMEM;
816
817         vtarget->starget = starget;
818         vtarget->ioc_id = hd->ioc->id;
819         vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
820         id = starget->id;
821         channel = 0;
822
823         /*
824          * RAID volumes placed beyond the last expected port.
825          */
826         if (starget->channel == MPTSAS_RAID_CHANNEL) {
827                 for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
828                         if (id == hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID)
829                                 channel = hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus;
830                 goto out;
831         }
832
833         rphy = dev_to_rphy(starget->dev.parent);
834         mutex_lock(&hd->ioc->sas_topology_mutex);
835         list_for_each_entry(p, &hd->ioc->sas_topology, list) {
836                 for (i = 0; i < p->num_phys; i++) {
837                         if (p->phy_info[i].attached.sas_address !=
838                                         rphy->identify.sas_address)
839                                 continue;
840                         id = p->phy_info[i].attached.id;
841                         channel = p->phy_info[i].attached.channel;
842                         mptsas_set_starget(&p->phy_info[i], starget);
843
844                         /*
845                          * Exposing hidden raid components
846                          */
847                         if (mptscsih_is_phys_disk(hd->ioc, channel, id)) {
848                                 id = mptscsih_raid_id_to_num(hd->ioc,
849                                                 channel, id);
850                                 vtarget->tflags |=
851                                     MPT_TARGET_FLAGS_RAID_COMPONENT;
852                                 p->phy_info[i].attached.phys_disk_num = id;
853                         }
854                         mutex_unlock(&hd->ioc->sas_topology_mutex);
855                         goto out;
856                 }
857         }
858         mutex_unlock(&hd->ioc->sas_topology_mutex);
859
860         kfree(vtarget);
861         return -ENXIO;
862
863  out:
864         vtarget->id = id;
865         vtarget->channel = channel;
866         starget->hostdata = vtarget;
867         return 0;
868 }
869
870 static void
871 mptsas_target_destroy(struct scsi_target *starget)
872 {
873         struct Scsi_Host *host = dev_to_shost(&starget->dev);
874         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
875         struct sas_rphy         *rphy;
876         struct mptsas_portinfo  *p;
877         int                      i;
878
879         if (!starget->hostdata)
880                 return;
881
882         if (starget->channel == MPTSAS_RAID_CHANNEL)
883                 goto out;
884
885         rphy = dev_to_rphy(starget->dev.parent);
886         list_for_each_entry(p, &hd->ioc->sas_topology, list) {
887                 for (i = 0; i < p->num_phys; i++) {
888                         if (p->phy_info[i].attached.sas_address !=
889                                         rphy->identify.sas_address)
890                                 continue;
891                         mptsas_set_starget(&p->phy_info[i], NULL);
892                         goto out;
893                 }
894         }
895
896  out:
897         kfree(starget->hostdata);
898         starget->hostdata = NULL;
899 }
900
901
902 static int
903 mptsas_slave_alloc(struct scsi_device *sdev)
904 {
905         struct Scsi_Host        *host = sdev->host;
906         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
907         struct sas_rphy         *rphy;
908         struct mptsas_portinfo  *p;
909         VirtDevice              *vdev;
910         struct scsi_target      *starget;
911         int                     i;
912
913         vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
914         if (!vdev) {
915                 printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
916                                 hd->ioc->name, sizeof(VirtDevice));
917                 return -ENOMEM;
918         }
919         starget = scsi_target(sdev);
920         vdev->vtarget = starget->hostdata;
921
922         if (sdev->channel == MPTSAS_RAID_CHANNEL)
923                 goto out;
924
925         rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
926         mutex_lock(&hd->ioc->sas_topology_mutex);
927         list_for_each_entry(p, &hd->ioc->sas_topology, list) {
928                 for (i = 0; i < p->num_phys; i++) {
929                         if (p->phy_info[i].attached.sas_address !=
930                                         rphy->identify.sas_address)
931                                 continue;
932                         vdev->lun = sdev->lun;
933                         /*
934                          * Exposing hidden raid components
935                          */
936                         if (mptscsih_is_phys_disk(hd->ioc,
937                             p->phy_info[i].attached.channel,
938                             p->phy_info[i].attached.id))
939                                 sdev->no_uld_attach = 1;
940                         mutex_unlock(&hd->ioc->sas_topology_mutex);
941                         goto out;
942                 }
943         }
944         mutex_unlock(&hd->ioc->sas_topology_mutex);
945
946         kfree(vdev);
947         return -ENXIO;
948
949  out:
950         vdev->vtarget->num_luns++;
951         sdev->hostdata = vdev;
952         return 0;
953 }
954
955 static int
956 mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
957 {
958         VirtDevice      *vdev = SCpnt->device->hostdata;
959
960         if (!vdev || !vdev->vtarget || vdev->vtarget->deleted) {
961                 SCpnt->result = DID_NO_CONNECT << 16;
962                 done(SCpnt);
963                 return 0;
964         }
965
966 //      scsi_print_command(SCpnt);
967
968         return mptscsih_qcmd(SCpnt,done);
969 }
970
971
972 static struct scsi_host_template mptsas_driver_template = {
973         .module                         = THIS_MODULE,
974         .proc_name                      = "mptsas",
975         .proc_info                      = mptscsih_proc_info,
976         .name                           = "MPT SPI Host",
977         .info                           = mptscsih_info,
978         .queuecommand                   = mptsas_qcmd,
979         .target_alloc                   = mptsas_target_alloc,
980         .slave_alloc                    = mptsas_slave_alloc,
981         .slave_configure                = mptsas_slave_configure,
982         .target_destroy                 = mptsas_target_destroy,
983         .slave_destroy                  = mptscsih_slave_destroy,
984         .change_queue_depth             = mptscsih_change_queue_depth,
985         .eh_abort_handler               = mptscsih_abort,
986         .eh_device_reset_handler        = mptscsih_dev_reset,
987         .eh_bus_reset_handler           = mptscsih_bus_reset,
988         .eh_host_reset_handler          = mptscsih_host_reset,
989         .bios_param                     = mptscsih_bios_param,
990         .can_queue                      = MPT_FC_CAN_QUEUE,
991         .this_id                        = -1,
992         .sg_tablesize                   = MPT_SCSI_SG_DEPTH,
993         .max_sectors                    = 8192,
994         .cmd_per_lun                    = 7,
995         .use_clustering                 = ENABLE_CLUSTERING,
996         .shost_attrs                    = mptscsih_host_attrs,
997 };
998
999 static int mptsas_get_linkerrors(struct sas_phy *phy)
1000 {
1001         MPT_ADAPTER *ioc = phy_to_ioc(phy);
1002         ConfigExtendedPageHeader_t hdr;
1003         CONFIGPARMS cfg;
1004         SasPhyPage1_t *buffer;
1005         dma_addr_t dma_handle;
1006         int error;
1007
1008         /* FIXME: only have link errors on local phys */
1009         if (!scsi_is_sas_phy_local(phy))
1010                 return -EINVAL;
1011
1012         hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
1013         hdr.ExtPageLength = 0;
1014         hdr.PageNumber = 1 /* page number 1*/;
1015         hdr.Reserved1 = 0;
1016         hdr.Reserved2 = 0;
1017         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1018         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1019
1020         cfg.cfghdr.ehdr = &hdr;
1021         cfg.physAddr = -1;
1022         cfg.pageAddr = phy->identify.phy_identifier;
1023         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1024         cfg.dir = 0;    /* read */
1025         cfg.timeout = 10;
1026
1027         error = mpt_config(ioc, &cfg);
1028         if (error)
1029                 return error;
1030         if (!hdr.ExtPageLength)
1031                 return -ENXIO;
1032
1033         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1034                                       &dma_handle);
1035         if (!buffer)
1036                 return -ENOMEM;
1037
1038         cfg.physAddr = dma_handle;
1039         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1040
1041         error = mpt_config(ioc, &cfg);
1042         if (error)
1043                 goto out_free_consistent;
1044
1045         mptsas_print_phy_pg1(ioc, buffer);
1046
1047         phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
1048         phy->running_disparity_error_count =
1049                 le32_to_cpu(buffer->RunningDisparityErrorCount);
1050         phy->loss_of_dword_sync_count =
1051                 le32_to_cpu(buffer->LossDwordSynchCount);
1052         phy->phy_reset_problem_count =
1053                 le32_to_cpu(buffer->PhyResetProblemCount);
1054
1055  out_free_consistent:
1056         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1057                             buffer, dma_handle);
1058         return error;
1059 }
1060
1061 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
1062                 MPT_FRAME_HDR *reply)
1063 {
1064         ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
1065         if (reply != NULL) {
1066                 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
1067                 memcpy(ioc->sas_mgmt.reply, reply,
1068                     min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
1069         }
1070         complete(&ioc->sas_mgmt.done);
1071         return 1;
1072 }
1073
1074 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
1075 {
1076         MPT_ADAPTER *ioc = phy_to_ioc(phy);
1077         SasIoUnitControlRequest_t *req;
1078         SasIoUnitControlReply_t *reply;
1079         MPT_FRAME_HDR *mf;
1080         MPIHeader_t *hdr;
1081         unsigned long timeleft;
1082         int error = -ERESTARTSYS;
1083
1084         /* FIXME: fusion doesn't allow non-local phy reset */
1085         if (!scsi_is_sas_phy_local(phy))
1086                 return -EINVAL;
1087
1088         /* not implemented for expanders */
1089         if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
1090                 return -ENXIO;
1091
1092         if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
1093                 goto out;
1094
1095         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
1096         if (!mf) {
1097                 error = -ENOMEM;
1098                 goto out_unlock;
1099         }
1100
1101         hdr = (MPIHeader_t *) mf;
1102         req = (SasIoUnitControlRequest_t *)mf;
1103         memset(req, 0, sizeof(SasIoUnitControlRequest_t));
1104         req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
1105         req->MsgContext = hdr->MsgContext;
1106         req->Operation = hard_reset ?
1107                 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
1108         req->PhyNum = phy->identify.phy_identifier;
1109
1110         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1111
1112         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
1113                         10 * HZ);
1114         if (!timeleft) {
1115                 /* On timeout reset the board */
1116                 mpt_free_msg_frame(ioc, mf);
1117                 mpt_HardResetHandler(ioc, CAN_SLEEP);
1118                 error = -ETIMEDOUT;
1119                 goto out_unlock;
1120         }
1121
1122         /* a reply frame is expected */
1123         if ((ioc->sas_mgmt.status &
1124             MPT_IOCTL_STATUS_RF_VALID) == 0) {
1125                 error = -ENXIO;
1126                 goto out_unlock;
1127         }
1128
1129         /* process the completed Reply Message Frame */
1130         reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
1131         if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
1132                 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
1133                     __FUNCTION__,
1134                     reply->IOCStatus,
1135                     reply->IOCLogInfo);
1136                 error = -ENXIO;
1137                 goto out_unlock;
1138         }
1139
1140         error = 0;
1141
1142  out_unlock:
1143         mutex_unlock(&ioc->sas_mgmt.mutex);
1144  out:
1145         return error;
1146 }
1147
1148 static int
1149 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
1150 {
1151         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1152         int i, error;
1153         struct mptsas_portinfo *p;
1154         struct mptsas_enclosure enclosure_info;
1155         u64 enclosure_handle;
1156
1157         mutex_lock(&ioc->sas_topology_mutex);
1158         list_for_each_entry(p, &ioc->sas_topology, list) {
1159                 for (i = 0; i < p->num_phys; i++) {
1160                         if (p->phy_info[i].attached.sas_address ==
1161                             rphy->identify.sas_address) {
1162                                 enclosure_handle = p->phy_info[i].
1163                                         attached.handle_enclosure;
1164                                 goto found_info;
1165                         }
1166                 }
1167         }
1168         mutex_unlock(&ioc->sas_topology_mutex);
1169         return -ENXIO;
1170
1171  found_info:
1172         mutex_unlock(&ioc->sas_topology_mutex);
1173         memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
1174         error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
1175                         (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
1176                          MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
1177         if (!error)
1178                 *identifier = enclosure_info.enclosure_logical_id;
1179         return error;
1180 }
1181
1182 static int
1183 mptsas_get_bay_identifier(struct sas_rphy *rphy)
1184 {
1185         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1186         struct mptsas_portinfo *p;
1187         int i, rc;
1188
1189         mutex_lock(&ioc->sas_topology_mutex);
1190         list_for_each_entry(p, &ioc->sas_topology, list) {
1191                 for (i = 0; i < p->num_phys; i++) {
1192                         if (p->phy_info[i].attached.sas_address ==
1193                             rphy->identify.sas_address) {
1194                                 rc = p->phy_info[i].attached.slot;
1195                                 goto out;
1196                         }
1197                 }
1198         }
1199         rc = -ENXIO;
1200  out:
1201         mutex_unlock(&ioc->sas_topology_mutex);
1202         return rc;
1203 }
1204
1205 static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1206                               struct request *req)
1207 {
1208         MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
1209         MPT_FRAME_HDR *mf;
1210         SmpPassthroughRequest_t *smpreq;
1211         struct request *rsp = req->next_rq;
1212         int ret;
1213         int flagsLength;
1214         unsigned long timeleft;
1215         char *psge;
1216         dma_addr_t dma_addr_in = 0;
1217         dma_addr_t dma_addr_out = 0;
1218         u64 sas_address = 0;
1219
1220         if (!rsp) {
1221                 printk(KERN_ERR "%s: the smp response space is missing\n",
1222                        __FUNCTION__);
1223                 return -EINVAL;
1224         }
1225
1226         /* do we need to support multiple segments? */
1227         if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
1228                 printk(KERN_ERR "%s: multiple segments req %u %u, rsp %u %u\n",
1229                        __FUNCTION__, req->bio->bi_vcnt, req->data_len,
1230                        rsp->bio->bi_vcnt, rsp->data_len);
1231                 return -EINVAL;
1232         }
1233
1234         ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
1235         if (ret)
1236                 goto out;
1237
1238         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
1239         if (!mf) {
1240                 ret = -ENOMEM;
1241                 goto out_unlock;
1242         }
1243
1244         smpreq = (SmpPassthroughRequest_t *)mf;
1245         memset(smpreq, 0, sizeof(*smpreq));
1246
1247         smpreq->RequestDataLength = cpu_to_le16(req->data_len - 4);
1248         smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
1249
1250         if (rphy)
1251                 sas_address = rphy->identify.sas_address;
1252         else {
1253                 struct mptsas_portinfo *port_info;
1254
1255                 mutex_lock(&ioc->sas_topology_mutex);
1256                 port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
1257                 if (port_info && port_info->phy_info)
1258                         sas_address =
1259                                 port_info->phy_info[0].phy->identify.sas_address;
1260                 mutex_unlock(&ioc->sas_topology_mutex);
1261         }
1262
1263         *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
1264
1265         psge = (char *)
1266                 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
1267
1268         /* request */
1269         flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1270                        MPI_SGE_FLAGS_END_OF_BUFFER |
1271                        MPI_SGE_FLAGS_DIRECTION |
1272                        mpt_addr_size()) << MPI_SGE_FLAGS_SHIFT;
1273         flagsLength |= (req->data_len - 4);
1274
1275         dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
1276                                       req->data_len, PCI_DMA_BIDIRECTIONAL);
1277         if (!dma_addr_out)
1278                 goto put_mf;
1279         mpt_add_sge(psge, flagsLength, dma_addr_out);
1280         psge += (sizeof(u32) + sizeof(dma_addr_t));
1281
1282         /* response */
1283         flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
1284         flagsLength |= rsp->data_len + 4;
1285         dma_addr_in =  pci_map_single(ioc->pcidev, bio_data(rsp->bio),
1286                                       rsp->data_len, PCI_DMA_BIDIRECTIONAL);
1287         if (!dma_addr_in)
1288                 goto unmap;
1289         mpt_add_sge(psge, flagsLength, dma_addr_in);
1290
1291         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1292
1293         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
1294         if (!timeleft) {
1295                 printk(KERN_ERR "%s: smp timeout!\n", __FUNCTION__);
1296                 /* On timeout reset the board */
1297                 mpt_HardResetHandler(ioc, CAN_SLEEP);
1298                 ret = -ETIMEDOUT;
1299                 goto unmap;
1300         }
1301         mf = NULL;
1302
1303         if (ioc->sas_mgmt.status & MPT_IOCTL_STATUS_RF_VALID) {
1304                 SmpPassthroughReply_t *smprep;
1305
1306                 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
1307                 memcpy(req->sense, smprep, sizeof(*smprep));
1308                 req->sense_len = sizeof(*smprep);
1309         } else {
1310                 printk(KERN_ERR "%s: smp passthru reply failed to be returned\n",
1311                        __FUNCTION__);
1312                 ret = -ENXIO;
1313         }
1314 unmap:
1315         if (dma_addr_out)
1316                 pci_unmap_single(ioc->pcidev, dma_addr_out, req->data_len,
1317                                  PCI_DMA_BIDIRECTIONAL);
1318         if (dma_addr_in)
1319                 pci_unmap_single(ioc->pcidev, dma_addr_in, rsp->data_len,
1320                                  PCI_DMA_BIDIRECTIONAL);
1321 put_mf:
1322         if (mf)
1323                 mpt_free_msg_frame(ioc, mf);
1324 out_unlock:
1325         mutex_unlock(&ioc->sas_mgmt.mutex);
1326 out:
1327         return ret;
1328 }
1329
1330 static struct sas_function_template mptsas_transport_functions = {
1331         .get_linkerrors         = mptsas_get_linkerrors,
1332         .get_enclosure_identifier = mptsas_get_enclosure_identifier,
1333         .get_bay_identifier     = mptsas_get_bay_identifier,
1334         .phy_reset              = mptsas_phy_reset,
1335         .smp_handler            = mptsas_smp_handler,
1336 };
1337
1338 static struct scsi_transport_template *mptsas_transport_template;
1339
1340 static int
1341 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
1342 {
1343         ConfigExtendedPageHeader_t hdr;
1344         CONFIGPARMS cfg;
1345         SasIOUnitPage0_t *buffer;
1346         dma_addr_t dma_handle;
1347         int error, i;
1348
1349         hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
1350         hdr.ExtPageLength = 0;
1351         hdr.PageNumber = 0;
1352         hdr.Reserved1 = 0;
1353         hdr.Reserved2 = 0;
1354         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1355         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1356
1357         cfg.cfghdr.ehdr = &hdr;
1358         cfg.physAddr = -1;
1359         cfg.pageAddr = 0;
1360         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1361         cfg.dir = 0;    /* read */
1362         cfg.timeout = 10;
1363
1364         error = mpt_config(ioc, &cfg);
1365         if (error)
1366                 goto out;
1367         if (!hdr.ExtPageLength) {
1368                 error = -ENXIO;
1369                 goto out;
1370         }
1371
1372         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1373                                             &dma_handle);
1374         if (!buffer) {
1375                 error = -ENOMEM;
1376                 goto out;
1377         }
1378
1379         cfg.physAddr = dma_handle;
1380         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1381
1382         error = mpt_config(ioc, &cfg);
1383         if (error)
1384                 goto out_free_consistent;
1385
1386         port_info->num_phys = buffer->NumPhys;
1387         port_info->phy_info = kcalloc(port_info->num_phys,
1388                 sizeof(*port_info->phy_info),GFP_KERNEL);
1389         if (!port_info->phy_info) {
1390                 error = -ENOMEM;
1391                 goto out_free_consistent;
1392         }
1393
1394         ioc->nvdata_version_persistent =
1395             le16_to_cpu(buffer->NvdataVersionPersistent);
1396         ioc->nvdata_version_default =
1397             le16_to_cpu(buffer->NvdataVersionDefault);
1398
1399         for (i = 0; i < port_info->num_phys; i++) {
1400                 mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
1401                 port_info->phy_info[i].phy_id = i;
1402                 port_info->phy_info[i].port_id =
1403                     buffer->PhyData[i].Port;
1404                 port_info->phy_info[i].negotiated_link_rate =
1405                     buffer->PhyData[i].NegotiatedLinkRate;
1406                 port_info->phy_info[i].portinfo = port_info;
1407                 port_info->phy_info[i].handle =
1408                     le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
1409         }
1410
1411  out_free_consistent:
1412         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1413                             buffer, dma_handle);
1414  out:
1415         return error;
1416 }
1417
1418 static int
1419 mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
1420 {
1421         ConfigExtendedPageHeader_t hdr;
1422         CONFIGPARMS cfg;
1423         SasIOUnitPage1_t *buffer;
1424         dma_addr_t dma_handle;
1425         int error;
1426         u16 device_missing_delay;
1427
1428         memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
1429         memset(&cfg, 0, sizeof(CONFIGPARMS));
1430
1431         cfg.cfghdr.ehdr = &hdr;
1432         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1433         cfg.timeout = 10;
1434         cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1435         cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1436         cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
1437         cfg.cfghdr.ehdr->PageNumber = 1;
1438
1439         error = mpt_config(ioc, &cfg);
1440         if (error)
1441                 goto out;
1442         if (!hdr.ExtPageLength) {
1443                 error = -ENXIO;
1444                 goto out;
1445         }
1446
1447         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1448                                             &dma_handle);
1449         if (!buffer) {
1450                 error = -ENOMEM;
1451                 goto out;
1452         }
1453
1454         cfg.physAddr = dma_handle;
1455         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1456
1457         error = mpt_config(ioc, &cfg);
1458         if (error)
1459                 goto out_free_consistent;
1460
1461         ioc->io_missing_delay  =
1462             le16_to_cpu(buffer->IODeviceMissingDelay);
1463         device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay);
1464         ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
1465             (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
1466             device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
1467
1468  out_free_consistent:
1469         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1470                             buffer, dma_handle);
1471  out:
1472         return error;
1473 }
1474
1475 static int
1476 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1477                 u32 form, u32 form_specific)
1478 {
1479         ConfigExtendedPageHeader_t hdr;
1480         CONFIGPARMS cfg;
1481         SasPhyPage0_t *buffer;
1482         dma_addr_t dma_handle;
1483         int error;
1484
1485         hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
1486         hdr.ExtPageLength = 0;
1487         hdr.PageNumber = 0;
1488         hdr.Reserved1 = 0;
1489         hdr.Reserved2 = 0;
1490         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1491         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1492
1493         cfg.cfghdr.ehdr = &hdr;
1494         cfg.dir = 0;    /* read */
1495         cfg.timeout = 10;
1496
1497         /* Get Phy Pg 0 for each Phy. */
1498         cfg.physAddr = -1;
1499         cfg.pageAddr = form + form_specific;
1500         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1501
1502         error = mpt_config(ioc, &cfg);
1503         if (error)
1504                 goto out;
1505
1506         if (!hdr.ExtPageLength) {
1507                 error = -ENXIO;
1508                 goto out;
1509         }
1510
1511         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1512                                       &dma_handle);
1513         if (!buffer) {
1514                 error = -ENOMEM;
1515                 goto out;
1516         }
1517
1518         cfg.physAddr = dma_handle;
1519         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1520
1521         error = mpt_config(ioc, &cfg);
1522         if (error)
1523                 goto out_free_consistent;
1524
1525         mptsas_print_phy_pg0(ioc, buffer);
1526
1527         phy_info->hw_link_rate = buffer->HwLinkRate;
1528         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1529         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1530         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1531
1532  out_free_consistent:
1533         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1534                             buffer, dma_handle);
1535  out:
1536         return error;
1537 }
1538
1539 static int
1540 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
1541                 u32 form, u32 form_specific)
1542 {
1543         ConfigExtendedPageHeader_t hdr;
1544         CONFIGPARMS cfg;
1545         SasDevicePage0_t *buffer;
1546         dma_addr_t dma_handle;
1547         __le64 sas_address;
1548         int error=0;
1549
1550         if (ioc->sas_discovery_runtime &&
1551                 mptsas_is_end_device(device_info))
1552                         goto out;
1553
1554         hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
1555         hdr.ExtPageLength = 0;
1556         hdr.PageNumber = 0;
1557         hdr.Reserved1 = 0;
1558         hdr.Reserved2 = 0;
1559         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1560         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1561
1562         cfg.cfghdr.ehdr = &hdr;
1563         cfg.pageAddr = form + form_specific;
1564         cfg.physAddr = -1;
1565         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1566         cfg.dir = 0;    /* read */
1567         cfg.timeout = 10;
1568
1569         memset(device_info, 0, sizeof(struct mptsas_devinfo));
1570         error = mpt_config(ioc, &cfg);
1571         if (error)
1572                 goto out;
1573         if (!hdr.ExtPageLength) {
1574                 error = -ENXIO;
1575                 goto out;
1576         }
1577
1578         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1579                                       &dma_handle);
1580         if (!buffer) {
1581                 error = -ENOMEM;
1582                 goto out;
1583         }
1584
1585         cfg.physAddr = dma_handle;
1586         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1587
1588         error = mpt_config(ioc, &cfg);
1589         if (error)
1590                 goto out_free_consistent;
1591
1592         mptsas_print_device_pg0(ioc, buffer);
1593
1594         device_info->handle = le16_to_cpu(buffer->DevHandle);
1595         device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
1596         device_info->handle_enclosure =
1597             le16_to_cpu(buffer->EnclosureHandle);
1598         device_info->slot = le16_to_cpu(buffer->Slot);
1599         device_info->phy_id = buffer->PhyNum;
1600         device_info->port_id = buffer->PhysicalPort;
1601         device_info->id = buffer->TargetID;
1602         device_info->phys_disk_num = ~0;
1603         device_info->channel = buffer->Bus;
1604         memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
1605         device_info->sas_address = le64_to_cpu(sas_address);
1606         device_info->device_info =
1607             le32_to_cpu(buffer->DeviceInfo);
1608
1609  out_free_consistent:
1610         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1611                             buffer, dma_handle);
1612  out:
1613         return error;
1614 }
1615
1616 static int
1617 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
1618                 u32 form, u32 form_specific)
1619 {
1620         ConfigExtendedPageHeader_t hdr;
1621         CONFIGPARMS cfg;
1622         SasExpanderPage0_t *buffer;
1623         dma_addr_t dma_handle;
1624         int i, error;
1625
1626         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1627         hdr.ExtPageLength = 0;
1628         hdr.PageNumber = 0;
1629         hdr.Reserved1 = 0;
1630         hdr.Reserved2 = 0;
1631         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1632         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1633
1634         cfg.cfghdr.ehdr = &hdr;
1635         cfg.physAddr = -1;
1636         cfg.pageAddr = form + form_specific;
1637         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1638         cfg.dir = 0;    /* read */
1639         cfg.timeout = 10;
1640
1641         memset(port_info, 0, sizeof(struct mptsas_portinfo));
1642         error = mpt_config(ioc, &cfg);
1643         if (error)
1644                 goto out;
1645
1646         if (!hdr.ExtPageLength) {
1647                 error = -ENXIO;
1648                 goto out;
1649         }
1650
1651         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1652                                       &dma_handle);
1653         if (!buffer) {
1654                 error = -ENOMEM;
1655                 goto out;
1656         }
1657
1658         cfg.physAddr = dma_handle;
1659         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1660
1661         error = mpt_config(ioc, &cfg);
1662         if (error)
1663                 goto out_free_consistent;
1664
1665         /* save config data */
1666         port_info->num_phys = buffer->NumPhys;
1667         port_info->phy_info = kcalloc(port_info->num_phys,
1668                 sizeof(*port_info->phy_info),GFP_KERNEL);
1669         if (!port_info->phy_info) {
1670                 error = -ENOMEM;
1671                 goto out_free_consistent;
1672         }
1673
1674         for (i = 0; i < port_info->num_phys; i++) {
1675                 port_info->phy_info[i].portinfo = port_info;
1676                 port_info->phy_info[i].handle =
1677                     le16_to_cpu(buffer->DevHandle);
1678         }
1679
1680  out_free_consistent:
1681         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1682                             buffer, dma_handle);
1683  out:
1684         return error;
1685 }
1686
1687 static int
1688 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1689                 u32 form, u32 form_specific)
1690 {
1691         ConfigExtendedPageHeader_t hdr;
1692         CONFIGPARMS cfg;
1693         SasExpanderPage1_t *buffer;
1694         dma_addr_t dma_handle;
1695         int error=0;
1696
1697         if (ioc->sas_discovery_runtime &&
1698                 mptsas_is_end_device(&phy_info->attached))
1699                         goto out;
1700
1701         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1702         hdr.ExtPageLength = 0;
1703         hdr.PageNumber = 1;
1704         hdr.Reserved1 = 0;
1705         hdr.Reserved2 = 0;
1706         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1707         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1708
1709         cfg.cfghdr.ehdr = &hdr;
1710         cfg.physAddr = -1;
1711         cfg.pageAddr = form + form_specific;
1712         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1713         cfg.dir = 0;    /* read */
1714         cfg.timeout = 10;
1715
1716         error = mpt_config(ioc, &cfg);
1717         if (error)
1718                 goto out;
1719
1720         if (!hdr.ExtPageLength) {
1721                 error = -ENXIO;
1722                 goto out;
1723         }
1724
1725         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1726                                       &dma_handle);
1727         if (!buffer) {
1728                 error = -ENOMEM;
1729                 goto out;
1730         }
1731
1732         cfg.physAddr = dma_handle;
1733         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1734
1735         error = mpt_config(ioc, &cfg);
1736         if (error)
1737                 goto out_free_consistent;
1738
1739
1740         mptsas_print_expander_pg1(ioc, buffer);
1741
1742         /* save config data */
1743         phy_info->phy_id = buffer->PhyIdentifier;
1744         phy_info->port_id = buffer->PhysicalPort;
1745         phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
1746         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1747         phy_info->hw_link_rate = buffer->HwLinkRate;
1748         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1749         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1750
1751  out_free_consistent:
1752         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1753                             buffer, dma_handle);
1754  out:
1755         return error;
1756 }
1757
1758 static void
1759 mptsas_parse_device_info(struct sas_identify *identify,
1760                 struct mptsas_devinfo *device_info)
1761 {
1762         u16 protocols;
1763
1764         identify->sas_address = device_info->sas_address;
1765         identify->phy_identifier = device_info->phy_id;
1766
1767         /*
1768          * Fill in Phy Initiator Port Protocol.
1769          * Bits 6:3, more than one bit can be set, fall through cases.
1770          */
1771         protocols = device_info->device_info & 0x78;
1772         identify->initiator_port_protocols = 0;
1773         if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
1774                 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
1775         if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1776                 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
1777         if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
1778                 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
1779         if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
1780                 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
1781
1782         /*
1783          * Fill in Phy Target Port Protocol.
1784          * Bits 10:7, more than one bit can be set, fall through cases.
1785          */
1786         protocols = device_info->device_info & 0x780;
1787         identify->target_port_protocols = 0;
1788         if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1789                 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
1790         if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
1791                 identify->target_port_protocols |= SAS_PROTOCOL_STP;
1792         if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
1793                 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
1794         if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1795                 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
1796
1797         /*
1798          * Fill in Attached device type.
1799          */
1800         switch (device_info->device_info &
1801                         MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
1802         case MPI_SAS_DEVICE_INFO_NO_DEVICE:
1803                 identify->device_type = SAS_PHY_UNUSED;
1804                 break;
1805         case MPI_SAS_DEVICE_INFO_END_DEVICE:
1806                 identify->device_type = SAS_END_DEVICE;
1807                 break;
1808         case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
1809                 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
1810                 break;
1811         case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
1812                 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
1813                 break;
1814         }
1815 }
1816
1817 static int mptsas_probe_one_phy(struct device *dev,
1818                 struct mptsas_phyinfo *phy_info, int index, int local)
1819 {
1820         MPT_ADAPTER *ioc;
1821         struct sas_phy *phy;
1822         struct sas_port *port;
1823         int error = 0;
1824
1825         if (!dev) {
1826                 error = -ENODEV;
1827                 goto out;
1828         }
1829
1830         if (!phy_info->phy) {
1831                 phy = sas_phy_alloc(dev, index);
1832                 if (!phy) {
1833                         error = -ENOMEM;
1834                         goto out;
1835                 }
1836         } else
1837                 phy = phy_info->phy;
1838
1839         mptsas_parse_device_info(&phy->identify, &phy_info->identify);
1840
1841         /*
1842          * Set Negotiated link rate.
1843          */
1844         switch (phy_info->negotiated_link_rate) {
1845         case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
1846                 phy->negotiated_linkrate = SAS_PHY_DISABLED;
1847                 break;
1848         case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
1849                 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
1850                 break;
1851         case MPI_SAS_IOUNIT0_RATE_1_5:
1852                 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
1853                 break;
1854         case MPI_SAS_IOUNIT0_RATE_3_0:
1855                 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
1856                 break;
1857         case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
1858         case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
1859         default:
1860                 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
1861                 break;
1862         }
1863
1864         /*
1865          * Set Max hardware link rate.
1866          */
1867         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1868         case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
1869                 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1870                 break;
1871         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1872                 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1873                 break;
1874         default:
1875                 break;
1876         }
1877
1878         /*
1879          * Set Max programmed link rate.
1880          */
1881         switch (phy_info->programmed_link_rate &
1882                         MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1883         case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
1884                 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1885                 break;
1886         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1887                 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1888                 break;
1889         default:
1890                 break;
1891         }
1892
1893         /*
1894          * Set Min hardware link rate.
1895          */
1896         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
1897         case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
1898                 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1899                 break;
1900         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1901                 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1902                 break;
1903         default:
1904                 break;
1905         }
1906
1907         /*
1908          * Set Min programmed link rate.
1909          */
1910         switch (phy_info->programmed_link_rate &
1911                         MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
1912         case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
1913                 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1914                 break;
1915         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1916                 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1917                 break;
1918         default:
1919                 break;
1920         }
1921
1922         if (!phy_info->phy) {
1923
1924                 error = sas_phy_add(phy);
1925                 if (error) {
1926                         sas_phy_free(phy);
1927                         goto out;
1928                 }
1929                 phy_info->phy = phy;
1930         }
1931
1932         if (!phy_info->attached.handle ||
1933                         !phy_info->port_details)
1934                 goto out;
1935
1936         port = mptsas_get_port(phy_info);
1937         ioc = phy_to_ioc(phy_info->phy);
1938
1939         if (phy_info->sas_port_add_phy) {
1940
1941                 if (!port) {
1942                         port = sas_port_alloc_num(dev);
1943                         if (!port) {
1944                                 error = -ENOMEM;
1945                                 goto out;
1946                         }
1947                         error = sas_port_add(port);
1948                         if (error) {
1949                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1950                                         "%s: exit at line=%d\n", ioc->name,
1951                                         __FUNCTION__, __LINE__));
1952                                 goto out;
1953                         }
1954                         mptsas_set_port(ioc, phy_info, port);
1955                         dsaswideprintk(ioc, printk(KERN_DEBUG
1956                             "sas_port_alloc: port=%p dev=%p port_id=%d\n",
1957                             port, dev, port->port_identifier));
1958                 }
1959                 dsaswideprintk(ioc, printk(KERN_DEBUG "sas_port_add_phy: phy_id=%d\n",
1960                     phy_info->phy_id));
1961                 sas_port_add_phy(port, phy_info->phy);
1962                 phy_info->sas_port_add_phy = 0;
1963         }
1964
1965         if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
1966
1967                 struct sas_rphy *rphy;
1968                 struct device *parent;
1969                 struct sas_identify identify;
1970
1971                 parent = dev->parent->parent;
1972                 /*
1973                  * Let the hotplug_work thread handle processing
1974                  * the adding/removing of devices that occur
1975                  * after start of day.
1976                  */
1977                 if (ioc->sas_discovery_runtime &&
1978                         mptsas_is_end_device(&phy_info->attached))
1979                                 goto out;
1980
1981                 mptsas_parse_device_info(&identify, &phy_info->attached);
1982                 if (scsi_is_host_device(parent)) {
1983                         struct mptsas_portinfo *port_info;
1984                         int i;
1985
1986                         mutex_lock(&ioc->sas_topology_mutex);
1987                         port_info = mptsas_find_portinfo_by_handle(ioc,
1988                                                                    ioc->handle);
1989                         mutex_unlock(&ioc->sas_topology_mutex);
1990
1991                         for (i = 0; i < port_info->num_phys; i++)
1992                                 if (port_info->phy_info[i].identify.sas_address ==
1993                                     identify.sas_address) {
1994                                         sas_port_mark_backlink(port);
1995                                         goto out;
1996                                 }
1997
1998                 } else if (scsi_is_sas_rphy(parent)) {
1999                         struct sas_rphy *parent_rphy = dev_to_rphy(parent);
2000                         if (identify.sas_address ==
2001                             parent_rphy->identify.sas_address) {
2002                                 sas_port_mark_backlink(port);
2003                                 goto out;
2004                         }
2005                 }
2006
2007                 switch (identify.device_type) {
2008                 case SAS_END_DEVICE:
2009                         rphy = sas_end_device_alloc(port);
2010                         break;
2011                 case SAS_EDGE_EXPANDER_DEVICE:
2012                 case SAS_FANOUT_EXPANDER_DEVICE:
2013                         rphy = sas_expander_alloc(port, identify.device_type);
2014                         break;
2015                 default:
2016                         rphy = NULL;
2017                         break;
2018                 }
2019                 if (!rphy) {
2020                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2021                                 "%s: exit at line=%d\n", ioc->name,
2022                                 __FUNCTION__, __LINE__));
2023                         goto out;
2024                 }
2025
2026                 rphy->identify = identify;
2027                 error = sas_rphy_add(rphy);
2028                 if (error) {
2029                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2030                                 "%s: exit at line=%d\n", ioc->name,
2031                                 __FUNCTION__, __LINE__));
2032                         sas_rphy_free(rphy);
2033                         goto out;
2034                 }
2035                 mptsas_set_rphy(ioc, phy_info, rphy);
2036         }
2037
2038  out:
2039         return error;
2040 }
2041
2042 static int
2043 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
2044 {
2045         struct mptsas_portinfo *port_info, *hba;
2046         int error = -ENOMEM, i;
2047
2048         hba = kzalloc(sizeof(*port_info), GFP_KERNEL);
2049         if (! hba)
2050                 goto out;
2051
2052         error = mptsas_sas_io_unit_pg0(ioc, hba);
2053         if (error)
2054                 goto out_free_port_info;
2055
2056         mptsas_sas_io_unit_pg1(ioc);
2057         mutex_lock(&ioc->sas_topology_mutex);
2058         ioc->handle = hba->phy_info[0].handle;
2059         port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
2060         if (!port_info) {
2061                 port_info = hba;
2062                 list_add_tail(&port_info->list, &ioc->sas_topology);
2063         } else {
2064                 for (i = 0; i < hba->num_phys; i++) {
2065                         port_info->phy_info[i].negotiated_link_rate =
2066                                 hba->phy_info[i].negotiated_link_rate;
2067                         port_info->phy_info[i].handle =
2068                                 hba->phy_info[i].handle;
2069                         port_info->phy_info[i].port_id =
2070                                 hba->phy_info[i].port_id;
2071                 }
2072                 kfree(hba->phy_info);
2073                 kfree(hba);
2074                 hba = NULL;
2075         }
2076         mutex_unlock(&ioc->sas_topology_mutex);
2077         for (i = 0; i < port_info->num_phys; i++) {
2078                 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
2079                         (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
2080                          MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
2081
2082                 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
2083                         (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2084                          MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2085                          port_info->phy_info[i].handle);
2086                 port_info->phy_info[i].identify.phy_id =
2087                     port_info->phy_info[i].phy_id = i;
2088                 if (port_info->phy_info[i].attached.handle)
2089                         mptsas_sas_device_pg0(ioc,
2090                                 &port_info->phy_info[i].attached,
2091                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2092                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2093                                 port_info->phy_info[i].attached.handle);
2094         }
2095
2096         mptsas_setup_wide_ports(ioc, port_info);
2097
2098         for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
2099                 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
2100                     &port_info->phy_info[i], ioc->sas_index, 1);
2101
2102         return 0;
2103
2104  out_free_port_info:
2105         kfree(hba);
2106  out:
2107         return error;
2108 }
2109
2110 static int
2111 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
2112 {
2113         struct mptsas_portinfo *port_info, *p, *ex;
2114         struct device *parent;
2115         struct sas_rphy *rphy;
2116         int error = -ENOMEM, i, j;
2117
2118         ex = kzalloc(sizeof(*port_info), GFP_KERNEL);
2119         if (!ex)
2120                 goto out;
2121
2122         error = mptsas_sas_expander_pg0(ioc, ex,
2123             (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
2124              MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
2125         if (error)
2126                 goto out_free_port_info;
2127
2128         *handle = ex->phy_info[0].handle;
2129
2130         mutex_lock(&ioc->sas_topology_mutex);
2131         port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
2132         if (!port_info) {
2133                 port_info = ex;
2134                 list_add_tail(&port_info->list, &ioc->sas_topology);
2135         } else {
2136                 for (i = 0; i < ex->num_phys; i++) {
2137                         port_info->phy_info[i].handle =
2138                                 ex->phy_info[i].handle;
2139                         port_info->phy_info[i].port_id =
2140                                 ex->phy_info[i].port_id;
2141                 }
2142                 kfree(ex->phy_info);
2143                 kfree(ex);
2144                 ex = NULL;
2145         }
2146         mutex_unlock(&ioc->sas_topology_mutex);
2147
2148         for (i = 0; i < port_info->num_phys; i++) {
2149                 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
2150                         (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
2151                          MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
2152
2153                 if (port_info->phy_info[i].identify.handle) {
2154                         mptsas_sas_device_pg0(ioc,
2155                                 &port_info->phy_info[i].identify,
2156                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2157                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2158                                 port_info->phy_info[i].identify.handle);
2159                         port_info->phy_info[i].identify.phy_id =
2160                             port_info->phy_info[i].phy_id;
2161                 }
2162
2163                 if (port_info->phy_info[i].attached.handle) {
2164                         mptsas_sas_device_pg0(ioc,
2165                                 &port_info->phy_info[i].attached,
2166                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2167                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2168                                 port_info->phy_info[i].attached.handle);
2169                         port_info->phy_info[i].attached.phy_id =
2170                             port_info->phy_info[i].phy_id;
2171                 }
2172         }
2173
2174         parent = &ioc->sh->shost_gendev;
2175         for (i = 0; i < port_info->num_phys; i++) {
2176                 mutex_lock(&ioc->sas_topology_mutex);
2177                 list_for_each_entry(p, &ioc->sas_topology, list) {
2178                         for (j = 0; j < p->num_phys; j++) {
2179                                 if (port_info->phy_info[i].identify.handle !=
2180                                                 p->phy_info[j].attached.handle)
2181                                         continue;
2182                                 rphy = mptsas_get_rphy(&p->phy_info[j]);
2183                                 parent = &rphy->dev;
2184                         }
2185                 }
2186                 mutex_unlock(&ioc->sas_topology_mutex);
2187         }
2188
2189         mptsas_setup_wide_ports(ioc, port_info);
2190
2191         for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
2192                 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
2193                     ioc->sas_index, 0);
2194
2195         return 0;
2196
2197  out_free_port_info:
2198         if (ex) {
2199                 kfree(ex->phy_info);
2200                 kfree(ex);
2201         }
2202  out:
2203         return error;
2204 }
2205
2206 /*
2207  * mptsas_delete_expander_phys
2208  *
2209  *
2210  * This will traverse topology, and remove expanders
2211  * that are no longer present
2212  */
2213 static void
2214 mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
2215 {
2216         struct mptsas_portinfo buffer;
2217         struct mptsas_portinfo *port_info, *n, *parent;
2218         struct mptsas_phyinfo *phy_info;
2219         struct sas_port * port;
2220         int i;
2221         u64     expander_sas_address;
2222
2223         mutex_lock(&ioc->sas_topology_mutex);
2224         list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
2225
2226                 if (port_info->phy_info &&
2227                     (!(port_info->phy_info[0].identify.device_info &
2228                     MPI_SAS_DEVICE_INFO_SMP_TARGET)))
2229                         continue;
2230
2231                 if (mptsas_sas_expander_pg0(ioc, &buffer,
2232                      (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
2233                      MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
2234                      port_info->phy_info[0].handle)) {
2235
2236                         /*
2237                          * Obtain the port_info instance to the parent port
2238                          */
2239                         parent = mptsas_find_portinfo_by_handle(ioc,
2240                             port_info->phy_info[0].identify.handle_parent);
2241
2242                         if (!parent)
2243                                 goto next_port;
2244
2245                         expander_sas_address =
2246                                 port_info->phy_info[0].identify.sas_address;
2247
2248                         /*
2249                          * Delete rphys in the parent that point
2250                          * to this expander.  The transport layer will
2251                          * cleanup all the children.
2252                          */
2253                         phy_info = parent->phy_info;
2254                         for (i = 0; i < parent->num_phys; i++, phy_info++) {
2255                                 port = mptsas_get_port(phy_info);
2256                                 if (!port)
2257                                         continue;
2258                                 if (phy_info->attached.sas_address !=
2259                                         expander_sas_address)
2260                                         continue;
2261                                 dsaswideprintk(ioc,
2262                                         dev_printk(KERN_DEBUG, &port->dev,
2263                                         "delete port (%d)\n", port->port_identifier));
2264                                 sas_port_delete(port);
2265                                 mptsas_port_delete(ioc, phy_info->port_details);
2266                         }
2267  next_port:
2268
2269                         phy_info = port_info->phy_info;
2270                         for (i = 0; i < port_info->num_phys; i++, phy_info++)
2271                                 mptsas_port_delete(ioc, phy_info->port_details);
2272
2273                         list_del(&port_info->list);
2274                         kfree(port_info->phy_info);
2275                         kfree(port_info);
2276                 }
2277                 /*
2278                 * Free this memory allocated from inside
2279                 * mptsas_sas_expander_pg0
2280                 */
2281                 kfree(buffer.phy_info);
2282         }
2283         mutex_unlock(&ioc->sas_topology_mutex);
2284 }
2285
2286 /*
2287  * Start of day discovery
2288  */
2289 static void
2290 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
2291 {
2292         u32 handle = 0xFFFF;
2293         int i;
2294
2295         mutex_lock(&ioc->sas_discovery_mutex);
2296         mptsas_probe_hba_phys(ioc);
2297         while (!mptsas_probe_expander_phys(ioc, &handle))
2298                 ;
2299         /*
2300           Reporting RAID volumes.
2301         */
2302         if (!ioc->ir_firmware)
2303                 goto out;
2304         if (!ioc->raid_data.pIocPg2)
2305                 goto out;
2306         if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
2307                 goto out;
2308         for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
2309                 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
2310                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
2311         }
2312  out:
2313         mutex_unlock(&ioc->sas_discovery_mutex);
2314 }
2315
2316 /*
2317  * Work queue thread to handle Runtime discovery
2318  * Mere purpose is the hot add/delete of expanders
2319  *(Mutex UNLOCKED)
2320  */
2321 static void
2322 __mptsas_discovery_work(MPT_ADAPTER *ioc)
2323 {
2324         u32 handle = 0xFFFF;
2325
2326         ioc->sas_discovery_runtime=1;
2327         mptsas_delete_expander_phys(ioc);
2328         mptsas_probe_hba_phys(ioc);
2329         while (!mptsas_probe_expander_phys(ioc, &handle))
2330                 ;
2331         ioc->sas_discovery_runtime=0;
2332 }
2333
2334 /*
2335  * Work queue thread to handle Runtime discovery
2336  * Mere purpose is the hot add/delete of expanders
2337  *(Mutex LOCKED)
2338  */
2339 static void
2340 mptsas_discovery_work(struct work_struct *work)
2341 {
2342         struct mptsas_discovery_event *ev =
2343                 container_of(work, struct mptsas_discovery_event, work);
2344         MPT_ADAPTER *ioc = ev->ioc;
2345
2346         mutex_lock(&ioc->sas_discovery_mutex);
2347         __mptsas_discovery_work(ioc);
2348         mutex_unlock(&ioc->sas_discovery_mutex);
2349         kfree(ev);
2350 }
2351
2352 static struct mptsas_phyinfo *
2353 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
2354 {
2355         struct mptsas_portinfo *port_info;
2356         struct mptsas_phyinfo *phy_info = NULL;
2357         int i;
2358
2359         mutex_lock(&ioc->sas_topology_mutex);
2360         list_for_each_entry(port_info, &ioc->sas_topology, list) {
2361                 for (i = 0; i < port_info->num_phys; i++) {
2362                         if (!mptsas_is_end_device(
2363                                 &port_info->phy_info[i].attached))
2364                                 continue;
2365                         if (port_info->phy_info[i].attached.sas_address
2366                             != sas_address)
2367                                 continue;
2368                         phy_info = &port_info->phy_info[i];
2369                         break;
2370                 }
2371         }
2372         mutex_unlock(&ioc->sas_topology_mutex);
2373         return phy_info;
2374 }
2375
2376 static struct mptsas_phyinfo *
2377 mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u8 channel, u8 id)
2378 {
2379         struct mptsas_portinfo *port_info;
2380         struct mptsas_phyinfo *phy_info = NULL;
2381         int i;
2382
2383         mutex_lock(&ioc->sas_topology_mutex);
2384         list_for_each_entry(port_info, &ioc->sas_topology, list) {
2385                 for (i = 0; i < port_info->num_phys; i++) {
2386                         if (!mptsas_is_end_device(
2387                                 &port_info->phy_info[i].attached))
2388                                 continue;
2389                         if (port_info->phy_info[i].attached.id != id)
2390                                 continue;
2391                         if (port_info->phy_info[i].attached.channel != channel)
2392                                 continue;
2393                         phy_info = &port_info->phy_info[i];
2394                         break;
2395                 }
2396         }
2397         mutex_unlock(&ioc->sas_topology_mutex);
2398         return phy_info;
2399 }
2400
2401 static struct mptsas_phyinfo *
2402 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2403 {
2404         struct mptsas_portinfo *port_info;
2405         struct mptsas_phyinfo *phy_info = NULL;
2406         int i;
2407
2408         mutex_lock(&ioc->sas_topology_mutex);
2409         list_for_each_entry(port_info, &ioc->sas_topology, list) {
2410                 for (i = 0; i < port_info->num_phys; i++) {
2411                         if (!mptsas_is_end_device(
2412                                 &port_info->phy_info[i].attached))
2413                                 continue;
2414                         if (port_info->phy_info[i].attached.phys_disk_num == ~0)
2415                                 continue;
2416                         if (port_info->phy_info[i].attached.phys_disk_num != id)
2417                                 continue;
2418                         if (port_info->phy_info[i].attached.channel != channel)
2419                                 continue;
2420                         phy_info = &port_info->phy_info[i];
2421                         break;
2422                 }
2423         }
2424         mutex_unlock(&ioc->sas_topology_mutex);
2425         return phy_info;
2426 }
2427
2428 /*
2429  * Work queue thread to clear the persitency table
2430  */
2431 static void
2432 mptsas_persist_clear_table(struct work_struct *work)
2433 {
2434         MPT_ADAPTER *ioc = container_of(work, MPT_ADAPTER, sas_persist_task);
2435
2436         mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2437 }
2438
2439 static void
2440 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
2441 {
2442         int rc;
2443
2444         sdev->no_uld_attach = data ? 1 : 0;
2445         rc = scsi_device_reprobe(sdev);
2446 }
2447
2448 static void
2449 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
2450 {
2451         starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
2452                         mptsas_reprobe_lun);
2453 }
2454
2455 static void
2456 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
2457 {
2458         CONFIGPARMS                     cfg;
2459         ConfigPageHeader_t              hdr;
2460         dma_addr_t                      dma_handle;
2461         pRaidVolumePage0_t              buffer = NULL;
2462         RaidPhysDiskPage0_t             phys_disk;
2463         int                             i;
2464         struct mptsas_hotplug_event     *ev;
2465
2466         memset(&cfg, 0 , sizeof(CONFIGPARMS));
2467         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
2468         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
2469         cfg.pageAddr = (channel << 8) + id;
2470         cfg.cfghdr.hdr = &hdr;
2471         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2472
2473         if (mpt_config(ioc, &cfg) != 0)
2474                 goto out;
2475
2476         if (!hdr.PageLength)
2477                 goto out;
2478
2479         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
2480             &dma_handle);
2481
2482         if (!buffer)
2483                 goto out;
2484
2485         cfg.physAddr = dma_handle;
2486         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2487
2488         if (mpt_config(ioc, &cfg) != 0)
2489                 goto out;
2490
2491         if (!(buffer->VolumeStatus.Flags &
2492             MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
2493                 goto out;
2494
2495         if (!buffer->NumPhysDisks)
2496                 goto out;
2497
2498         for (i = 0; i < buffer->NumPhysDisks; i++) {
2499
2500                 if (mpt_raid_phys_disk_pg0(ioc,
2501                     buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
2502                         continue;
2503
2504                 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2505                 if (!ev) {
2506                         printk(KERN_WARNING "mptsas: lost hotplug event\n");
2507                         goto out;
2508                 }
2509
2510                 INIT_WORK(&ev->work, mptsas_hotplug_work);
2511                 ev->ioc = ioc;
2512                 ev->id = phys_disk.PhysDiskID;
2513                 ev->channel = phys_disk.PhysDiskBus;
2514                 ev->phys_disk_num_valid = 1;
2515                 ev->phys_disk_num = phys_disk.PhysDiskNum;
2516                 ev->event_type = MPTSAS_ADD_DEVICE;
2517                 schedule_work(&ev->work);
2518         }
2519
2520  out:
2521         if (buffer)
2522                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
2523                     dma_handle);
2524 }
2525 /*
2526  * Work queue thread to handle SAS hotplug events
2527  */
2528 static void
2529 mptsas_hotplug_work(struct work_struct *work)
2530 {
2531         struct mptsas_hotplug_event *ev =
2532                 container_of(work, struct mptsas_hotplug_event, work);
2533
2534         MPT_ADAPTER *ioc = ev->ioc;
2535         struct mptsas_phyinfo *phy_info;
2536         struct sas_rphy *rphy;
2537         struct sas_port *port;
2538         struct scsi_device *sdev;
2539         struct scsi_target * starget;
2540         struct sas_identify identify;
2541         char *ds = NULL;
2542         struct mptsas_devinfo sas_device;
2543         VirtTarget *vtarget;
2544         VirtDevice *vdevice;
2545
2546         mutex_lock(&ioc->sas_discovery_mutex);
2547         switch (ev->event_type) {
2548         case MPTSAS_DEL_DEVICE:
2549
2550                 phy_info = NULL;
2551                 if (ev->phys_disk_num_valid) {
2552                         if (ev->hidden_raid_component){
2553                                 if (mptsas_sas_device_pg0(ioc, &sas_device,
2554                                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2555                                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2556                                     (ev->channel << 8) + ev->id)) {
2557                                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2558                                         "%s: exit at line=%d\n", ioc->name,
2559                                                 __FUNCTION__, __LINE__));
2560                                         break;
2561                                 }
2562                                 phy_info = mptsas_find_phyinfo_by_sas_address(
2563                                     ioc, sas_device.sas_address);
2564                         }else
2565                                 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
2566                                     ioc, ev->channel, ev->phys_disk_num);
2567                 }
2568
2569                 if (!phy_info)
2570                         phy_info = mptsas_find_phyinfo_by_target(ioc,
2571                             ev->channel, ev->id);
2572
2573                 /*
2574                  * Sanity checks, for non-existing phys and remote rphys.
2575                  */
2576                 if (!phy_info){
2577                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2578                                 "%s: exit at line=%d\n", ioc->name,
2579                                 __FUNCTION__, __LINE__));
2580                         break;
2581                 }
2582                 if (!phy_info->port_details) {
2583                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2584                                 "%s: exit at line=%d\n", ioc->name,
2585                                 __FUNCTION__, __LINE__));
2586                         break;
2587                 }
2588                 rphy = mptsas_get_rphy(phy_info);
2589                 if (!rphy) {
2590                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2591                                 "%s: exit at line=%d\n", ioc->name,
2592                                 __FUNCTION__, __LINE__));
2593                         break;
2594                 }
2595
2596                 port = mptsas_get_port(phy_info);
2597                 if (!port) {
2598                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2599                                 "%s: exit at line=%d\n", ioc->name,
2600                                 __FUNCTION__, __LINE__));
2601                         break;
2602                 }
2603
2604                 starget = mptsas_get_starget(phy_info);
2605                 if (starget) {
2606                         vtarget = starget->hostdata;
2607
2608                         if (!vtarget) {
2609                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2610                                         "%s: exit at line=%d\n", ioc->name,
2611                                         __FUNCTION__, __LINE__));
2612                                 break;
2613                         }
2614
2615                         /*
2616                          * Handling  RAID components
2617                          */
2618                         if (ev->phys_disk_num_valid &&
2619                             ev->hidden_raid_component) {
2620                                 printk(MYIOC_s_INFO_FMT
2621                                     "RAID Hidding: channel=%d, id=%d, "
2622                                     "physdsk %d \n", ioc->name, ev->channel,
2623                                     ev->id, ev->phys_disk_num);
2624                                 vtarget->id = ev->phys_disk_num;
2625                                 vtarget->tflags |=
2626                                     MPT_TARGET_FLAGS_RAID_COMPONENT;
2627                                 mptsas_reprobe_target(starget, 1);
2628                                 phy_info->attached.phys_disk_num =
2629                                     ev->phys_disk_num;
2630                         break;
2631                         }
2632                 }
2633
2634                 if (phy_info->attached.device_info &
2635                     MPI_SAS_DEVICE_INFO_SSP_TARGET)
2636                         ds = "ssp";
2637                 if (phy_info->attached.device_info &
2638                     MPI_SAS_DEVICE_INFO_STP_TARGET)
2639                         ds = "stp";
2640                 if (phy_info->attached.device_info &
2641                     MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2642                         ds = "sata";
2643
2644                 printk(MYIOC_s_INFO_FMT
2645                        "removing %s device, channel %d, id %d, phy %d\n",
2646                        ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
2647                 dev_printk(KERN_DEBUG, &port->dev,
2648                     "delete port (%d)\n", port->port_identifier);
2649                 sas_port_delete(port);
2650                 mptsas_port_delete(ioc, phy_info->port_details);
2651                 break;
2652         case MPTSAS_ADD_DEVICE:
2653
2654                 if (ev->phys_disk_num_valid)
2655                         mpt_findImVolumes(ioc);
2656
2657                 /*
2658                  * Refresh sas device pg0 data
2659                  */
2660                 if (mptsas_sas_device_pg0(ioc, &sas_device,
2661                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2662                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2663                         (ev->channel << 8) + ev->id)) {
2664                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2665                                         "%s: exit at line=%d\n", ioc->name,
2666                                         __FUNCTION__, __LINE__));
2667                         break;
2668                 }
2669
2670                 __mptsas_discovery_work(ioc);
2671
2672                 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
2673                                 sas_device.sas_address);
2674
2675                 if (!phy_info || !phy_info->port_details) {
2676                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2677                                 "%s: exit at line=%d\n", ioc->name,
2678                                 __FUNCTION__, __LINE__));
2679                         break;
2680                 }
2681
2682                 starget = mptsas_get_starget(phy_info);
2683                 if (starget && (!ev->hidden_raid_component)){
2684
2685                         vtarget = starget->hostdata;
2686
2687                         if (!vtarget) {
2688                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2689                                         "%s: exit at line=%d\n", ioc->name,
2690                                         __FUNCTION__, __LINE__));
2691                                 break;
2692                         }
2693                         /*
2694                          * Handling  RAID components
2695                          */
2696                         if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
2697                                 printk(MYIOC_s_INFO_FMT
2698                                     "RAID Exposing: channel=%d, id=%d, "
2699                                     "physdsk %d \n", ioc->name, ev->channel,
2700                                     ev->id, ev->phys_disk_num);
2701                                 vtarget->tflags &=
2702                                     ~MPT_TARGET_FLAGS_RAID_COMPONENT;
2703                                 vtarget->id = ev->id;
2704                                 mptsas_reprobe_target(starget, 0);
2705                                 phy_info->attached.phys_disk_num = ~0;
2706                         }
2707                         break;
2708                 }
2709
2710                 if (mptsas_get_rphy(phy_info)) {
2711                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2712                                 "%s: exit at line=%d\n", ioc->name,
2713                                 __FUNCTION__, __LINE__));
2714                         if (ev->channel) printk("%d\n", __LINE__);
2715                         break;
2716                 }
2717
2718                 port = mptsas_get_port(phy_info);
2719                 if (!port) {
2720                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2721                                 "%s: exit at line=%d\n", ioc->name,
2722                                 __FUNCTION__, __LINE__));
2723                         break;
2724                 }
2725                 memcpy(&phy_info->attached, &sas_device,
2726                     sizeof(struct mptsas_devinfo));
2727
2728                 if (phy_info->attached.device_info &
2729                     MPI_SAS_DEVICE_INFO_SSP_TARGET)
2730                         ds = "ssp";
2731                 if (phy_info->attached.device_info &
2732                     MPI_SAS_DEVICE_INFO_STP_TARGET)
2733                         ds = "stp";
2734                 if (phy_info->attached.device_info &
2735                     MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2736                         ds = "sata";
2737
2738                 printk(MYIOC_s_INFO_FMT
2739                        "attaching %s device, channel %d, id %d, phy %d\n",
2740                        ioc->name, ds, ev->channel, ev->id, ev->phy_id);
2741
2742                 mptsas_parse_device_info(&identify, &phy_info->attached);
2743                 rphy = sas_end_device_alloc(port);
2744                 if (!rphy) {
2745                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2746                                 "%s: exit at line=%d\n", ioc->name,
2747                                 __FUNCTION__, __LINE__));
2748                         break; /* non-fatal: an rphy can be added later */
2749                 }
2750
2751                 rphy->identify = identify;
2752                 if (sas_rphy_add(rphy)) {
2753                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2754                                 "%s: exit at line=%d\n", ioc->name,
2755                                 __FUNCTION__, __LINE__));
2756                         sas_rphy_free(rphy);
2757                         break;
2758                 }
2759                 mptsas_set_rphy(ioc, phy_info, rphy);
2760                 break;
2761         case MPTSAS_ADD_RAID:
2762                 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2763                     ev->id, 0);
2764                 if (sdev) {
2765                         scsi_device_put(sdev);
2766                         break;
2767                 }
2768                 printk(MYIOC_s_INFO_FMT
2769                        "attaching raid volume, channel %d, id %d\n",
2770                        ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2771                 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ev->id, 0);
2772                 mpt_findImVolumes(ioc);
2773                 break;
2774         case MPTSAS_DEL_RAID:
2775                 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2776                     ev->id, 0);
2777                 if (!sdev)
2778                         break;
2779                 printk(MYIOC_s_INFO_FMT
2780                        "removing raid volume, channel %d, id %d\n",
2781                        ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2782                 vdevice = sdev->hostdata;
2783                 scsi_remove_device(sdev);
2784                 scsi_device_put(sdev);
2785                 mpt_findImVolumes(ioc);
2786                 break;
2787         case MPTSAS_ADD_INACTIVE_VOLUME:
2788                 mptsas_adding_inactive_raid_components(ioc,
2789                     ev->channel, ev->id);
2790                 break;
2791         case MPTSAS_IGNORE_EVENT:
2792         default:
2793                 break;
2794         }
2795
2796         mutex_unlock(&ioc->sas_discovery_mutex);
2797         kfree(ev);
2798 }
2799
2800 static void
2801 mptsas_send_sas_event(MPT_ADAPTER *ioc,
2802                 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
2803 {
2804         struct mptsas_hotplug_event *ev;
2805         u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
2806         __le64 sas_address;
2807
2808         if ((device_info &
2809              (MPI_SAS_DEVICE_INFO_SSP_TARGET |
2810               MPI_SAS_DEVICE_INFO_STP_TARGET |
2811               MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
2812                 return;
2813
2814         switch (sas_event_data->ReasonCode) {
2815         case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
2816
2817                 mptsas_target_reset_queue(ioc, sas_event_data);
2818                 break;
2819
2820         case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
2821                 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2822                 if (!ev) {
2823                         printk(KERN_WARNING "mptsas: lost hotplug event\n");
2824                         break;
2825                 }
2826
2827                 INIT_WORK(&ev->work, mptsas_hotplug_work);
2828                 ev->ioc = ioc;
2829                 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
2830                 ev->parent_handle =
2831                     le16_to_cpu(sas_event_data->ParentDevHandle);
2832                 ev->channel = sas_event_data->Bus;
2833                 ev->id = sas_event_data->TargetID;
2834                 ev->phy_id = sas_event_data->PhyNum;
2835                 memcpy(&sas_address, &sas_event_data->SASAddress,
2836                     sizeof(__le64));
2837                 ev->sas_address = le64_to_cpu(sas_address);
2838                 ev->device_info = device_info;
2839
2840                 if (sas_event_data->ReasonCode &
2841                     MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
2842                         ev->event_type = MPTSAS_ADD_DEVICE;
2843                 else
2844                         ev->event_type = MPTSAS_DEL_DEVICE;
2845                 schedule_work(&ev->work);
2846                 break;
2847         case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
2848         /*
2849          * Persistent table is full.
2850          */
2851                 INIT_WORK(&ioc->sas_persist_task,
2852                     mptsas_persist_clear_table);
2853                 schedule_work(&ioc->sas_persist_task);
2854                 break;
2855         /*
2856          * TODO, handle other events
2857          */
2858         case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
2859         case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
2860         case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
2861         case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
2862         case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
2863         case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
2864         case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
2865         default:
2866                 break;
2867         }
2868 }
2869 static void
2870 mptsas_send_raid_event(MPT_ADAPTER *ioc,
2871                 EVENT_DATA_RAID *raid_event_data)
2872 {
2873         struct mptsas_hotplug_event *ev;
2874         int status = le32_to_cpu(raid_event_data->SettingsStatus);
2875         int state = (status >> 8) & 0xff;
2876
2877         if (ioc->bus_type != SAS)
2878                 return;
2879
2880         ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2881         if (!ev) {
2882                 printk(KERN_WARNING "mptsas: lost hotplug event\n");
2883                 return;
2884         }
2885
2886         INIT_WORK(&ev->work, mptsas_hotplug_work);
2887         ev->ioc = ioc;
2888         ev->id = raid_event_data->VolumeID;
2889         ev->channel = raid_event_data->VolumeBus;
2890         ev->event_type = MPTSAS_IGNORE_EVENT;
2891
2892         switch (raid_event_data->ReasonCode) {
2893         case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
2894                 ev->phys_disk_num_valid = 1;
2895                 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2896                 ev->event_type = MPTSAS_ADD_DEVICE;
2897                 break;
2898         case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
2899                 ev->phys_disk_num_valid = 1;
2900                 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2901                 ev->hidden_raid_component = 1;
2902                 ev->event_type = MPTSAS_DEL_DEVICE;
2903                 break;
2904         case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
2905                 switch (state) {
2906                 case MPI_PD_STATE_ONLINE:
2907                 case MPI_PD_STATE_NOT_COMPATIBLE:
2908                         ev->phys_disk_num_valid = 1;
2909                         ev->phys_disk_num = raid_event_data->PhysDiskNum;
2910                         ev->hidden_raid_component = 1;
2911                         ev->event_type = MPTSAS_ADD_DEVICE;
2912                         break;
2913                 case MPI_PD_STATE_MISSING:
2914                 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
2915                 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
2916                 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
2917                         ev->phys_disk_num_valid = 1;
2918                         ev->phys_disk_num = raid_event_data->PhysDiskNum;
2919                         ev->event_type = MPTSAS_DEL_DEVICE;
2920                         break;
2921                 default:
2922                         break;
2923                 }
2924                 break;
2925         case MPI_EVENT_RAID_RC_VOLUME_DELETED:
2926                 ev->event_type = MPTSAS_DEL_RAID;
2927                 break;
2928         case MPI_EVENT_RAID_RC_VOLUME_CREATED:
2929                 ev->event_type = MPTSAS_ADD_RAID;
2930                 break;
2931         case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
2932                 switch (state) {
2933                 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
2934                 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
2935                         ev->event_type = MPTSAS_DEL_RAID;
2936                         break;
2937                 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
2938                 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
2939                         ev->event_type = MPTSAS_ADD_RAID;
2940                         break;
2941                 default:
2942                         break;
2943                 }
2944                 break;
2945         default:
2946                 break;
2947         }
2948         schedule_work(&ev->work);
2949 }
2950
2951 static void
2952 mptsas_send_discovery_event(MPT_ADAPTER *ioc,
2953         EVENT_DATA_SAS_DISCOVERY *discovery_data)
2954 {
2955         struct mptsas_discovery_event *ev;
2956
2957         /*
2958          * DiscoveryStatus
2959          *
2960          * This flag will be non-zero when firmware
2961          * kicks off discovery, and return to zero
2962          * once its completed.
2963          */
2964         if (discovery_data->DiscoveryStatus)
2965                 return;
2966
2967         ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2968         if (!ev)
2969                 return;
2970         INIT_WORK(&ev->work, mptsas_discovery_work);
2971         ev->ioc = ioc;
2972         schedule_work(&ev->work);
2973 };
2974
2975 /*
2976  * mptsas_send_ir2_event - handle exposing hidden disk when
2977  * an inactive raid volume is added
2978  *
2979  * @ioc: Pointer to MPT_ADAPTER structure
2980  * @ir2_data
2981  *
2982  */
2983 static void
2984 mptsas_send_ir2_event(MPT_ADAPTER *ioc, PTR_MPI_EVENT_DATA_IR2 ir2_data)
2985 {
2986         struct mptsas_hotplug_event *ev;
2987
2988         if (ir2_data->ReasonCode !=
2989             MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED)
2990                 return;
2991
2992         ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2993         if (!ev)
2994                 return;
2995
2996         INIT_WORK(&ev->work, mptsas_hotplug_work);
2997         ev->ioc = ioc;
2998         ev->id = ir2_data->TargetID;
2999         ev->channel = ir2_data->Bus;
3000         ev->event_type = MPTSAS_ADD_INACTIVE_VOLUME;
3001
3002         schedule_work(&ev->work);
3003 };
3004
3005 static int
3006 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
3007 {
3008         int rc=1;
3009         u8 event = le32_to_cpu(reply->Event) & 0xFF;
3010
3011         if (!ioc->sh)
3012                 goto out;
3013
3014         /*
3015          * sas_discovery_ignore_events
3016          *
3017          * This flag is to prevent anymore processing of
3018          * sas events once mptsas_remove function is called.
3019          */
3020         if (ioc->sas_discovery_ignore_events) {
3021                 rc = mptscsih_event_process(ioc, reply);
3022                 goto out;
3023         }
3024
3025         switch (event) {
3026         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
3027                 mptsas_send_sas_event(ioc,
3028                         (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
3029                 break;
3030         case MPI_EVENT_INTEGRATED_RAID:
3031                 mptsas_send_raid_event(ioc,
3032                         (EVENT_DATA_RAID *)reply->Data);
3033                 break;
3034         case MPI_EVENT_PERSISTENT_TABLE_FULL:
3035                 INIT_WORK(&ioc->sas_persist_task,
3036                     mptsas_persist_clear_table);
3037                 schedule_work(&ioc->sas_persist_task);
3038                 break;
3039          case MPI_EVENT_SAS_DISCOVERY:
3040                 mptsas_send_discovery_event(ioc,
3041                         (EVENT_DATA_SAS_DISCOVERY *)reply->Data);
3042                 break;
3043         case MPI_EVENT_IR2:
3044                 mptsas_send_ir2_event(ioc,
3045                     (PTR_MPI_EVENT_DATA_IR2)reply->Data);
3046                 break;
3047         default:
3048                 rc = mptscsih_event_process(ioc, reply);
3049                 break;
3050         }
3051  out:
3052
3053         return rc;
3054 }
3055
3056 static int
3057 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3058 {
3059         struct Scsi_Host        *sh;
3060         MPT_SCSI_HOST           *hd;
3061         MPT_ADAPTER             *ioc;
3062         unsigned long            flags;
3063         int                      ii;
3064         int                      numSGE = 0;
3065         int                      scale;
3066         int                      ioc_cap;
3067         int                     error=0;
3068         int                     r;
3069
3070         r = mpt_attach(pdev,id);
3071         if (r)
3072                 return r;
3073
3074         ioc = pci_get_drvdata(pdev);
3075         ioc->DoneCtx = mptsasDoneCtx;
3076         ioc->TaskCtx = mptsasTaskCtx;
3077         ioc->InternalCtx = mptsasInternalCtx;
3078
3079         /*  Added sanity check on readiness of the MPT adapter.
3080          */
3081         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
3082                 printk(MYIOC_s_WARN_FMT
3083                   "Skipping because it's not operational!\n",
3084                   ioc->name);
3085                 error = -ENODEV;
3086                 goto out_mptsas_probe;
3087         }
3088
3089         if (!ioc->active) {
3090                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
3091                   ioc->name);
3092                 error = -ENODEV;
3093                 goto out_mptsas_probe;
3094         }
3095
3096         /*  Sanity check - ensure at least 1 port is INITIATOR capable
3097          */
3098         ioc_cap = 0;
3099         for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
3100                 if (ioc->pfacts[ii].ProtocolFlags &
3101                                 MPI_PORTFACTS_PROTOCOL_INITIATOR)
3102                         ioc_cap++;
3103         }
3104
3105         if (!ioc_cap) {
3106                 printk(MYIOC_s_WARN_FMT
3107                         "Skipping ioc=%p because SCSI Initiator mode "
3108                         "is NOT enabled!\n", ioc->name, ioc);
3109                 return 0;
3110         }
3111
3112         sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
3113         if (!sh) {
3114                 printk(MYIOC_s_WARN_FMT
3115                         "Unable to register controller with SCSI subsystem\n",
3116                         ioc->name);
3117                 error = -1;
3118                 goto out_mptsas_probe;
3119         }
3120
3121         spin_lock_irqsave(&ioc->FreeQlock, flags);
3122
3123         /* Attach the SCSI Host to the IOC structure
3124          */
3125         ioc->sh = sh;
3126
3127         sh->io_port = 0;
3128         sh->n_io_port = 0;
3129         sh->irq = 0;
3130
3131         /* set 16 byte cdb's */
3132         sh->max_cmd_len = 16;
3133
3134         sh->max_id = ioc->pfacts[0].PortSCSIID;
3135         sh->max_lun = max_lun;
3136
3137         sh->transportt = mptsas_transport_template;
3138
3139         sh->this_id = ioc->pfacts[0].PortSCSIID;
3140
3141         /* Required entry.
3142          */
3143         sh->unique_id = ioc->id;
3144
3145         INIT_LIST_HEAD(&ioc->sas_topology);
3146         mutex_init(&ioc->sas_topology_mutex);
3147         mutex_init(&ioc->sas_discovery_mutex);
3148         mutex_init(&ioc->sas_mgmt.mutex);
3149         init_completion(&ioc->sas_mgmt.done);
3150
3151         /* Verify that we won't exceed the maximum
3152          * number of chain buffers
3153          * We can optimize:  ZZ = req_sz/sizeof(SGE)
3154          * For 32bit SGE's:
3155          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
3156          *               + (req_sz - 64)/sizeof(SGE)
3157          * A slightly different algorithm is required for
3158          * 64bit SGEs.
3159          */
3160         scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3161         if (sizeof(dma_addr_t) == sizeof(u64)) {
3162                 numSGE = (scale - 1) *
3163                   (ioc->facts.MaxChainDepth-1) + scale +
3164                   (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
3165                   sizeof(u32));
3166         } else {
3167                 numSGE = 1 + (scale - 1) *
3168                   (ioc->facts.MaxChainDepth-1) + scale +
3169                   (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
3170                   sizeof(u32));
3171         }
3172
3173         if (numSGE < sh->sg_tablesize) {
3174                 /* Reset this value */
3175                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3176                   "Resetting sg_tablesize to %d from %d\n",
3177                   ioc->name, numSGE, sh->sg_tablesize));
3178                 sh->sg_tablesize = numSGE;
3179         }
3180
3181         hd = (MPT_SCSI_HOST *) sh->hostdata;
3182         hd->ioc = ioc;
3183
3184         /* SCSI needs scsi_cmnd lookup table!
3185          * (with size equal to req_depth*PtrSz!)
3186          */
3187         hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
3188         if (!hd->ScsiLookup) {
3189                 error = -ENOMEM;
3190                 goto out_mptsas_probe;
3191         }
3192
3193         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
3194                  ioc->name, hd->ScsiLookup));
3195
3196         /* Clear the TM flags
3197          */
3198         hd->tmPending = 0;
3199         hd->tmState = TM_STATE_NONE;
3200         hd->resetPending = 0;
3201         hd->abortSCpnt = NULL;
3202
3203         /* Clear the pointer used to store
3204          * single-threaded commands, i.e., those
3205          * issued during a bus scan, dv and
3206          * configuration pages.
3207          */
3208         hd->cmdPtr = NULL;
3209
3210         /* Initialize this SCSI Hosts' timers
3211          * To use, set the timer expires field
3212          * and add_timer
3213          */
3214         init_timer(&hd->timer);
3215         hd->timer.data = (unsigned long) hd;
3216         hd->timer.function = mptscsih_timer_expired;
3217
3218         ioc->sas_data.ptClear = mpt_pt_clear;
3219
3220         init_waitqueue_head(&hd->scandv_waitq);
3221         hd->scandv_wait_done = 0;
3222         hd->last_queue_full = 0;
3223         INIT_LIST_HEAD(&hd->target_reset_list);
3224         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3225
3226         if (ioc->sas_data.ptClear==1) {
3227                 mptbase_sas_persist_operation(
3228                     ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
3229         }
3230
3231         error = scsi_add_host(sh, &ioc->pcidev->dev);
3232         if (error) {
3233                 dprintk(ioc, printk(KERN_ERR MYNAM
3234                   "scsi_add_host failed\n"));
3235                 goto out_mptsas_probe;
3236         }
3237
3238         mptsas_scan_sas_topology(ioc);
3239
3240         return 0;
3241
3242  out_mptsas_probe:
3243
3244         mptscsih_remove(pdev);
3245         return error;
3246 }
3247
3248 static void __devexit mptsas_remove(struct pci_dev *pdev)
3249 {
3250         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
3251         struct mptsas_portinfo *p, *n;
3252         int i;
3253
3254         ioc->sas_discovery_ignore_events = 1;
3255         sas_remove_host(ioc->sh);
3256
3257         mutex_lock(&ioc->sas_topology_mutex);
3258         list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
3259                 list_del(&p->list);
3260                 for (i = 0 ; i < p->num_phys ; i++)
3261                         mptsas_port_delete(ioc, p->phy_info[i].port_details);
3262                 kfree(p->phy_info);
3263                 kfree(p);
3264         }
3265         mutex_unlock(&ioc->sas_topology_mutex);
3266
3267         mptscsih_remove(pdev);
3268 }
3269
3270 static struct pci_device_id mptsas_pci_table[] = {
3271         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
3272                 PCI_ANY_ID, PCI_ANY_ID },
3273         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
3274                 PCI_ANY_ID, PCI_ANY_ID },
3275         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
3276                 PCI_ANY_ID, PCI_ANY_ID },
3277         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
3278                 PCI_ANY_ID, PCI_ANY_ID },
3279         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
3280                 PCI_ANY_ID, PCI_ANY_ID },
3281         {0}     /* Terminating entry */
3282 };
3283 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
3284
3285
3286 static struct pci_driver mptsas_driver = {
3287         .name           = "mptsas",
3288         .id_table       = mptsas_pci_table,
3289         .probe          = mptsas_probe,
3290         .remove         = __devexit_p(mptsas_remove),
3291         .shutdown       = mptscsih_shutdown,
3292 #ifdef CONFIG_PM
3293         .suspend        = mptscsih_suspend,
3294         .resume         = mptscsih_resume,
3295 #endif
3296 };
3297
3298 static int __init
3299 mptsas_init(void)
3300 {
3301         int error;
3302
3303         show_mptmod_ver(my_NAME, my_VERSION);
3304
3305         mptsas_transport_template =
3306             sas_attach_transport(&mptsas_transport_functions);
3307         if (!mptsas_transport_template)
3308                 return -ENODEV;
3309
3310         mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
3311         mptsasTaskCtx = mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
3312         mptsasInternalCtx =
3313                 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
3314         mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
3315
3316         mpt_event_register(mptsasDoneCtx, mptsas_event_process);
3317         mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
3318
3319         error = pci_register_driver(&mptsas_driver);
3320         if (error)
3321                 sas_release_transport(mptsas_transport_template);
3322
3323         return error;
3324 }
3325
3326 static void __exit
3327 mptsas_exit(void)
3328 {
3329         pci_unregister_driver(&mptsas_driver);
3330         sas_release_transport(mptsas_transport_template);
3331
3332         mpt_reset_deregister(mptsasDoneCtx);
3333         mpt_event_deregister(mptsasDoneCtx);
3334
3335         mpt_deregister(mptsasMgmtCtx);
3336         mpt_deregister(mptsasInternalCtx);
3337         mpt_deregister(mptsasTaskCtx);
3338         mpt_deregister(mptsasDoneCtx);
3339 }
3340
3341 module_init(mptsas_init);
3342 module_exit(mptsas_exit);