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