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