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