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