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