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