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