OSDN Git Service

[SCSI] mptsas : FW event thread and scsi mid layer deadlock in SYNCHRONIZE CACHE...
[sagit-ice-cold/kernel_xiaomi_msm8998.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 #define SAS_CONFIG_PAGE_TIMEOUT         30
76 MODULE_AUTHOR(MODULEAUTHOR);
77 MODULE_DESCRIPTION(my_NAME);
78 MODULE_LICENSE("GPL");
79 MODULE_VERSION(my_VERSION);
80
81 static int mpt_pt_clear;
82 module_param(mpt_pt_clear, int, 0);
83 MODULE_PARM_DESC(mpt_pt_clear,
84                 " Clear persistency table: enable=1  "
85                 "(default=MPTSCSIH_PT_CLEAR=0)");
86
87 /* scsi-mid layer global parmeter is max_report_luns, which is 511 */
88 #define MPTSAS_MAX_LUN (16895)
89 static int max_lun = MPTSAS_MAX_LUN;
90 module_param(max_lun, int, 0);
91 MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
92
93 static u8       mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
94 static u8       mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
95 static u8       mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */
96 static u8       mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS;
97 static u8       mptsasDeviceResetCtx = MPT_MAX_PROTOCOL_DRIVERS;
98
99 static void mptsas_firmware_event_work(struct work_struct *work);
100 static void mptsas_send_sas_event(struct fw_event_work *fw_event);
101 static void mptsas_send_raid_event(struct fw_event_work *fw_event);
102 static void mptsas_send_ir2_event(struct fw_event_work *fw_event);
103 static void mptsas_parse_device_info(struct sas_identify *identify,
104                 struct mptsas_devinfo *device_info);
105 static inline void mptsas_set_rphy(MPT_ADAPTER *ioc,
106                 struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy);
107 static struct mptsas_phyinfo    *mptsas_find_phyinfo_by_sas_address
108                 (MPT_ADAPTER *ioc, u64 sas_address);
109 static int mptsas_sas_device_pg0(MPT_ADAPTER *ioc,
110         struct mptsas_devinfo *device_info, u32 form, u32 form_specific);
111 static int mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc,
112         struct mptsas_enclosure *enclosure, u32 form, u32 form_specific);
113 static int mptsas_add_end_device(MPT_ADAPTER *ioc,
114         struct mptsas_phyinfo *phy_info);
115 static void mptsas_del_end_device(MPT_ADAPTER *ioc,
116         struct mptsas_phyinfo *phy_info);
117 static void mptsas_send_link_status_event(struct fw_event_work *fw_event);
118 static struct mptsas_portinfo   *mptsas_find_portinfo_by_sas_address
119                 (MPT_ADAPTER *ioc, u64 sas_address);
120 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
121                 struct mptsas_portinfo *port_info, u8 force);
122 static void mptsas_send_expander_event(struct fw_event_work *fw_event);
123 static void mptsas_not_responding_devices(MPT_ADAPTER *ioc);
124 static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
125 static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event);
126 static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
127 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
128
129 static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
130                                         MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
131 {
132         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
133             "---- IO UNIT PAGE 0 ------------\n", ioc->name));
134         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
135             ioc->name, le16_to_cpu(phy_data->AttachedDeviceHandle)));
136         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Controller Handle=0x%X\n",
137             ioc->name, le16_to_cpu(phy_data->ControllerDevHandle)));
138         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port=0x%X\n",
139             ioc->name, phy_data->Port));
140         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port Flags=0x%X\n",
141             ioc->name, phy_data->PortFlags));
142         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Flags=0x%X\n",
143             ioc->name, phy_data->PhyFlags));
144         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
145             ioc->name, phy_data->NegotiatedLinkRate));
146         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
147             "Controller PHY Device Info=0x%X\n", ioc->name,
148             le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
149         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DiscoveryStatus=0x%X\n\n",
150             ioc->name, le32_to_cpu(phy_data->DiscoveryStatus)));
151 }
152
153 static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
154 {
155         __le64 sas_address;
156
157         memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
158
159         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
160             "---- SAS PHY PAGE 0 ------------\n", ioc->name));
161         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
162             "Attached Device Handle=0x%X\n", ioc->name,
163             le16_to_cpu(pg0->AttachedDevHandle)));
164         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
165             ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
166         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
167             "Attached PHY Identifier=0x%X\n", ioc->name,
168             pg0->AttachedPhyIdentifier));
169         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Attached Device Info=0x%X\n",
170             ioc->name, le32_to_cpu(pg0->AttachedDeviceInfo)));
171         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
172             ioc->name,  pg0->ProgrammedLinkRate));
173         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Change Count=0x%X\n",
174             ioc->name, pg0->ChangeCount));
175         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Info=0x%X\n\n",
176             ioc->name, le32_to_cpu(pg0->PhyInfo)));
177 }
178
179 static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
180 {
181         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
182             "---- SAS PHY PAGE 1 ------------\n", ioc->name));
183         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Invalid Dword Count=0x%x\n",
184             ioc->name,  pg1->InvalidDwordCount));
185         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
186             "Running Disparity Error Count=0x%x\n", ioc->name,
187             pg1->RunningDisparityErrorCount));
188         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
189             "Loss Dword Synch Count=0x%x\n", ioc->name,
190             pg1->LossDwordSynchCount));
191         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
192             "PHY Reset Problem Count=0x%x\n\n", ioc->name,
193             pg1->PhyResetProblemCount));
194 }
195
196 static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
197 {
198         __le64 sas_address;
199
200         memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
201
202         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
203             "---- SAS DEVICE PAGE 0 ---------\n", ioc->name));
204         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
205             ioc->name, le16_to_cpu(pg0->DevHandle)));
206         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Handle=0x%X\n",
207             ioc->name, le16_to_cpu(pg0->ParentDevHandle)));
208         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Enclosure Handle=0x%X\n",
209             ioc->name, le16_to_cpu(pg0->EnclosureHandle)));
210         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Slot=0x%X\n",
211             ioc->name, le16_to_cpu(pg0->Slot)));
212         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
213             ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
214         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Target ID=0x%X\n",
215             ioc->name, pg0->TargetID));
216         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Bus=0x%X\n",
217             ioc->name, pg0->Bus));
218         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Phy Num=0x%X\n",
219             ioc->name, pg0->PhyNum));
220         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Access Status=0x%X\n",
221             ioc->name, le16_to_cpu(pg0->AccessStatus)));
222         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Device Info=0x%X\n",
223             ioc->name, le32_to_cpu(pg0->DeviceInfo)));
224         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Flags=0x%X\n",
225             ioc->name, le16_to_cpu(pg0->Flags)));
226         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n\n",
227             ioc->name, pg0->PhysicalPort));
228 }
229
230 static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
231 {
232         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
233             "---- SAS EXPANDER PAGE 1 ------------\n", ioc->name));
234         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n",
235             ioc->name, pg1->PhysicalPort));
236         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Identifier=0x%X\n",
237             ioc->name, pg1->PhyIdentifier));
238         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
239             ioc->name, pg1->NegotiatedLinkRate));
240         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
241             ioc->name, pg1->ProgrammedLinkRate));
242         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hardware Link Rate=0x%X\n",
243             ioc->name, pg1->HwLinkRate));
244         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Owner Device Handle=0x%X\n",
245             ioc->name, le16_to_cpu(pg1->OwnerDevHandle)));
246         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
247             "Attached Device Handle=0x%X\n\n", ioc->name,
248             le16_to_cpu(pg1->AttachedDevHandle)));
249 }
250
251 /* inhibit sas firmware event handling */
252 static void
253 mptsas_fw_event_off(MPT_ADAPTER *ioc)
254 {
255         unsigned long flags;
256
257         spin_lock_irqsave(&ioc->fw_event_lock, flags);
258         ioc->fw_events_off = 1;
259         ioc->sas_discovery_quiesce_io = 0;
260         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
261
262 }
263
264 /* enable sas firmware event handling */
265 static void
266 mptsas_fw_event_on(MPT_ADAPTER *ioc)
267 {
268         unsigned long flags;
269
270         spin_lock_irqsave(&ioc->fw_event_lock, flags);
271         ioc->fw_events_off = 0;
272         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
273 }
274
275 /* queue a sas firmware event */
276 static void
277 mptsas_add_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
278     unsigned long delay)
279 {
280         unsigned long flags;
281
282         spin_lock_irqsave(&ioc->fw_event_lock, flags);
283         list_add_tail(&fw_event->list, &ioc->fw_event_list);
284         INIT_DELAYED_WORK(&fw_event->work, mptsas_firmware_event_work);
285         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: add (fw_event=0x%p)\n",
286             ioc->name, __func__, fw_event));
287         queue_delayed_work(ioc->fw_event_q, &fw_event->work,
288             delay);
289         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
290 }
291
292 /* requeue a sas firmware event */
293 static void
294 mptsas_requeue_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
295     unsigned long delay)
296 {
297         unsigned long flags;
298         spin_lock_irqsave(&ioc->fw_event_lock, flags);
299         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: reschedule task "
300             "(fw_event=0x%p)\n", ioc->name, __func__, fw_event));
301         fw_event->retries++;
302         queue_delayed_work(ioc->fw_event_q, &fw_event->work,
303             msecs_to_jiffies(delay));
304         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
305 }
306
307 /* free memory assoicated to a sas firmware event */
308 static void
309 mptsas_free_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event)
310 {
311         unsigned long flags;
312
313         spin_lock_irqsave(&ioc->fw_event_lock, flags);
314         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: kfree (fw_event=0x%p)\n",
315             ioc->name, __func__, fw_event));
316         list_del(&fw_event->list);
317         kfree(fw_event);
318         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
319 }
320
321 /* walk the firmware event queue, and either stop or wait for
322  * outstanding events to complete */
323 static void
324 mptsas_cleanup_fw_event_q(MPT_ADAPTER *ioc)
325 {
326         struct fw_event_work *fw_event, *next;
327         struct mptsas_target_reset_event *target_reset_list, *n;
328         MPT_SCSI_HOST   *hd = shost_priv(ioc->sh);
329
330         /* flush the target_reset_list */
331         if (!list_empty(&hd->target_reset_list)) {
332                 list_for_each_entry_safe(target_reset_list, n,
333                     &hd->target_reset_list, list) {
334                         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
335                             "%s: removing target reset for id=%d\n",
336                             ioc->name, __func__,
337                            target_reset_list->sas_event_data.TargetID));
338                         list_del(&target_reset_list->list);
339                         kfree(target_reset_list);
340                 }
341         }
342
343         if (list_empty(&ioc->fw_event_list) ||
344              !ioc->fw_event_q || in_interrupt())
345                 return;
346
347         list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) {
348                 if (cancel_delayed_work(&fw_event->work))
349                         mptsas_free_fw_event(ioc, fw_event);
350         }
351 }
352
353
354 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
355 {
356         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
357         return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
358 }
359
360 static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
361 {
362         struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
363         return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
364 }
365
366 /*
367  * mptsas_find_portinfo_by_handle
368  *
369  * This function should be called with the sas_topology_mutex already held
370  */
371 static struct mptsas_portinfo *
372 mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
373 {
374         struct mptsas_portinfo *port_info, *rc=NULL;
375         int i;
376
377         list_for_each_entry(port_info, &ioc->sas_topology, list)
378                 for (i = 0; i < port_info->num_phys; i++)
379                         if (port_info->phy_info[i].identify.handle == handle) {
380                                 rc = port_info;
381                                 goto out;
382                         }
383  out:
384         return rc;
385 }
386
387 /**
388  *      mptsas_find_portinfo_by_sas_address -
389  *      @ioc: Pointer to MPT_ADAPTER structure
390  *      @handle:
391  *
392  *      This function should be called with the sas_topology_mutex already held
393  *
394  **/
395 static struct mptsas_portinfo *
396 mptsas_find_portinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
397 {
398         struct mptsas_portinfo *port_info, *rc = NULL;
399         int i;
400
401         if (sas_address >= ioc->hba_port_sas_addr &&
402             sas_address < (ioc->hba_port_sas_addr +
403             ioc->hba_port_num_phy))
404                 return ioc->hba_port_info;
405
406         mutex_lock(&ioc->sas_topology_mutex);
407         list_for_each_entry(port_info, &ioc->sas_topology, list)
408                 for (i = 0; i < port_info->num_phys; i++)
409                         if (port_info->phy_info[i].identify.sas_address ==
410                             sas_address) {
411                                 rc = port_info;
412                                 goto out;
413                         }
414  out:
415         mutex_unlock(&ioc->sas_topology_mutex);
416         return rc;
417 }
418
419 /*
420  * Returns true if there is a scsi end device
421  */
422 static inline int
423 mptsas_is_end_device(struct mptsas_devinfo * attached)
424 {
425         if ((attached->sas_address) &&
426             (attached->device_info &
427             MPI_SAS_DEVICE_INFO_END_DEVICE) &&
428             ((attached->device_info &
429             MPI_SAS_DEVICE_INFO_SSP_TARGET) |
430             (attached->device_info &
431             MPI_SAS_DEVICE_INFO_STP_TARGET) |
432             (attached->device_info &
433             MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
434                 return 1;
435         else
436                 return 0;
437 }
438
439 /* no mutex */
440 static void
441 mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
442 {
443         struct mptsas_portinfo *port_info;
444         struct mptsas_phyinfo *phy_info;
445         u8      i;
446
447         if (!port_details)
448                 return;
449
450         port_info = port_details->port_info;
451         phy_info = port_info->phy_info;
452
453         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d "
454             "bitmask=0x%016llX\n", ioc->name, __func__, port_details,
455             port_details->num_phys, (unsigned long long)
456             port_details->phy_bitmask));
457
458         for (i = 0; i < port_info->num_phys; i++, phy_info++) {
459                 if(phy_info->port_details != port_details)
460                         continue;
461                 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
462                 mptsas_set_rphy(ioc, phy_info, NULL);
463                 phy_info->port_details = NULL;
464         }
465         kfree(port_details);
466 }
467
468 static inline struct sas_rphy *
469 mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
470 {
471         if (phy_info->port_details)
472                 return phy_info->port_details->rphy;
473         else
474                 return NULL;
475 }
476
477 static inline void
478 mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
479 {
480         if (phy_info->port_details) {
481                 phy_info->port_details->rphy = rphy;
482                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
483                     ioc->name, rphy));
484         }
485
486         if (rphy) {
487                 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
488                     &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
489                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
490                     ioc->name, rphy, rphy->dev.release));
491         }
492 }
493
494 static inline struct sas_port *
495 mptsas_get_port(struct mptsas_phyinfo *phy_info)
496 {
497         if (phy_info->port_details)
498                 return phy_info->port_details->port;
499         else
500                 return NULL;
501 }
502
503 static inline void
504 mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_port *port)
505 {
506         if (phy_info->port_details)
507                 phy_info->port_details->port = port;
508
509         if (port) {
510                 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
511                     &port->dev, MYIOC_s_FMT "add:", ioc->name));
512                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "port=%p release=%p\n",
513                     ioc->name, port, port->dev.release));
514         }
515 }
516
517 static inline struct scsi_target *
518 mptsas_get_starget(struct mptsas_phyinfo *phy_info)
519 {
520         if (phy_info->port_details)
521                 return phy_info->port_details->starget;
522         else
523                 return NULL;
524 }
525
526 static inline void
527 mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
528 starget)
529 {
530         if (phy_info->port_details)
531                 phy_info->port_details->starget = starget;
532 }
533
534 /**
535  *      mptsas_add_device_component -
536  *      @ioc: Pointer to MPT_ADAPTER structure
537  *      @channel: fw mapped id's
538  *      @id:
539  *      @sas_address:
540  *      @device_info:
541  *
542  **/
543 static void
544 mptsas_add_device_component(MPT_ADAPTER *ioc, u8 channel, u8 id,
545         u64 sas_address, u32 device_info, u16 slot, u64 enclosure_logical_id)
546 {
547         struct mptsas_device_info       *sas_info, *next;
548         struct scsi_device      *sdev;
549         struct scsi_target      *starget;
550         struct sas_rphy *rphy;
551
552         /*
553          * Delete all matching devices out of the list
554          */
555         mutex_lock(&ioc->sas_device_info_mutex);
556         list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
557             list) {
558                 if (!sas_info->is_logical_volume &&
559                     (sas_info->sas_address == sas_address ||
560                     (sas_info->fw.channel == channel &&
561                      sas_info->fw.id == id))) {
562                         list_del(&sas_info->list);
563                         kfree(sas_info);
564                 }
565         }
566
567         sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
568         if (!sas_info)
569                 goto out;
570
571         /*
572          * Set Firmware mapping
573          */
574         sas_info->fw.id = id;
575         sas_info->fw.channel = channel;
576
577         sas_info->sas_address = sas_address;
578         sas_info->device_info = device_info;
579         sas_info->slot = slot;
580         sas_info->enclosure_logical_id = enclosure_logical_id;
581         INIT_LIST_HEAD(&sas_info->list);
582         list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
583
584         /*
585          * Set OS mapping
586          */
587         shost_for_each_device(sdev, ioc->sh) {
588                 starget = scsi_target(sdev);
589                 rphy = dev_to_rphy(starget->dev.parent);
590                 if (rphy->identify.sas_address == sas_address) {
591                         sas_info->os.id = starget->id;
592                         sas_info->os.channel = starget->channel;
593                 }
594         }
595
596  out:
597         mutex_unlock(&ioc->sas_device_info_mutex);
598         return;
599 }
600
601 /**
602  *      mptsas_add_device_component_by_fw -
603  *      @ioc: Pointer to MPT_ADAPTER structure
604  *      @channel:  fw mapped id's
605  *      @id:
606  *
607  **/
608 static void
609 mptsas_add_device_component_by_fw(MPT_ADAPTER *ioc, u8 channel, u8 id)
610 {
611         struct mptsas_devinfo sas_device;
612         struct mptsas_enclosure enclosure_info;
613         int rc;
614
615         rc = mptsas_sas_device_pg0(ioc, &sas_device,
616             (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
617              MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
618             (channel << 8) + id);
619         if (rc)
620                 return;
621
622         memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
623         mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
624             (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
625              MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
626              sas_device.handle_enclosure);
627
628         mptsas_add_device_component(ioc, sas_device.channel,
629             sas_device.id, sas_device.sas_address, sas_device.device_info,
630             sas_device.slot, enclosure_info.enclosure_logical_id);
631 }
632
633 /**
634  *      mptsas_add_device_component_starget_ir - Handle Integrated RAID, adding each individual device to list
635  *      @ioc: Pointer to MPT_ADAPTER structure
636  *      @channel: fw mapped id's
637  *      @id:
638  *
639  **/
640 static void
641 mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc,
642                 struct scsi_target *starget)
643 {
644         CONFIGPARMS                     cfg;
645         ConfigPageHeader_t              hdr;
646         dma_addr_t                      dma_handle;
647         pRaidVolumePage0_t              buffer = NULL;
648         int                             i;
649         RaidPhysDiskPage0_t             phys_disk;
650         struct mptsas_device_info       *sas_info, *next;
651
652         memset(&cfg, 0 , sizeof(CONFIGPARMS));
653         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
654         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
655         /* assumption that all volumes on channel = 0 */
656         cfg.pageAddr = starget->id;
657         cfg.cfghdr.hdr = &hdr;
658         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
659         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
660
661         if (mpt_config(ioc, &cfg) != 0)
662                 goto out;
663
664         if (!hdr.PageLength)
665                 goto out;
666
667         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
668             &dma_handle);
669
670         if (!buffer)
671                 goto out;
672
673         cfg.physAddr = dma_handle;
674         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
675
676         if (mpt_config(ioc, &cfg) != 0)
677                 goto out;
678
679         if (!buffer->NumPhysDisks)
680                 goto out;
681
682         /*
683          * Adding entry for hidden components
684          */
685         for (i = 0; i < buffer->NumPhysDisks; i++) {
686
687                 if (mpt_raid_phys_disk_pg0(ioc,
688                     buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
689                         continue;
690
691                 mptsas_add_device_component_by_fw(ioc, phys_disk.PhysDiskBus,
692                     phys_disk.PhysDiskID);
693
694                 mutex_lock(&ioc->sas_device_info_mutex);
695                 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
696                     list) {
697                         if (!sas_info->is_logical_volume &&
698                             (sas_info->fw.channel == phys_disk.PhysDiskBus &&
699                             sas_info->fw.id == phys_disk.PhysDiskID)) {
700                                 sas_info->is_hidden_raid_component = 1;
701                                 sas_info->volume_id = starget->id;
702                         }
703                 }
704                 mutex_unlock(&ioc->sas_device_info_mutex);
705
706         }
707
708         /*
709          * Delete all matching devices out of the list
710          */
711         mutex_lock(&ioc->sas_device_info_mutex);
712         list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
713             list) {
714                 if (sas_info->is_logical_volume && sas_info->fw.id ==
715                     starget->id) {
716                         list_del(&sas_info->list);
717                         kfree(sas_info);
718                 }
719         }
720
721         sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
722         if (sas_info) {
723                 sas_info->fw.id = starget->id;
724                 sas_info->os.id = starget->id;
725                 sas_info->os.channel = starget->channel;
726                 sas_info->is_logical_volume = 1;
727                 INIT_LIST_HEAD(&sas_info->list);
728                 list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
729         }
730         mutex_unlock(&ioc->sas_device_info_mutex);
731
732  out:
733         if (buffer)
734                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
735                     dma_handle);
736 }
737
738 /**
739  *      mptsas_add_device_component_starget -
740  *      @ioc: Pointer to MPT_ADAPTER structure
741  *      @starget:
742  *
743  **/
744 static void
745 mptsas_add_device_component_starget(MPT_ADAPTER *ioc,
746         struct scsi_target *starget)
747 {
748         VirtTarget      *vtarget;
749         struct sas_rphy *rphy;
750         struct mptsas_phyinfo   *phy_info = NULL;
751         struct mptsas_enclosure enclosure_info;
752
753         rphy = dev_to_rphy(starget->dev.parent);
754         vtarget = starget->hostdata;
755         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
756                         rphy->identify.sas_address);
757         if (!phy_info)
758                 return;
759
760         memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
761         mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
762                 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
763                 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
764                 phy_info->attached.handle_enclosure);
765
766         mptsas_add_device_component(ioc, phy_info->attached.channel,
767                 phy_info->attached.id, phy_info->attached.sas_address,
768                 phy_info->attached.device_info,
769                 phy_info->attached.slot, enclosure_info.enclosure_logical_id);
770 }
771
772 /**
773  *      mptsas_del_device_component_by_os - Once a device has been removed, we mark the entry in the list as being cached
774  *      @ioc: Pointer to MPT_ADAPTER structure
775  *      @channel: os mapped id's
776  *      @id:
777  *
778  **/
779 static void
780 mptsas_del_device_component_by_os(MPT_ADAPTER *ioc, u8 channel, u8 id)
781 {
782         struct mptsas_device_info       *sas_info, *next;
783
784         /*
785          * Set is_cached flag
786          */
787         list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
788                 list) {
789                 if (sas_info->os.channel == channel && sas_info->os.id == id)
790                         sas_info->is_cached = 1;
791         }
792 }
793
794 /**
795  *      mptsas_del_device_components - Cleaning the list
796  *      @ioc: Pointer to MPT_ADAPTER structure
797  *
798  **/
799 static void
800 mptsas_del_device_components(MPT_ADAPTER *ioc)
801 {
802         struct mptsas_device_info       *sas_info, *next;
803
804         mutex_lock(&ioc->sas_device_info_mutex);
805         list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
806                 list) {
807                 list_del(&sas_info->list);
808                 kfree(sas_info);
809         }
810         mutex_unlock(&ioc->sas_device_info_mutex);
811 }
812
813
814 /*
815  * mptsas_setup_wide_ports
816  *
817  * Updates for new and existing narrow/wide port configuration
818  * in the sas_topology
819  */
820 static void
821 mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
822 {
823         struct mptsas_portinfo_details * port_details;
824         struct mptsas_phyinfo *phy_info, *phy_info_cmp;
825         u64     sas_address;
826         int     i, j;
827
828         mutex_lock(&ioc->sas_topology_mutex);
829
830         phy_info = port_info->phy_info;
831         for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
832                 if (phy_info->attached.handle)
833                         continue;
834                 port_details = phy_info->port_details;
835                 if (!port_details)
836                         continue;
837                 if (port_details->num_phys < 2)
838                         continue;
839                 /*
840                  * Removing a phy from a port, letting the last
841                  * phy be removed by firmware events.
842                  */
843                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
844                     "%s: [%p]: deleting phy = %d\n",
845                     ioc->name, __func__, port_details, i));
846                 port_details->num_phys--;
847                 port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
848                 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
849                 if (phy_info->phy) {
850                         devtprintk(ioc, dev_printk(KERN_DEBUG,
851                                 &phy_info->phy->dev, MYIOC_s_FMT
852                                 "delete phy %d, phy-obj (0x%p)\n", ioc->name,
853                                 phy_info->phy_id, phy_info->phy));
854                         sas_port_delete_phy(port_details->port, phy_info->phy);
855                 }
856                 phy_info->port_details = NULL;
857         }
858
859         /*
860          * Populate and refresh the tree
861          */
862         phy_info = port_info->phy_info;
863         for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
864                 sas_address = phy_info->attached.sas_address;
865                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "phy_id=%d sas_address=0x%018llX\n",
866                     ioc->name, i, (unsigned long long)sas_address));
867                 if (!sas_address)
868                         continue;
869                 port_details = phy_info->port_details;
870                 /*
871                  * Forming a port
872                  */
873                 if (!port_details) {
874                         port_details = kzalloc(sizeof(struct
875                                 mptsas_portinfo_details), GFP_KERNEL);
876                         if (!port_details)
877                                 goto out;
878                         port_details->num_phys = 1;
879                         port_details->port_info = port_info;
880                         if (phy_info->phy_id < 64 )
881                                 port_details->phy_bitmask |=
882                                     (1 << phy_info->phy_id);
883                         phy_info->sas_port_add_phy=1;
884                         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tForming port\n\t\t"
885                             "phy_id=%d sas_address=0x%018llX\n",
886                             ioc->name, i, (unsigned long long)sas_address));
887                         phy_info->port_details = port_details;
888                 }
889
890                 if (i == port_info->num_phys - 1)
891                         continue;
892                 phy_info_cmp = &port_info->phy_info[i + 1];
893                 for (j = i + 1 ; j < port_info->num_phys ; j++,
894                     phy_info_cmp++) {
895                         if (!phy_info_cmp->attached.sas_address)
896                                 continue;
897                         if (sas_address != phy_info_cmp->attached.sas_address)
898                                 continue;
899                         if (phy_info_cmp->port_details == port_details )
900                                 continue;
901                         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
902                             "\t\tphy_id=%d sas_address=0x%018llX\n",
903                             ioc->name, j, (unsigned long long)
904                             phy_info_cmp->attached.sas_address));
905                         if (phy_info_cmp->port_details) {
906                                 port_details->rphy =
907                                     mptsas_get_rphy(phy_info_cmp);
908                                 port_details->port =
909                                     mptsas_get_port(phy_info_cmp);
910                                 port_details->starget =
911                                     mptsas_get_starget(phy_info_cmp);
912                                 port_details->num_phys =
913                                         phy_info_cmp->port_details->num_phys;
914                                 if (!phy_info_cmp->port_details->num_phys)
915                                         kfree(phy_info_cmp->port_details);
916                         } else
917                                 phy_info_cmp->sas_port_add_phy=1;
918                         /*
919                          * Adding a phy to a port
920                          */
921                         phy_info_cmp->port_details = port_details;
922                         if (phy_info_cmp->phy_id < 64 )
923                                 port_details->phy_bitmask |=
924                                 (1 << phy_info_cmp->phy_id);
925                         port_details->num_phys++;
926                 }
927         }
928
929  out:
930
931         for (i = 0; i < port_info->num_phys; i++) {
932                 port_details = port_info->phy_info[i].port_details;
933                 if (!port_details)
934                         continue;
935                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
936                     "%s: [%p]: phy_id=%02d num_phys=%02d "
937                     "bitmask=0x%016llX\n", ioc->name, __func__,
938                     port_details, i, port_details->num_phys,
939                     (unsigned long long)port_details->phy_bitmask));
940                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n",
941                     ioc->name, port_details->port, port_details->rphy));
942         }
943         dsaswideprintk(ioc, printk("\n"));
944         mutex_unlock(&ioc->sas_topology_mutex);
945 }
946
947 /**
948  * csmisas_find_vtarget
949  *
950  * @ioc
951  * @volume_id
952  * @volume_bus
953  *
954  **/
955 static VirtTarget *
956 mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
957 {
958         struct scsi_device              *sdev;
959         VirtDevice                      *vdevice;
960         VirtTarget                      *vtarget = NULL;
961
962         shost_for_each_device(sdev, ioc->sh) {
963                 vdevice = sdev->hostdata;
964                 if ((vdevice == NULL) ||
965                         (vdevice->vtarget == NULL))
966                         continue;
967                 if ((vdevice->vtarget->tflags &
968                     MPT_TARGET_FLAGS_RAID_COMPONENT ||
969                     vdevice->vtarget->raidVolume))
970                         continue;
971                 if (vdevice->vtarget->id == id &&
972                         vdevice->vtarget->channel == channel)
973                         vtarget = vdevice->vtarget;
974         }
975         return vtarget;
976 }
977
978 static void
979 mptsas_queue_device_delete(MPT_ADAPTER *ioc,
980         MpiEventDataSasDeviceStatusChange_t *sas_event_data)
981 {
982         struct fw_event_work *fw_event;
983         int sz;
984
985         sz = offsetof(struct fw_event_work, event_data) +
986             sizeof(MpiEventDataSasDeviceStatusChange_t);
987         fw_event = kzalloc(sz, GFP_ATOMIC);
988         if (!fw_event) {
989                 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
990                     ioc->name, __func__, __LINE__);
991                 return;
992         }
993         memcpy(fw_event->event_data, sas_event_data,
994             sizeof(MpiEventDataSasDeviceStatusChange_t));
995         fw_event->event = MPI_EVENT_SAS_DEVICE_STATUS_CHANGE;
996         fw_event->ioc = ioc;
997         mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
998 }
999
1000 static void
1001 mptsas_queue_rescan(MPT_ADAPTER *ioc)
1002 {
1003         struct fw_event_work *fw_event;
1004         int sz;
1005
1006         sz = offsetof(struct fw_event_work, event_data);
1007         fw_event = kzalloc(sz, GFP_ATOMIC);
1008         if (!fw_event) {
1009                 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
1010                     ioc->name, __func__, __LINE__);
1011                 return;
1012         }
1013         fw_event->event = -1;
1014         fw_event->ioc = ioc;
1015         mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
1016 }
1017
1018
1019 /**
1020  * mptsas_target_reset
1021  *
1022  * Issues TARGET_RESET to end device using handshaking method
1023  *
1024  * @ioc
1025  * @channel
1026  * @id
1027  *
1028  * Returns (1) success
1029  *         (0) failure
1030  *
1031  **/
1032 static int
1033 mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
1034 {
1035         MPT_FRAME_HDR   *mf;
1036         SCSITaskMgmt_t  *pScsiTm;
1037         if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0)
1038                 return 0;
1039
1040
1041         mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
1042         if (mf == NULL) {
1043                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1044                         "%s, no msg frames @%d!!\n", ioc->name,
1045                         __func__, __LINE__));
1046                 goto out_fail;
1047         }
1048
1049         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1050                 ioc->name, mf));
1051
1052         /* Format the Request
1053          */
1054         pScsiTm = (SCSITaskMgmt_t *) mf;
1055         memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
1056         pScsiTm->TargetID = id;
1057         pScsiTm->Bus = channel;
1058         pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1059         pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
1060         pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
1061
1062         DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
1063
1064         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1065            "TaskMgmt type=%d (sas device delete) fw_channel = %d fw_id = %d)\n",
1066            ioc->name, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, channel, id));
1067
1068         mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
1069
1070         return 1;
1071
1072  out_fail:
1073
1074         mpt_clear_taskmgmt_in_progress_flag(ioc);
1075         return 0;
1076 }
1077
1078 /**
1079  * mptsas_target_reset_queue
1080  *
1081  * Receive request for TARGET_RESET after recieving an firmware
1082  * event NOT_RESPONDING_EVENT, then put command in link list
1083  * and queue if task_queue already in use.
1084  *
1085  * @ioc
1086  * @sas_event_data
1087  *
1088  **/
1089 static void
1090 mptsas_target_reset_queue(MPT_ADAPTER *ioc,
1091     EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1092 {
1093         MPT_SCSI_HOST   *hd = shost_priv(ioc->sh);
1094         VirtTarget *vtarget = NULL;
1095         struct mptsas_target_reset_event *target_reset_list;
1096         u8              id, channel;
1097
1098         id = sas_event_data->TargetID;
1099         channel = sas_event_data->Bus;
1100
1101         if (!(vtarget = mptsas_find_vtarget(ioc, channel, id)))
1102                 return;
1103
1104         vtarget->deleted = 1; /* block IO */
1105
1106         target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event),
1107             GFP_ATOMIC);
1108         if (!target_reset_list) {
1109                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1110                         "%s, failed to allocate mem @%d..!!\n",
1111                         ioc->name, __func__, __LINE__));
1112                 return;
1113         }
1114
1115         memcpy(&target_reset_list->sas_event_data, sas_event_data,
1116                 sizeof(*sas_event_data));
1117         list_add_tail(&target_reset_list->list, &hd->target_reset_list);
1118
1119         target_reset_list->time_count = jiffies;
1120
1121         if (mptsas_target_reset(ioc, channel, id)) {
1122                 target_reset_list->target_reset_issued = 1;
1123         }
1124 }
1125
1126 /**
1127  *      mptsas_taskmgmt_complete - complete SAS task management function
1128  *      @ioc: Pointer to MPT_ADAPTER structure
1129  *
1130  *      Completion for TARGET_RESET after NOT_RESPONDING_EVENT, enable work
1131  *      queue to finish off removing device from upper layers. then send next
1132  *      TARGET_RESET in the queue.
1133  **/
1134 static int
1135 mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
1136 {
1137         MPT_SCSI_HOST   *hd = shost_priv(ioc->sh);
1138         struct list_head *head = &hd->target_reset_list;
1139         u8              id, channel;
1140         struct mptsas_target_reset_event        *target_reset_list;
1141         SCSITaskMgmtReply_t *pScsiTmReply;
1142
1143         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt completed: "
1144             "(mf = %p, mr = %p)\n", ioc->name, mf, mr));
1145
1146         pScsiTmReply = (SCSITaskMgmtReply_t *)mr;
1147         if (pScsiTmReply) {
1148                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1149                     "\tTaskMgmt completed: fw_channel = %d, fw_id = %d,\n"
1150                     "\ttask_type = 0x%02X, iocstatus = 0x%04X "
1151                     "loginfo = 0x%08X,\n\tresponse_code = 0x%02X, "
1152                     "term_cmnds = %d\n", ioc->name,
1153                     pScsiTmReply->Bus, pScsiTmReply->TargetID,
1154                     pScsiTmReply->TaskType,
1155                     le16_to_cpu(pScsiTmReply->IOCStatus),
1156                     le32_to_cpu(pScsiTmReply->IOCLogInfo),
1157                     pScsiTmReply->ResponseCode,
1158                     le32_to_cpu(pScsiTmReply->TerminationCount)));
1159
1160                 if (pScsiTmReply->ResponseCode)
1161                         mptscsih_taskmgmt_response_code(ioc,
1162                         pScsiTmReply->ResponseCode);
1163         }
1164
1165         if (pScsiTmReply && (pScsiTmReply->TaskType ==
1166             MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK || pScsiTmReply->TaskType ==
1167              MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET)) {
1168                 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
1169                 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
1170                 memcpy(ioc->taskmgmt_cmds.reply, mr,
1171                     min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
1172                 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
1173                         ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
1174                         complete(&ioc->taskmgmt_cmds.done);
1175                         return 1;
1176                 }
1177                 return 0;
1178         }
1179
1180         mpt_clear_taskmgmt_in_progress_flag(ioc);
1181
1182         if (list_empty(head))
1183                 return 1;
1184
1185         target_reset_list = list_entry(head->next,
1186             struct mptsas_target_reset_event, list);
1187
1188         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1189             "TaskMgmt: completed (%d seconds)\n",
1190             ioc->name, jiffies_to_msecs(jiffies -
1191             target_reset_list->time_count)/1000));
1192
1193         id = pScsiTmReply->TargetID;
1194         channel = pScsiTmReply->Bus;
1195         target_reset_list->time_count = jiffies;
1196
1197         /*
1198          * retry target reset
1199          */
1200         if (!target_reset_list->target_reset_issued) {
1201                 if (mptsas_target_reset(ioc, channel, id))
1202                         target_reset_list->target_reset_issued = 1;
1203                 return 1;
1204         }
1205
1206         /*
1207          * enable work queue to remove device from upper layers
1208          */
1209         list_del(&target_reset_list->list);
1210         if ((mptsas_find_vtarget(ioc, channel, id)) && !ioc->fw_events_off)
1211                 mptsas_queue_device_delete(ioc,
1212                         &target_reset_list->sas_event_data);
1213
1214
1215         /*
1216          * issue target reset to next device in the queue
1217          */
1218
1219         head = &hd->target_reset_list;
1220         if (list_empty(head))
1221                 return 1;
1222
1223         target_reset_list = list_entry(head->next, struct mptsas_target_reset_event,
1224             list);
1225
1226         id = target_reset_list->sas_event_data.TargetID;
1227         channel = target_reset_list->sas_event_data.Bus;
1228         target_reset_list->time_count = jiffies;
1229
1230         if (mptsas_target_reset(ioc, channel, id))
1231                 target_reset_list->target_reset_issued = 1;
1232
1233         return 1;
1234 }
1235
1236 /**
1237  * mptscsih_ioc_reset
1238  *
1239  * @ioc
1240  * @reset_phase
1241  *
1242  **/
1243 static int
1244 mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1245 {
1246         MPT_SCSI_HOST   *hd;
1247         int rc;
1248
1249         rc = mptscsih_ioc_reset(ioc, reset_phase);
1250         if ((ioc->bus_type != SAS) || (!rc))
1251                 return rc;
1252
1253         hd = shost_priv(ioc->sh);
1254         if (!hd->ioc)
1255                 goto out;
1256
1257         switch (reset_phase) {
1258         case MPT_IOC_SETUP_RESET:
1259                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1260                     "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
1261                 mptsas_fw_event_off(ioc);
1262                 break;
1263         case MPT_IOC_PRE_RESET:
1264                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1265                     "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
1266                 break;
1267         case MPT_IOC_POST_RESET:
1268                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1269                     "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
1270                 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
1271                         ioc->sas_mgmt.status |= MPT_MGMT_STATUS_DID_IOCRESET;
1272                         complete(&ioc->sas_mgmt.done);
1273                 }
1274                 mptsas_cleanup_fw_event_q(ioc);
1275                 mptsas_queue_rescan(ioc);
1276                 break;
1277         default:
1278                 break;
1279         }
1280
1281  out:
1282         return rc;
1283 }
1284
1285
1286 /**
1287  * enum device_state -
1288  * @DEVICE_RETRY: need to retry the TUR
1289  * @DEVICE_ERROR: TUR return error, don't add device
1290  * @DEVICE_READY: device can be added
1291  *
1292  */
1293 enum device_state{
1294         DEVICE_RETRY,
1295         DEVICE_ERROR,
1296         DEVICE_READY,
1297 };
1298
1299 static int
1300 mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
1301                 u32 form, u32 form_specific)
1302 {
1303         ConfigExtendedPageHeader_t hdr;
1304         CONFIGPARMS cfg;
1305         SasEnclosurePage0_t *buffer;
1306         dma_addr_t dma_handle;
1307         int error;
1308         __le64 le_identifier;
1309
1310         memset(&hdr, 0, sizeof(hdr));
1311         hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
1312         hdr.PageNumber = 0;
1313         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1314         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
1315
1316         cfg.cfghdr.ehdr = &hdr;
1317         cfg.physAddr = -1;
1318         cfg.pageAddr = form + form_specific;
1319         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1320         cfg.dir = 0;    /* read */
1321         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
1322
1323         error = mpt_config(ioc, &cfg);
1324         if (error)
1325                 goto out;
1326         if (!hdr.ExtPageLength) {
1327                 error = -ENXIO;
1328                 goto out;
1329         }
1330
1331         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1332                         &dma_handle);
1333         if (!buffer) {
1334                 error = -ENOMEM;
1335                 goto out;
1336         }
1337
1338         cfg.physAddr = dma_handle;
1339         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1340
1341         error = mpt_config(ioc, &cfg);
1342         if (error)
1343                 goto out_free_consistent;
1344
1345         /* save config data */
1346         memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
1347         enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
1348         enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
1349         enclosure->flags = le16_to_cpu(buffer->Flags);
1350         enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
1351         enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
1352         enclosure->start_id = buffer->StartTargetID;
1353         enclosure->start_channel = buffer->StartBus;
1354         enclosure->sep_id = buffer->SEPTargetID;
1355         enclosure->sep_channel = buffer->SEPBus;
1356
1357  out_free_consistent:
1358         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1359                             buffer, dma_handle);
1360  out:
1361         return error;
1362 }
1363
1364 /**
1365  *      mptsas_add_end_device - report a new end device to sas transport layer
1366  *      @ioc: Pointer to MPT_ADAPTER structure
1367  *      @phy_info: decribes attached device
1368  *
1369  *      return (0) success (1) failure
1370  *
1371  **/
1372 static int
1373 mptsas_add_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1374 {
1375         struct sas_rphy *rphy;
1376         struct sas_port *port;
1377         struct sas_identify identify;
1378         char *ds = NULL;
1379         u8 fw_id;
1380
1381         if (!phy_info) {
1382                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1383                         "%s: exit at line=%d\n", ioc->name,
1384                          __func__, __LINE__));
1385                 return 1;
1386         }
1387
1388         fw_id = phy_info->attached.id;
1389
1390         if (mptsas_get_rphy(phy_info)) {
1391                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1392                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1393                          __func__, fw_id, __LINE__));
1394                 return 2;
1395         }
1396
1397         port = mptsas_get_port(phy_info);
1398         if (!port) {
1399                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1400                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1401                          __func__, fw_id, __LINE__));
1402                 return 3;
1403         }
1404
1405         if (phy_info->attached.device_info &
1406             MPI_SAS_DEVICE_INFO_SSP_TARGET)
1407                 ds = "ssp";
1408         if (phy_info->attached.device_info &
1409             MPI_SAS_DEVICE_INFO_STP_TARGET)
1410                 ds = "stp";
1411         if (phy_info->attached.device_info &
1412             MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1413                 ds = "sata";
1414
1415         printk(MYIOC_s_INFO_FMT "attaching %s device: fw_channel %d, fw_id %d,"
1416             " phy %d, sas_addr 0x%llx\n", ioc->name, ds,
1417             phy_info->attached.channel, phy_info->attached.id,
1418             phy_info->attached.phy_id, (unsigned long long)
1419             phy_info->attached.sas_address);
1420
1421         mptsas_parse_device_info(&identify, &phy_info->attached);
1422         rphy = sas_end_device_alloc(port);
1423         if (!rphy) {
1424                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1425                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1426                          __func__, fw_id, __LINE__));
1427                 return 5; /* non-fatal: an rphy can be added later */
1428         }
1429
1430         rphy->identify = identify;
1431         if (sas_rphy_add(rphy)) {
1432                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1433                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1434                          __func__, fw_id, __LINE__));
1435                 sas_rphy_free(rphy);
1436                 return 6;
1437         }
1438         mptsas_set_rphy(ioc, phy_info, rphy);
1439         return 0;
1440 }
1441
1442 /**
1443  *      mptsas_del_end_device - report a deleted end device to sas transport layer
1444  *      @ioc: Pointer to MPT_ADAPTER structure
1445  *      @phy_info: decribes attached device
1446  *
1447  **/
1448 static void
1449 mptsas_del_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1450 {
1451         struct sas_rphy *rphy;
1452         struct sas_port *port;
1453         struct mptsas_portinfo *port_info;
1454         struct mptsas_phyinfo *phy_info_parent;
1455         int i;
1456         char *ds = NULL;
1457         u8 fw_id;
1458         u64 sas_address;
1459
1460         if (!phy_info)
1461                 return;
1462
1463         fw_id = phy_info->attached.id;
1464         sas_address = phy_info->attached.sas_address;
1465
1466         if (!phy_info->port_details) {
1467                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1468                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1469                          __func__, fw_id, __LINE__));
1470                 return;
1471         }
1472         rphy = mptsas_get_rphy(phy_info);
1473         if (!rphy) {
1474                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1475                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1476                          __func__, fw_id, __LINE__));
1477                 return;
1478         }
1479
1480         if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_INITIATOR
1481                 || phy_info->attached.device_info
1482                         & MPI_SAS_DEVICE_INFO_SMP_INITIATOR
1483                 || phy_info->attached.device_info
1484                         & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1485                 ds = "initiator";
1486         if (phy_info->attached.device_info &
1487             MPI_SAS_DEVICE_INFO_SSP_TARGET)
1488                 ds = "ssp";
1489         if (phy_info->attached.device_info &
1490             MPI_SAS_DEVICE_INFO_STP_TARGET)
1491                 ds = "stp";
1492         if (phy_info->attached.device_info &
1493             MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1494                 ds = "sata";
1495
1496         dev_printk(KERN_DEBUG, &rphy->dev, MYIOC_s_FMT
1497             "removing %s device: fw_channel %d, fw_id %d, phy %d,"
1498             "sas_addr 0x%llx\n", ioc->name, ds, phy_info->attached.channel,
1499             phy_info->attached.id, phy_info->attached.phy_id,
1500             (unsigned long long) sas_address);
1501
1502         port = mptsas_get_port(phy_info);
1503         if (!port) {
1504                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1505                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1506                          __func__, fw_id, __LINE__));
1507                 return;
1508         }
1509         port_info = phy_info->portinfo;
1510         phy_info_parent = port_info->phy_info;
1511         for (i = 0; i < port_info->num_phys; i++, phy_info_parent++) {
1512                 if (!phy_info_parent->phy)
1513                         continue;
1514                 if (phy_info_parent->attached.sas_address !=
1515                     sas_address)
1516                         continue;
1517                 dev_printk(KERN_DEBUG, &phy_info_parent->phy->dev,
1518                     MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n",
1519                     ioc->name, phy_info_parent->phy_id,
1520                     phy_info_parent->phy);
1521                 sas_port_delete_phy(port, phy_info_parent->phy);
1522         }
1523
1524         dev_printk(KERN_DEBUG, &port->dev, MYIOC_s_FMT
1525             "delete port %d, sas_addr (0x%llx)\n", ioc->name,
1526              port->port_identifier, (unsigned long long)sas_address);
1527         sas_port_delete(port);
1528         mptsas_set_port(ioc, phy_info, NULL);
1529         mptsas_port_delete(ioc, phy_info->port_details);
1530 }
1531
1532 struct mptsas_phyinfo *
1533 mptsas_refreshing_device_handles(MPT_ADAPTER *ioc,
1534         struct mptsas_devinfo *sas_device)
1535 {
1536         struct mptsas_phyinfo *phy_info;
1537         struct mptsas_portinfo *port_info;
1538         int i;
1539
1540         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
1541             sas_device->sas_address);
1542         if (!phy_info)
1543                 goto out;
1544         port_info = phy_info->portinfo;
1545         if (!port_info)
1546                 goto out;
1547         mutex_lock(&ioc->sas_topology_mutex);
1548         for (i = 0; i < port_info->num_phys; i++) {
1549                 if (port_info->phy_info[i].attached.sas_address !=
1550                         sas_device->sas_address)
1551                         continue;
1552                 port_info->phy_info[i].attached.channel = sas_device->channel;
1553                 port_info->phy_info[i].attached.id = sas_device->id;
1554                 port_info->phy_info[i].attached.sas_address =
1555                     sas_device->sas_address;
1556                 port_info->phy_info[i].attached.handle = sas_device->handle;
1557                 port_info->phy_info[i].attached.handle_parent =
1558                     sas_device->handle_parent;
1559                 port_info->phy_info[i].attached.handle_enclosure =
1560                     sas_device->handle_enclosure;
1561         }
1562         mutex_unlock(&ioc->sas_topology_mutex);
1563  out:
1564         return phy_info;
1565 }
1566
1567 /**
1568  * mptsas_firmware_event_work - work thread for processing fw events
1569  * @work: work queue payload containing info describing the event
1570  * Context: user
1571  *
1572  */
1573 static void
1574 mptsas_firmware_event_work(struct work_struct *work)
1575 {
1576         struct fw_event_work *fw_event =
1577                 container_of(work, struct fw_event_work, work.work);
1578         MPT_ADAPTER *ioc = fw_event->ioc;
1579
1580         /* special rescan topology handling */
1581         if (fw_event->event == -1) {
1582                 if (ioc->in_rescan) {
1583                         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1584                                 "%s: rescan ignored as it is in progress\n",
1585                                 ioc->name, __func__));
1586                         return;
1587                 }
1588                 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: rescan after "
1589                     "reset\n", ioc->name, __func__));
1590                 ioc->in_rescan = 1;
1591                 mptsas_not_responding_devices(ioc);
1592                 mptsas_scan_sas_topology(ioc);
1593                 ioc->in_rescan = 0;
1594                 mptsas_free_fw_event(ioc, fw_event);
1595                 mptsas_fw_event_on(ioc);
1596                 return;
1597         }
1598
1599         /* events handling turned off during host reset */
1600         if (ioc->fw_events_off) {
1601                 mptsas_free_fw_event(ioc, fw_event);
1602                 return;
1603         }
1604
1605         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: fw_event=(0x%p), "
1606             "event = (0x%02x)\n", ioc->name, __func__, fw_event,
1607             (fw_event->event & 0xFF)));
1608
1609         switch (fw_event->event) {
1610         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1611                 mptsas_send_sas_event(fw_event);
1612                 break;
1613         case MPI_EVENT_INTEGRATED_RAID:
1614                 mptsas_send_raid_event(fw_event);
1615                 break;
1616         case MPI_EVENT_IR2:
1617                 mptsas_send_ir2_event(fw_event);
1618                 break;
1619         case MPI_EVENT_PERSISTENT_TABLE_FULL:
1620                 mptbase_sas_persist_operation(ioc,
1621                     MPI_SAS_OP_CLEAR_NOT_PRESENT);
1622                 mptsas_free_fw_event(ioc, fw_event);
1623                 break;
1624         case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
1625                 mptsas_broadcast_primative_work(fw_event);
1626                 break;
1627         case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
1628                 mptsas_send_expander_event(fw_event);
1629                 break;
1630         case MPI_EVENT_SAS_PHY_LINK_STATUS:
1631                 mptsas_send_link_status_event(fw_event);
1632                 break;
1633         case MPI_EVENT_QUEUE_FULL:
1634                 mptsas_handle_queue_full_event(fw_event);
1635                 break;
1636         }
1637 }
1638
1639
1640
1641 static int
1642 mptsas_slave_configure(struct scsi_device *sdev)
1643 {
1644         struct Scsi_Host        *host = sdev->host;
1645         MPT_SCSI_HOST   *hd = shost_priv(host);
1646         MPT_ADAPTER     *ioc = hd->ioc;
1647         VirtDevice      *vdevice = sdev->hostdata;
1648
1649         if (vdevice->vtarget->deleted) {
1650                 sdev_printk(KERN_INFO, sdev, "clearing deleted flag\n");
1651                 vdevice->vtarget->deleted = 0;
1652         }
1653
1654         /*
1655          * RAID volumes placed beyond the last expected port.
1656          * Ignore sending sas mode pages in that case..
1657          */
1658         if (sdev->channel == MPTSAS_RAID_CHANNEL) {
1659                 mptsas_add_device_component_starget_ir(ioc, scsi_target(sdev));
1660                 goto out;
1661         }
1662
1663         sas_read_port_mode_page(sdev);
1664
1665         mptsas_add_device_component_starget(ioc, scsi_target(sdev));
1666
1667  out:
1668         return mptscsih_slave_configure(sdev);
1669 }
1670
1671 static int
1672 mptsas_target_alloc(struct scsi_target *starget)
1673 {
1674         struct Scsi_Host *host = dev_to_shost(&starget->dev);
1675         MPT_SCSI_HOST           *hd = shost_priv(host);
1676         VirtTarget              *vtarget;
1677         u8                      id, channel;
1678         struct sas_rphy         *rphy;
1679         struct mptsas_portinfo  *p;
1680         int                      i;
1681         MPT_ADAPTER             *ioc = hd->ioc;
1682
1683         vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
1684         if (!vtarget)
1685                 return -ENOMEM;
1686
1687         vtarget->starget = starget;
1688         vtarget->ioc_id = ioc->id;
1689         vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
1690         id = starget->id;
1691         channel = 0;
1692
1693         /*
1694          * RAID volumes placed beyond the last expected port.
1695          */
1696         if (starget->channel == MPTSAS_RAID_CHANNEL) {
1697                 if (!ioc->raid_data.pIocPg2) {
1698                         kfree(vtarget);
1699                         return -ENXIO;
1700                 }
1701                 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
1702                         if (id == ioc->raid_data.pIocPg2->
1703                                         RaidVolume[i].VolumeID) {
1704                                 channel = ioc->raid_data.pIocPg2->
1705                                         RaidVolume[i].VolumeBus;
1706                         }
1707                 }
1708                 vtarget->raidVolume = 1;
1709                 goto out;
1710         }
1711
1712         rphy = dev_to_rphy(starget->dev.parent);
1713         mutex_lock(&ioc->sas_topology_mutex);
1714         list_for_each_entry(p, &ioc->sas_topology, list) {
1715                 for (i = 0; i < p->num_phys; i++) {
1716                         if (p->phy_info[i].attached.sas_address !=
1717                                         rphy->identify.sas_address)
1718                                 continue;
1719                         id = p->phy_info[i].attached.id;
1720                         channel = p->phy_info[i].attached.channel;
1721                         mptsas_set_starget(&p->phy_info[i], starget);
1722
1723                         /*
1724                          * Exposing hidden raid components
1725                          */
1726                         if (mptscsih_is_phys_disk(ioc, channel, id)) {
1727                                 id = mptscsih_raid_id_to_num(ioc,
1728                                                 channel, id);
1729                                 vtarget->tflags |=
1730                                     MPT_TARGET_FLAGS_RAID_COMPONENT;
1731                                 p->phy_info[i].attached.phys_disk_num = id;
1732                         }
1733                         mutex_unlock(&ioc->sas_topology_mutex);
1734                         goto out;
1735                 }
1736         }
1737         mutex_unlock(&ioc->sas_topology_mutex);
1738
1739         kfree(vtarget);
1740         return -ENXIO;
1741
1742  out:
1743         vtarget->id = id;
1744         vtarget->channel = channel;
1745         starget->hostdata = vtarget;
1746         return 0;
1747 }
1748
1749 static void
1750 mptsas_target_destroy(struct scsi_target *starget)
1751 {
1752         struct Scsi_Host *host = dev_to_shost(&starget->dev);
1753         MPT_SCSI_HOST           *hd = shost_priv(host);
1754         struct sas_rphy         *rphy;
1755         struct mptsas_portinfo  *p;
1756         int                      i;
1757         MPT_ADAPTER     *ioc = hd->ioc;
1758         VirtTarget      *vtarget;
1759
1760         if (!starget->hostdata)
1761                 return;
1762
1763         vtarget = starget->hostdata;
1764
1765         mptsas_del_device_component_by_os(ioc, starget->channel,
1766             starget->id);
1767
1768
1769         if (starget->channel == MPTSAS_RAID_CHANNEL)
1770                 goto out;
1771
1772         rphy = dev_to_rphy(starget->dev.parent);
1773         list_for_each_entry(p, &ioc->sas_topology, list) {
1774                 for (i = 0; i < p->num_phys; i++) {
1775                         if (p->phy_info[i].attached.sas_address !=
1776                                         rphy->identify.sas_address)
1777                                 continue;
1778
1779                         starget_printk(KERN_INFO, starget, MYIOC_s_FMT
1780                         "delete device: fw_channel %d, fw_id %d, phy %d, "
1781                         "sas_addr 0x%llx\n", ioc->name,
1782                         p->phy_info[i].attached.channel,
1783                         p->phy_info[i].attached.id,
1784                         p->phy_info[i].attached.phy_id, (unsigned long long)
1785                         p->phy_info[i].attached.sas_address);
1786
1787                         mptsas_set_starget(&p->phy_info[i], NULL);
1788                 }
1789         }
1790
1791  out:
1792         vtarget->starget = NULL;
1793         kfree(starget->hostdata);
1794         starget->hostdata = NULL;
1795 }
1796
1797
1798 static int
1799 mptsas_slave_alloc(struct scsi_device *sdev)
1800 {
1801         struct Scsi_Host        *host = sdev->host;
1802         MPT_SCSI_HOST           *hd = shost_priv(host);
1803         struct sas_rphy         *rphy;
1804         struct mptsas_portinfo  *p;
1805         VirtDevice              *vdevice;
1806         struct scsi_target      *starget;
1807         int                     i;
1808         MPT_ADAPTER *ioc = hd->ioc;
1809
1810         vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
1811         if (!vdevice) {
1812                 printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
1813                                 ioc->name, sizeof(VirtDevice));
1814                 return -ENOMEM;
1815         }
1816         starget = scsi_target(sdev);
1817         vdevice->vtarget = starget->hostdata;
1818
1819         if (sdev->channel == MPTSAS_RAID_CHANNEL)
1820                 goto out;
1821
1822         rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
1823         mutex_lock(&ioc->sas_topology_mutex);
1824         list_for_each_entry(p, &ioc->sas_topology, list) {
1825                 for (i = 0; i < p->num_phys; i++) {
1826                         if (p->phy_info[i].attached.sas_address !=
1827                                         rphy->identify.sas_address)
1828                                 continue;
1829                         vdevice->lun = sdev->lun;
1830                         /*
1831                          * Exposing hidden raid components
1832                          */
1833                         if (mptscsih_is_phys_disk(ioc,
1834                             p->phy_info[i].attached.channel,
1835                             p->phy_info[i].attached.id))
1836                                 sdev->no_uld_attach = 1;
1837                         mutex_unlock(&ioc->sas_topology_mutex);
1838                         goto out;
1839                 }
1840         }
1841         mutex_unlock(&ioc->sas_topology_mutex);
1842
1843         kfree(vdevice);
1844         return -ENXIO;
1845
1846  out:
1847         vdevice->vtarget->num_luns++;
1848         sdev->hostdata = vdevice;
1849         return 0;
1850 }
1851
1852 static int
1853 mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1854 {
1855         MPT_SCSI_HOST   *hd;
1856         MPT_ADAPTER     *ioc;
1857         VirtDevice      *vdevice = SCpnt->device->hostdata;
1858
1859         if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
1860                 SCpnt->result = DID_NO_CONNECT << 16;
1861                 done(SCpnt);
1862                 return 0;
1863         }
1864
1865         hd = shost_priv(SCpnt->device->host);
1866         ioc = hd->ioc;
1867
1868         if (ioc->sas_discovery_quiesce_io)
1869                 return SCSI_MLQUEUE_HOST_BUSY;
1870
1871 //      scsi_print_command(SCpnt);
1872
1873         return mptscsih_qcmd(SCpnt,done);
1874 }
1875
1876
1877 static struct scsi_host_template mptsas_driver_template = {
1878         .module                         = THIS_MODULE,
1879         .proc_name                      = "mptsas",
1880         .proc_info                      = mptscsih_proc_info,
1881         .name                           = "MPT SPI Host",
1882         .info                           = mptscsih_info,
1883         .queuecommand                   = mptsas_qcmd,
1884         .target_alloc                   = mptsas_target_alloc,
1885         .slave_alloc                    = mptsas_slave_alloc,
1886         .slave_configure                = mptsas_slave_configure,
1887         .target_destroy                 = mptsas_target_destroy,
1888         .slave_destroy                  = mptscsih_slave_destroy,
1889         .change_queue_depth             = mptscsih_change_queue_depth,
1890         .eh_abort_handler               = mptscsih_abort,
1891         .eh_device_reset_handler        = mptscsih_dev_reset,
1892         .eh_bus_reset_handler           = mptscsih_bus_reset,
1893         .eh_host_reset_handler          = mptscsih_host_reset,
1894         .bios_param                     = mptscsih_bios_param,
1895         .can_queue                      = MPT_SAS_CAN_QUEUE,
1896         .this_id                        = -1,
1897         .sg_tablesize                   = MPT_SCSI_SG_DEPTH,
1898         .max_sectors                    = 8192,
1899         .cmd_per_lun                    = 7,
1900         .use_clustering                 = ENABLE_CLUSTERING,
1901         .shost_attrs                    = mptscsih_host_attrs,
1902 };
1903
1904 static int mptsas_get_linkerrors(struct sas_phy *phy)
1905 {
1906         MPT_ADAPTER *ioc = phy_to_ioc(phy);
1907         ConfigExtendedPageHeader_t hdr;
1908         CONFIGPARMS cfg;
1909         SasPhyPage1_t *buffer;
1910         dma_addr_t dma_handle;
1911         int error;
1912
1913         /* FIXME: only have link errors on local phys */
1914         if (!scsi_is_sas_phy_local(phy))
1915                 return -EINVAL;
1916
1917         hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
1918         hdr.ExtPageLength = 0;
1919         hdr.PageNumber = 1 /* page number 1*/;
1920         hdr.Reserved1 = 0;
1921         hdr.Reserved2 = 0;
1922         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1923         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1924
1925         cfg.cfghdr.ehdr = &hdr;
1926         cfg.physAddr = -1;
1927         cfg.pageAddr = phy->identify.phy_identifier;
1928         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1929         cfg.dir = 0;    /* read */
1930         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
1931
1932         error = mpt_config(ioc, &cfg);
1933         if (error)
1934                 return error;
1935         if (!hdr.ExtPageLength)
1936                 return -ENXIO;
1937
1938         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1939                                       &dma_handle);
1940         if (!buffer)
1941                 return -ENOMEM;
1942
1943         cfg.physAddr = dma_handle;
1944         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1945
1946         error = mpt_config(ioc, &cfg);
1947         if (error)
1948                 goto out_free_consistent;
1949
1950         mptsas_print_phy_pg1(ioc, buffer);
1951
1952         phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
1953         phy->running_disparity_error_count =
1954                 le32_to_cpu(buffer->RunningDisparityErrorCount);
1955         phy->loss_of_dword_sync_count =
1956                 le32_to_cpu(buffer->LossDwordSynchCount);
1957         phy->phy_reset_problem_count =
1958                 le32_to_cpu(buffer->PhyResetProblemCount);
1959
1960  out_free_consistent:
1961         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1962                             buffer, dma_handle);
1963         return error;
1964 }
1965
1966 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
1967                 MPT_FRAME_HDR *reply)
1968 {
1969         ioc->sas_mgmt.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
1970         if (reply != NULL) {
1971                 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_RF_VALID;
1972                 memcpy(ioc->sas_mgmt.reply, reply,
1973                     min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
1974         }
1975
1976         if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
1977                 ioc->sas_mgmt.status &= ~MPT_MGMT_STATUS_PENDING;
1978                 complete(&ioc->sas_mgmt.done);
1979                 return 1;
1980         }
1981         return 0;
1982 }
1983
1984 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
1985 {
1986         MPT_ADAPTER *ioc = phy_to_ioc(phy);
1987         SasIoUnitControlRequest_t *req;
1988         SasIoUnitControlReply_t *reply;
1989         MPT_FRAME_HDR *mf;
1990         MPIHeader_t *hdr;
1991         unsigned long timeleft;
1992         int error = -ERESTARTSYS;
1993
1994         /* FIXME: fusion doesn't allow non-local phy reset */
1995         if (!scsi_is_sas_phy_local(phy))
1996                 return -EINVAL;
1997
1998         /* not implemented for expanders */
1999         if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
2000                 return -ENXIO;
2001
2002         if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
2003                 goto out;
2004
2005         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2006         if (!mf) {
2007                 error = -ENOMEM;
2008                 goto out_unlock;
2009         }
2010
2011         hdr = (MPIHeader_t *) mf;
2012         req = (SasIoUnitControlRequest_t *)mf;
2013         memset(req, 0, sizeof(SasIoUnitControlRequest_t));
2014         req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
2015         req->MsgContext = hdr->MsgContext;
2016         req->Operation = hard_reset ?
2017                 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
2018         req->PhyNum = phy->identify.phy_identifier;
2019
2020         INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2021         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2022
2023         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
2024                         10 * HZ);
2025         if (!timeleft) {
2026                 /* On timeout reset the board */
2027                 mpt_free_msg_frame(ioc, mf);
2028                 mpt_HardResetHandler(ioc, CAN_SLEEP);
2029                 error = -ETIMEDOUT;
2030                 goto out_unlock;
2031         }
2032
2033         /* a reply frame is expected */
2034         if ((ioc->sas_mgmt.status &
2035             MPT_MGMT_STATUS_RF_VALID) == 0) {
2036                 error = -ENXIO;
2037                 goto out_unlock;
2038         }
2039
2040         /* process the completed Reply Message Frame */
2041         reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
2042         if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
2043                 printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
2044                     ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo);
2045                 error = -ENXIO;
2046                 goto out_unlock;
2047         }
2048
2049         error = 0;
2050
2051  out_unlock:
2052         CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2053         mutex_unlock(&ioc->sas_mgmt.mutex);
2054  out:
2055         return error;
2056 }
2057
2058 static int
2059 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
2060 {
2061         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2062         int i, error;
2063         struct mptsas_portinfo *p;
2064         struct mptsas_enclosure enclosure_info;
2065         u64 enclosure_handle;
2066
2067         mutex_lock(&ioc->sas_topology_mutex);
2068         list_for_each_entry(p, &ioc->sas_topology, list) {
2069                 for (i = 0; i < p->num_phys; i++) {
2070                         if (p->phy_info[i].attached.sas_address ==
2071                             rphy->identify.sas_address) {
2072                                 enclosure_handle = p->phy_info[i].
2073                                         attached.handle_enclosure;
2074                                 goto found_info;
2075                         }
2076                 }
2077         }
2078         mutex_unlock(&ioc->sas_topology_mutex);
2079         return -ENXIO;
2080
2081  found_info:
2082         mutex_unlock(&ioc->sas_topology_mutex);
2083         memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
2084         error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
2085                         (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
2086                          MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
2087         if (!error)
2088                 *identifier = enclosure_info.enclosure_logical_id;
2089         return error;
2090 }
2091
2092 static int
2093 mptsas_get_bay_identifier(struct sas_rphy *rphy)
2094 {
2095         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2096         struct mptsas_portinfo *p;
2097         int i, rc;
2098
2099         mutex_lock(&ioc->sas_topology_mutex);
2100         list_for_each_entry(p, &ioc->sas_topology, list) {
2101                 for (i = 0; i < p->num_phys; i++) {
2102                         if (p->phy_info[i].attached.sas_address ==
2103                             rphy->identify.sas_address) {
2104                                 rc = p->phy_info[i].attached.slot;
2105                                 goto out;
2106                         }
2107                 }
2108         }
2109         rc = -ENXIO;
2110  out:
2111         mutex_unlock(&ioc->sas_topology_mutex);
2112         return rc;
2113 }
2114
2115 static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
2116                               struct request *req)
2117 {
2118         MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
2119         MPT_FRAME_HDR *mf;
2120         SmpPassthroughRequest_t *smpreq;
2121         struct request *rsp = req->next_rq;
2122         int ret;
2123         int flagsLength;
2124         unsigned long timeleft;
2125         char *psge;
2126         dma_addr_t dma_addr_in = 0;
2127         dma_addr_t dma_addr_out = 0;
2128         u64 sas_address = 0;
2129
2130         if (!rsp) {
2131                 printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n",
2132                     ioc->name, __func__);
2133                 return -EINVAL;
2134         }
2135
2136         /* do we need to support multiple segments? */
2137         if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
2138                 printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
2139                     ioc->name, __func__, req->bio->bi_vcnt, blk_rq_bytes(req),
2140                     rsp->bio->bi_vcnt, blk_rq_bytes(rsp));
2141                 return -EINVAL;
2142         }
2143
2144         ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2145         if (ret)
2146                 goto out;
2147
2148         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2149         if (!mf) {
2150                 ret = -ENOMEM;
2151                 goto out_unlock;
2152         }
2153
2154         smpreq = (SmpPassthroughRequest_t *)mf;
2155         memset(smpreq, 0, sizeof(*smpreq));
2156
2157         smpreq->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
2158         smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2159
2160         if (rphy)
2161                 sas_address = rphy->identify.sas_address;
2162         else {
2163                 struct mptsas_portinfo *port_info;
2164
2165                 mutex_lock(&ioc->sas_topology_mutex);
2166                 port_info = ioc->hba_port_info;
2167                 if (port_info && port_info->phy_info)
2168                         sas_address =
2169                                 port_info->phy_info[0].phy->identify.sas_address;
2170                 mutex_unlock(&ioc->sas_topology_mutex);
2171         }
2172
2173         *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2174
2175         psge = (char *)
2176                 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2177
2178         /* request */
2179         flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2180                        MPI_SGE_FLAGS_END_OF_BUFFER |
2181                        MPI_SGE_FLAGS_DIRECTION)
2182                        << MPI_SGE_FLAGS_SHIFT;
2183         flagsLength |= (blk_rq_bytes(req) - 4);
2184
2185         dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
2186                                       blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
2187         if (!dma_addr_out)
2188                 goto put_mf;
2189         ioc->add_sge(psge, flagsLength, dma_addr_out);
2190         psge += ioc->SGE_size;
2191
2192         /* response */
2193         flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2194                 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2195                 MPI_SGE_FLAGS_IOC_TO_HOST |
2196                 MPI_SGE_FLAGS_END_OF_BUFFER;
2197
2198         flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2199         flagsLength |= blk_rq_bytes(rsp) + 4;
2200         dma_addr_in =  pci_map_single(ioc->pcidev, bio_data(rsp->bio),
2201                                       blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
2202         if (!dma_addr_in)
2203                 goto unmap;
2204         ioc->add_sge(psge, flagsLength, dma_addr_in);
2205
2206         INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2207         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2208
2209         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2210         if (!timeleft) {
2211                 printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __func__);
2212                 /* On timeout reset the board */
2213                 mpt_HardResetHandler(ioc, CAN_SLEEP);
2214                 ret = -ETIMEDOUT;
2215                 goto unmap;
2216         }
2217         mf = NULL;
2218
2219         if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2220                 SmpPassthroughReply_t *smprep;
2221
2222                 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2223                 memcpy(req->sense, smprep, sizeof(*smprep));
2224                 req->sense_len = sizeof(*smprep);
2225                 req->resid_len = 0;
2226                 rsp->resid_len -= smprep->ResponseDataLength;
2227         } else {
2228                 printk(MYIOC_s_ERR_FMT
2229                     "%s: smp passthru reply failed to be returned\n",
2230                     ioc->name, __func__);
2231                 ret = -ENXIO;
2232         }
2233 unmap:
2234         if (dma_addr_out)
2235                 pci_unmap_single(ioc->pcidev, dma_addr_out, blk_rq_bytes(req),
2236                                  PCI_DMA_BIDIRECTIONAL);
2237         if (dma_addr_in)
2238                 pci_unmap_single(ioc->pcidev, dma_addr_in, blk_rq_bytes(rsp),
2239                                  PCI_DMA_BIDIRECTIONAL);
2240 put_mf:
2241         if (mf)
2242                 mpt_free_msg_frame(ioc, mf);
2243 out_unlock:
2244         CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2245         mutex_unlock(&ioc->sas_mgmt.mutex);
2246 out:
2247         return ret;
2248 }
2249
2250 static struct sas_function_template mptsas_transport_functions = {
2251         .get_linkerrors         = mptsas_get_linkerrors,
2252         .get_enclosure_identifier = mptsas_get_enclosure_identifier,
2253         .get_bay_identifier     = mptsas_get_bay_identifier,
2254         .phy_reset              = mptsas_phy_reset,
2255         .smp_handler            = mptsas_smp_handler,
2256 };
2257
2258 static struct scsi_transport_template *mptsas_transport_template;
2259
2260 static int
2261 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
2262 {
2263         ConfigExtendedPageHeader_t hdr;
2264         CONFIGPARMS cfg;
2265         SasIOUnitPage0_t *buffer;
2266         dma_addr_t dma_handle;
2267         int error, i;
2268
2269         hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
2270         hdr.ExtPageLength = 0;
2271         hdr.PageNumber = 0;
2272         hdr.Reserved1 = 0;
2273         hdr.Reserved2 = 0;
2274         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2275         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2276
2277         cfg.cfghdr.ehdr = &hdr;
2278         cfg.physAddr = -1;
2279         cfg.pageAddr = 0;
2280         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2281         cfg.dir = 0;    /* read */
2282         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2283
2284         error = mpt_config(ioc, &cfg);
2285         if (error)
2286                 goto out;
2287         if (!hdr.ExtPageLength) {
2288                 error = -ENXIO;
2289                 goto out;
2290         }
2291
2292         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2293                                             &dma_handle);
2294         if (!buffer) {
2295                 error = -ENOMEM;
2296                 goto out;
2297         }
2298
2299         cfg.physAddr = dma_handle;
2300         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2301
2302         error = mpt_config(ioc, &cfg);
2303         if (error)
2304                 goto out_free_consistent;
2305
2306         port_info->num_phys = buffer->NumPhys;
2307         port_info->phy_info = kcalloc(port_info->num_phys,
2308                 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2309         if (!port_info->phy_info) {
2310                 error = -ENOMEM;
2311                 goto out_free_consistent;
2312         }
2313
2314         ioc->nvdata_version_persistent =
2315             le16_to_cpu(buffer->NvdataVersionPersistent);
2316         ioc->nvdata_version_default =
2317             le16_to_cpu(buffer->NvdataVersionDefault);
2318
2319         for (i = 0; i < port_info->num_phys; i++) {
2320                 mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
2321                 port_info->phy_info[i].phy_id = i;
2322                 port_info->phy_info[i].port_id =
2323                     buffer->PhyData[i].Port;
2324                 port_info->phy_info[i].negotiated_link_rate =
2325                     buffer->PhyData[i].NegotiatedLinkRate;
2326                 port_info->phy_info[i].portinfo = port_info;
2327                 port_info->phy_info[i].handle =
2328                     le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
2329         }
2330
2331  out_free_consistent:
2332         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2333                             buffer, dma_handle);
2334  out:
2335         return error;
2336 }
2337
2338 static int
2339 mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
2340 {
2341         ConfigExtendedPageHeader_t hdr;
2342         CONFIGPARMS cfg;
2343         SasIOUnitPage1_t *buffer;
2344         dma_addr_t dma_handle;
2345         int error;
2346         u16 device_missing_delay;
2347
2348         memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
2349         memset(&cfg, 0, sizeof(CONFIGPARMS));
2350
2351         cfg.cfghdr.ehdr = &hdr;
2352         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2353         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2354         cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2355         cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2356         cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
2357         cfg.cfghdr.ehdr->PageNumber = 1;
2358
2359         error = mpt_config(ioc, &cfg);
2360         if (error)
2361                 goto out;
2362         if (!hdr.ExtPageLength) {
2363                 error = -ENXIO;
2364                 goto out;
2365         }
2366
2367         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2368                                             &dma_handle);
2369         if (!buffer) {
2370                 error = -ENOMEM;
2371                 goto out;
2372         }
2373
2374         cfg.physAddr = dma_handle;
2375         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2376
2377         error = mpt_config(ioc, &cfg);
2378         if (error)
2379                 goto out_free_consistent;
2380
2381         ioc->io_missing_delay  =
2382             le16_to_cpu(buffer->IODeviceMissingDelay);
2383         device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay);
2384         ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
2385             (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
2386             device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
2387
2388  out_free_consistent:
2389         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2390                             buffer, dma_handle);
2391  out:
2392         return error;
2393 }
2394
2395 static int
2396 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2397                 u32 form, u32 form_specific)
2398 {
2399         ConfigExtendedPageHeader_t hdr;
2400         CONFIGPARMS cfg;
2401         SasPhyPage0_t *buffer;
2402         dma_addr_t dma_handle;
2403         int error;
2404
2405         hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
2406         hdr.ExtPageLength = 0;
2407         hdr.PageNumber = 0;
2408         hdr.Reserved1 = 0;
2409         hdr.Reserved2 = 0;
2410         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2411         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2412
2413         cfg.cfghdr.ehdr = &hdr;
2414         cfg.dir = 0;    /* read */
2415         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2416
2417         /* Get Phy Pg 0 for each Phy. */
2418         cfg.physAddr = -1;
2419         cfg.pageAddr = form + form_specific;
2420         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2421
2422         error = mpt_config(ioc, &cfg);
2423         if (error)
2424                 goto out;
2425
2426         if (!hdr.ExtPageLength) {
2427                 error = -ENXIO;
2428                 goto out;
2429         }
2430
2431         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2432                                       &dma_handle);
2433         if (!buffer) {
2434                 error = -ENOMEM;
2435                 goto out;
2436         }
2437
2438         cfg.physAddr = dma_handle;
2439         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2440
2441         error = mpt_config(ioc, &cfg);
2442         if (error)
2443                 goto out_free_consistent;
2444
2445         mptsas_print_phy_pg0(ioc, buffer);
2446
2447         phy_info->hw_link_rate = buffer->HwLinkRate;
2448         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2449         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2450         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2451
2452  out_free_consistent:
2453         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2454                             buffer, dma_handle);
2455  out:
2456         return error;
2457 }
2458
2459 static int
2460 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
2461                 u32 form, u32 form_specific)
2462 {
2463         ConfigExtendedPageHeader_t hdr;
2464         CONFIGPARMS cfg;
2465         SasDevicePage0_t *buffer;
2466         dma_addr_t dma_handle;
2467         __le64 sas_address;
2468         int error=0;
2469
2470         hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
2471         hdr.ExtPageLength = 0;
2472         hdr.PageNumber = 0;
2473         hdr.Reserved1 = 0;
2474         hdr.Reserved2 = 0;
2475         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2476         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
2477
2478         cfg.cfghdr.ehdr = &hdr;
2479         cfg.pageAddr = form + form_specific;
2480         cfg.physAddr = -1;
2481         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2482         cfg.dir = 0;    /* read */
2483         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2484
2485         memset(device_info, 0, sizeof(struct mptsas_devinfo));
2486         error = mpt_config(ioc, &cfg);
2487         if (error)
2488                 goto out;
2489         if (!hdr.ExtPageLength) {
2490                 error = -ENXIO;
2491                 goto out;
2492         }
2493
2494         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2495                                       &dma_handle);
2496         if (!buffer) {
2497                 error = -ENOMEM;
2498                 goto out;
2499         }
2500
2501         cfg.physAddr = dma_handle;
2502         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2503
2504         error = mpt_config(ioc, &cfg);
2505         if (error)
2506                 goto out_free_consistent;
2507
2508         mptsas_print_device_pg0(ioc, buffer);
2509
2510         memset(device_info, 0, sizeof(struct mptsas_devinfo));
2511         device_info->handle = le16_to_cpu(buffer->DevHandle);
2512         device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
2513         device_info->handle_enclosure =
2514             le16_to_cpu(buffer->EnclosureHandle);
2515         device_info->slot = le16_to_cpu(buffer->Slot);
2516         device_info->phy_id = buffer->PhyNum;
2517         device_info->port_id = buffer->PhysicalPort;
2518         device_info->id = buffer->TargetID;
2519         device_info->phys_disk_num = ~0;
2520         device_info->channel = buffer->Bus;
2521         memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2522         device_info->sas_address = le64_to_cpu(sas_address);
2523         device_info->device_info =
2524             le32_to_cpu(buffer->DeviceInfo);
2525
2526  out_free_consistent:
2527         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2528                             buffer, dma_handle);
2529  out:
2530         return error;
2531 }
2532
2533 static int
2534 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
2535                 u32 form, u32 form_specific)
2536 {
2537         ConfigExtendedPageHeader_t hdr;
2538         CONFIGPARMS cfg;
2539         SasExpanderPage0_t *buffer;
2540         dma_addr_t dma_handle;
2541         int i, error;
2542         __le64 sas_address;
2543
2544         memset(port_info, 0, sizeof(struct mptsas_portinfo));
2545         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
2546         hdr.ExtPageLength = 0;
2547         hdr.PageNumber = 0;
2548         hdr.Reserved1 = 0;
2549         hdr.Reserved2 = 0;
2550         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2551         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2552
2553         cfg.cfghdr.ehdr = &hdr;
2554         cfg.physAddr = -1;
2555         cfg.pageAddr = form + form_specific;
2556         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2557         cfg.dir = 0;    /* read */
2558         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2559
2560         memset(port_info, 0, sizeof(struct mptsas_portinfo));
2561         error = mpt_config(ioc, &cfg);
2562         if (error)
2563                 goto out;
2564
2565         if (!hdr.ExtPageLength) {
2566                 error = -ENXIO;
2567                 goto out;
2568         }
2569
2570         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2571                                       &dma_handle);
2572         if (!buffer) {
2573                 error = -ENOMEM;
2574                 goto out;
2575         }
2576
2577         cfg.physAddr = dma_handle;
2578         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2579
2580         error = mpt_config(ioc, &cfg);
2581         if (error)
2582                 goto out_free_consistent;
2583
2584         if (!buffer->NumPhys) {
2585                 error = -ENODEV;
2586                 goto out_free_consistent;
2587         }
2588
2589         /* save config data */
2590         port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1;
2591         port_info->phy_info = kcalloc(port_info->num_phys,
2592                 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2593         if (!port_info->phy_info) {
2594                 error = -ENOMEM;
2595                 goto out_free_consistent;
2596         }
2597
2598         memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2599         for (i = 0; i < port_info->num_phys; i++) {
2600                 port_info->phy_info[i].portinfo = port_info;
2601                 port_info->phy_info[i].handle =
2602                     le16_to_cpu(buffer->DevHandle);
2603                 port_info->phy_info[i].identify.sas_address =
2604                     le64_to_cpu(sas_address);
2605                 port_info->phy_info[i].identify.handle_parent =
2606                     le16_to_cpu(buffer->ParentDevHandle);
2607         }
2608
2609  out_free_consistent:
2610         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2611                             buffer, dma_handle);
2612  out:
2613         return error;
2614 }
2615
2616 static int
2617 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2618                 u32 form, u32 form_specific)
2619 {
2620         ConfigExtendedPageHeader_t hdr;
2621         CONFIGPARMS cfg;
2622         SasExpanderPage1_t *buffer;
2623         dma_addr_t dma_handle;
2624         int error=0;
2625
2626         hdr.PageVersion = MPI_SASEXPANDER1_PAGEVERSION;
2627         hdr.ExtPageLength = 0;
2628         hdr.PageNumber = 1;
2629         hdr.Reserved1 = 0;
2630         hdr.Reserved2 = 0;
2631         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2632         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2633
2634         cfg.cfghdr.ehdr = &hdr;
2635         cfg.physAddr = -1;
2636         cfg.pageAddr = form + form_specific;
2637         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2638         cfg.dir = 0;    /* read */
2639         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2640
2641         error = mpt_config(ioc, &cfg);
2642         if (error)
2643                 goto out;
2644
2645         if (!hdr.ExtPageLength) {
2646                 error = -ENXIO;
2647                 goto out;
2648         }
2649
2650         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2651                                       &dma_handle);
2652         if (!buffer) {
2653                 error = -ENOMEM;
2654                 goto out;
2655         }
2656
2657         cfg.physAddr = dma_handle;
2658         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2659
2660         error = mpt_config(ioc, &cfg);
2661
2662         if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2663                 error = -ENODEV;
2664                 goto out;
2665         }
2666
2667         if (error)
2668                 goto out_free_consistent;
2669
2670
2671         mptsas_print_expander_pg1(ioc, buffer);
2672
2673         /* save config data */
2674         phy_info->phy_id = buffer->PhyIdentifier;
2675         phy_info->port_id = buffer->PhysicalPort;
2676         phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
2677         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2678         phy_info->hw_link_rate = buffer->HwLinkRate;
2679         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2680         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2681
2682  out_free_consistent:
2683         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2684                             buffer, dma_handle);
2685  out:
2686         return error;
2687 }
2688
2689 static void
2690 mptsas_parse_device_info(struct sas_identify *identify,
2691                 struct mptsas_devinfo *device_info)
2692 {
2693         u16 protocols;
2694
2695         identify->sas_address = device_info->sas_address;
2696         identify->phy_identifier = device_info->phy_id;
2697
2698         /*
2699          * Fill in Phy Initiator Port Protocol.
2700          * Bits 6:3, more than one bit can be set, fall through cases.
2701          */
2702         protocols = device_info->device_info & 0x78;
2703         identify->initiator_port_protocols = 0;
2704         if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
2705                 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
2706         if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
2707                 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
2708         if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
2709                 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
2710         if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
2711                 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
2712
2713         /*
2714          * Fill in Phy Target Port Protocol.
2715          * Bits 10:7, more than one bit can be set, fall through cases.
2716          */
2717         protocols = device_info->device_info & 0x780;
2718         identify->target_port_protocols = 0;
2719         if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
2720                 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
2721         if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
2722                 identify->target_port_protocols |= SAS_PROTOCOL_STP;
2723         if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
2724                 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
2725         if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2726                 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
2727
2728         /*
2729          * Fill in Attached device type.
2730          */
2731         switch (device_info->device_info &
2732                         MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
2733         case MPI_SAS_DEVICE_INFO_NO_DEVICE:
2734                 identify->device_type = SAS_PHY_UNUSED;
2735                 break;
2736         case MPI_SAS_DEVICE_INFO_END_DEVICE:
2737                 identify->device_type = SAS_END_DEVICE;
2738                 break;
2739         case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
2740                 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
2741                 break;
2742         case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
2743                 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
2744                 break;
2745         }
2746 }
2747
2748 static int mptsas_probe_one_phy(struct device *dev,
2749                 struct mptsas_phyinfo *phy_info, int index, int local)
2750 {
2751         MPT_ADAPTER *ioc;
2752         struct sas_phy *phy;
2753         struct sas_port *port;
2754         int error = 0;
2755
2756         if (!dev) {
2757                 error = -ENODEV;
2758                 goto out;
2759         }
2760
2761         if (!phy_info->phy) {
2762                 phy = sas_phy_alloc(dev, index);
2763                 if (!phy) {
2764                         error = -ENOMEM;
2765                         goto out;
2766                 }
2767         } else
2768                 phy = phy_info->phy;
2769
2770         mptsas_parse_device_info(&phy->identify, &phy_info->identify);
2771
2772         /*
2773          * Set Negotiated link rate.
2774          */
2775         switch (phy_info->negotiated_link_rate) {
2776         case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
2777                 phy->negotiated_linkrate = SAS_PHY_DISABLED;
2778                 break;
2779         case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
2780                 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
2781                 break;
2782         case MPI_SAS_IOUNIT0_RATE_1_5:
2783                 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
2784                 break;
2785         case MPI_SAS_IOUNIT0_RATE_3_0:
2786                 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
2787                 break;
2788         case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
2789         case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
2790         default:
2791                 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
2792                 break;
2793         }
2794
2795         /*
2796          * Set Max hardware link rate.
2797          */
2798         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
2799         case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
2800                 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
2801                 break;
2802         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
2803                 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
2804                 break;
2805         default:
2806                 break;
2807         }
2808
2809         /*
2810          * Set Max programmed link rate.
2811          */
2812         switch (phy_info->programmed_link_rate &
2813                         MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
2814         case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
2815                 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
2816                 break;
2817         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
2818                 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
2819                 break;
2820         default:
2821                 break;
2822         }
2823
2824         /*
2825          * Set Min hardware link rate.
2826          */
2827         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
2828         case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
2829                 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
2830                 break;
2831         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
2832                 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
2833                 break;
2834         default:
2835                 break;
2836         }
2837
2838         /*
2839          * Set Min programmed link rate.
2840          */
2841         switch (phy_info->programmed_link_rate &
2842                         MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
2843         case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
2844                 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
2845                 break;
2846         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
2847                 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
2848                 break;
2849         default:
2850                 break;
2851         }
2852
2853         if (!phy_info->phy) {
2854
2855                 error = sas_phy_add(phy);
2856                 if (error) {
2857                         sas_phy_free(phy);
2858                         goto out;
2859                 }
2860                 phy_info->phy = phy;
2861         }
2862
2863         if (!phy_info->attached.handle ||
2864                         !phy_info->port_details)
2865                 goto out;
2866
2867         port = mptsas_get_port(phy_info);
2868         ioc = phy_to_ioc(phy_info->phy);
2869
2870         if (phy_info->sas_port_add_phy) {
2871
2872                 if (!port) {
2873                         port = sas_port_alloc_num(dev);
2874                         if (!port) {
2875                                 error = -ENOMEM;
2876                                 goto out;
2877                         }
2878                         error = sas_port_add(port);
2879                         if (error) {
2880                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2881                                         "%s: exit at line=%d\n", ioc->name,
2882                                         __func__, __LINE__));
2883                                 goto out;
2884                         }
2885                         mptsas_set_port(ioc, phy_info, port);
2886                         devtprintk(ioc, dev_printk(KERN_DEBUG, &port->dev,
2887                             MYIOC_s_FMT "add port %d, sas_addr (0x%llx)\n",
2888                             ioc->name, port->port_identifier,
2889                             (unsigned long long)phy_info->
2890                             attached.sas_address));
2891                 }
2892                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2893                         "sas_port_add_phy: phy_id=%d\n",
2894                         ioc->name, phy_info->phy_id));
2895                 sas_port_add_phy(port, phy_info->phy);
2896                 phy_info->sas_port_add_phy = 0;
2897                 devtprintk(ioc, dev_printk(KERN_DEBUG, &phy_info->phy->dev,
2898                     MYIOC_s_FMT "add phy %d, phy-obj (0x%p)\n", ioc->name,
2899                      phy_info->phy_id, phy_info->phy));
2900         }
2901         if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
2902
2903                 struct sas_rphy *rphy;
2904                 struct device *parent;
2905                 struct sas_identify identify;
2906
2907                 parent = dev->parent->parent;
2908                 /*
2909                  * Let the hotplug_work thread handle processing
2910                  * the adding/removing of devices that occur
2911                  * after start of day.
2912                  */
2913                 if (mptsas_is_end_device(&phy_info->attached) &&
2914                     phy_info->attached.handle_parent) {
2915                         goto out;
2916                 }
2917
2918                 mptsas_parse_device_info(&identify, &phy_info->attached);
2919                 if (scsi_is_host_device(parent)) {
2920                         struct mptsas_portinfo *port_info;
2921                         int i;
2922
2923                         port_info = ioc->hba_port_info;
2924
2925                         for (i = 0; i < port_info->num_phys; i++)
2926                                 if (port_info->phy_info[i].identify.sas_address ==
2927                                     identify.sas_address) {
2928                                         sas_port_mark_backlink(port);
2929                                         goto out;
2930                                 }
2931
2932                 } else if (scsi_is_sas_rphy(parent)) {
2933                         struct sas_rphy *parent_rphy = dev_to_rphy(parent);
2934                         if (identify.sas_address ==
2935                             parent_rphy->identify.sas_address) {
2936                                 sas_port_mark_backlink(port);
2937                                 goto out;
2938                         }
2939                 }
2940
2941                 switch (identify.device_type) {
2942                 case SAS_END_DEVICE:
2943                         rphy = sas_end_device_alloc(port);
2944                         break;
2945                 case SAS_EDGE_EXPANDER_DEVICE:
2946                 case SAS_FANOUT_EXPANDER_DEVICE:
2947                         rphy = sas_expander_alloc(port, identify.device_type);
2948                         break;
2949                 default:
2950                         rphy = NULL;
2951                         break;
2952                 }
2953                 if (!rphy) {
2954                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2955                                 "%s: exit at line=%d\n", ioc->name,
2956                                 __func__, __LINE__));
2957                         goto out;
2958                 }
2959
2960                 rphy->identify = identify;
2961                 error = sas_rphy_add(rphy);
2962                 if (error) {
2963                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2964                                 "%s: exit at line=%d\n", ioc->name,
2965                                 __func__, __LINE__));
2966                         sas_rphy_free(rphy);
2967                         goto out;
2968                 }
2969                 mptsas_set_rphy(ioc, phy_info, rphy);
2970         }
2971
2972  out:
2973         return error;
2974 }
2975
2976 static int
2977 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
2978 {
2979         struct mptsas_portinfo *port_info, *hba;
2980         int error = -ENOMEM, i;
2981
2982         hba = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
2983         if (! hba)
2984                 goto out;
2985
2986         error = mptsas_sas_io_unit_pg0(ioc, hba);
2987         if (error)
2988                 goto out_free_port_info;
2989
2990         mptsas_sas_io_unit_pg1(ioc);
2991         mutex_lock(&ioc->sas_topology_mutex);
2992         port_info = ioc->hba_port_info;
2993         if (!port_info) {
2994                 ioc->hba_port_info = port_info = hba;
2995                 ioc->hba_port_num_phy = port_info->num_phys;
2996                 list_add_tail(&port_info->list, &ioc->sas_topology);
2997         } else {
2998                 for (i = 0; i < hba->num_phys; i++) {
2999                         port_info->phy_info[i].negotiated_link_rate =
3000                                 hba->phy_info[i].negotiated_link_rate;
3001                         port_info->phy_info[i].handle =
3002                                 hba->phy_info[i].handle;
3003                         port_info->phy_info[i].port_id =
3004                                 hba->phy_info[i].port_id;
3005                 }
3006                 kfree(hba->phy_info);
3007                 kfree(hba);
3008                 hba = NULL;
3009         }
3010         mutex_unlock(&ioc->sas_topology_mutex);
3011 #if defined(CPQ_CIM)
3012         ioc->num_ports = port_info->num_phys;
3013 #endif
3014         for (i = 0; i < port_info->num_phys; i++) {
3015                 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
3016                         (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
3017                          MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
3018                 port_info->phy_info[i].identify.handle =
3019                     port_info->phy_info[i].handle;
3020                 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
3021                         (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3022                          MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3023                          port_info->phy_info[i].identify.handle);
3024                 if (!ioc->hba_port_sas_addr)
3025                         ioc->hba_port_sas_addr =
3026                             port_info->phy_info[i].identify.sas_address;
3027                 port_info->phy_info[i].identify.phy_id =
3028                     port_info->phy_info[i].phy_id = i;
3029                 if (port_info->phy_info[i].attached.handle)
3030                         mptsas_sas_device_pg0(ioc,
3031                                 &port_info->phy_info[i].attached,
3032                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3033                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3034                                 port_info->phy_info[i].attached.handle);
3035         }
3036
3037         mptsas_setup_wide_ports(ioc, port_info);
3038
3039         for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3040                 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
3041                     &port_info->phy_info[i], ioc->sas_index, 1);
3042
3043         return 0;
3044
3045  out_free_port_info:
3046         kfree(hba);
3047  out:
3048         return error;
3049 }
3050
3051 static void
3052 mptsas_expander_refresh(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
3053 {
3054         struct mptsas_portinfo *parent;
3055         struct device *parent_dev;
3056         struct sas_rphy *rphy;
3057         int             i;
3058         u64             sas_address; /* expander sas address */
3059         u32             handle;
3060
3061         handle = port_info->phy_info[0].handle;
3062         sas_address = port_info->phy_info[0].identify.sas_address;
3063         for (i = 0; i < port_info->num_phys; i++) {
3064                 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
3065                     (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
3066                     MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + handle);
3067
3068                 mptsas_sas_device_pg0(ioc,
3069                     &port_info->phy_info[i].identify,
3070                     (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3071                     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3072                     port_info->phy_info[i].identify.handle);
3073                 port_info->phy_info[i].identify.phy_id =
3074                     port_info->phy_info[i].phy_id;
3075
3076                 if (port_info->phy_info[i].attached.handle) {
3077                         mptsas_sas_device_pg0(ioc,
3078                             &port_info->phy_info[i].attached,
3079                             (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3080                              MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3081                             port_info->phy_info[i].attached.handle);
3082                         port_info->phy_info[i].attached.phy_id =
3083                             port_info->phy_info[i].phy_id;
3084                 }
3085         }
3086
3087         mutex_lock(&ioc->sas_topology_mutex);
3088         parent = mptsas_find_portinfo_by_handle(ioc,
3089             port_info->phy_info[0].identify.handle_parent);
3090         if (!parent) {
3091                 mutex_unlock(&ioc->sas_topology_mutex);
3092                 return;
3093         }
3094         for (i = 0, parent_dev = NULL; i < parent->num_phys && !parent_dev;
3095             i++) {
3096                 if (parent->phy_info[i].attached.sas_address == sas_address) {
3097                         rphy = mptsas_get_rphy(&parent->phy_info[i]);
3098                         parent_dev = &rphy->dev;
3099                 }
3100         }
3101         mutex_unlock(&ioc->sas_topology_mutex);
3102
3103         mptsas_setup_wide_ports(ioc, port_info);
3104         for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3105                 mptsas_probe_one_phy(parent_dev, &port_info->phy_info[i],
3106                     ioc->sas_index, 0);
3107 }
3108
3109 static void
3110 mptsas_expander_event_add(MPT_ADAPTER *ioc,
3111     MpiEventDataSasExpanderStatusChange_t *expander_data)
3112 {
3113         struct mptsas_portinfo *port_info;
3114         int i;
3115         __le64 sas_address;
3116
3117         port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3118         if (!port_info)
3119                 BUG();
3120         port_info->num_phys = (expander_data->NumPhys) ?
3121             expander_data->NumPhys : 1;
3122         port_info->phy_info = kcalloc(port_info->num_phys,
3123             sizeof(struct mptsas_phyinfo), GFP_KERNEL);
3124         if (!port_info->phy_info)
3125                 BUG();
3126         memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3127         for (i = 0; i < port_info->num_phys; i++) {
3128                 port_info->phy_info[i].portinfo = port_info;
3129                 port_info->phy_info[i].handle =
3130                     le16_to_cpu(expander_data->DevHandle);
3131                 port_info->phy_info[i].identify.sas_address =
3132                     le64_to_cpu(sas_address);
3133                 port_info->phy_info[i].identify.handle_parent =
3134                     le16_to_cpu(expander_data->ParentDevHandle);
3135         }
3136
3137         mutex_lock(&ioc->sas_topology_mutex);
3138         list_add_tail(&port_info->list, &ioc->sas_topology);
3139         mutex_unlock(&ioc->sas_topology_mutex);
3140
3141         printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3142             "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3143             (unsigned long long)sas_address);
3144
3145         mptsas_expander_refresh(ioc, port_info);
3146 }
3147
3148 /**
3149  * mptsas_delete_expander_siblings - remove siblings attached to expander
3150  * @ioc: Pointer to MPT_ADAPTER structure
3151  * @parent: the parent port_info object
3152  * @expander: the expander port_info object
3153  **/
3154 static void
3155 mptsas_delete_expander_siblings(MPT_ADAPTER *ioc, struct mptsas_portinfo
3156     *parent, struct mptsas_portinfo *expander)
3157 {
3158         struct mptsas_phyinfo *phy_info;
3159         struct mptsas_portinfo *port_info;
3160         struct sas_rphy *rphy;
3161         int i;
3162
3163         phy_info = expander->phy_info;
3164         for (i = 0; i < expander->num_phys; i++, phy_info++) {
3165                 rphy = mptsas_get_rphy(phy_info);
3166                 if (!rphy)
3167                         continue;
3168                 if (rphy->identify.device_type == SAS_END_DEVICE)
3169                         mptsas_del_end_device(ioc, phy_info);
3170         }
3171
3172         phy_info = expander->phy_info;
3173         for (i = 0; i < expander->num_phys; i++, phy_info++) {
3174                 rphy = mptsas_get_rphy(phy_info);
3175                 if (!rphy)
3176                         continue;
3177                 if (rphy->identify.device_type ==
3178                     MPI_SAS_DEVICE_INFO_EDGE_EXPANDER ||
3179                     rphy->identify.device_type ==
3180                     MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
3181                         port_info = mptsas_find_portinfo_by_sas_address(ioc,
3182                             rphy->identify.sas_address);
3183                         if (!port_info)
3184                                 continue;
3185                         if (port_info == parent) /* backlink rphy */
3186                                 continue;
3187                         /*
3188                         Delete this expander even if the expdevpage is exists
3189                         because the parent expander is already deleted
3190                         */
3191                         mptsas_expander_delete(ioc, port_info, 1);
3192                 }
3193         }
3194 }
3195
3196
3197 /**
3198  *      mptsas_expander_delete - remove this expander
3199  *      @ioc: Pointer to MPT_ADAPTER structure
3200  *      @port_info: expander port_info struct
3201  *      @force: Flag to forcefully delete the expander
3202  *
3203  **/
3204
3205 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
3206                 struct mptsas_portinfo *port_info, u8 force)
3207 {
3208
3209         struct mptsas_portinfo *parent;
3210         int             i;
3211         u64             expander_sas_address;
3212         struct mptsas_phyinfo *phy_info;
3213         struct mptsas_portinfo buffer;
3214         struct mptsas_portinfo_details *port_details;
3215         struct sas_port *port;
3216
3217         if (!port_info)
3218                 return;
3219
3220         /* see if expander is still there before deleting */
3221         mptsas_sas_expander_pg0(ioc, &buffer,
3222             (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3223             MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
3224             port_info->phy_info[0].identify.handle);
3225
3226         if (buffer.num_phys) {
3227                 kfree(buffer.phy_info);
3228                 if (!force)
3229                         return;
3230         }
3231
3232
3233         /*
3234          * Obtain the port_info instance to the parent port
3235          */
3236         port_details = NULL;
3237         expander_sas_address =
3238             port_info->phy_info[0].identify.sas_address;
3239         parent = mptsas_find_portinfo_by_handle(ioc,
3240             port_info->phy_info[0].identify.handle_parent);
3241         mptsas_delete_expander_siblings(ioc, parent, port_info);
3242         if (!parent)
3243                 goto out;
3244
3245         /*
3246          * Delete rphys in the parent that point
3247          * to this expander.
3248          */
3249         phy_info = parent->phy_info;
3250         port = NULL;
3251         for (i = 0; i < parent->num_phys; i++, phy_info++) {
3252                 if (!phy_info->phy)
3253                         continue;
3254                 if (phy_info->attached.sas_address !=
3255                     expander_sas_address)
3256                         continue;
3257                 if (!port) {
3258                         port = mptsas_get_port(phy_info);
3259                         port_details = phy_info->port_details;
3260                 }
3261                 dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3262                     MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n", ioc->name,
3263                     phy_info->phy_id, phy_info->phy);
3264                 sas_port_delete_phy(port, phy_info->phy);
3265         }
3266         if (port) {
3267                 dev_printk(KERN_DEBUG, &port->dev,
3268                     MYIOC_s_FMT "delete port %d, sas_addr (0x%llx)\n",
3269                     ioc->name, port->port_identifier,
3270                     (unsigned long long)expander_sas_address);
3271                 sas_port_delete(port);
3272                 mptsas_port_delete(ioc, port_details);
3273         }
3274  out:
3275
3276         printk(MYIOC_s_INFO_FMT "delete expander: num_phys %d, "
3277             "sas_addr (0x%llx)\n",  ioc->name, port_info->num_phys,
3278             (unsigned long long)expander_sas_address);
3279
3280         /*
3281          * free link
3282          */
3283         list_del(&port_info->list);
3284         kfree(port_info->phy_info);
3285         kfree(port_info);
3286 }
3287
3288
3289 /**
3290  * mptsas_send_expander_event - expanders events
3291  * @ioc: Pointer to MPT_ADAPTER structure
3292  * @expander_data: event data
3293  *
3294  *
3295  * This function handles adding, removing, and refreshing
3296  * device handles within the expander objects.
3297  */
3298 static void
3299 mptsas_send_expander_event(struct fw_event_work *fw_event)
3300 {
3301         MPT_ADAPTER *ioc;
3302         MpiEventDataSasExpanderStatusChange_t *expander_data;
3303         struct mptsas_portinfo *port_info;
3304         __le64 sas_address;
3305         int i;
3306
3307         ioc = fw_event->ioc;
3308         expander_data = (MpiEventDataSasExpanderStatusChange_t *)
3309             fw_event->event_data;
3310         memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3311         sas_address = le64_to_cpu(sas_address);
3312         port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3313
3314         if (expander_data->ReasonCode == MPI_EVENT_SAS_EXP_RC_ADDED) {
3315                 if (port_info) {
3316                         for (i = 0; i < port_info->num_phys; i++) {
3317                                 port_info->phy_info[i].portinfo = port_info;
3318                                 port_info->phy_info[i].handle =
3319                                     le16_to_cpu(expander_data->DevHandle);
3320                                 port_info->phy_info[i].identify.sas_address =
3321                                     le64_to_cpu(sas_address);
3322                                 port_info->phy_info[i].identify.handle_parent =
3323                                     le16_to_cpu(expander_data->ParentDevHandle);
3324                         }
3325                         mptsas_expander_refresh(ioc, port_info);
3326                 } else if (!port_info && expander_data->NumPhys)
3327                         mptsas_expander_event_add(ioc, expander_data);
3328         } else if (expander_data->ReasonCode ==
3329             MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING)
3330                 mptsas_expander_delete(ioc, port_info, 0);
3331
3332         mptsas_free_fw_event(ioc, fw_event);
3333 }
3334
3335
3336 /**
3337  * mptsas_expander_add -
3338  * @ioc: Pointer to MPT_ADAPTER structure
3339  * @handle:
3340  *
3341  */
3342 struct mptsas_portinfo *
3343 mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
3344 {
3345         struct mptsas_portinfo buffer, *port_info;
3346         int i;
3347
3348         if ((mptsas_sas_expander_pg0(ioc, &buffer,
3349             (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3350             MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)))
3351                 return NULL;
3352
3353         port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_ATOMIC);
3354         if (!port_info) {
3355                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3356                 "%s: exit at line=%d\n", ioc->name,
3357                 __func__, __LINE__));
3358                 return NULL;
3359         }
3360         port_info->num_phys = buffer.num_phys;
3361         port_info->phy_info = buffer.phy_info;
3362         for (i = 0; i < port_info->num_phys; i++)
3363                 port_info->phy_info[i].portinfo = port_info;
3364         mutex_lock(&ioc->sas_topology_mutex);
3365         list_add_tail(&port_info->list, &ioc->sas_topology);
3366         mutex_unlock(&ioc->sas_topology_mutex);
3367         printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3368             "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3369             (unsigned long long)buffer.phy_info[0].identify.sas_address);
3370         mptsas_expander_refresh(ioc, port_info);
3371         return port_info;
3372 }
3373
3374 static void
3375 mptsas_send_link_status_event(struct fw_event_work *fw_event)
3376 {
3377         MPT_ADAPTER *ioc;
3378         MpiEventDataSasPhyLinkStatus_t *link_data;
3379         struct mptsas_portinfo *port_info;
3380         struct mptsas_phyinfo *phy_info = NULL;
3381         __le64 sas_address;
3382         u8 phy_num;
3383         u8 link_rate;
3384
3385         ioc = fw_event->ioc;
3386         link_data = (MpiEventDataSasPhyLinkStatus_t *)fw_event->event_data;
3387
3388         memcpy(&sas_address, &link_data->SASAddress, sizeof(__le64));
3389         sas_address = le64_to_cpu(sas_address);
3390         link_rate = link_data->LinkRates >> 4;
3391         phy_num = link_data->PhyNum;
3392
3393         port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3394         if (port_info) {
3395                 phy_info = &port_info->phy_info[phy_num];
3396                 if (phy_info)
3397                         phy_info->negotiated_link_rate = link_rate;
3398         }
3399
3400         if (link_rate == MPI_SAS_IOUNIT0_RATE_1_5 ||
3401             link_rate == MPI_SAS_IOUNIT0_RATE_3_0) {
3402
3403                 if (!port_info) {
3404                         if (ioc->old_sas_discovery_protocal) {
3405                                 port_info = mptsas_expander_add(ioc,
3406                                         le16_to_cpu(link_data->DevHandle));
3407                                 if (port_info)
3408                                         goto out;
3409                         }
3410                         goto out;
3411                 }
3412
3413                 if (port_info == ioc->hba_port_info)
3414                         mptsas_probe_hba_phys(ioc);
3415                 else
3416                         mptsas_expander_refresh(ioc, port_info);
3417         } else if (phy_info && phy_info->phy) {
3418                 if (link_rate ==  MPI_SAS_IOUNIT0_RATE_PHY_DISABLED)
3419                         phy_info->phy->negotiated_linkrate =
3420                             SAS_PHY_DISABLED;
3421                 else if (link_rate ==
3422                     MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION)
3423                         phy_info->phy->negotiated_linkrate =
3424                             SAS_LINK_RATE_FAILED;
3425                 else
3426                         phy_info->phy->negotiated_linkrate =
3427                             SAS_LINK_RATE_UNKNOWN;
3428         }
3429  out:
3430         mptsas_free_fw_event(ioc, fw_event);
3431 }
3432
3433 static void
3434 mptsas_not_responding_devices(MPT_ADAPTER *ioc)
3435 {
3436         struct mptsas_portinfo buffer, *port_info;
3437         struct mptsas_device_info       *sas_info;
3438         struct mptsas_devinfo sas_device;
3439         u32     handle;
3440         VirtTarget *vtarget = NULL;
3441         struct mptsas_phyinfo *phy_info;
3442         u8 found_expander;
3443         int retval, retry_count;
3444         unsigned long flags;
3445
3446         mpt_findImVolumes(ioc);
3447
3448         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3449         if (ioc->ioc_reset_in_progress) {
3450                 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3451                    "%s: exiting due to a parallel reset \n", ioc->name,
3452                     __func__));
3453                 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3454                 return;
3455         }
3456         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3457
3458         /* devices, logical volumes */
3459         mutex_lock(&ioc->sas_device_info_mutex);
3460  redo_device_scan:
3461         list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) {
3462                 if (sas_info->is_cached)
3463                         continue;
3464                 if (!sas_info->is_logical_volume) {
3465                         sas_device.handle = 0;
3466                         retry_count = 0;
3467 retry_page:
3468                         retval = mptsas_sas_device_pg0(ioc, &sas_device,
3469                                 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID
3470                                 << MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3471                                 (sas_info->fw.channel << 8) +
3472                                 sas_info->fw.id);
3473
3474                         if (sas_device.handle)
3475                                 continue;
3476                         if (retval == -EBUSY) {
3477                                 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3478                                 if (ioc->ioc_reset_in_progress) {
3479                                         dfailprintk(ioc,
3480                                         printk(MYIOC_s_DEBUG_FMT
3481                                         "%s: exiting due to reset\n",
3482                                         ioc->name, __func__));
3483                                         spin_unlock_irqrestore
3484                                         (&ioc->taskmgmt_lock, flags);
3485                                         mutex_unlock(&ioc->
3486                                         sas_device_info_mutex);
3487                                         return;
3488                                 }
3489                                 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
3490                                 flags);
3491                         }
3492
3493                         if (retval && (retval != -ENODEV)) {
3494                                 if (retry_count < 10) {
3495                                         retry_count++;
3496                                         goto retry_page;
3497                                 } else {
3498                                         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3499                                         "%s: Config page retry exceeded retry "
3500                                         "count deleting device 0x%llx\n",
3501                                         ioc->name, __func__,
3502                                         sas_info->sas_address));
3503                                 }
3504                         }
3505
3506                         /* delete device */
3507                         vtarget = mptsas_find_vtarget(ioc,
3508                                 sas_info->fw.channel, sas_info->fw.id);
3509
3510                         if (vtarget)
3511                                 vtarget->deleted = 1;
3512
3513                         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3514                                         sas_info->sas_address);
3515
3516                         if (phy_info) {
3517                                 mptsas_del_end_device(ioc, phy_info);
3518                                 goto redo_device_scan;
3519                         }
3520                 } else
3521                         mptsas_volume_delete(ioc, sas_info->fw.id);
3522         }
3523         mutex_unlock(&ioc->sas_device_info_mutex);
3524
3525         /* expanders */
3526         mutex_lock(&ioc->sas_topology_mutex);
3527  redo_expander_scan:
3528         list_for_each_entry(port_info, &ioc->sas_topology, list) {
3529
3530                 if (port_info->phy_info &&
3531                     (!(port_info->phy_info[0].identify.device_info &
3532                     MPI_SAS_DEVICE_INFO_SMP_TARGET)))
3533                         continue;
3534                 found_expander = 0;
3535                 handle = 0xFFFF;
3536                 while (!mptsas_sas_expander_pg0(ioc, &buffer,
3537                     (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3538                      MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle) &&
3539                     !found_expander) {
3540
3541                         handle = buffer.phy_info[0].handle;
3542                         if (buffer.phy_info[0].identify.sas_address ==
3543                             port_info->phy_info[0].identify.sas_address) {
3544                                 found_expander = 1;
3545                         }
3546                         kfree(buffer.phy_info);
3547                 }
3548
3549                 if (!found_expander) {
3550                         mptsas_expander_delete(ioc, port_info, 0);
3551                         goto redo_expander_scan;
3552                 }
3553         }
3554         mutex_unlock(&ioc->sas_topology_mutex);
3555 }
3556
3557 /**
3558  *      mptsas_probe_expanders - adding expanders
3559  *      @ioc: Pointer to MPT_ADAPTER structure
3560  *
3561  **/
3562 static void
3563 mptsas_probe_expanders(MPT_ADAPTER *ioc)
3564 {
3565         struct mptsas_portinfo buffer, *port_info;
3566         u32                     handle;
3567         int i;
3568
3569         handle = 0xFFFF;
3570         while (!mptsas_sas_expander_pg0(ioc, &buffer,
3571             (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3572              MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)) {
3573
3574                 handle = buffer.phy_info[0].handle;
3575                 port_info = mptsas_find_portinfo_by_sas_address(ioc,
3576                     buffer.phy_info[0].identify.sas_address);
3577
3578                 if (port_info) {
3579                         /* refreshing handles */
3580                         for (i = 0; i < buffer.num_phys; i++) {
3581                                 port_info->phy_info[i].handle = handle;
3582                                 port_info->phy_info[i].identify.handle_parent =
3583                                     buffer.phy_info[0].identify.handle_parent;
3584                         }
3585                         mptsas_expander_refresh(ioc, port_info);
3586                         kfree(buffer.phy_info);
3587                         continue;
3588                 }
3589
3590                 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3591                 if (!port_info) {
3592                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3593                         "%s: exit at line=%d\n", ioc->name,
3594                         __func__, __LINE__));
3595                         return;
3596                 }
3597                 port_info->num_phys = buffer.num_phys;
3598                 port_info->phy_info = buffer.phy_info;
3599                 for (i = 0; i < port_info->num_phys; i++)
3600                         port_info->phy_info[i].portinfo = port_info;
3601                 mutex_lock(&ioc->sas_topology_mutex);
3602                 list_add_tail(&port_info->list, &ioc->sas_topology);
3603                 mutex_unlock(&ioc->sas_topology_mutex);
3604                 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3605                     "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3606             (unsigned long long)buffer.phy_info[0].identify.sas_address);
3607                 mptsas_expander_refresh(ioc, port_info);
3608         }
3609 }
3610
3611 static void
3612 mptsas_probe_devices(MPT_ADAPTER *ioc)
3613 {
3614         u16 handle;
3615         struct mptsas_devinfo sas_device;
3616         struct mptsas_phyinfo *phy_info;
3617
3618         handle = 0xFFFF;
3619         while (!(mptsas_sas_device_pg0(ioc, &sas_device,
3620             MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
3621
3622                 handle = sas_device.handle;
3623
3624                 if ((sas_device.device_info &
3625                      (MPI_SAS_DEVICE_INFO_SSP_TARGET |
3626                       MPI_SAS_DEVICE_INFO_STP_TARGET |
3627                       MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0)
3628                         continue;
3629
3630                 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3631                 if (!phy_info)
3632                         continue;
3633
3634                 if (mptsas_get_rphy(phy_info))
3635                         continue;
3636
3637                 mptsas_add_end_device(ioc, phy_info);
3638         }
3639 }
3640
3641 /**
3642  *      mptsas_scan_sas_topology -
3643  *      @ioc: Pointer to MPT_ADAPTER structure
3644  *      @sas_address:
3645  *
3646  **/
3647 static void
3648 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
3649 {
3650         struct scsi_device *sdev;
3651         int i;
3652
3653         mptsas_probe_hba_phys(ioc);
3654         mptsas_probe_expanders(ioc);
3655         mptsas_probe_devices(ioc);
3656
3657         /*
3658           Reporting RAID volumes.
3659         */
3660         if (!ioc->ir_firmware || !ioc->raid_data.pIocPg2 ||
3661             !ioc->raid_data.pIocPg2->NumActiveVolumes)
3662                 return;
3663         for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
3664                 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
3665                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
3666                 if (sdev) {
3667                         scsi_device_put(sdev);
3668                         continue;
3669                 }
3670                 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
3671                     "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
3672                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID);
3673                 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
3674                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
3675         }
3676 }
3677
3678
3679 static void
3680 mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
3681 {
3682         MPT_ADAPTER *ioc;
3683         EventDataQueueFull_t *qfull_data;
3684         struct mptsas_device_info *sas_info;
3685         struct scsi_device      *sdev;
3686         int depth;
3687         int id = -1;
3688         int channel = -1;
3689         int fw_id, fw_channel;
3690         u16 current_depth;
3691
3692
3693         ioc = fw_event->ioc;
3694         qfull_data = (EventDataQueueFull_t *)fw_event->event_data;
3695         fw_id = qfull_data->TargetID;
3696         fw_channel = qfull_data->Bus;
3697         current_depth = le16_to_cpu(qfull_data->CurrentDepth);
3698
3699         /* if hidden raid component, look for the volume id */
3700         mutex_lock(&ioc->sas_device_info_mutex);
3701         if (mptscsih_is_phys_disk(ioc, fw_channel, fw_id)) {
3702                 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
3703                     list) {
3704                         if (sas_info->is_cached ||
3705                             sas_info->is_logical_volume)
3706                                 continue;
3707                         if (sas_info->is_hidden_raid_component &&
3708                             (sas_info->fw.channel == fw_channel &&
3709                             sas_info->fw.id == fw_id)) {
3710                                 id = sas_info->volume_id;
3711                                 channel = MPTSAS_RAID_CHANNEL;
3712                                 goto out;
3713                         }
3714                 }
3715         } else {
3716                 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
3717                     list) {
3718                         if (sas_info->is_cached ||
3719                             sas_info->is_hidden_raid_component ||
3720                             sas_info->is_logical_volume)
3721                                 continue;
3722                         if (sas_info->fw.channel == fw_channel &&
3723                             sas_info->fw.id == fw_id) {
3724                                 id = sas_info->os.id;
3725                                 channel = sas_info->os.channel;
3726                                 goto out;
3727                         }
3728                 }
3729
3730         }
3731
3732  out:
3733         mutex_unlock(&ioc->sas_device_info_mutex);
3734
3735         if (id != -1) {
3736                 shost_for_each_device(sdev, ioc->sh) {
3737                         if (sdev->id == id && sdev->channel == channel) {
3738                                 if (current_depth > sdev->queue_depth) {
3739                                         sdev_printk(KERN_INFO, sdev,
3740                                             "strange observation, the queue "
3741                                             "depth is (%d) meanwhile fw queue "
3742                                             "depth (%d)\n", sdev->queue_depth,
3743                                             current_depth);
3744                                         continue;
3745                                 }
3746                                 depth = scsi_track_queue_full(sdev,
3747                                     current_depth - 1);
3748                                 if (depth > 0)
3749                                         sdev_printk(KERN_INFO, sdev,
3750                                         "Queue depth reduced to (%d)\n",
3751                                            depth);
3752                                 else if (depth < 0)
3753                                         sdev_printk(KERN_INFO, sdev,
3754                                         "Tagged Command Queueing is being "
3755                                         "disabled\n");
3756                                 else if (depth == 0)
3757                                         sdev_printk(KERN_INFO, sdev,
3758                                         "Queue depth not changed yet\n");
3759                         }
3760                 }
3761         }
3762
3763         mptsas_free_fw_event(ioc, fw_event);
3764 }
3765
3766
3767 static struct mptsas_phyinfo *
3768 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
3769 {
3770         struct mptsas_portinfo *port_info;
3771         struct mptsas_phyinfo *phy_info = NULL;
3772         int i;
3773
3774         mutex_lock(&ioc->sas_topology_mutex);
3775         list_for_each_entry(port_info, &ioc->sas_topology, list) {
3776                 for (i = 0; i < port_info->num_phys; i++) {
3777                         if (!mptsas_is_end_device(
3778                                 &port_info->phy_info[i].attached))
3779                                 continue;
3780                         if (port_info->phy_info[i].attached.sas_address
3781                             != sas_address)
3782                                 continue;
3783                         phy_info = &port_info->phy_info[i];
3784                         break;
3785                 }
3786         }
3787         mutex_unlock(&ioc->sas_topology_mutex);
3788         return phy_info;
3789 }
3790
3791 /**
3792  *      mptsas_find_phyinfo_by_phys_disk_num -
3793  *      @ioc: Pointer to MPT_ADAPTER structure
3794  *      @phys_disk_num:
3795  *      @channel:
3796  *      @id:
3797  *
3798  **/
3799 static struct mptsas_phyinfo *
3800 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
3801         u8 channel, u8 id)
3802 {
3803         struct mptsas_phyinfo *phy_info = NULL;
3804         struct mptsas_portinfo *port_info;
3805         RaidPhysDiskPage1_t *phys_disk = NULL;
3806         int num_paths;
3807         u64 sas_address = 0;
3808         int i;
3809
3810         phy_info = NULL;
3811         if (!ioc->raid_data.pIocPg3)
3812                 return NULL;
3813         /* dual port support */
3814         num_paths = mpt_raid_phys_disk_get_num_paths(ioc, phys_disk_num);
3815         if (!num_paths)
3816                 goto out;
3817         phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
3818            (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
3819         if (!phys_disk)
3820                 goto out;
3821         mpt_raid_phys_disk_pg1(ioc, phys_disk_num, phys_disk);
3822         for (i = 0; i < num_paths; i++) {
3823                 if ((phys_disk->Path[i].Flags & 1) != 0)
3824                         /* entry no longer valid */
3825                         continue;
3826                 if ((id == phys_disk->Path[i].PhysDiskID) &&
3827                     (channel == phys_disk->Path[i].PhysDiskBus)) {
3828                         memcpy(&sas_address, &phys_disk->Path[i].WWID,
3829                                 sizeof(u64));
3830                         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3831                                         sas_address);
3832                         goto out;
3833                 }
3834         }
3835
3836  out:
3837         kfree(phys_disk);
3838         if (phy_info)
3839                 return phy_info;
3840
3841         /*
3842          * Extra code to handle RAID0 case, where the sas_address is not updated
3843          * in phys_disk_page_1 when hotswapped
3844          */
3845         mutex_lock(&ioc->sas_topology_mutex);
3846         list_for_each_entry(port_info, &ioc->sas_topology, list) {
3847                 for (i = 0; i < port_info->num_phys && !phy_info; i++) {
3848                         if (!mptsas_is_end_device(
3849                                 &port_info->phy_info[i].attached))
3850                                 continue;
3851                         if (port_info->phy_info[i].attached.phys_disk_num == ~0)
3852                                 continue;
3853                         if ((port_info->phy_info[i].attached.phys_disk_num ==
3854                             phys_disk_num) &&
3855                             (port_info->phy_info[i].attached.id == id) &&
3856                             (port_info->phy_info[i].attached.channel ==
3857                              channel))
3858                                 phy_info = &port_info->phy_info[i];
3859                 }
3860         }
3861         mutex_unlock(&ioc->sas_topology_mutex);
3862         return phy_info;
3863 }
3864
3865 static void
3866 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
3867 {
3868         int rc;
3869
3870         sdev->no_uld_attach = data ? 1 : 0;
3871         rc = scsi_device_reprobe(sdev);
3872 }
3873
3874 static void
3875 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
3876 {
3877         starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
3878                         mptsas_reprobe_lun);
3879 }
3880
3881 static void
3882 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
3883 {
3884         CONFIGPARMS                     cfg;
3885         ConfigPageHeader_t              hdr;
3886         dma_addr_t                      dma_handle;
3887         pRaidVolumePage0_t              buffer = NULL;
3888         RaidPhysDiskPage0_t             phys_disk;
3889         int                             i;
3890         struct mptsas_phyinfo   *phy_info;
3891         struct mptsas_devinfo           sas_device;
3892
3893         memset(&cfg, 0 , sizeof(CONFIGPARMS));
3894         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
3895         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
3896         cfg.pageAddr = (channel << 8) + id;
3897         cfg.cfghdr.hdr = &hdr;
3898         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3899
3900         if (mpt_config(ioc, &cfg) != 0)
3901                 goto out;
3902
3903         if (!hdr.PageLength)
3904                 goto out;
3905
3906         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
3907             &dma_handle);
3908
3909         if (!buffer)
3910                 goto out;
3911
3912         cfg.physAddr = dma_handle;
3913         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3914
3915         if (mpt_config(ioc, &cfg) != 0)
3916                 goto out;
3917
3918         if (!(buffer->VolumeStatus.Flags &
3919             MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
3920                 goto out;
3921
3922         if (!buffer->NumPhysDisks)
3923                 goto out;
3924
3925         for (i = 0; i < buffer->NumPhysDisks; i++) {
3926
3927                 if (mpt_raid_phys_disk_pg0(ioc,
3928                     buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
3929                         continue;
3930
3931                 if (mptsas_sas_device_pg0(ioc, &sas_device,
3932                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
3933                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3934                         (phys_disk.PhysDiskBus << 8) +
3935                         phys_disk.PhysDiskID))
3936                         continue;
3937
3938                 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3939                     sas_device.sas_address);
3940                 mptsas_add_end_device(ioc, phy_info);
3941         }
3942
3943  out:
3944         if (buffer)
3945                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
3946                     dma_handle);
3947 }
3948 /*
3949  * Work queue thread to handle SAS hotplug events
3950  */
3951 static void
3952 mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
3953     struct mptsas_hotplug_event *hot_plug_info)
3954 {
3955         struct mptsas_phyinfo *phy_info;
3956         struct scsi_target * starget;
3957         struct mptsas_devinfo sas_device;
3958         VirtTarget *vtarget;
3959         int i;
3960
3961         switch (hot_plug_info->event_type) {
3962
3963         case MPTSAS_ADD_PHYSDISK:
3964
3965                 if (!ioc->raid_data.pIocPg2)
3966                         break;
3967
3968                 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
3969                         if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID ==
3970                             hot_plug_info->id) {
3971                                 printk(MYIOC_s_WARN_FMT "firmware bug: unable "
3972                                     "to add hidden disk - target_id matchs "
3973                                     "volume_id\n", ioc->name);
3974                                 mptsas_free_fw_event(ioc, fw_event);
3975                                 return;
3976                         }
3977                 }
3978                 mpt_findImVolumes(ioc);
3979
3980         case MPTSAS_ADD_DEVICE:
3981                 memset(&sas_device, 0, sizeof(struct mptsas_devinfo));
3982                 mptsas_sas_device_pg0(ioc, &sas_device,
3983                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
3984                     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3985                     (hot_plug_info->channel << 8) +
3986                     hot_plug_info->id);
3987
3988                 if (!sas_device.handle)
3989                         return;
3990
3991                 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3992                 if (!phy_info)
3993                         break;
3994
3995                 if (mptsas_get_rphy(phy_info))
3996                         break;
3997
3998                 mptsas_add_end_device(ioc, phy_info);
3999                 break;
4000
4001         case MPTSAS_DEL_DEVICE:
4002                 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4003                     hot_plug_info->sas_address);
4004                 mptsas_del_end_device(ioc, phy_info);
4005                 break;
4006
4007         case MPTSAS_DEL_PHYSDISK:
4008
4009                 mpt_findImVolumes(ioc);
4010
4011                 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
4012                                 ioc, hot_plug_info->phys_disk_num,
4013                                 hot_plug_info->channel,
4014                                 hot_plug_info->id);
4015                 mptsas_del_end_device(ioc, phy_info);
4016                 break;
4017
4018         case MPTSAS_ADD_PHYSDISK_REPROBE:
4019
4020                 if (mptsas_sas_device_pg0(ioc, &sas_device,
4021                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4022                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4023                     (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4024                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4025                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
4026                                  __func__, hot_plug_info->id, __LINE__));
4027                         break;
4028                 }
4029
4030                 phy_info = mptsas_find_phyinfo_by_sas_address(
4031                     ioc, sas_device.sas_address);
4032
4033                 if (!phy_info) {
4034                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4035                                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4036                                  __func__, hot_plug_info->id, __LINE__));
4037                         break;
4038                 }
4039
4040                 starget = mptsas_get_starget(phy_info);
4041                 if (!starget) {
4042                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4043                                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4044                                  __func__, hot_plug_info->id, __LINE__));
4045                         break;
4046                 }
4047
4048                 vtarget = starget->hostdata;
4049                 if (!vtarget) {
4050                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4051                                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4052                                  __func__, hot_plug_info->id, __LINE__));
4053                         break;
4054                 }
4055
4056                 mpt_findImVolumes(ioc);
4057
4058                 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Hidding: "
4059                     "fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4060                     ioc->name, hot_plug_info->channel, hot_plug_info->id,
4061                     hot_plug_info->phys_disk_num, (unsigned long long)
4062                     sas_device.sas_address);
4063
4064                 vtarget->id = hot_plug_info->phys_disk_num;
4065                 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
4066                 phy_info->attached.phys_disk_num = hot_plug_info->phys_disk_num;
4067                 mptsas_reprobe_target(starget, 1);
4068                 break;
4069
4070         case MPTSAS_DEL_PHYSDISK_REPROBE:
4071
4072                 if (mptsas_sas_device_pg0(ioc, &sas_device,
4073                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4074                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4075                         (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4076                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4077                                     "%s: fw_id=%d exit at line=%d\n",
4078                                     ioc->name, __func__,
4079                                     hot_plug_info->id, __LINE__));
4080                         break;
4081                 }
4082
4083                 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4084                                 sas_device.sas_address);
4085                 if (!phy_info) {
4086                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4087                             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4088                          __func__, hot_plug_info->id, __LINE__));
4089                         break;
4090                 }
4091
4092                 starget = mptsas_get_starget(phy_info);
4093                 if (!starget) {
4094                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4095                             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4096                          __func__, hot_plug_info->id, __LINE__));
4097                         break;
4098                 }
4099
4100                 vtarget = starget->hostdata;
4101                 if (!vtarget) {
4102                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4103                             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4104                          __func__, hot_plug_info->id, __LINE__));
4105                         break;
4106                 }
4107
4108                 if (!(vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)) {
4109                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4110                             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4111                          __func__, hot_plug_info->id, __LINE__));
4112                         break;
4113                 }
4114
4115                 mpt_findImVolumes(ioc);
4116
4117                 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Exposing:"
4118                     " fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4119                     ioc->name, hot_plug_info->channel, hot_plug_info->id,
4120                     hot_plug_info->phys_disk_num, (unsigned long long)
4121                     sas_device.sas_address);
4122
4123                 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
4124                 vtarget->id = hot_plug_info->id;
4125                 phy_info->attached.phys_disk_num = ~0;
4126                 mptsas_reprobe_target(starget, 0);
4127                 mptsas_add_device_component_by_fw(ioc,
4128                     hot_plug_info->channel, hot_plug_info->id);
4129                 break;
4130
4131         case MPTSAS_ADD_RAID:
4132
4133                 mpt_findImVolumes(ioc);
4134                 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4135                     "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4136                     hot_plug_info->id);
4137                 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4138                     hot_plug_info->id, 0);
4139                 break;
4140
4141         case MPTSAS_DEL_RAID:
4142
4143                 mpt_findImVolumes(ioc);
4144                 printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4145                     "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4146                     hot_plug_info->id);
4147                 scsi_remove_device(hot_plug_info->sdev);
4148                 scsi_device_put(hot_plug_info->sdev);
4149                 break;
4150
4151         case MPTSAS_ADD_INACTIVE_VOLUME:
4152
4153                 mpt_findImVolumes(ioc);
4154                 mptsas_adding_inactive_raid_components(ioc,
4155                     hot_plug_info->channel, hot_plug_info->id);
4156                 break;
4157
4158         default:
4159                 break;
4160         }
4161
4162         mptsas_free_fw_event(ioc, fw_event);
4163 }
4164
4165 static void
4166 mptsas_send_sas_event(struct fw_event_work *fw_event)
4167 {
4168         MPT_ADAPTER *ioc;
4169         struct mptsas_hotplug_event hot_plug_info;
4170         EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
4171         u32 device_info;
4172         u64 sas_address;
4173
4174         ioc = fw_event->ioc;
4175         sas_event_data = (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
4176             fw_event->event_data;
4177         device_info = le32_to_cpu(sas_event_data->DeviceInfo);
4178
4179         if ((device_info &
4180                 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
4181                 MPI_SAS_DEVICE_INFO_STP_TARGET |
4182                 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0) {
4183                 mptsas_free_fw_event(ioc, fw_event);
4184                 return;
4185         }
4186
4187         if (sas_event_data->ReasonCode ==
4188                 MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED) {
4189                 mptbase_sas_persist_operation(ioc,
4190                 MPI_SAS_OP_CLEAR_NOT_PRESENT);
4191                 mptsas_free_fw_event(ioc, fw_event);
4192                 return;
4193         }
4194
4195         switch (sas_event_data->ReasonCode) {
4196         case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
4197         case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
4198                 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4199                 hot_plug_info.handle = le16_to_cpu(sas_event_data->DevHandle);
4200                 hot_plug_info.channel = sas_event_data->Bus;
4201                 hot_plug_info.id = sas_event_data->TargetID;
4202                 hot_plug_info.phy_id = sas_event_data->PhyNum;
4203                 memcpy(&sas_address, &sas_event_data->SASAddress,
4204                     sizeof(u64));
4205                 hot_plug_info.sas_address = le64_to_cpu(sas_address);
4206                 hot_plug_info.device_info = device_info;
4207                 if (sas_event_data->ReasonCode &
4208                     MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
4209                         hot_plug_info.event_type = MPTSAS_ADD_DEVICE;
4210                 else
4211                         hot_plug_info.event_type = MPTSAS_DEL_DEVICE;
4212                 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4213                 break;
4214
4215         case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
4216                 mptbase_sas_persist_operation(ioc,
4217                     MPI_SAS_OP_CLEAR_NOT_PRESENT);
4218                 mptsas_free_fw_event(ioc, fw_event);
4219                 break;
4220
4221         case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
4222         /* TODO */
4223         case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
4224         /* TODO */
4225         default:
4226                 mptsas_free_fw_event(ioc, fw_event);
4227                 break;
4228         }
4229 }
4230
4231 static void
4232 mptsas_send_raid_event(struct fw_event_work *fw_event)
4233 {
4234         MPT_ADAPTER *ioc;
4235         EVENT_DATA_RAID *raid_event_data;
4236         struct mptsas_hotplug_event hot_plug_info;
4237         int status;
4238         int state;
4239         struct scsi_device *sdev = NULL;
4240         VirtDevice *vdevice = NULL;
4241         RaidPhysDiskPage0_t phys_disk;
4242
4243         ioc = fw_event->ioc;
4244         raid_event_data = (EVENT_DATA_RAID *)fw_event->event_data;
4245         status = le32_to_cpu(raid_event_data->SettingsStatus);
4246         state = (status >> 8) & 0xff;
4247
4248         memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4249         hot_plug_info.id = raid_event_data->VolumeID;
4250         hot_plug_info.channel = raid_event_data->VolumeBus;
4251         hot_plug_info.phys_disk_num = raid_event_data->PhysDiskNum;
4252
4253         if (raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_DELETED ||
4254             raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_CREATED ||
4255             raid_event_data->ReasonCode ==
4256             MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED) {
4257                 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
4258                     hot_plug_info.id, 0);
4259                 hot_plug_info.sdev = sdev;
4260                 if (sdev)
4261                         vdevice = sdev->hostdata;
4262         }
4263
4264         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4265             "ReasonCode=%02x\n", ioc->name, __func__,
4266             raid_event_data->ReasonCode));
4267
4268         switch (raid_event_data->ReasonCode) {
4269         case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4270                 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK_REPROBE;
4271                 break;
4272         case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4273                 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK_REPROBE;
4274                 break;
4275         case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4276                 switch (state) {
4277                 case MPI_PD_STATE_ONLINE:
4278                 case MPI_PD_STATE_NOT_COMPATIBLE:
4279                         mpt_raid_phys_disk_pg0(ioc,
4280                             raid_event_data->PhysDiskNum, &phys_disk);
4281                         hot_plug_info.id = phys_disk.PhysDiskID;
4282                         hot_plug_info.channel = phys_disk.PhysDiskBus;
4283                         hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4284                         break;
4285                 case MPI_PD_STATE_FAILED:
4286                 case MPI_PD_STATE_MISSING:
4287                 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
4288                 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
4289                 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
4290                         hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4291                         break;
4292                 default:
4293                         break;
4294                 }
4295                 break;
4296         case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4297                 if (!sdev)
4298                         break;
4299                 vdevice->vtarget->deleted = 1; /* block IO */
4300                 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4301                 break;
4302         case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4303                 if (sdev) {
4304                         scsi_device_put(sdev);
4305                         break;
4306                 }
4307                 hot_plug_info.event_type = MPTSAS_ADD_RAID;
4308                 break;
4309         case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4310                 if (!(status & MPI_RAIDVOL0_STATUS_FLAG_ENABLED)) {
4311                         if (!sdev)
4312                                 break;
4313                         vdevice->vtarget->deleted = 1; /* block IO */
4314                         hot_plug_info.event_type = MPTSAS_DEL_RAID;
4315                         break;
4316                 }
4317                 switch (state) {
4318                 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
4319                 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
4320                         if (!sdev)
4321                                 break;
4322                         vdevice->vtarget->deleted = 1; /* block IO */
4323                         hot_plug_info.event_type = MPTSAS_DEL_RAID;
4324                         break;
4325                 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
4326                 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
4327                         if (sdev) {
4328                                 scsi_device_put(sdev);
4329                                 break;
4330                         }
4331                         hot_plug_info.event_type = MPTSAS_ADD_RAID;
4332                         break;
4333                 default:
4334                         break;
4335                 }
4336                 break;
4337         default:
4338                 break;
4339         }
4340
4341         if (hot_plug_info.event_type != MPTSAS_IGNORE_EVENT)
4342                 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4343         else
4344                 mptsas_free_fw_event(ioc, fw_event);
4345 }
4346
4347 /**
4348  *      mptsas_issue_tm - send mptsas internal tm request
4349  *      @ioc: Pointer to MPT_ADAPTER structure
4350  *      @type: Task Management type
4351  *      @channel: channel number for task management
4352  *      @id: Logical Target ID for reset (if appropriate)
4353  *      @lun: Logical unit for reset (if appropriate)
4354  *      @task_context: Context for the task to be aborted
4355  *      @timeout: timeout for task management control
4356  *
4357  *      return 0 on success and -1 on failure:
4358  *
4359  */
4360 static int
4361 mptsas_issue_tm(MPT_ADAPTER *ioc, u8 type, u8 channel, u8 id, u64 lun,
4362         int task_context, ulong timeout, u8 *issue_reset)
4363 {
4364         MPT_FRAME_HDR   *mf;
4365         SCSITaskMgmt_t  *pScsiTm;
4366         int              retval;
4367         unsigned long    timeleft;
4368
4369         *issue_reset = 0;
4370         mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
4371         if (mf == NULL) {
4372                 retval = -1; /* return failure */
4373                 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "TaskMgmt request: no "
4374                     "msg frames!!\n", ioc->name));
4375                 goto out;
4376         }
4377
4378         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request: mr = %p, "
4379             "task_type = 0x%02X,\n\t timeout = %ld, fw_channel = %d, "
4380             "fw_id = %d, lun = %lld,\n\t task_context = 0x%x\n", ioc->name, mf,
4381              type, timeout, channel, id, (unsigned long long)lun,
4382              task_context));
4383
4384         pScsiTm = (SCSITaskMgmt_t *) mf;
4385         memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
4386         pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
4387         pScsiTm->TaskType = type;
4388         pScsiTm->MsgFlags = 0;
4389         pScsiTm->TargetID = id;
4390         pScsiTm->Bus = channel;
4391         pScsiTm->ChainOffset = 0;
4392         pScsiTm->Reserved = 0;
4393         pScsiTm->Reserved1 = 0;
4394         pScsiTm->TaskMsgContext = task_context;
4395         int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
4396
4397         INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4398         CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
4399         retval = 0;
4400         mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
4401
4402         /* Now wait for the command to complete */
4403         timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
4404             timeout*HZ);
4405         if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
4406                 retval = -1; /* return failure */
4407                 dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
4408                     "TaskMgmt request: TIMED OUT!(mr=%p)\n", ioc->name, mf));
4409                 mpt_free_msg_frame(ioc, mf);
4410                 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
4411                         goto out;
4412                 *issue_reset = 1;
4413                 goto out;
4414         }
4415
4416         if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
4417                 retval = -1; /* return failure */
4418                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4419                     "TaskMgmt request: failed with no reply\n", ioc->name));
4420                 goto out;
4421         }
4422
4423  out:
4424         CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4425         return retval;
4426 }
4427
4428 /**
4429  *      mptsas_broadcast_primative_work - Handle broadcast primitives
4430  *      @work: work queue payload containing info describing the event
4431  *
4432  *      this will be handled in workqueue context.
4433  */
4434 static void
4435 mptsas_broadcast_primative_work(struct fw_event_work *fw_event)
4436 {
4437         MPT_ADAPTER *ioc = fw_event->ioc;
4438         MPT_FRAME_HDR   *mf;
4439         VirtDevice      *vdevice;
4440         int                     ii;
4441         struct scsi_cmnd        *sc;
4442         SCSITaskMgmtReply_t     *pScsiTmReply;
4443         u8                      issue_reset;
4444         int                     task_context;
4445         u8                      channel, id;
4446         int                      lun;
4447         u32                      termination_count;
4448         u32                      query_count;
4449
4450         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4451             "%s - enter\n", ioc->name, __func__));
4452
4453         mutex_lock(&ioc->taskmgmt_cmds.mutex);
4454         if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
4455                 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4456                 mptsas_requeue_fw_event(ioc, fw_event, 1000);
4457                 return;
4458         }
4459
4460         issue_reset = 0;
4461         termination_count = 0;
4462         query_count = 0;
4463         mpt_findImVolumes(ioc);
4464         pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
4465
4466         for (ii = 0; ii < ioc->req_depth; ii++) {
4467                 if (ioc->fw_events_off)
4468                         goto out;
4469                 sc = mptscsih_get_scsi_lookup(ioc, ii);
4470                 if (!sc)
4471                         continue;
4472                 mf = MPT_INDEX_2_MFPTR(ioc, ii);
4473                 if (!mf)
4474                         continue;
4475                 task_context = mf->u.frame.hwhdr.msgctxu.MsgContext;
4476                 vdevice = sc->device->hostdata;
4477                 if (!vdevice || !vdevice->vtarget)
4478                         continue;
4479                 if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
4480                         continue; /* skip hidden raid components */
4481                 if (vdevice->vtarget->raidVolume)
4482                         continue; /* skip hidden raid components */
4483                 channel = vdevice->vtarget->channel;
4484                 id = vdevice->vtarget->id;
4485                 lun = vdevice->lun;
4486                 if (mptsas_issue_tm(ioc, MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK,
4487                     channel, id, (u64)lun, task_context, 30, &issue_reset))
4488                         goto out;
4489                 query_count++;
4490                 termination_count +=
4491                     le32_to_cpu(pScsiTmReply->TerminationCount);
4492                 if ((pScsiTmReply->IOCStatus == MPI_IOCSTATUS_SUCCESS) &&
4493                     (pScsiTmReply->ResponseCode ==
4494                     MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
4495                     pScsiTmReply->ResponseCode ==
4496                     MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
4497                         continue;
4498                 if (mptsas_issue_tm(ioc,
4499                     MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET,
4500                     channel, id, (u64)lun, 0, 30, &issue_reset))
4501                         goto out;
4502                 termination_count +=
4503                     le32_to_cpu(pScsiTmReply->TerminationCount);
4504         }
4505
4506  out:
4507         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4508             "%s - exit, query_count = %d termination_count = %d\n",
4509             ioc->name, __func__, query_count, termination_count));
4510
4511         ioc->broadcast_aen_busy = 0;
4512         mpt_clear_taskmgmt_in_progress_flag(ioc);
4513         mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4514
4515         if (issue_reset) {
4516                 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
4517                     ioc->name, __func__);
4518                 mpt_HardResetHandler(ioc, CAN_SLEEP);
4519         }
4520         mptsas_free_fw_event(ioc, fw_event);
4521 }
4522
4523 /*
4524  * mptsas_send_ir2_event - handle exposing hidden disk when
4525  * an inactive raid volume is added
4526  *
4527  * @ioc: Pointer to MPT_ADAPTER structure
4528  * @ir2_data
4529  *
4530  */
4531 static void
4532 mptsas_send_ir2_event(struct fw_event_work *fw_event)
4533 {
4534         MPT_ADAPTER     *ioc;
4535         struct mptsas_hotplug_event hot_plug_info;
4536         MPI_EVENT_DATA_IR2      *ir2_data;
4537         u8 reasonCode;
4538         RaidPhysDiskPage0_t phys_disk;
4539
4540         ioc = fw_event->ioc;
4541         ir2_data = (MPI_EVENT_DATA_IR2 *)fw_event->event_data;
4542         reasonCode = ir2_data->ReasonCode;
4543
4544         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4545             "ReasonCode=%02x\n", ioc->name, __func__, reasonCode));
4546
4547         memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4548         hot_plug_info.id = ir2_data->TargetID;
4549         hot_plug_info.channel = ir2_data->Bus;
4550         switch (reasonCode) {
4551         case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
4552                 hot_plug_info.event_type = MPTSAS_ADD_INACTIVE_VOLUME;
4553                 break;
4554         case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
4555                 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4556                 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4557                 break;
4558         case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
4559                 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4560                 mpt_raid_phys_disk_pg0(ioc,
4561                     ir2_data->PhysDiskNum, &phys_disk);
4562                 hot_plug_info.id = phys_disk.PhysDiskID;
4563                 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4564                 break;
4565         default:
4566                 mptsas_free_fw_event(ioc, fw_event);
4567                 return;
4568         }
4569         mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4570 }
4571
4572 static int
4573 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
4574 {
4575         u32 event = le32_to_cpu(reply->Event);
4576         int sz, event_data_sz;
4577         struct fw_event_work *fw_event;
4578         unsigned long delay;
4579
4580         /* events turned off due to host reset or driver unloading */
4581         if (ioc->fw_events_off)
4582                 return 0;
4583
4584         delay = msecs_to_jiffies(1);
4585         switch (event) {
4586         case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
4587         {
4588                 EVENT_DATA_SAS_BROADCAST_PRIMITIVE *broadcast_event_data =
4589                     (EVENT_DATA_SAS_BROADCAST_PRIMITIVE *)reply->Data;
4590                 if (broadcast_event_data->Primitive !=
4591                     MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
4592                         return 0;
4593                 if (ioc->broadcast_aen_busy)
4594                         return 0;
4595                 ioc->broadcast_aen_busy = 1;
4596                 break;
4597         }
4598         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
4599         {
4600                 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data =
4601                     (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data;
4602
4603                 if (sas_event_data->ReasonCode ==
4604                     MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) {
4605                         mptsas_target_reset_queue(ioc, sas_event_data);
4606                         return 0;
4607                 }
4608                 break;
4609         }
4610         case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
4611         {
4612                 MpiEventDataSasExpanderStatusChange_t *expander_data =
4613                     (MpiEventDataSasExpanderStatusChange_t *)reply->Data;
4614
4615                 if (ioc->old_sas_discovery_protocal)
4616                         return 0;
4617
4618                 if (expander_data->ReasonCode ==
4619                     MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING &&
4620                     ioc->device_missing_delay)
4621                         delay = HZ * ioc->device_missing_delay;
4622                 break;
4623         }
4624         case MPI_EVENT_SAS_DISCOVERY:
4625         {
4626                 u32 discovery_status;
4627                 EventDataSasDiscovery_t *discovery_data =
4628                     (EventDataSasDiscovery_t *)reply->Data;
4629
4630                 discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus);
4631                 ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0;
4632                 if (ioc->old_sas_discovery_protocal && !discovery_status)
4633                         mptsas_queue_rescan(ioc);
4634                 return 0;
4635         }
4636         case MPI_EVENT_INTEGRATED_RAID:
4637         case MPI_EVENT_PERSISTENT_TABLE_FULL:
4638         case MPI_EVENT_IR2:
4639         case MPI_EVENT_SAS_PHY_LINK_STATUS:
4640         case MPI_EVENT_QUEUE_FULL:
4641                 break;
4642         default:
4643                 return 0;
4644         }
4645
4646         event_data_sz = ((reply->MsgLength * 4) -
4647             offsetof(EventNotificationReply_t, Data));
4648         sz = offsetof(struct fw_event_work, event_data) + event_data_sz;
4649         fw_event = kzalloc(sz, GFP_ATOMIC);
4650         if (!fw_event) {
4651                 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name,
4652                  __func__, __LINE__);
4653                 return 0;
4654         }
4655         memcpy(fw_event->event_data, reply->Data, event_data_sz);
4656         fw_event->event = event;
4657         fw_event->ioc = ioc;
4658         mptsas_add_fw_event(ioc, fw_event, delay);
4659         return 0;
4660 }
4661
4662 /* Delete a volume when no longer listed in ioc pg2
4663  */
4664 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id)
4665 {
4666         struct scsi_device *sdev;
4667         int i;
4668
4669         sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, id, 0);
4670         if (!sdev)
4671                 return;
4672         if (!ioc->raid_data.pIocPg2)
4673                 goto out;
4674         if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
4675                 goto out;
4676         for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
4677                 if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id)
4678                         goto release_sdev;
4679  out:
4680         printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4681             "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL, id);
4682         scsi_remove_device(sdev);
4683  release_sdev:
4684         scsi_device_put(sdev);
4685 }
4686
4687 static int
4688 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
4689 {
4690         struct Scsi_Host        *sh;
4691         MPT_SCSI_HOST           *hd;
4692         MPT_ADAPTER             *ioc;
4693         unsigned long            flags;
4694         int                      ii;
4695         int                      numSGE = 0;
4696         int                      scale;
4697         int                      ioc_cap;
4698         int                     error=0;
4699         int                     r;
4700
4701         r = mpt_attach(pdev,id);
4702         if (r)
4703                 return r;
4704
4705         ioc = pci_get_drvdata(pdev);
4706         mptsas_fw_event_off(ioc);
4707         ioc->DoneCtx = mptsasDoneCtx;
4708         ioc->TaskCtx = mptsasTaskCtx;
4709         ioc->InternalCtx = mptsasInternalCtx;
4710
4711         /*  Added sanity check on readiness of the MPT adapter.
4712          */
4713         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
4714                 printk(MYIOC_s_WARN_FMT
4715                   "Skipping because it's not operational!\n",
4716                   ioc->name);
4717                 error = -ENODEV;
4718                 goto out_mptsas_probe;
4719         }
4720
4721         if (!ioc->active) {
4722                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
4723                   ioc->name);
4724                 error = -ENODEV;
4725                 goto out_mptsas_probe;
4726         }
4727
4728         /*  Sanity check - ensure at least 1 port is INITIATOR capable
4729          */
4730         ioc_cap = 0;
4731         for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
4732                 if (ioc->pfacts[ii].ProtocolFlags &
4733                                 MPI_PORTFACTS_PROTOCOL_INITIATOR)
4734                         ioc_cap++;
4735         }
4736
4737         if (!ioc_cap) {
4738                 printk(MYIOC_s_WARN_FMT
4739                         "Skipping ioc=%p because SCSI Initiator mode "
4740                         "is NOT enabled!\n", ioc->name, ioc);
4741                 return 0;
4742         }
4743
4744         sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
4745         if (!sh) {
4746                 printk(MYIOC_s_WARN_FMT
4747                         "Unable to register controller with SCSI subsystem\n",
4748                         ioc->name);
4749                 error = -1;
4750                 goto out_mptsas_probe;
4751         }
4752
4753         spin_lock_irqsave(&ioc->FreeQlock, flags);
4754
4755         /* Attach the SCSI Host to the IOC structure
4756          */
4757         ioc->sh = sh;
4758
4759         sh->io_port = 0;
4760         sh->n_io_port = 0;
4761         sh->irq = 0;
4762
4763         /* set 16 byte cdb's */
4764         sh->max_cmd_len = 16;
4765         sh->can_queue = min_t(int, ioc->req_depth - 10, sh->can_queue);
4766         sh->max_id = -1;
4767         sh->max_lun = max_lun;
4768         sh->transportt = mptsas_transport_template;
4769
4770         /* Required entry.
4771          */
4772         sh->unique_id = ioc->id;
4773
4774         INIT_LIST_HEAD(&ioc->sas_topology);
4775         mutex_init(&ioc->sas_topology_mutex);
4776         mutex_init(&ioc->sas_discovery_mutex);
4777         mutex_init(&ioc->sas_mgmt.mutex);
4778         init_completion(&ioc->sas_mgmt.done);
4779
4780         /* Verify that we won't exceed the maximum
4781          * number of chain buffers
4782          * We can optimize:  ZZ = req_sz/sizeof(SGE)
4783          * For 32bit SGE's:
4784          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
4785          *               + (req_sz - 64)/sizeof(SGE)
4786          * A slightly different algorithm is required for
4787          * 64bit SGEs.
4788          */
4789         scale = ioc->req_sz/ioc->SGE_size;
4790         if (ioc->sg_addr_size == sizeof(u64)) {
4791                 numSGE = (scale - 1) *
4792                   (ioc->facts.MaxChainDepth-1) + scale +
4793                   (ioc->req_sz - 60) / ioc->SGE_size;
4794         } else {
4795                 numSGE = 1 + (scale - 1) *
4796                   (ioc->facts.MaxChainDepth-1) + scale +
4797                   (ioc->req_sz - 64) / ioc->SGE_size;
4798         }
4799
4800         if (numSGE < sh->sg_tablesize) {
4801                 /* Reset this value */
4802                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4803                   "Resetting sg_tablesize to %d from %d\n",
4804                   ioc->name, numSGE, sh->sg_tablesize));
4805                 sh->sg_tablesize = numSGE;
4806         }
4807
4808         hd = shost_priv(sh);
4809         hd->ioc = ioc;
4810
4811         /* SCSI needs scsi_cmnd lookup table!
4812          * (with size equal to req_depth*PtrSz!)
4813          */
4814         ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
4815         if (!ioc->ScsiLookup) {
4816                 error = -ENOMEM;
4817                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4818                 goto out_mptsas_probe;
4819         }
4820         spin_lock_init(&ioc->scsi_lookup_lock);
4821
4822         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
4823                  ioc->name, ioc->ScsiLookup));
4824
4825         ioc->sas_data.ptClear = mpt_pt_clear;
4826
4827         hd->last_queue_full = 0;
4828         INIT_LIST_HEAD(&hd->target_reset_list);
4829         INIT_LIST_HEAD(&ioc->sas_device_info_list);
4830         mutex_init(&ioc->sas_device_info_mutex);
4831
4832         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4833
4834         if (ioc->sas_data.ptClear==1) {
4835                 mptbase_sas_persist_operation(
4836                     ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
4837         }
4838
4839         error = scsi_add_host(sh, &ioc->pcidev->dev);
4840         if (error) {
4841                 dprintk(ioc, printk(MYIOC_s_ERR_FMT
4842                   "scsi_add_host failed\n", ioc->name));
4843                 goto out_mptsas_probe;
4844         }
4845
4846         /* older firmware doesn't support expander events */
4847         if ((ioc->facts.HeaderVersion >> 8) < 0xE)
4848                 ioc->old_sas_discovery_protocal = 1;
4849         mptsas_scan_sas_topology(ioc);
4850         mptsas_fw_event_on(ioc);
4851         return 0;
4852
4853  out_mptsas_probe:
4854
4855         mptscsih_remove(pdev);
4856         return error;
4857 }
4858
4859 void
4860 mptsas_shutdown(struct pci_dev *pdev)
4861 {
4862         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
4863
4864         mptsas_fw_event_off(ioc);
4865         mptsas_cleanup_fw_event_q(ioc);
4866 }
4867
4868 static void __devexit mptsas_remove(struct pci_dev *pdev)
4869 {
4870         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
4871         struct mptsas_portinfo *p, *n;
4872         int i;
4873
4874         mptsas_shutdown(pdev);
4875
4876         mptsas_del_device_components(ioc);
4877
4878         ioc->sas_discovery_ignore_events = 1;
4879         sas_remove_host(ioc->sh);
4880
4881         mutex_lock(&ioc->sas_topology_mutex);
4882         list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
4883                 list_del(&p->list);
4884                 for (i = 0 ; i < p->num_phys ; i++)
4885                         mptsas_port_delete(ioc, p->phy_info[i].port_details);
4886
4887                 kfree(p->phy_info);
4888                 kfree(p);
4889         }
4890         mutex_unlock(&ioc->sas_topology_mutex);
4891         ioc->hba_port_info = NULL;
4892         mptscsih_remove(pdev);
4893 }
4894
4895 static struct pci_device_id mptsas_pci_table[] = {
4896         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
4897                 PCI_ANY_ID, PCI_ANY_ID },
4898         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
4899                 PCI_ANY_ID, PCI_ANY_ID },
4900         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
4901                 PCI_ANY_ID, PCI_ANY_ID },
4902         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
4903                 PCI_ANY_ID, PCI_ANY_ID },
4904         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
4905                 PCI_ANY_ID, PCI_ANY_ID },
4906         {0}     /* Terminating entry */
4907 };
4908 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
4909
4910
4911 static struct pci_driver mptsas_driver = {
4912         .name           = "mptsas",
4913         .id_table       = mptsas_pci_table,
4914         .probe          = mptsas_probe,
4915         .remove         = __devexit_p(mptsas_remove),
4916         .shutdown       = mptsas_shutdown,
4917 #ifdef CONFIG_PM
4918         .suspend        = mptscsih_suspend,
4919         .resume         = mptscsih_resume,
4920 #endif
4921 };
4922
4923 static int __init
4924 mptsas_init(void)
4925 {
4926         int error;
4927
4928         show_mptmod_ver(my_NAME, my_VERSION);
4929
4930         mptsas_transport_template =
4931             sas_attach_transport(&mptsas_transport_functions);
4932         if (!mptsas_transport_template)
4933                 return -ENODEV;
4934
4935         mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
4936         mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
4937         mptsasInternalCtx =
4938                 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
4939         mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
4940         mptsasDeviceResetCtx =
4941                 mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
4942
4943         mpt_event_register(mptsasDoneCtx, mptsas_event_process);
4944         mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
4945
4946         error = pci_register_driver(&mptsas_driver);
4947         if (error)
4948                 sas_release_transport(mptsas_transport_template);
4949
4950         return error;
4951 }
4952
4953 static void __exit
4954 mptsas_exit(void)
4955 {
4956         pci_unregister_driver(&mptsas_driver);
4957         sas_release_transport(mptsas_transport_template);
4958
4959         mpt_reset_deregister(mptsasDoneCtx);
4960         mpt_event_deregister(mptsasDoneCtx);
4961
4962         mpt_deregister(mptsasMgmtCtx);
4963         mpt_deregister(mptsasInternalCtx);
4964         mpt_deregister(mptsasTaskCtx);
4965         mpt_deregister(mptsasDoneCtx);
4966         mpt_deregister(mptsasDeviceResetCtx);
4967 }
4968
4969 module_init(mptsas_init);
4970 module_exit(mptsas_exit);