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