[SCSI] mptfusion: Added new less expensive RESET (Message Unit Reset)
[linux-2.6.git] / drivers / message / fusion / mptsas.c
1 /*
2  *  linux/drivers/message/fusion/mptsas.c
3  *      For use with LSI PCI chip/adapter(s)
4  *      running LSI Fusion MPT (Message Passing Technology) firmware.
5  *
6  *  Copyright (c) 1999-2008 LSI Corporation
7  *  (mailto:DL-MPTFusionLinux@lsi.com)
8  */
9 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
10 /*
11     This program is free software; you can redistribute it and/or modify
12     it under the terms of the GNU General Public License as published by
13     the Free Software Foundation; version 2 of the License.
14
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18     GNU General Public License for more details.
19
20     NO WARRANTY
21     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
22     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
23     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
24     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
25     solely responsible for determining the appropriateness of using and
26     distributing the Program and assumes all risks associated with its
27     exercise of rights under this Agreement, including but not limited to
28     the risks and costs of program errors, damage to or loss of data,
29     programs or equipment, and unavailability or interruption of operations.
30
31     DISCLAIMER OF LIABILITY
32     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
33     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
35     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
38     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
39
40     You should have received a copy of the GNU General Public License
41     along with this program; if not, write to the Free Software
42     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
43 */
44 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
45
46 #include <linux/module.h>
47 #include <linux/kernel.h>
48 #include <linux/slab.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/jiffies.h>
52 #include <linux/workqueue.h>
53 #include <linux/delay.h>        /* for mdelay */
54
55 #include <scsi/scsi.h>
56 #include <scsi/scsi_cmnd.h>
57 #include <scsi/scsi_device.h>
58 #include <scsi/scsi_host.h>
59 #include <scsi/scsi_transport_sas.h>
60 #include <scsi/scsi_dbg.h>
61
62 #include "mptbase.h"
63 #include "mptscsih.h"
64 #include "mptsas.h"
65
66
67 #define my_NAME         "Fusion MPT SAS Host driver"
68 #define my_VERSION      MPT_LINUX_VERSION_COMMON
69 #define MYNAM           "mptsas"
70
71 /*
72  * Reserved channel for integrated raid
73  */
74 #define MPTSAS_RAID_CHANNEL     1
75
76 #define SAS_CONFIG_PAGE_TIMEOUT         30
77 MODULE_AUTHOR(MODULEAUTHOR);
78 MODULE_DESCRIPTION(my_NAME);
79 MODULE_LICENSE("GPL");
80 MODULE_VERSION(my_VERSION);
81
82 static int mpt_pt_clear;
83 module_param(mpt_pt_clear, int, 0);
84 MODULE_PARM_DESC(mpt_pt_clear,
85                 " Clear persistency table: enable=1  "
86                 "(default=MPTSCSIH_PT_CLEAR=0)");
87
88 /* scsi-mid layer global parmeter is max_report_luns, which is 511 */
89 #define MPTSAS_MAX_LUN (16895)
90 static int max_lun = MPTSAS_MAX_LUN;
91 module_param(max_lun, int, 0);
92 MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
93
94 static u8       mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
95 static u8       mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
96 static u8       mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */
97 static u8       mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS;
98 static u8       mptsasDeviceResetCtx = MPT_MAX_PROTOCOL_DRIVERS;
99
100 static void mptsas_firmware_event_work(struct work_struct *work);
101 static void mptsas_send_sas_event(struct fw_event_work *fw_event);
102 static void mptsas_send_raid_event(struct fw_event_work *fw_event);
103 static void mptsas_send_ir2_event(struct fw_event_work *fw_event);
104 static void mptsas_parse_device_info(struct sas_identify *identify,
105                 struct mptsas_devinfo *device_info);
106 static inline void mptsas_set_rphy(MPT_ADAPTER *ioc,
107                 struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy);
108 static struct mptsas_phyinfo    *mptsas_find_phyinfo_by_sas_address
109                 (MPT_ADAPTER *ioc, u64 sas_address);
110 static int mptsas_sas_device_pg0(MPT_ADAPTER *ioc,
111         struct mptsas_devinfo *device_info, u32 form, u32 form_specific);
112 static int mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc,
113         struct mptsas_enclosure *enclosure, u32 form, u32 form_specific);
114 static int mptsas_add_end_device(MPT_ADAPTER *ioc,
115         struct mptsas_phyinfo *phy_info);
116 static void mptsas_del_end_device(MPT_ADAPTER *ioc,
117         struct mptsas_phyinfo *phy_info);
118 static void mptsas_send_link_status_event(struct fw_event_work *fw_event);
119 static struct mptsas_portinfo   *mptsas_find_portinfo_by_sas_address
120                 (MPT_ADAPTER *ioc, u64 sas_address);
121 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
122                 struct mptsas_portinfo *port_info, u8 force);
123 static void mptsas_send_expander_event(struct fw_event_work *fw_event);
124 static void mptsas_not_responding_devices(MPT_ADAPTER *ioc);
125 static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
126 static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event);
127 static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
128 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
129
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 SPI 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 (!timeleft) {
2042                 /* On timeout reset the board */
2043                 mpt_free_msg_frame(ioc, mf);
2044                 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2045                 error = -ETIMEDOUT;
2046                 goto out_unlock;
2047         }
2048
2049         /* a reply frame is expected */
2050         if ((ioc->sas_mgmt.status &
2051             MPT_MGMT_STATUS_RF_VALID) == 0) {
2052                 error = -ENXIO;
2053                 goto out_unlock;
2054         }
2055
2056         /* process the completed Reply Message Frame */
2057         reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
2058         if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
2059                 printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
2060                     ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo);
2061                 error = -ENXIO;
2062                 goto out_unlock;
2063         }
2064
2065         error = 0;
2066
2067  out_unlock:
2068         CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2069         mutex_unlock(&ioc->sas_mgmt.mutex);
2070  out:
2071         return error;
2072 }
2073
2074 static int
2075 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
2076 {
2077         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2078         int i, error;
2079         struct mptsas_portinfo *p;
2080         struct mptsas_enclosure enclosure_info;
2081         u64 enclosure_handle;
2082
2083         mutex_lock(&ioc->sas_topology_mutex);
2084         list_for_each_entry(p, &ioc->sas_topology, list) {
2085                 for (i = 0; i < p->num_phys; i++) {
2086                         if (p->phy_info[i].attached.sas_address ==
2087                             rphy->identify.sas_address) {
2088                                 enclosure_handle = p->phy_info[i].
2089                                         attached.handle_enclosure;
2090                                 goto found_info;
2091                         }
2092                 }
2093         }
2094         mutex_unlock(&ioc->sas_topology_mutex);
2095         return -ENXIO;
2096
2097  found_info:
2098         mutex_unlock(&ioc->sas_topology_mutex);
2099         memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
2100         error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
2101                         (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
2102                          MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
2103         if (!error)
2104                 *identifier = enclosure_info.enclosure_logical_id;
2105         return error;
2106 }
2107
2108 static int
2109 mptsas_get_bay_identifier(struct sas_rphy *rphy)
2110 {
2111         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2112         struct mptsas_portinfo *p;
2113         int i, rc;
2114
2115         mutex_lock(&ioc->sas_topology_mutex);
2116         list_for_each_entry(p, &ioc->sas_topology, list) {
2117                 for (i = 0; i < p->num_phys; i++) {
2118                         if (p->phy_info[i].attached.sas_address ==
2119                             rphy->identify.sas_address) {
2120                                 rc = p->phy_info[i].attached.slot;
2121                                 goto out;
2122                         }
2123                 }
2124         }
2125         rc = -ENXIO;
2126  out:
2127         mutex_unlock(&ioc->sas_topology_mutex);
2128         return rc;
2129 }
2130
2131 static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
2132                               struct request *req)
2133 {
2134         MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
2135         MPT_FRAME_HDR *mf;
2136         SmpPassthroughRequest_t *smpreq;
2137         struct request *rsp = req->next_rq;
2138         int ret;
2139         int flagsLength;
2140         unsigned long timeleft;
2141         char *psge;
2142         dma_addr_t dma_addr_in = 0;
2143         dma_addr_t dma_addr_out = 0;
2144         u64 sas_address = 0;
2145
2146         if (!rsp) {
2147                 printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n",
2148                     ioc->name, __func__);
2149                 return -EINVAL;
2150         }
2151
2152         /* do we need to support multiple segments? */
2153         if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
2154                 printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
2155                     ioc->name, __func__, req->bio->bi_vcnt, blk_rq_bytes(req),
2156                     rsp->bio->bi_vcnt, blk_rq_bytes(rsp));
2157                 return -EINVAL;
2158         }
2159
2160         ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2161         if (ret)
2162                 goto out;
2163
2164         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2165         if (!mf) {
2166                 ret = -ENOMEM;
2167                 goto out_unlock;
2168         }
2169
2170         smpreq = (SmpPassthroughRequest_t *)mf;
2171         memset(smpreq, 0, sizeof(*smpreq));
2172
2173         smpreq->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
2174         smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2175
2176         if (rphy)
2177                 sas_address = rphy->identify.sas_address;
2178         else {
2179                 struct mptsas_portinfo *port_info;
2180
2181                 mutex_lock(&ioc->sas_topology_mutex);
2182                 port_info = ioc->hba_port_info;
2183                 if (port_info && port_info->phy_info)
2184                         sas_address =
2185                                 port_info->phy_info[0].phy->identify.sas_address;
2186                 mutex_unlock(&ioc->sas_topology_mutex);
2187         }
2188
2189         *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2190
2191         psge = (char *)
2192                 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2193
2194         /* request */
2195         flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2196                        MPI_SGE_FLAGS_END_OF_BUFFER |
2197                        MPI_SGE_FLAGS_DIRECTION)
2198                        << MPI_SGE_FLAGS_SHIFT;
2199         flagsLength |= (blk_rq_bytes(req) - 4);
2200
2201         dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
2202                                       blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
2203         if (!dma_addr_out)
2204                 goto put_mf;
2205         ioc->add_sge(psge, flagsLength, dma_addr_out);
2206         psge += ioc->SGE_size;
2207
2208         /* response */
2209         flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2210                 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2211                 MPI_SGE_FLAGS_IOC_TO_HOST |
2212                 MPI_SGE_FLAGS_END_OF_BUFFER;
2213
2214         flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2215         flagsLength |= blk_rq_bytes(rsp) + 4;
2216         dma_addr_in =  pci_map_single(ioc->pcidev, bio_data(rsp->bio),
2217                                       blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
2218         if (!dma_addr_in)
2219                 goto unmap;
2220         ioc->add_sge(psge, flagsLength, dma_addr_in);
2221
2222         INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2223         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2224
2225         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2226         if (!timeleft) {
2227                 printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __func__);
2228                 /* On timeout reset the board */
2229                 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2230                 ret = -ETIMEDOUT;
2231                 goto unmap;
2232         }
2233         mf = NULL;
2234
2235         if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2236                 SmpPassthroughReply_t *smprep;
2237
2238                 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2239                 memcpy(req->sense, smprep, sizeof(*smprep));
2240                 req->sense_len = sizeof(*smprep);
2241                 req->resid_len = 0;
2242                 rsp->resid_len -= smprep->ResponseDataLength;
2243         } else {
2244                 printk(MYIOC_s_ERR_FMT
2245                     "%s: smp passthru reply failed to be returned\n",
2246                     ioc->name, __func__);
2247                 ret = -ENXIO;
2248         }
2249 unmap:
2250         if (dma_addr_out)
2251                 pci_unmap_single(ioc->pcidev, dma_addr_out, blk_rq_bytes(req),
2252                                  PCI_DMA_BIDIRECTIONAL);
2253         if (dma_addr_in)
2254                 pci_unmap_single(ioc->pcidev, dma_addr_in, blk_rq_bytes(rsp),
2255                                  PCI_DMA_BIDIRECTIONAL);
2256 put_mf:
2257         if (mf)
2258                 mpt_free_msg_frame(ioc, mf);
2259 out_unlock:
2260         CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2261         mutex_unlock(&ioc->sas_mgmt.mutex);
2262 out:
2263         return ret;
2264 }
2265
2266 static struct sas_function_template mptsas_transport_functions = {
2267         .get_linkerrors         = mptsas_get_linkerrors,
2268         .get_enclosure_identifier = mptsas_get_enclosure_identifier,
2269         .get_bay_identifier     = mptsas_get_bay_identifier,
2270         .phy_reset              = mptsas_phy_reset,
2271         .smp_handler            = mptsas_smp_handler,
2272 };
2273
2274 static struct scsi_transport_template *mptsas_transport_template;
2275
2276 static int
2277 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
2278 {
2279         ConfigExtendedPageHeader_t hdr;
2280         CONFIGPARMS cfg;
2281         SasIOUnitPage0_t *buffer;
2282         dma_addr_t dma_handle;
2283         int error, i;
2284
2285         hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
2286         hdr.ExtPageLength = 0;
2287         hdr.PageNumber = 0;
2288         hdr.Reserved1 = 0;
2289         hdr.Reserved2 = 0;
2290         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2291         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2292
2293         cfg.cfghdr.ehdr = &hdr;
2294         cfg.physAddr = -1;
2295         cfg.pageAddr = 0;
2296         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2297         cfg.dir = 0;    /* read */
2298         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2299
2300         error = mpt_config(ioc, &cfg);
2301         if (error)
2302                 goto out;
2303         if (!hdr.ExtPageLength) {
2304                 error = -ENXIO;
2305                 goto out;
2306         }
2307
2308         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2309                                             &dma_handle);
2310         if (!buffer) {
2311                 error = -ENOMEM;
2312                 goto out;
2313         }
2314
2315         cfg.physAddr = dma_handle;
2316         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2317
2318         error = mpt_config(ioc, &cfg);
2319         if (error)
2320                 goto out_free_consistent;
2321
2322         port_info->num_phys = buffer->NumPhys;
2323         port_info->phy_info = kcalloc(port_info->num_phys,
2324                 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2325         if (!port_info->phy_info) {
2326                 error = -ENOMEM;
2327                 goto out_free_consistent;
2328         }
2329
2330         ioc->nvdata_version_persistent =
2331             le16_to_cpu(buffer->NvdataVersionPersistent);
2332         ioc->nvdata_version_default =
2333             le16_to_cpu(buffer->NvdataVersionDefault);
2334
2335         for (i = 0; i < port_info->num_phys; i++) {
2336                 mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
2337                 port_info->phy_info[i].phy_id = i;
2338                 port_info->phy_info[i].port_id =
2339                     buffer->PhyData[i].Port;
2340                 port_info->phy_info[i].negotiated_link_rate =
2341                     buffer->PhyData[i].NegotiatedLinkRate;
2342                 port_info->phy_info[i].portinfo = port_info;
2343                 port_info->phy_info[i].handle =
2344                     le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
2345         }
2346
2347  out_free_consistent:
2348         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2349                             buffer, dma_handle);
2350  out:
2351         return error;
2352 }
2353
2354 static int
2355 mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
2356 {
2357         ConfigExtendedPageHeader_t hdr;
2358         CONFIGPARMS cfg;
2359         SasIOUnitPage1_t *buffer;
2360         dma_addr_t dma_handle;
2361         int error;
2362         u16 device_missing_delay;
2363
2364         memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
2365         memset(&cfg, 0, sizeof(CONFIGPARMS));
2366
2367         cfg.cfghdr.ehdr = &hdr;
2368         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2369         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2370         cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2371         cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2372         cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
2373         cfg.cfghdr.ehdr->PageNumber = 1;
2374
2375         error = mpt_config(ioc, &cfg);
2376         if (error)
2377                 goto out;
2378         if (!hdr.ExtPageLength) {
2379                 error = -ENXIO;
2380                 goto out;
2381         }
2382
2383         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2384                                             &dma_handle);
2385         if (!buffer) {
2386                 error = -ENOMEM;
2387                 goto out;
2388         }
2389
2390         cfg.physAddr = dma_handle;
2391         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2392
2393         error = mpt_config(ioc, &cfg);
2394         if (error)
2395                 goto out_free_consistent;
2396
2397         ioc->io_missing_delay  =
2398             le16_to_cpu(buffer->IODeviceMissingDelay);
2399         device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay);
2400         ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
2401             (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
2402             device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
2403
2404  out_free_consistent:
2405         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2406                             buffer, dma_handle);
2407  out:
2408         return error;
2409 }
2410
2411 static int
2412 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2413                 u32 form, u32 form_specific)
2414 {
2415         ConfigExtendedPageHeader_t hdr;
2416         CONFIGPARMS cfg;
2417         SasPhyPage0_t *buffer;
2418         dma_addr_t dma_handle;
2419         int error;
2420
2421         hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
2422         hdr.ExtPageLength = 0;
2423         hdr.PageNumber = 0;
2424         hdr.Reserved1 = 0;
2425         hdr.Reserved2 = 0;
2426         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2427         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2428
2429         cfg.cfghdr.ehdr = &hdr;
2430         cfg.dir = 0;    /* read */
2431         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2432
2433         /* Get Phy Pg 0 for each Phy. */
2434         cfg.physAddr = -1;
2435         cfg.pageAddr = form + form_specific;
2436         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2437
2438         error = mpt_config(ioc, &cfg);
2439         if (error)
2440                 goto out;
2441
2442         if (!hdr.ExtPageLength) {
2443                 error = -ENXIO;
2444                 goto out;
2445         }
2446
2447         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2448                                       &dma_handle);
2449         if (!buffer) {
2450                 error = -ENOMEM;
2451                 goto out;
2452         }
2453
2454         cfg.physAddr = dma_handle;
2455         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2456
2457         error = mpt_config(ioc, &cfg);
2458         if (error)
2459                 goto out_free_consistent;
2460
2461         mptsas_print_phy_pg0(ioc, buffer);
2462
2463         phy_info->hw_link_rate = buffer->HwLinkRate;
2464         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2465         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2466         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2467
2468  out_free_consistent:
2469         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2470                             buffer, dma_handle);
2471  out:
2472         return error;
2473 }
2474
2475 static int
2476 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
2477                 u32 form, u32 form_specific)
2478 {
2479         ConfigExtendedPageHeader_t hdr;
2480         CONFIGPARMS cfg;
2481         SasDevicePage0_t *buffer;
2482         dma_addr_t dma_handle;
2483         __le64 sas_address;
2484         int error=0;
2485
2486         hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
2487         hdr.ExtPageLength = 0;
2488         hdr.PageNumber = 0;
2489         hdr.Reserved1 = 0;
2490         hdr.Reserved2 = 0;
2491         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2492         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
2493
2494         cfg.cfghdr.ehdr = &hdr;
2495         cfg.pageAddr = form + form_specific;
2496         cfg.physAddr = -1;
2497         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2498         cfg.dir = 0;    /* read */
2499         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2500
2501         memset(device_info, 0, sizeof(struct mptsas_devinfo));
2502         error = mpt_config(ioc, &cfg);
2503         if (error)
2504                 goto out;
2505         if (!hdr.ExtPageLength) {
2506                 error = -ENXIO;
2507                 goto out;
2508         }
2509
2510         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2511                                       &dma_handle);
2512         if (!buffer) {
2513                 error = -ENOMEM;
2514                 goto out;
2515         }
2516
2517         cfg.physAddr = dma_handle;
2518         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2519
2520         error = mpt_config(ioc, &cfg);
2521         if (error)
2522                 goto out_free_consistent;
2523
2524         mptsas_print_device_pg0(ioc, buffer);
2525
2526         memset(device_info, 0, sizeof(struct mptsas_devinfo));
2527         device_info->handle = le16_to_cpu(buffer->DevHandle);
2528         device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
2529         device_info->handle_enclosure =
2530             le16_to_cpu(buffer->EnclosureHandle);
2531         device_info->slot = le16_to_cpu(buffer->Slot);
2532         device_info->phy_id = buffer->PhyNum;
2533         device_info->port_id = buffer->PhysicalPort;
2534         device_info->id = buffer->TargetID;
2535         device_info->phys_disk_num = ~0;
2536         device_info->channel = buffer->Bus;
2537         memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2538         device_info->sas_address = le64_to_cpu(sas_address);
2539         device_info->device_info =
2540             le32_to_cpu(buffer->DeviceInfo);
2541
2542  out_free_consistent:
2543         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2544                             buffer, dma_handle);
2545  out:
2546         return error;
2547 }
2548
2549 static int
2550 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
2551                 u32 form, u32 form_specific)
2552 {
2553         ConfigExtendedPageHeader_t hdr;
2554         CONFIGPARMS cfg;
2555         SasExpanderPage0_t *buffer;
2556         dma_addr_t dma_handle;
2557         int i, error;
2558         __le64 sas_address;
2559
2560         memset(port_info, 0, sizeof(struct mptsas_portinfo));
2561         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
2562         hdr.ExtPageLength = 0;
2563         hdr.PageNumber = 0;
2564         hdr.Reserved1 = 0;
2565         hdr.Reserved2 = 0;
2566         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2567         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2568
2569         cfg.cfghdr.ehdr = &hdr;
2570         cfg.physAddr = -1;
2571         cfg.pageAddr = form + form_specific;
2572         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2573         cfg.dir = 0;    /* read */
2574         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2575
2576         memset(port_info, 0, sizeof(struct mptsas_portinfo));
2577         error = mpt_config(ioc, &cfg);
2578         if (error)
2579                 goto out;
2580
2581         if (!hdr.ExtPageLength) {
2582                 error = -ENXIO;
2583                 goto out;
2584         }
2585
2586         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2587                                       &dma_handle);
2588         if (!buffer) {
2589                 error = -ENOMEM;
2590                 goto out;
2591         }
2592
2593         cfg.physAddr = dma_handle;
2594         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2595
2596         error = mpt_config(ioc, &cfg);
2597         if (error)
2598                 goto out_free_consistent;
2599
2600         if (!buffer->NumPhys) {
2601                 error = -ENODEV;
2602                 goto out_free_consistent;
2603         }
2604
2605         /* save config data */
2606         port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1;
2607         port_info->phy_info = kcalloc(port_info->num_phys,
2608                 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2609         if (!port_info->phy_info) {
2610                 error = -ENOMEM;
2611                 goto out_free_consistent;
2612         }
2613
2614         memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2615         for (i = 0; i < port_info->num_phys; i++) {
2616                 port_info->phy_info[i].portinfo = port_info;
2617                 port_info->phy_info[i].handle =
2618                     le16_to_cpu(buffer->DevHandle);
2619                 port_info->phy_info[i].identify.sas_address =
2620                     le64_to_cpu(sas_address);
2621                 port_info->phy_info[i].identify.handle_parent =
2622                     le16_to_cpu(buffer->ParentDevHandle);
2623         }
2624
2625  out_free_consistent:
2626         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2627                             buffer, dma_handle);
2628  out:
2629         return error;
2630 }
2631
2632 static int
2633 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2634                 u32 form, u32 form_specific)
2635 {
2636         ConfigExtendedPageHeader_t hdr;
2637         CONFIGPARMS cfg;
2638         SasExpanderPage1_t *buffer;
2639         dma_addr_t dma_handle;
2640         int error=0;
2641
2642         hdr.PageVersion = MPI_SASEXPANDER1_PAGEVERSION;
2643         hdr.ExtPageLength = 0;
2644         hdr.PageNumber = 1;
2645         hdr.Reserved1 = 0;
2646         hdr.Reserved2 = 0;
2647         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2648         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2649
2650         cfg.cfghdr.ehdr = &hdr;
2651         cfg.physAddr = -1;
2652         cfg.pageAddr = form + form_specific;
2653         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2654         cfg.dir = 0;    /* read */
2655         cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2656
2657         error = mpt_config(ioc, &cfg);
2658         if (error)
2659                 goto out;
2660
2661         if (!hdr.ExtPageLength) {
2662                 error = -ENXIO;
2663                 goto out;
2664         }
2665
2666         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2667                                       &dma_handle);
2668         if (!buffer) {
2669                 error = -ENOMEM;
2670                 goto out;
2671         }
2672
2673         cfg.physAddr = dma_handle;
2674         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2675
2676         error = mpt_config(ioc, &cfg);
2677
2678         if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2679                 error = -ENODEV;
2680                 goto out;
2681         }
2682
2683         if (error)
2684                 goto out_free_consistent;
2685
2686
2687         mptsas_print_expander_pg1(ioc, buffer);
2688
2689         /* save config data */
2690         phy_info->phy_id = buffer->PhyIdentifier;
2691         phy_info->port_id = buffer->PhysicalPort;
2692         phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
2693         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2694         phy_info->hw_link_rate = buffer->HwLinkRate;
2695         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2696         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2697
2698  out_free_consistent:
2699         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2700                             buffer, dma_handle);
2701  out:
2702         return error;
2703 }
2704
2705 struct rep_manu_request{
2706         u8 smp_frame_type;
2707         u8 function;
2708         u8 reserved;
2709         u8 request_length;
2710 };
2711
2712 struct rep_manu_reply{
2713         u8 smp_frame_type; /* 0x41 */
2714         u8 function; /* 0x01 */
2715         u8 function_result;
2716         u8 response_length;
2717         u16 expander_change_count;
2718         u8 reserved0[2];
2719         u8 sas_format:1;
2720         u8 reserved1:7;
2721         u8 reserved2[3];
2722         u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
2723         u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
2724         u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
2725         u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
2726         u16 component_id;
2727         u8 component_revision_id;
2728         u8 reserved3;
2729         u8 vendor_specific[8];
2730 };
2731
2732 /**
2733   * mptsas_exp_repmanufacture_info -
2734   * @ioc: per adapter object
2735   * @sas_address: expander sas address
2736   * @edev: the sas_expander_device object
2737   *
2738   * Fills in the sas_expander_device object when SMP port is created.
2739   *
2740   * Returns 0 for success, non-zero for failure.
2741   */
2742 static int
2743 mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
2744         u64 sas_address, struct sas_expander_device *edev)
2745 {
2746         MPT_FRAME_HDR *mf;
2747         SmpPassthroughRequest_t *smpreq;
2748         SmpPassthroughReply_t *smprep;
2749         struct rep_manu_reply *manufacture_reply;
2750         struct rep_manu_request *manufacture_request;
2751         int ret;
2752         int flagsLength;
2753         unsigned long timeleft;
2754         char *psge;
2755         unsigned long flags;
2756         void *data_out = NULL;
2757         dma_addr_t data_out_dma = 0;
2758         u32 sz;
2759
2760         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2761         if (ioc->ioc_reset_in_progress) {
2762                 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2763                 printk(MYIOC_s_INFO_FMT "%s: host reset in progress!\n",
2764                         __func__, ioc->name);
2765                 return -EFAULT;
2766         }
2767         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2768
2769         ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2770         if (ret)
2771                 goto out;
2772
2773         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2774         if (!mf) {
2775                 ret = -ENOMEM;
2776                 goto out_unlock;
2777         }
2778
2779         smpreq = (SmpPassthroughRequest_t *)mf;
2780         memset(smpreq, 0, sizeof(*smpreq));
2781
2782         sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
2783
2784         data_out = pci_alloc_consistent(ioc->pcidev, sz, &data_out_dma);
2785         if (!data_out) {
2786                 printk(KERN_ERR "Memory allocation failure at %s:%d/%s()!\n",
2787                         __FILE__, __LINE__, __func__);
2788                 ret = -ENOMEM;
2789                 goto put_mf;
2790         }
2791
2792         manufacture_request = data_out;
2793         manufacture_request->smp_frame_type = 0x40;
2794         manufacture_request->function = 1;
2795         manufacture_request->reserved = 0;
2796         manufacture_request->request_length = 0;
2797
2798         smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2799         smpreq->PhysicalPort = 0xFF;
2800         *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2801         smpreq->RequestDataLength = sizeof(struct rep_manu_request);
2802
2803         psge = (char *)
2804                 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2805
2806         flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2807                 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2808                 MPI_SGE_FLAGS_HOST_TO_IOC |
2809                 MPI_SGE_FLAGS_END_OF_BUFFER;
2810         flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2811         flagsLength |= sizeof(struct rep_manu_request);
2812
2813         ioc->add_sge(psge, flagsLength, data_out_dma);
2814         psge += ioc->SGE_size;
2815
2816         flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2817                 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2818                 MPI_SGE_FLAGS_IOC_TO_HOST |
2819                 MPI_SGE_FLAGS_END_OF_BUFFER;
2820         flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2821         flagsLength |= sizeof(struct rep_manu_reply);
2822         ioc->add_sge(psge, flagsLength, data_out_dma +
2823         sizeof(struct rep_manu_request));
2824
2825         INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2826         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2827
2828         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2829         if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2830                 ret = -ETIME;
2831                 mpt_free_msg_frame(ioc, mf);
2832                 mf = NULL;
2833                 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2834                         goto out_free;
2835                 if (!timeleft)
2836                         mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2837                 goto out_free;
2838         }
2839
2840         mf = NULL;
2841
2842         if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2843                 u8 *tmp;
2844
2845         smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2846         if (le16_to_cpu(smprep->ResponseDataLength) !=
2847                 sizeof(struct rep_manu_reply))
2848                         goto out_free;
2849
2850         manufacture_reply = data_out + sizeof(struct rep_manu_request);
2851         strncpy(edev->vendor_id, manufacture_reply->vendor_id,
2852                 SAS_EXPANDER_VENDOR_ID_LEN);
2853         strncpy(edev->product_id, manufacture_reply->product_id,
2854                 SAS_EXPANDER_PRODUCT_ID_LEN);
2855         strncpy(edev->product_rev, manufacture_reply->product_rev,
2856                 SAS_EXPANDER_PRODUCT_REV_LEN);
2857         edev->level = manufacture_reply->sas_format;
2858         if (manufacture_reply->sas_format) {
2859                 strncpy(edev->component_vendor_id,
2860                         manufacture_reply->component_vendor_id,
2861                                 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
2862                 tmp = (u8 *)&manufacture_reply->component_id;
2863                 edev->component_id = tmp[0] << 8 | tmp[1];
2864                 edev->component_revision_id =
2865                         manufacture_reply->component_revision_id;
2866                 }
2867         } else {
2868                 printk(MYIOC_s_ERR_FMT
2869                         "%s: smp passthru reply failed to be returned\n",
2870                         ioc->name, __func__);
2871                 ret = -ENXIO;
2872         }
2873 out_free:
2874         if (data_out_dma)
2875                 pci_free_consistent(ioc->pcidev, sz, data_out, data_out_dma);
2876 put_mf:
2877         if (mf)
2878                 mpt_free_msg_frame(ioc, mf);
2879 out_unlock:
2880         CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2881         mutex_unlock(&ioc->sas_mgmt.mutex);
2882 out:
2883         return ret;
2884  }
2885
2886 static void
2887 mptsas_parse_device_info(struct sas_identify *identify,
2888                 struct mptsas_devinfo *device_info)
2889 {
2890         u16 protocols;
2891
2892         identify->sas_address = device_info->sas_address;
2893         identify->phy_identifier = device_info->phy_id;
2894
2895         /*
2896          * Fill in Phy Initiator Port Protocol.
2897          * Bits 6:3, more than one bit can be set, fall through cases.
2898          */
2899         protocols = device_info->device_info & 0x78;
2900         identify->initiator_port_protocols = 0;
2901         if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
2902                 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
2903         if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
2904                 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
2905         if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
2906                 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
2907         if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
2908                 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
2909
2910         /*
2911          * Fill in Phy Target Port Protocol.
2912          * Bits 10:7, more than one bit can be set, fall through cases.
2913          */
2914         protocols = device_info->device_info & 0x780;
2915         identify->target_port_protocols = 0;
2916         if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
2917                 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
2918         if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
2919                 identify->target_port_protocols |= SAS_PROTOCOL_STP;
2920         if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
2921                 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
2922         if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2923                 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
2924
2925         /*
2926          * Fill in Attached device type.
2927          */
2928         switch (device_info->device_info &
2929                         MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
2930         case MPI_SAS_DEVICE_INFO_NO_DEVICE:
2931                 identify->device_type = SAS_PHY_UNUSED;
2932                 break;
2933         case MPI_SAS_DEVICE_INFO_END_DEVICE:
2934                 identify->device_type = SAS_END_DEVICE;
2935                 break;
2936         case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
2937                 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
2938                 break;
2939         case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
2940                 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
2941                 break;
2942         }
2943 }
2944
2945 static int mptsas_probe_one_phy(struct device *dev,
2946                 struct mptsas_phyinfo *phy_info, int index, int local)
2947 {
2948         MPT_ADAPTER *ioc;
2949         struct sas_phy *phy;
2950         struct sas_port *port;
2951         int error = 0;
2952
2953         if (!dev) {
2954                 error = -ENODEV;
2955                 goto out;
2956         }
2957
2958         if (!phy_info->phy) {
2959                 phy = sas_phy_alloc(dev, index);
2960                 if (!phy) {
2961                         error = -ENOMEM;
2962                         goto out;
2963                 }
2964         } else
2965                 phy = phy_info->phy;
2966
2967         mptsas_parse_device_info(&phy->identify, &phy_info->identify);
2968
2969         /*
2970          * Set Negotiated link rate.
2971          */
2972         switch (phy_info->negotiated_link_rate) {
2973         case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
2974                 phy->negotiated_linkrate = SAS_PHY_DISABLED;
2975                 break;
2976         case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
2977                 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
2978                 break;
2979         case MPI_SAS_IOUNIT0_RATE_1_5:
2980                 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
2981                 break;
2982         case MPI_SAS_IOUNIT0_RATE_3_0:
2983                 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
2984                 break;
2985         case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
2986         case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
2987         default:
2988                 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
2989                 break;
2990         }
2991
2992         /*
2993          * Set Max hardware link rate.
2994          */
2995         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
2996         case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
2997                 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
2998                 break;
2999         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
3000                 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
3001                 break;
3002         default:
3003                 break;
3004         }
3005
3006         /*
3007          * Set Max programmed link rate.
3008          */
3009         switch (phy_info->programmed_link_rate &
3010                         MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
3011         case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
3012                 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
3013                 break;
3014         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
3015                 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
3016                 break;
3017         default:
3018                 break;
3019         }
3020
3021         /*
3022          * Set Min hardware link rate.
3023          */
3024         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
3025         case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
3026                 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
3027                 break;
3028         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
3029                 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
3030                 break;
3031         default:
3032                 break;
3033         }
3034
3035         /*
3036          * Set Min programmed link rate.
3037          */
3038         switch (phy_info->programmed_link_rate &
3039                         MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
3040         case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
3041                 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
3042                 break;
3043         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
3044                 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
3045                 break;
3046         default:
3047                 break;
3048         }
3049
3050         if (!phy_info->phy) {
3051
3052                 error = sas_phy_add(phy);
3053                 if (error) {
3054                         sas_phy_free(phy);
3055                         goto out;
3056                 }
3057                 phy_info->phy = phy;
3058         }
3059
3060         if (!phy_info->attached.handle ||
3061                         !phy_info->port_details)
3062                 goto out;
3063
3064         port = mptsas_get_port(phy_info);
3065         ioc = phy_to_ioc(phy_info->phy);
3066
3067         if (phy_info->sas_port_add_phy) {
3068
3069                 if (!port) {
3070                         port = sas_port_alloc_num(dev);
3071                         if (!port) {
3072                                 error = -ENOMEM;
3073                                 goto out;
3074                         }
3075                         error = sas_port_add(port);
3076                         if (error) {
3077                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3078                                         "%s: exit at line=%d\n", ioc->name,
3079                                         __func__, __LINE__));
3080                                 goto out;
3081                         }
3082                         mptsas_set_port(ioc, phy_info, port);
3083                         devtprintk(ioc, dev_printk(KERN_DEBUG, &port->dev,
3084                             MYIOC_s_FMT "add port %d, sas_addr (0x%llx)\n",
3085                             ioc->name, port->port_identifier,
3086                             (unsigned long long)phy_info->
3087                             attached.sas_address));
3088                 }
3089                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3090                         "sas_port_add_phy: phy_id=%d\n",
3091                         ioc->name, phy_info->phy_id));
3092                 sas_port_add_phy(port, phy_info->phy);
3093                 phy_info->sas_port_add_phy = 0;
3094                 devtprintk(ioc, dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3095                     MYIOC_s_FMT "add phy %d, phy-obj (0x%p)\n", ioc->name,
3096                      phy_info->phy_id, phy_info->phy));
3097         }
3098         if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
3099
3100                 struct sas_rphy *rphy;
3101                 struct device *parent;
3102                 struct sas_identify identify;
3103
3104                 parent = dev->parent->parent;
3105                 /*
3106                  * Let the hotplug_work thread handle processing
3107                  * the adding/removing of devices that occur
3108                  * after start of day.
3109                  */
3110                 if (mptsas_is_end_device(&phy_info->attached) &&
3111                     phy_info->attached.handle_parent) {
3112                         goto out;
3113                 }
3114
3115                 mptsas_parse_device_info(&identify, &phy_info->attached);
3116                 if (scsi_is_host_device(parent)) {
3117                         struct mptsas_portinfo *port_info;
3118                         int i;
3119
3120                         port_info = ioc->hba_port_info;
3121
3122                         for (i = 0; i < port_info->num_phys; i++)
3123                                 if (port_info->phy_info[i].identify.sas_address ==
3124                                     identify.sas_address) {
3125                                         sas_port_mark_backlink(port);
3126                                         goto out;
3127                                 }
3128
3129                 } else if (scsi_is_sas_rphy(parent)) {
3130                         struct sas_rphy *parent_rphy = dev_to_rphy(parent);
3131                         if (identify.sas_address ==
3132                             parent_rphy->identify.sas_address) {
3133                                 sas_port_mark_backlink(port);
3134                                 goto out;
3135                         }
3136                 }
3137
3138                 switch (identify.device_type) {
3139                 case SAS_END_DEVICE:
3140                         rphy = sas_end_device_alloc(port);
3141                         break;
3142                 case SAS_EDGE_EXPANDER_DEVICE:
3143                 case SAS_FANOUT_EXPANDER_DEVICE:
3144                         rphy = sas_expander_alloc(port, identify.device_type);
3145                         break;
3146                 default:
3147                         rphy = NULL;
3148                         break;
3149                 }
3150                 if (!rphy) {
3151                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3152                                 "%s: exit at line=%d\n", ioc->name,
3153                                 __func__, __LINE__));
3154                         goto out;
3155                 }
3156
3157                 rphy->identify = identify;
3158                 error = sas_rphy_add(rphy);
3159                 if (error) {
3160                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3161                                 "%s: exit at line=%d\n", ioc->name,
3162                                 __func__, __LINE__));
3163                         sas_rphy_free(rphy);
3164                         goto out;
3165                 }
3166                 mptsas_set_rphy(ioc, phy_info, rphy);
3167                 if (identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
3168                         identify.device_type == SAS_FANOUT_EXPANDER_DEVICE)
3169                                 mptsas_exp_repmanufacture_info(ioc,
3170                                         identify.sas_address,
3171                                         rphy_to_expander_device(rphy));
3172         }
3173
3174  out:
3175         return error;
3176 }
3177
3178 static int
3179 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
3180 {
3181         struct mptsas_portinfo *port_info, *hba;
3182         int error = -ENOMEM, i;
3183
3184         hba = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3185         if (! hba)
3186                 goto out;
3187
3188         error = mptsas_sas_io_unit_pg0(ioc, hba);
3189         if (error)
3190                 goto out_free_port_info;
3191
3192         mptsas_sas_io_unit_pg1(ioc);
3193         mutex_lock(&ioc->sas_topology_mutex);
3194         port_info = ioc->hba_port_info;
3195         if (!port_info) {
3196                 ioc->hba_port_info = port_info = hba;
3197                 ioc->hba_port_num_phy = port_info->num_phys;
3198                 list_add_tail(&port_info->list, &ioc->sas_topology);
3199         } else {
3200                 for (i = 0; i < hba->num_phys; i++) {
3201                         port_info->phy_info[i].negotiated_link_rate =
3202                                 hba->phy_info[i].negotiated_link_rate;
3203                         port_info->phy_info[i].handle =
3204                                 hba->phy_info[i].handle;
3205                         port_info->phy_info[i].port_id =
3206                                 hba->phy_info[i].port_id;
3207                 }
3208                 kfree(hba->phy_info);
3209                 kfree(hba);
3210                 hba = NULL;
3211         }
3212         mutex_unlock(&ioc->sas_topology_mutex);
3213 #if defined(CPQ_CIM)
3214         ioc->num_ports = port_info->num_phys;
3215 #endif
3216         for (i = 0; i < port_info->num_phys; i++) {
3217                 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
3218                         (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
3219                          MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
3220                 port_info->phy_info[i].identify.handle =
3221                     port_info->phy_info[i].handle;
3222                 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
3223                         (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3224                          MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3225                          port_info->phy_info[i].identify.handle);
3226                 if (!ioc->hba_port_sas_addr)
3227                         ioc->hba_port_sas_addr =
3228                             port_info->phy_info[i].identify.sas_address;
3229                 port_info->phy_info[i].identify.phy_id =
3230                     port_info->phy_info[i].phy_id = i;
3231                 if (port_info->phy_info[i].attached.handle)
3232                         mptsas_sas_device_pg0(ioc,
3233                                 &port_info->phy_info[i].attached,
3234                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3235                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3236                                 port_info->phy_info[i].attached.handle);
3237         }
3238
3239         mptsas_setup_wide_ports(ioc, port_info);
3240
3241         for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3242                 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
3243                     &port_info->phy_info[i], ioc->sas_index, 1);
3244
3245         return 0;
3246
3247  out_free_port_info:
3248         kfree(hba);
3249  out:
3250         return error;
3251 }
3252
3253 static void
3254 mptsas_expander_refresh(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
3255 {
3256         struct mptsas_portinfo *parent;
3257         struct device *parent_dev;
3258         struct sas_rphy *rphy;
3259         int             i;
3260         u64             sas_address; /* expander sas address */
3261         u32             handle;
3262
3263         handle = port_info->phy_info[0].handle;
3264         sas_address = port_info->phy_info[0].identify.sas_address;
3265         for (i = 0; i < port_info->num_phys; i++) {
3266                 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
3267                     (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
3268                     MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + handle);
3269
3270                 mptsas_sas_device_pg0(ioc,
3271                     &port_info->phy_info[i].identify,
3272                     (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3273                     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3274                     port_info->phy_info[i].identify.handle);
3275                 port_info->phy_info[i].identify.phy_id =
3276                     port_info->phy_info[i].phy_id;
3277
3278                 if (port_info->phy_info[i].attached.handle) {
3279                         mptsas_sas_device_pg0(ioc,
3280                             &port_info->phy_info[i].attached,
3281                             (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3282                              MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3283                             port_info->phy_info[i].attached.handle);
3284                         port_info->phy_info[i].attached.phy_id =
3285                             port_info->phy_info[i].phy_id;
3286                 }
3287         }
3288
3289         mutex_lock(&ioc->sas_topology_mutex);
3290         parent = mptsas_find_portinfo_by_handle(ioc,
3291             port_info->phy_info[0].identify.handle_parent);
3292         if (!parent) {
3293                 mutex_unlock(&ioc->sas_topology_mutex);
3294                 return;
3295         }
3296         for (i = 0, parent_dev = NULL; i < parent->num_phys && !parent_dev;
3297             i++) {
3298                 if (parent->phy_info[i].attached.sas_address == sas_address) {
3299                         rphy = mptsas_get_rphy(&parent->phy_info[i]);
3300                         parent_dev = &rphy->dev;
3301                 }
3302         }
3303         mutex_unlock(&ioc->sas_topology_mutex);
3304
3305         mptsas_setup_wide_ports(ioc, port_info);
3306         for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3307                 mptsas_probe_one_phy(parent_dev, &port_info->phy_info[i],
3308                     ioc->sas_index, 0);
3309 }
3310
3311 static void
3312 mptsas_expander_event_add(MPT_ADAPTER *ioc,
3313     MpiEventDataSasExpanderStatusChange_t *expander_data)
3314 {
3315         struct mptsas_portinfo *port_info;
3316         int i;
3317         __le64 sas_address;
3318
3319         port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3320         if (!port_info)
3321                 BUG();
3322         port_info->num_phys = (expander_data->NumPhys) ?
3323             expander_data->NumPhys : 1;
3324         port_info->phy_info = kcalloc(port_info->num_phys,
3325             sizeof(struct mptsas_phyinfo), GFP_KERNEL);
3326         if (!port_info->phy_info)
3327                 BUG();
3328         memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3329         for (i = 0; i < port_info->num_phys; i++) {
3330                 port_info->phy_info[i].portinfo = port_info;
3331                 port_info->phy_info[i].handle =
3332                     le16_to_cpu(expander_data->DevHandle);
3333                 port_info->phy_info[i].identify.sas_address =
3334                     le64_to_cpu(sas_address);
3335                 port_info->phy_info[i].identify.handle_parent =
3336                     le16_to_cpu(expander_data->ParentDevHandle);
3337         }
3338
3339         mutex_lock(&ioc->sas_topology_mutex);
3340         list_add_tail(&port_info->list, &ioc->sas_topology);
3341         mutex_unlock(&ioc->sas_topology_mutex);
3342
3343         printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3344             "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3345             (unsigned long long)sas_address);
3346
3347         mptsas_expander_refresh(ioc, port_info);
3348 }
3349
3350 /**
3351  * mptsas_delete_expander_siblings - remove siblings attached to expander
3352  * @ioc: Pointer to MPT_ADAPTER structure
3353  * @parent: the parent port_info object
3354  * @expander: the expander port_info object
3355  **/
3356 static void
3357 mptsas_delete_expander_siblings(MPT_ADAPTER *ioc, struct mptsas_portinfo
3358     *parent, struct mptsas_portinfo *expander)
3359 {
3360         struct mptsas_phyinfo *phy_info;
3361         struct mptsas_portinfo *port_info;
3362         struct sas_rphy *rphy;
3363         int i;
3364
3365         phy_info = expander->phy_info;
3366         for (i = 0; i < expander->num_phys; i++, phy_info++) {
3367                 rphy = mptsas_get_rphy(phy_info);
3368                 if (!rphy)
3369                         continue;
3370                 if (rphy->identify.device_type == SAS_END_DEVICE)
3371                         mptsas_del_end_device(ioc, phy_info);
3372         }
3373
3374         phy_info = expander->phy_info;
3375         for (i = 0; i < expander->num_phys; i++, phy_info++) {
3376                 rphy = mptsas_get_rphy(phy_info);
3377                 if (!rphy)
3378                         continue;
3379                 if (rphy->identify.device_type ==
3380                     MPI_SAS_DEVICE_INFO_EDGE_EXPANDER ||
3381                     rphy->identify.device_type ==
3382                     MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
3383                         port_info = mptsas_find_portinfo_by_sas_address(ioc,
3384                             rphy->identify.sas_address);
3385                         if (!port_info)
3386                                 continue;
3387                         if (port_info == parent) /* backlink rphy */
3388                                 continue;
3389                         /*
3390                         Delete this expander even if the expdevpage is exists
3391                         because the parent expander is already deleted
3392                         */
3393                         mptsas_expander_delete(ioc, port_info, 1);
3394                 }
3395         }
3396 }
3397
3398
3399 /**
3400  *      mptsas_expander_delete - remove this expander
3401  *      @ioc: Pointer to MPT_ADAPTER structure
3402  *      @port_info: expander port_info struct
3403  *      @force: Flag to forcefully delete the expander
3404  *
3405  **/
3406
3407 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
3408                 struct mptsas_portinfo *port_info, u8 force)
3409 {
3410
3411         struct mptsas_portinfo *parent;
3412         int             i;
3413         u64             expander_sas_address;
3414         struct mptsas_phyinfo *phy_info;
3415         struct mptsas_portinfo buffer;
3416         struct mptsas_portinfo_details *port_details;
3417         struct sas_port *port;
3418
3419         if (!port_info)
3420                 return;
3421
3422         /* see if expander is still there before deleting */
3423         mptsas_sas_expander_pg0(ioc, &buffer,
3424             (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3425             MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
3426             port_info->phy_info[0].identify.handle);
3427
3428         if (buffer.num_phys) {
3429                 kfree(buffer.phy_info);
3430                 if (!force)
3431                         return;
3432         }
3433
3434
3435         /*
3436          * Obtain the port_info instance to the parent port
3437          */
3438         port_details = NULL;
3439         expander_sas_address =
3440             port_info->phy_info[0].identify.sas_address;
3441         parent = mptsas_find_portinfo_by_handle(ioc,
3442             port_info->phy_info[0].identify.handle_parent);
3443         mptsas_delete_expander_siblings(ioc, parent, port_info);
3444         if (!parent)
3445                 goto out;
3446
3447         /*
3448          * Delete rphys in the parent that point
3449          * to this expander.
3450          */
3451         phy_info = parent->phy_info;
3452         port = NULL;
3453         for (i = 0; i < parent->num_phys; i++, phy_info++) {
3454                 if (!phy_info->phy)
3455                         continue;
3456                 if (phy_info->attached.sas_address !=
3457                     expander_sas_address)
3458                         continue;
3459                 if (!port) {
3460                         port = mptsas_get_port(phy_info);
3461                         port_details = phy_info->port_details;
3462                 }
3463                 dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3464                     MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n", ioc->name,
3465                     phy_info->phy_id, phy_info->phy);
3466                 sas_port_delete_phy(port, phy_info->phy);
3467         }
3468         if (port) {
3469                 dev_printk(KERN_DEBUG, &port->dev,
3470                     MYIOC_s_FMT "delete port %d, sas_addr (0x%llx)\n",
3471                     ioc->name, port->port_identifier,
3472                     (unsigned long long)expander_sas_address);
3473                 sas_port_delete(port);
3474                 mptsas_port_delete(ioc, port_details);
3475         }
3476  out:
3477
3478         printk(MYIOC_s_INFO_FMT "delete expander: num_phys %d, "
3479             "sas_addr (0x%llx)\n",  ioc->name, port_info->num_phys,
3480             (unsigned long long)expander_sas_address);
3481
3482         /*
3483          * free link
3484          */
3485         list_del(&port_info->list);
3486         kfree(port_info->phy_info);
3487         kfree(port_info);
3488 }
3489
3490
3491 /**
3492  * mptsas_send_expander_event - expanders events
3493  * @ioc: Pointer to MPT_ADAPTER structure
3494  * @expander_data: event data
3495  *
3496  *
3497  * This function handles adding, removing, and refreshing
3498  * device handles within the expander objects.
3499  */
3500 static void
3501 mptsas_send_expander_event(struct fw_event_work *fw_event)
3502 {
3503         MPT_ADAPTER *ioc;
3504         MpiEventDataSasExpanderStatusChange_t *expander_data;
3505         struct mptsas_portinfo *port_info;
3506         __le64 sas_address;
3507         int i;
3508
3509         ioc = fw_event->ioc;
3510         expander_data = (MpiEventDataSasExpanderStatusChange_t *)
3511             fw_event->event_data;
3512         memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3513         sas_address = le64_to_cpu(sas_address);
3514         port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3515
3516         if (expander_data->ReasonCode == MPI_EVENT_SAS_EXP_RC_ADDED) {
3517                 if (port_info) {
3518                         for (i = 0; i < port_info->num_phys; i++) {
3519                                 port_info->phy_info[i].portinfo = port_info;
3520                                 port_info->phy_info[i].handle =
3521                                     le16_to_cpu(expander_data->DevHandle);
3522                                 port_info->phy_info[i].identify.sas_address =
3523                                     le64_to_cpu(sas_address);
3524                                 port_info->phy_info[i].identify.handle_parent =
3525                                     le16_to_cpu(expander_data->ParentDevHandle);
3526                         }
3527                         mptsas_expander_refresh(ioc, port_info);
3528                 } else if (!port_info && expander_data->NumPhys)
3529                         mptsas_expander_event_add(ioc, expander_data);
3530         } else if (expander_data->ReasonCode ==
3531             MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING)
3532                 mptsas_expander_delete(ioc, port_info, 0);
3533
3534         mptsas_free_fw_event(ioc, fw_event);
3535 }
3536
3537
3538 /**
3539  * mptsas_expander_add -
3540  * @ioc: Pointer to MPT_ADAPTER structure
3541  * @handle:
3542  *
3543  */
3544 struct mptsas_portinfo *
3545 mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
3546 {
3547         struct mptsas_portinfo buffer, *port_info;
3548         int i;
3549
3550         if ((mptsas_sas_expander_pg0(ioc, &buffer,
3551             (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3552             MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)))
3553                 return NULL;
3554
3555         port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_ATOMIC);
3556         if (!port_info) {
3557                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3558                 "%s: exit at line=%d\n", ioc->name,
3559                 __func__, __LINE__));
3560                 return NULL;
3561         }
3562         port_info->num_phys = buffer.num_phys;
3563         port_info->phy_info = buffer.phy_info;
3564         for (i = 0; i < port_info->num_phys; i++)
3565                 port_info->phy_info[i].portinfo = port_info;
3566         mutex_lock(&ioc->sas_topology_mutex);
3567         list_add_tail(&port_info->list, &ioc->sas_topology);
3568         mutex_unlock(&ioc->sas_topology_mutex);
3569         printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3570             "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3571             (unsigned long long)buffer.phy_info[0].identify.sas_address);
3572         mptsas_expander_refresh(ioc, port_info);
3573         return port_info;
3574 }
3575
3576 static void
3577 mptsas_send_link_status_event(struct fw_event_work *fw_event)
3578 {
3579         MPT_ADAPTER *ioc;
3580         MpiEventDataSasPhyLinkStatus_t *link_data;
3581         struct mptsas_portinfo *port_info;
3582         struct mptsas_phyinfo *phy_info = NULL;
3583         __le64 sas_address;
3584         u8 phy_num;
3585         u8 link_rate;
3586
3587         ioc = fw_event->ioc;
3588         link_data = (MpiEventDataSasPhyLinkStatus_t *)fw_event->event_data;
3589
3590         memcpy(&sas_address, &link_data->SASAddress, sizeof(__le64));
3591         sas_address = le64_to_cpu(sas_address);
3592         link_rate = link_data->LinkRates >> 4;
3593         phy_num = link_data->PhyNum;
3594
3595         port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3596         if (port_info) {
3597                 phy_info = &port_info->phy_info[phy_num];
3598                 if (phy_info)
3599                         phy_info->negotiated_link_rate = link_rate;
3600         }
3601
3602         if (link_rate == MPI_SAS_IOUNIT0_RATE_1_5 ||
3603             link_rate == MPI_SAS_IOUNIT0_RATE_3_0) {
3604
3605                 if (!port_info) {
3606                         if (ioc->old_sas_discovery_protocal) {
3607                                 port_info = mptsas_expander_add(ioc,
3608                                         le16_to_cpu(link_data->DevHandle));
3609                                 if (port_info)
3610                                         goto out;
3611                         }
3612                         goto out;
3613                 }
3614
3615                 if (port_info == ioc->hba_port_info)
3616                         mptsas_probe_hba_phys(ioc);
3617                 else
3618                         mptsas_expander_refresh(ioc, port_info);
3619         } else if (phy_info && phy_info->phy) {
3620                 if (link_rate ==  MPI_SAS_IOUNIT0_RATE_PHY_DISABLED)
3621                         phy_info->phy->negotiated_linkrate =
3622                             SAS_PHY_DISABLED;
3623                 else if (link_rate ==
3624                     MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION)
3625                         phy_info->phy->negotiated_linkrate =
3626                             SAS_LINK_RATE_FAILED;
3627                 else
3628                         phy_info->phy->negotiated_linkrate =
3629                             SAS_LINK_RATE_UNKNOWN;
3630         }
3631  out:
3632         mptsas_free_fw_event(ioc, fw_event);
3633 }
3634
3635 static void
3636 mptsas_not_responding_devices(MPT_ADAPTER *ioc)
3637 {
3638         struct mptsas_portinfo buffer, *port_info;
3639         struct mptsas_device_info       *sas_info;
3640         struct mptsas_devinfo sas_device;
3641         u32     handle;
3642         VirtTarget *vtarget = NULL;
3643         struct mptsas_phyinfo *phy_info;
3644         u8 found_expander;
3645         int retval, retry_count;
3646         unsigned long flags;
3647
3648         mpt_findImVolumes(ioc);
3649
3650         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3651         if (ioc->ioc_reset_in_progress) {
3652                 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3653                    "%s: exiting due to a parallel reset \n", ioc->name,
3654                     __func__));
3655                 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3656                 return;
3657         }
3658         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3659
3660         /* devices, logical volumes */
3661         mutex_lock(&ioc->sas_device_info_mutex);
3662  redo_device_scan:
3663         list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) {
3664                 if (sas_info->is_cached)
3665                         continue;
3666                 if (!sas_info->is_logical_volume) {
3667                         sas_device.handle = 0;
3668                         retry_count = 0;
3669 retry_page:
3670                         retval = mptsas_sas_device_pg0(ioc, &sas_device,
3671                                 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID
3672                                 << MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3673                                 (sas_info->fw.channel << 8) +
3674                                 sas_info->fw.id);
3675
3676                         if (sas_device.handle)
3677                                 continue;
3678                         if (retval == -EBUSY) {
3679                                 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3680                                 if (ioc->ioc_reset_in_progress) {
3681                                         dfailprintk(ioc,
3682                                         printk(MYIOC_s_DEBUG_FMT
3683                                         "%s: exiting due to reset\n",
3684                                         ioc->name, __func__));
3685                                         spin_unlock_irqrestore
3686                                         (&ioc->taskmgmt_lock, flags);
3687                                         mutex_unlock(&ioc->
3688                                         sas_device_info_mutex);
3689                                         return;
3690                                 }
3691                                 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
3692                                 flags);
3693                         }
3694
3695                         if (retval && (retval != -ENODEV)) {
3696                                 if (retry_count < 10) {
3697                                         retry_count++;
3698                                         goto retry_page;
3699                                 } else {
3700                                         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3701                                         "%s: Config page retry exceeded retry "
3702                                         "count deleting device 0x%llx\n",
3703                                         ioc->name, __func__,
3704                                         sas_info->sas_address));
3705                                 }
3706                         }
3707
3708                         /* delete device */
3709                         vtarget = mptsas_find_vtarget(ioc,
3710                                 sas_info->fw.channel, sas_info->fw.id);
3711
3712                         if (vtarget)
3713                                 vtarget->deleted = 1;
3714
3715                         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3716                                         sas_info->sas_address);
3717
3718                         if (phy_info) {
3719                                 mptsas_del_end_device(ioc, phy_info);
3720                                 goto redo_device_scan;
3721                         }
3722                 } else
3723                         mptsas_volume_delete(ioc, sas_info->fw.id);
3724         }
3725         mutex_unlock(&ioc->sas_device_info_mutex);
3726
3727         /* expanders */
3728         mutex_lock(&ioc->sas_topology_mutex);
3729  redo_expander_scan:
3730         list_for_each_entry(port_info, &ioc->sas_topology, list) {
3731
3732                 if (port_info->phy_info &&
3733                     (!(port_info->phy_info[0].identify.device_info &
3734                     MPI_SAS_DEVICE_INFO_SMP_TARGET)))
3735                         continue;
3736                 found_expander = 0;
3737                 handle = 0xFFFF;
3738                 while (!mptsas_sas_expander_pg0(ioc, &buffer,
3739                     (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3740                      MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle) &&
3741                     !found_expander) {
3742
3743                         handle = buffer.phy_info[0].handle;
3744                         if (buffer.phy_info[0].identify.sas_address ==
3745                             port_info->phy_info[0].identify.sas_address) {
3746                                 found_expander = 1;
3747                         }
3748                         kfree(buffer.phy_info);
3749                 }
3750
3751                 if (!found_expander) {
3752                         mptsas_expander_delete(ioc, port_info, 0);
3753                         goto redo_expander_scan;
3754                 }
3755         }
3756         mutex_unlock(&ioc->sas_topology_mutex);
3757 }
3758
3759 /**
3760  *      mptsas_probe_expanders - adding expanders
3761  *      @ioc: Pointer to MPT_ADAPTER structure
3762  *
3763  **/
3764 static void
3765 mptsas_probe_expanders(MPT_ADAPTER *ioc)
3766 {
3767         struct mptsas_portinfo buffer, *port_info;
3768         u32                     handle;
3769         int i;
3770
3771         handle = 0xFFFF;
3772         while (!mptsas_sas_expander_pg0(ioc, &buffer,
3773             (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3774              MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)) {
3775
3776                 handle = buffer.phy_info[0].handle;
3777                 port_info = mptsas_find_portinfo_by_sas_address(ioc,
3778                     buffer.phy_info[0].identify.sas_address);
3779
3780                 if (port_info) {
3781                         /* refreshing handles */
3782                         for (i = 0; i < buffer.num_phys; i++) {
3783                                 port_info->phy_info[i].handle = handle;
3784                                 port_info->phy_info[i].identify.handle_parent =
3785                                     buffer.phy_info[0].identify.handle_parent;
3786                         }
3787                         mptsas_expander_refresh(ioc, port_info);
3788                         kfree(buffer.phy_info);
3789                         continue;
3790                 }
3791
3792                 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3793                 if (!port_info) {
3794                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3795                         "%s: exit at line=%d\n", ioc->name,
3796                         __func__, __LINE__));
3797                         return;
3798                 }
3799                 port_info->num_phys = buffer.num_phys;
3800                 port_info->phy_info = buffer.phy_info;
3801                 for (i = 0; i < port_info->num_phys; i++)
3802                         port_info->phy_info[i].portinfo = port_info;
3803                 mutex_lock(&ioc->sas_topology_mutex);
3804                 list_add_tail(&port_info->list, &ioc->sas_topology);
3805                 mutex_unlock(&ioc->sas_topology_mutex);
3806                 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3807                     "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3808             (unsigned long long)buffer.phy_info[0].identify.sas_address);
3809                 mptsas_expander_refresh(ioc, port_info);
3810         }
3811 }
3812
3813 static void
3814 mptsas_probe_devices(MPT_ADAPTER *ioc)
3815 {
3816         u16 handle;
3817         struct mptsas_devinfo sas_device;
3818         struct mptsas_phyinfo *phy_info;
3819
3820         handle = 0xFFFF;
3821         while (!(mptsas_sas_device_pg0(ioc, &sas_device,
3822             MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
3823
3824                 handle = sas_device.handle;
3825
3826                 if ((sas_device.device_info &
3827                      (MPI_SAS_DEVICE_INFO_SSP_TARGET |
3828                       MPI_SAS_DEVICE_INFO_STP_TARGET |
3829                       MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0)
3830                         continue;
3831
3832                 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3833                 if (!phy_info)
3834                         continue;
3835
3836                 if (mptsas_get_rphy(phy_info))
3837                         continue;
3838
3839                 mptsas_add_end_device(ioc, phy_info);
3840         }
3841 }
3842
3843 /**
3844  *      mptsas_scan_sas_topology -
3845  *      @ioc: Pointer to MPT_ADAPTER structure
3846  *      @sas_address:
3847  *
3848  **/
3849 static void
3850 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
3851 {
3852         struct scsi_device *sdev;
3853         int i;
3854
3855         mptsas_probe_hba_phys(ioc);
3856         mptsas_probe_expanders(ioc);
3857         mptsas_probe_devices(ioc);
3858
3859         /*
3860           Reporting RAID volumes.
3861         */
3862         if (!ioc->ir_firmware || !ioc->raid_data.pIocPg2 ||
3863             !ioc->raid_data.pIocPg2->NumActiveVolumes)
3864                 return;
3865         for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
3866                 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
3867                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
3868                 if (sdev) {
3869                         scsi_device_put(sdev);
3870                         continue;
3871                 }
3872                 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
3873                     "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
3874                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID);
3875                 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
3876                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
3877         }
3878 }
3879
3880
3881 static void
3882 mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
3883 {
3884         MPT_ADAPTER *ioc;
3885         EventDataQueueFull_t *qfull_data;
3886         struct mptsas_device_info *sas_info;
3887         struct scsi_device      *sdev;
3888         int depth;
3889         int id = -1;
3890         int channel = -1;
3891         int fw_id, fw_channel;
3892         u16 current_depth;
3893
3894
3895         ioc = fw_event->ioc;
3896         qfull_data = (EventDataQueueFull_t *)fw_event->event_data;
3897         fw_id = qfull_data->TargetID;
3898         fw_channel = qfull_data->Bus;
3899         current_depth = le16_to_cpu(qfull_data->CurrentDepth);
3900
3901         /* if hidden raid component, look for the volume id */
3902         mutex_lock(&ioc->sas_device_info_mutex);
3903         if (mptscsih_is_phys_disk(ioc, fw_channel, fw_id)) {
3904                 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
3905                     list) {
3906                         if (sas_info->is_cached ||
3907                             sas_info->is_logical_volume)
3908                                 continue;
3909                         if (sas_info->is_hidden_raid_component &&
3910                             (sas_info->fw.channel == fw_channel &&
3911                             sas_info->fw.id == fw_id)) {
3912                                 id = sas_info->volume_id;
3913                                 channel = MPTSAS_RAID_CHANNEL;
3914                                 goto out;
3915                         }
3916                 }
3917         } else {
3918                 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
3919                     list) {
3920                         if (sas_info->is_cached ||
3921                             sas_info->is_hidden_raid_component ||
3922                             sas_info->is_logical_volume)
3923                                 continue;
3924                         if (sas_info->fw.channel == fw_channel &&
3925                             sas_info->fw.id == fw_id) {
3926                                 id = sas_info->os.id;
3927                                 channel = sas_info->os.channel;
3928                                 goto out;
3929                         }
3930                 }
3931
3932         }
3933
3934  out:
3935         mutex_unlock(&ioc->sas_device_info_mutex);
3936
3937         if (id != -1) {
3938                 shost_for_each_device(sdev, ioc->sh) {
3939                         if (sdev->id == id && sdev->channel == channel) {
3940                                 if (current_depth > sdev->queue_depth) {
3941                                         sdev_printk(KERN_INFO, sdev,
3942                                             "strange observation, the queue "
3943                                             "depth is (%d) meanwhile fw queue "
3944                                             "depth (%d)\n", sdev->queue_depth,
3945                                             current_depth);
3946                                         continue;
3947                                 }
3948                                 depth = scsi_track_queue_full(sdev,
3949                                     current_depth - 1);
3950                                 if (depth > 0)
3951                                         sdev_printk(KERN_INFO, sdev,
3952                                         "Queue depth reduced to (%d)\n",
3953                                            depth);
3954                                 else if (depth < 0)
3955                                         sdev_printk(KERN_INFO, sdev,
3956                                         "Tagged Command Queueing is being "
3957                                         "disabled\n");
3958                                 else if (depth == 0)
3959                                         sdev_printk(KERN_INFO, sdev,
3960                                         "Queue depth not changed yet\n");
3961                         }
3962                 }
3963         }
3964
3965         mptsas_free_fw_event(ioc, fw_event);
3966 }
3967
3968
3969 static struct mptsas_phyinfo *
3970 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
3971 {
3972         struct mptsas_portinfo *port_info;
3973         struct mptsas_phyinfo *phy_info = NULL;
3974         int i;
3975
3976         mutex_lock(&ioc->sas_topology_mutex);
3977         list_for_each_entry(port_info, &ioc->sas_topology, list) {
3978                 for (i = 0; i < port_info->num_phys; i++) {
3979                         if (!mptsas_is_end_device(
3980                                 &port_info->phy_info[i].attached))
3981                                 continue;
3982                         if (port_info->phy_info[i].attached.sas_address
3983                             != sas_address)
3984                                 continue;
3985                         phy_info = &port_info->phy_info[i];
3986                         break;
3987                 }
3988         }
3989         mutex_unlock(&ioc->sas_topology_mutex);
3990         return phy_info;
3991 }
3992
3993 /**
3994  *      mptsas_find_phyinfo_by_phys_disk_num -
3995  *      @ioc: Pointer to MPT_ADAPTER structure
3996  *      @phys_disk_num:
3997  *      @channel:
3998  *      @id:
3999  *
4000  **/
4001 static struct mptsas_phyinfo *
4002 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
4003         u8 channel, u8 id)
4004 {
4005         struct mptsas_phyinfo *phy_info = NULL;
4006         struct mptsas_portinfo *port_info;
4007         RaidPhysDiskPage1_t *phys_disk = NULL;
4008         int num_paths;
4009         u64 sas_address = 0;
4010         int i;
4011
4012         phy_info = NULL;
4013         if (!ioc->raid_data.pIocPg3)
4014                 return NULL;
4015         /* dual port support */
4016         num_paths = mpt_raid_phys_disk_get_num_paths(ioc, phys_disk_num);
4017         if (!num_paths)
4018                 goto out;
4019         phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
4020            (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
4021         if (!phys_disk)
4022                 goto out;
4023         mpt_raid_phys_disk_pg1(ioc, phys_disk_num, phys_disk);
4024         for (i = 0; i < num_paths; i++) {
4025                 if ((phys_disk->Path[i].Flags & 1) != 0)
4026                         /* entry no longer valid */
4027                         continue;
4028                 if ((id == phys_disk->Path[i].PhysDiskID) &&
4029                     (channel == phys_disk->Path[i].PhysDiskBus)) {
4030                         memcpy(&sas_address, &phys_disk->Path[i].WWID,
4031                                 sizeof(u64));
4032                         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4033                                         sas_address);
4034                         goto out;
4035                 }
4036         }
4037
4038  out:
4039         kfree(phys_disk);
4040         if (phy_info)
4041                 return phy_info;
4042
4043         /*
4044          * Extra code to handle RAID0 case, where the sas_address is not updated
4045          * in phys_disk_page_1 when hotswapped
4046          */
4047         mutex_lock(&ioc->sas_topology_mutex);
4048         list_for_each_entry(port_info, &ioc->sas_topology, list) {
4049                 for (i = 0; i < port_info->num_phys && !phy_info; i++) {
4050                         if (!mptsas_is_end_device(
4051                                 &port_info->phy_info[i].attached))
4052                                 continue;
4053                         if (port_info->phy_info[i].attached.phys_disk_num == ~0)
4054                                 continue;
4055                         if ((port_info->phy_info[i].attached.phys_disk_num ==
4056                             phys_disk_num) &&
4057                             (port_info->phy_info[i].attached.id == id) &&
4058                             (port_info->phy_info[i].attached.channel ==
4059                              channel))
4060                                 phy_info = &port_info->phy_info[i];
4061                 }
4062         }
4063         mutex_unlock(&ioc->sas_topology_mutex);
4064         return phy_info;
4065 }
4066
4067 static void
4068 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
4069 {
4070         int rc;
4071
4072         sdev->no_uld_attach = data ? 1 : 0;
4073         rc = scsi_device_reprobe(sdev);
4074 }
4075
4076 static void
4077 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
4078 {
4079         starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
4080                         mptsas_reprobe_lun);
4081 }
4082
4083 static void
4084 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
4085 {
4086         CONFIGPARMS                     cfg;
4087         ConfigPageHeader_t              hdr;
4088         dma_addr_t                      dma_handle;
4089         pRaidVolumePage0_t              buffer = NULL;
4090         RaidPhysDiskPage0_t             phys_disk;
4091         int                             i;
4092         struct mptsas_phyinfo   *phy_info;
4093         struct mptsas_devinfo           sas_device;
4094
4095         memset(&cfg, 0 , sizeof(CONFIGPARMS));
4096         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4097         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
4098         cfg.pageAddr = (channel << 8) + id;
4099         cfg.cfghdr.hdr = &hdr;
4100         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4101
4102         if (mpt_config(ioc, &cfg) != 0)
4103                 goto out;
4104
4105         if (!hdr.PageLength)
4106                 goto out;
4107
4108         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4109             &dma_handle);
4110
4111         if (!buffer)
4112                 goto out;
4113
4114         cfg.physAddr = dma_handle;
4115         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4116
4117         if (mpt_config(ioc, &cfg) != 0)
4118                 goto out;
4119
4120         if (!(buffer->VolumeStatus.Flags &
4121             MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
4122                 goto out;
4123
4124         if (!buffer->NumPhysDisks)
4125                 goto out;
4126
4127         for (i = 0; i < buffer->NumPhysDisks; i++) {
4128
4129                 if (mpt_raid_phys_disk_pg0(ioc,
4130                     buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
4131                         continue;
4132
4133                 if (mptsas_sas_device_pg0(ioc, &sas_device,
4134                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4135                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4136                         (phys_disk.PhysDiskBus << 8) +
4137                         phys_disk.PhysDiskID))
4138                         continue;
4139
4140                 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4141                     sas_device.sas_address);
4142                 mptsas_add_end_device(ioc, phy_info);
4143         }
4144
4145  out:
4146         if (buffer)
4147                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4148                     dma_handle);
4149 }
4150 /*
4151  * Work queue thread to handle SAS hotplug events
4152  */
4153 static void
4154 mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
4155     struct mptsas_hotplug_event *hot_plug_info)
4156 {
4157         struct mptsas_phyinfo *phy_info;
4158         struct scsi_target * starget;
4159         struct mptsas_devinfo sas_device;
4160         VirtTarget *vtarget;
4161         int i;
4162
4163         switch (hot_plug_info->event_type) {
4164
4165         case MPTSAS_ADD_PHYSDISK:
4166
4167                 if (!ioc->raid_data.pIocPg2)
4168                         break;
4169
4170                 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
4171                         if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID ==
4172                             hot_plug_info->id) {
4173                                 printk(MYIOC_s_WARN_FMT "firmware bug: unable "
4174                                     "to add hidden disk - target_id matchs "
4175                                     "volume_id\n", ioc->name);
4176                                 mptsas_free_fw_event(ioc, fw_event);
4177                                 return;
4178                         }
4179                 }
4180                 mpt_findImVolumes(ioc);
4181
4182         case MPTSAS_ADD_DEVICE:
4183                 memset(&sas_device, 0, sizeof(struct mptsas_devinfo));
4184                 mptsas_sas_device_pg0(ioc, &sas_device,
4185                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4186                     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4187                     (hot_plug_info->channel << 8) +
4188                     hot_plug_info->id);
4189
4190                 if (!sas_device.handle)
4191                         return;
4192
4193                 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
4194                 if (!phy_info)
4195                         break;
4196
4197                 if (mptsas_get_rphy(phy_info))
4198                         break;
4199
4200                 mptsas_add_end_device(ioc, phy_info);
4201                 break;
4202
4203         case MPTSAS_DEL_DEVICE:
4204                 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4205                     hot_plug_info->sas_address);
4206                 mptsas_del_end_device(ioc, phy_info);
4207                 break;
4208
4209         case MPTSAS_DEL_PHYSDISK:
4210
4211                 mpt_findImVolumes(ioc);
4212
4213                 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
4214                                 ioc, hot_plug_info->phys_disk_num,
4215                                 hot_plug_info->channel,
4216                                 hot_plug_info->id);
4217                 mptsas_del_end_device(ioc, phy_info);
4218                 break;
4219
4220         case MPTSAS_ADD_PHYSDISK_REPROBE:
4221
4222                 if (mptsas_sas_device_pg0(ioc, &sas_device,
4223                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4224                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4225                     (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4226                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4227                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
4228                                  __func__, hot_plug_info->id, __LINE__));
4229                         break;
4230                 }
4231
4232                 phy_info = mptsas_find_phyinfo_by_sas_address(
4233                     ioc, sas_device.sas_address);
4234
4235                 if (!phy_info) {
4236                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4237                                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4238                                  __func__, hot_plug_info->id, __LINE__));
4239                         break;
4240                 }
4241
4242                 starget = mptsas_get_starget(phy_info);
4243                 if (!starget) {
4244                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4245                                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4246                                  __func__, hot_plug_info->id, __LINE__));
4247                         break;
4248                 }
4249
4250                 vtarget = starget->hostdata;
4251                 if (!vtarget) {
4252                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4253                                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4254                                  __func__, hot_plug_info->id, __LINE__));
4255                         break;
4256                 }
4257
4258                 mpt_findImVolumes(ioc);
4259
4260                 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Hidding: "
4261                     "fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4262                     ioc->name, hot_plug_info->channel, hot_plug_info->id,
4263                     hot_plug_info->phys_disk_num, (unsigned long long)
4264                     sas_device.sas_address);
4265
4266                 vtarget->id = hot_plug_info->phys_disk_num;
4267                 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
4268                 phy_info->attached.phys_disk_num = hot_plug_info->phys_disk_num;
4269                 mptsas_reprobe_target(starget, 1);
4270                 break;
4271
4272         case MPTSAS_DEL_PHYSDISK_REPROBE:
4273
4274                 if (mptsas_sas_device_pg0(ioc, &sas_device,
4275                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4276                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4277                         (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4278                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4279                                     "%s: fw_id=%d exit at line=%d\n",
4280                                     ioc->name, __func__,
4281                                     hot_plug_info->id, __LINE__));
4282                         break;
4283                 }
4284
4285                 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4286                                 sas_device.sas_address);
4287                 if (!phy_info) {
4288                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4289                             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4290                          __func__, hot_plug_info->id, __LINE__));
4291                         break;
4292                 }
4293
4294                 starget = mptsas_get_starget(phy_info);
4295                 if (!starget) {
4296                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4297                             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4298                          __func__, hot_plug_info->id, __LINE__));
4299                         break;
4300                 }
4301
4302                 vtarget = starget->hostdata;
4303                 if (!vtarget) {
4304                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4305                             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4306                          __func__, hot_plug_info->id, __LINE__));
4307                         break;
4308                 }
4309
4310                 if (!(vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)) {
4311                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4312                             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4313                          __func__, hot_plug_info->id, __LINE__));
4314                         break;
4315                 }
4316
4317                 mpt_findImVolumes(ioc);
4318
4319                 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Exposing:"
4320                     " fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4321                     ioc->name, hot_plug_info->channel, hot_plug_info->id,
4322                     hot_plug_info->phys_disk_num, (unsigned long long)
4323                     sas_device.sas_address);
4324
4325                 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
4326                 vtarget->id = hot_plug_info->id;
4327                 phy_info->attached.phys_disk_num = ~0;
4328                 mptsas_reprobe_target(starget, 0);
4329                 mptsas_add_device_component_by_fw(ioc,
4330                     hot_plug_info->channel, hot_plug_info->id);
4331                 break;
4332
4333         case MPTSAS_ADD_RAID:
4334
4335                 mpt_findImVolumes(ioc);
4336                 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4337                     "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4338                     hot_plug_info->id);
4339                 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4340                     hot_plug_info->id, 0);
4341                 break;
4342
4343         case MPTSAS_DEL_RAID:
4344
4345                 mpt_findImVolumes(ioc);
4346                 printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4347                     "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4348                     hot_plug_info->id);
4349                 scsi_remove_device(hot_plug_info->sdev);
4350                 scsi_device_put(hot_plug_info->sdev);
4351                 break;
4352
4353         case MPTSAS_ADD_INACTIVE_VOLUME:
4354
4355                 mpt_findImVolumes(ioc);
4356                 mptsas_adding_inactive_raid_components(ioc,
4357                     hot_plug_info->channel, hot_plug_info->id);
4358                 break;
4359
4360         default:
4361                 break;
4362         }
4363
4364         mptsas_free_fw_event(ioc, fw_event);
4365 }
4366
4367 static void
4368 mptsas_send_sas_event(struct fw_event_work *fw_event)
4369 {
4370         MPT_ADAPTER *ioc;
4371         struct mptsas_hotplug_event hot_plug_info;
4372         EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
4373         u32 device_info;
4374         u64 sas_address;
4375
4376         ioc = fw_event->ioc;
4377         sas_event_data = (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
4378             fw_event->event_data;
4379         device_info = le32_to_cpu(sas_event_data->DeviceInfo);
4380
4381         if ((device_info &
4382                 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
4383                 MPI_SAS_DEVICE_INFO_STP_TARGET |
4384                 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0) {
4385                 mptsas_free_fw_event(ioc, fw_event);
4386                 return;
4387         }
4388
4389         if (sas_event_data->ReasonCode ==
4390                 MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED) {
4391                 mptbase_sas_persist_operation(ioc,
4392                 MPI_SAS_OP_CLEAR_NOT_PRESENT);
4393                 mptsas_free_fw_event(ioc, fw_event);
4394                 return;
4395         }
4396
4397         switch (sas_event_data->ReasonCode) {
4398         case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
4399         case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
4400                 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4401                 hot_plug_info.handle = le16_to_cpu(sas_event_data->DevHandle);
4402                 hot_plug_info.channel = sas_event_data->Bus;
4403                 hot_plug_info.id = sas_event_data->TargetID;
4404                 hot_plug_info.phy_id = sas_event_data->PhyNum;
4405                 memcpy(&sas_address, &sas_event_data->SASAddress,
4406                     sizeof(u64));
4407                 hot_plug_info.sas_address = le64_to_cpu(sas_address);
4408                 hot_plug_info.device_info = device_info;
4409                 if (sas_event_data->ReasonCode &
4410                     MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
4411                         hot_plug_info.event_type = MPTSAS_ADD_DEVICE;
4412                 else
4413                         hot_plug_info.event_type = MPTSAS_DEL_DEVICE;
4414                 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4415                 break;
4416
4417         case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
4418                 mptbase_sas_persist_operation(ioc,
4419                     MPI_SAS_OP_CLEAR_NOT_PRESENT);
4420                 mptsas_free_fw_event(ioc, fw_event);
4421                 break;
4422
4423         case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
4424         /* TODO */
4425         case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
4426         /* TODO */
4427         default:
4428                 mptsas_free_fw_event(ioc, fw_event);
4429                 break;
4430         }
4431 }
4432
4433 static void
4434 mptsas_send_raid_event(struct fw_event_work *fw_event)
4435 {
4436         MPT_ADAPTER *ioc;
4437         EVENT_DATA_RAID *raid_event_data;
4438         struct mptsas_hotplug_event hot_plug_info;
4439         int status;
4440         int state;
4441         struct scsi_device *sdev = NULL;
4442         VirtDevice *vdevice = NULL;
4443         RaidPhysDiskPage0_t phys_disk;
4444
4445         ioc = fw_event->ioc;
4446         raid_event_data = (EVENT_DATA_RAID *)fw_event->event_data;
4447         status = le32_to_cpu(raid_event_data->SettingsStatus);
4448         state = (status >> 8) & 0xff;
4449
4450         memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4451         hot_plug_info.id = raid_event_data->VolumeID;
4452         hot_plug_info.channel = raid_event_data->VolumeBus;
4453         hot_plug_info.phys_disk_num = raid_event_data->PhysDiskNum;
4454
4455         if (raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_DELETED ||
4456             raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_CREATED ||
4457             raid_event_data->ReasonCode ==
4458             MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED) {
4459                 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
4460                     hot_plug_info.id, 0);
4461                 hot_plug_info.sdev = sdev;
4462                 if (sdev)
4463                         vdevice = sdev->hostdata;
4464         }
4465
4466         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4467             "ReasonCode=%02x\n", ioc->name, __func__,
4468             raid_event_data->ReasonCode));
4469
4470         switch (raid_event_data->ReasonCode) {
4471         case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4472                 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK_REPROBE;
4473                 break;
4474         case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4475                 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK_REPROBE;
4476                 break;
4477         case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4478                 switch (state) {
4479                 case MPI_PD_STATE_ONLINE:
4480                 case MPI_PD_STATE_NOT_COMPATIBLE:
4481                         mpt_raid_phys_disk_pg0(ioc,
4482                             raid_event_data->PhysDiskNum, &phys_disk);
4483                         hot_plug_info.id = phys_disk.PhysDiskID;
4484                         hot_plug_info.channel = phys_disk.PhysDiskBus;
4485                         hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4486                         break;
4487                 case MPI_PD_STATE_FAILED:
4488                 case MPI_PD_STATE_MISSING:
4489                 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
4490                 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
4491                 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
4492                         hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4493                         break;
4494                 default:
4495                         break;
4496                 }
4497                 break;
4498         case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4499                 if (!sdev)
4500                         break;
4501                 vdevice->vtarget->deleted = 1; /* block IO */
4502                 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4503                 break;
4504         case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4505                 if (sdev) {
4506                         scsi_device_put(sdev);
4507                         break;
4508                 }
4509                 hot_plug_info.event_type = MPTSAS_ADD_RAID;
4510                 break;
4511         case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4512                 if (!(status & MPI_RAIDVOL0_STATUS_FLAG_ENABLED)) {
4513                         if (!sdev)
4514                                 break;
4515                         vdevice->vtarget->deleted = 1; /* block IO */
4516                         hot_plug_info.event_type = MPTSAS_DEL_RAID;
4517                         break;
4518                 }
4519                 switch (state) {
4520                 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
4521                 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
4522                         if (!sdev)
4523                                 break;
4524                         vdevice->vtarget->deleted = 1; /* block IO */
4525                         hot_plug_info.event_type = MPTSAS_DEL_RAID;
4526                         break;
4527                 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
4528                 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
4529                         if (sdev) {
4530                                 scsi_device_put(sdev);
4531                                 break;
4532                         }
4533                         hot_plug_info.event_type = MPTSAS_ADD_RAID;
4534                         break;
4535                 default:
4536                         break;
4537                 }
4538                 break;
4539         default:
4540                 break;
4541         }
4542
4543         if (hot_plug_info.event_type != MPTSAS_IGNORE_EVENT)
4544                 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4545         else
4546                 mptsas_free_fw_event(ioc, fw_event);
4547 }
4548
4549 /**
4550  *      mptsas_issue_tm - send mptsas internal tm request
4551  *      @ioc: Pointer to MPT_ADAPTER structure
4552  *      @type: Task Management type
4553  *      @channel: channel number for task management
4554  *      @id: Logical Target ID for reset (if appropriate)
4555  *      @lun: Logical unit for reset (if appropriate)
4556  *      @task_context: Context for the task to be aborted
4557  *      @timeout: timeout for task management control
4558  *
4559  *      return 0 on success and -1 on failure:
4560  *
4561  */
4562 static int
4563 mptsas_issue_tm(MPT_ADAPTER *ioc, u8 type, u8 channel, u8 id, u64 lun,
4564         int task_context, ulong timeout, u8 *issue_reset)
4565 {
4566         MPT_FRAME_HDR   *mf;
4567         SCSITaskMgmt_t  *pScsiTm;
4568         int              retval;
4569         unsigned long    timeleft;
4570
4571         *issue_reset = 0;
4572         mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
4573         if (mf == NULL) {
4574                 retval = -1; /* return failure */
4575                 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "TaskMgmt request: no "
4576                     "msg frames!!\n", ioc->name));
4577                 goto out;
4578         }
4579
4580         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request: mr = %p, "
4581             "task_type = 0x%02X,\n\t timeout = %ld, fw_channel = %d, "
4582             "fw_id = %d, lun = %lld,\n\t task_context = 0x%x\n", ioc->name, mf,
4583              type, timeout, channel, id, (unsigned long long)lun,
4584              task_context));
4585
4586         pScsiTm = (SCSITaskMgmt_t *) mf;
4587         memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
4588         pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
4589         pScsiTm->TaskType = type;
4590         pScsiTm->MsgFlags = 0;
4591         pScsiTm->TargetID = id;
4592         pScsiTm->Bus = channel;
4593         pScsiTm->ChainOffset = 0;
4594         pScsiTm->Reserved = 0;
4595         pScsiTm->Reserved1 = 0;
4596         pScsiTm->TaskMsgContext = task_context;
4597         int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
4598
4599         INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4600         CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
4601         retval = 0;
4602         mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
4603
4604         /* Now wait for the command to complete */
4605         timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
4606             timeout*HZ);
4607         if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
4608                 retval = -1; /* return failure */
4609                 dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
4610                     "TaskMgmt request: TIMED OUT!(mr=%p)\n", ioc->name, mf));
4611                 mpt_free_msg_frame(ioc, mf);
4612                 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
4613                         goto out;
4614                 *issue_reset = 1;
4615                 goto out;
4616         }
4617
4618         if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
4619                 retval = -1; /* return failure */
4620                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4621                     "TaskMgmt request: failed with no reply\n", ioc->name));
4622                 goto out;
4623         }
4624
4625  out:
4626         CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4627         return retval;
4628 }
4629
4630 /**
4631  *      mptsas_broadcast_primative_work - Handle broadcast primitives
4632  *      @work: work queue payload containing info describing the event
4633  *
4634  *      this will be handled in workqueue context.
4635  */
4636 static void
4637 mptsas_broadcast_primative_work(struct fw_event_work *fw_event)
4638 {
4639         MPT_ADAPTER *ioc = fw_event->ioc;
4640         MPT_FRAME_HDR   *mf;
4641         VirtDevice      *vdevice;
4642         int                     ii;
4643         struct scsi_cmnd        *sc;
4644         SCSITaskMgmtReply_t     *pScsiTmReply;
4645         u8                      issue_reset;
4646         int                     task_context;
4647         u8                      channel, id;
4648         int                      lun;
4649         u32                      termination_count;
4650         u32                      query_count;
4651
4652         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4653             "%s - enter\n", ioc->name, __func__));
4654
4655         mutex_lock(&ioc->taskmgmt_cmds.mutex);
4656         if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
4657                 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4658                 mptsas_requeue_fw_event(ioc, fw_event, 1000);
4659                 return;
4660         }
4661
4662         issue_reset = 0;
4663         termination_count = 0;
4664         query_count = 0;
4665         mpt_findImVolumes(ioc);
4666         pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
4667
4668         for (ii = 0; ii < ioc->req_depth; ii++) {
4669                 if (ioc->fw_events_off)
4670                         goto out;
4671                 sc = mptscsih_get_scsi_lookup(ioc, ii);
4672                 if (!sc)
4673                         continue;
4674                 mf = MPT_INDEX_2_MFPTR(ioc, ii);
4675                 if (!mf)
4676                         continue;
4677                 task_context = mf->u.frame.hwhdr.msgctxu.MsgContext;
4678                 vdevice = sc->device->hostdata;
4679                 if (!vdevice || !vdevice->vtarget)
4680                         continue;
4681                 if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
4682                         continue; /* skip hidden raid components */
4683                 if (vdevice->vtarget->raidVolume)
4684                         continue; /* skip hidden raid components */
4685                 channel = vdevice->vtarget->channel;
4686                 id = vdevice->vtarget->id;
4687                 lun = vdevice->lun;
4688                 if (mptsas_issue_tm(ioc, MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK,
4689                     channel, id, (u64)lun, task_context, 30, &issue_reset))
4690                         goto out;
4691                 query_count++;
4692                 termination_count +=
4693                     le32_to_cpu(pScsiTmReply->TerminationCount);
4694                 if ((pScsiTmReply->IOCStatus == MPI_IOCSTATUS_SUCCESS) &&
4695                     (pScsiTmReply->ResponseCode ==
4696                     MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
4697                     pScsiTmReply->ResponseCode ==
4698                     MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
4699                         continue;
4700                 if (mptsas_issue_tm(ioc,
4701                     MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET,
4702                     channel, id, (u64)lun, 0, 30, &issue_reset))
4703                         goto out;
4704                 termination_count +=
4705                     le32_to_cpu(pScsiTmReply->TerminationCount);
4706         }
4707
4708  out:
4709         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4710             "%s - exit, query_count = %d termination_count = %d\n",
4711             ioc->name, __func__, query_count, termination_count));
4712
4713         ioc->broadcast_aen_busy = 0;
4714         mpt_clear_taskmgmt_in_progress_flag(ioc);
4715         mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4716
4717         if (issue_reset) {
4718                 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
4719                     ioc->name, __func__);
4720                 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
4721         }
4722         mptsas_free_fw_event(ioc, fw_event);
4723 }
4724
4725 /*
4726  * mptsas_send_ir2_event - handle exposing hidden disk when
4727  * an inactive raid volume is added
4728  *
4729  * @ioc: Pointer to MPT_ADAPTER structure
4730  * @ir2_data
4731  *
4732  */
4733 static void
4734 mptsas_send_ir2_event(struct fw_event_work *fw_event)
4735 {
4736         MPT_ADAPTER     *ioc;
4737         struct mptsas_hotplug_event hot_plug_info;
4738         MPI_EVENT_DATA_IR2      *ir2_data;
4739         u8 reasonCode;
4740         RaidPhysDiskPage0_t phys_disk;
4741
4742         ioc = fw_event->ioc;
4743         ir2_data = (MPI_EVENT_DATA_IR2 *)fw_event->event_data;
4744         reasonCode = ir2_data->ReasonCode;
4745
4746         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4747             "ReasonCode=%02x\n", ioc->name, __func__, reasonCode));
4748
4749         memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4750         hot_plug_info.id = ir2_data->TargetID;
4751         hot_plug_info.channel = ir2_data->Bus;
4752         switch (reasonCode) {
4753         case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
4754                 hot_plug_info.event_type = MPTSAS_ADD_INACTIVE_VOLUME;
4755                 break;
4756         case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
4757                 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4758                 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4759                 break;
4760         case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
4761                 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4762                 mpt_raid_phys_disk_pg0(ioc,
4763                     ir2_data->PhysDiskNum, &phys_disk);
4764                 hot_plug_info.id = phys_disk.PhysDiskID;
4765                 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4766                 break;
4767         default:
4768                 mptsas_free_fw_event(ioc, fw_event);
4769                 return;
4770         }
4771         mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4772 }
4773
4774 static int
4775 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
4776 {
4777         u32 event = le32_to_cpu(reply->Event);
4778         int sz, event_data_sz;
4779         struct fw_event_work *fw_event;
4780         unsigned long delay;
4781
4782         /* events turned off due to host reset or driver unloading */
4783         if (ioc->fw_events_off)
4784                 return 0;
4785
4786         delay = msecs_to_jiffies(1);
4787         switch (event) {
4788         case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
4789         {
4790                 EVENT_DATA_SAS_BROADCAST_PRIMITIVE *broadcast_event_data =
4791                     (EVENT_DATA_SAS_BROADCAST_PRIMITIVE *)reply->Data;
4792                 if (broadcast_event_data->Primitive !=
4793                     MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
4794                         return 0;
4795                 if (ioc->broadcast_aen_busy)
4796                         return 0;
4797                 ioc->broadcast_aen_busy = 1;
4798                 break;
4799         }
4800         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
4801         {
4802                 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data =
4803                     (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data;
4804
4805                 if (sas_event_data->ReasonCode ==
4806                     MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) {
4807                         mptsas_target_reset_queue(ioc, sas_event_data);
4808                         return 0;
4809                 }
4810                 break;
4811         }
4812         case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
4813         {
4814                 MpiEventDataSasExpanderStatusChange_t *expander_data =
4815                     (MpiEventDataSasExpanderStatusChange_t *)reply->Data;
4816
4817                 if (ioc->old_sas_discovery_protocal)
4818                         return 0;
4819
4820                 if (expander_data->ReasonCode ==
4821                     MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING &&
4822                     ioc->device_missing_delay)
4823                         delay = HZ * ioc->device_missing_delay;
4824                 break;
4825         }
4826         case MPI_EVENT_SAS_DISCOVERY:
4827         {
4828                 u32 discovery_status;
4829                 EventDataSasDiscovery_t *discovery_data =
4830                     (EventDataSasDiscovery_t *)reply->Data;
4831
4832                 discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus);
4833                 ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0;
4834                 if (ioc->old_sas_discovery_protocal && !discovery_status)
4835                         mptsas_queue_rescan(ioc);
4836                 return 0;
4837         }
4838         case MPI_EVENT_INTEGRATED_RAID:
4839         case MPI_EVENT_PERSISTENT_TABLE_FULL:
4840         case MPI_EVENT_IR2:
4841         case MPI_EVENT_SAS_PHY_LINK_STATUS:
4842         case MPI_EVENT_QUEUE_FULL:
4843                 break;
4844         default:
4845                 return 0;
4846         }
4847
4848         event_data_sz = ((reply->MsgLength * 4) -
4849             offsetof(EventNotificationReply_t, Data));
4850         sz = offsetof(struct fw_event_work, event_data) + event_data_sz;
4851         fw_event = kzalloc(sz, GFP_ATOMIC);
4852         if (!fw_event) {
4853                 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name,
4854                  __func__, __LINE__);
4855                 return 0;
4856         }
4857         memcpy(fw_event->event_data, reply->Data, event_data_sz);
4858         fw_event->event = event;
4859         fw_event->ioc = ioc;
4860         mptsas_add_fw_event(ioc, fw_event, delay);
4861         return 0;
4862 }
4863
4864 /* Delete a volume when no longer listed in ioc pg2
4865  */
4866 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id)
4867 {
4868         struct scsi_device *sdev;
4869         int i;
4870
4871         sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, id, 0);
4872         if (!sdev)
4873                 return;
4874         if (!ioc->raid_data.pIocPg2)
4875                 goto out;
4876         if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
4877                 goto out;
4878         for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
4879                 if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id)
4880                         goto release_sdev;
4881  out:
4882         printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4883             "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL, id);
4884         scsi_remove_device(sdev);
4885  release_sdev:
4886         scsi_device_put(sdev);
4887 }
4888
4889 static int
4890 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
4891 {
4892         struct Scsi_Host        *sh;
4893         MPT_SCSI_HOST           *hd;
4894         MPT_ADAPTER             *ioc;
4895         unsigned long            flags;
4896         int                      ii;
4897         int                      numSGE = 0;
4898         int                      scale;
4899         int                      ioc_cap;
4900         int                     error=0;
4901         int                     r;
4902
4903         r = mpt_attach(pdev,id);
4904         if (r)
4905                 return r;
4906
4907         ioc = pci_get_drvdata(pdev);
4908         mptsas_fw_event_off(ioc);
4909         ioc->DoneCtx = mptsasDoneCtx;
4910         ioc->TaskCtx = mptsasTaskCtx;
4911         ioc->InternalCtx = mptsasInternalCtx;
4912
4913         /*  Added sanity check on readiness of the MPT adapter.
4914          */
4915         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
4916                 printk(MYIOC_s_WARN_FMT
4917                   "Skipping because it's not operational!\n",
4918                   ioc->name);
4919                 error = -ENODEV;
4920                 goto out_mptsas_probe;
4921         }
4922
4923         if (!ioc->active) {
4924                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
4925                   ioc->name);
4926                 error = -ENODEV;
4927                 goto out_mptsas_probe;
4928         }
4929
4930         /*  Sanity check - ensure at least 1 port is INITIATOR capable
4931          */
4932         ioc_cap = 0;
4933         for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
4934                 if (ioc->pfacts[ii].ProtocolFlags &
4935                                 MPI_PORTFACTS_PROTOCOL_INITIATOR)
4936                         ioc_cap++;
4937         }
4938
4939         if (!ioc_cap) {
4940                 printk(MYIOC_s_WARN_FMT
4941                         "Skipping ioc=%p because SCSI Initiator mode "
4942                         "is NOT enabled!\n", ioc->name, ioc);
4943                 return 0;
4944         }
4945
4946         sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
4947         if (!sh) {
4948                 printk(MYIOC_s_WARN_FMT
4949                         "Unable to register controller with SCSI subsystem\n",
4950                         ioc->name);
4951                 error = -1;
4952                 goto out_mptsas_probe;
4953         }
4954
4955         spin_lock_irqsave(&ioc->FreeQlock, flags);
4956
4957         /* Attach the SCSI Host to the IOC structure
4958          */
4959         ioc->sh = sh;
4960
4961         sh->io_port = 0;
4962         sh->n_io_port = 0;
4963         sh->irq = 0;
4964
4965         /* set 16 byte cdb's */
4966         sh->max_cmd_len = 16;
4967         sh->can_queue = min_t(int, ioc->req_depth - 10, sh->can_queue);
4968         sh->max_id = -1;
4969         sh->max_lun = max_lun;
4970         sh->transportt = mptsas_transport_template;
4971
4972         /* Required entry.
4973          */
4974         sh->unique_id = ioc->id;
4975
4976         INIT_LIST_HEAD(&ioc->sas_topology);
4977         mutex_init(&ioc->sas_topology_mutex);
4978         mutex_init(&ioc->sas_discovery_mutex);
4979         mutex_init(&ioc->sas_mgmt.mutex);
4980         init_completion(&ioc->sas_mgmt.done);
4981
4982         /* Verify that we won't exceed the maximum
4983          * number of chain buffers
4984          * We can optimize:  ZZ = req_sz/sizeof(SGE)
4985          * For 32bit SGE's:
4986          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
4987          *               + (req_sz - 64)/sizeof(SGE)
4988          * A slightly different algorithm is required for
4989          * 64bit SGEs.
4990          */
4991         scale = ioc->req_sz/ioc->SGE_size;
4992         if (ioc->sg_addr_size == sizeof(u64)) {
4993                 numSGE = (scale - 1) *
4994                   (ioc->facts.MaxChainDepth-1) + scale +
4995                   (ioc->req_sz - 60) / ioc->SGE_size;
4996         } else {
4997                 numSGE = 1 + (scale - 1) *
4998                   (ioc->facts.MaxChainDepth-1) + scale +
4999                   (ioc->req_sz - 64) / ioc->SGE_size;
5000         }
5001
5002         if (numSGE < sh->sg_tablesize) {
5003                 /* Reset this value */
5004                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5005                   "Resetting sg_tablesize to %d from %d\n",
5006                   ioc->name, numSGE, sh->sg_tablesize));
5007                 sh->sg_tablesize = numSGE;
5008         }
5009
5010         hd = shost_priv(sh);
5011         hd->ioc = ioc;
5012
5013         /* SCSI needs scsi_cmnd lookup table!
5014          * (with size equal to req_depth*PtrSz!)
5015          */
5016         ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
5017         if (!ioc->ScsiLookup) {
5018                 error = -ENOMEM;
5019                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5020                 goto out_mptsas_probe;
5021         }
5022         spin_lock_init(&ioc->scsi_lookup_lock);
5023
5024         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
5025                  ioc->name, ioc->ScsiLookup));
5026
5027         ioc->sas_data.ptClear = mpt_pt_clear;
5028
5029         hd->last_queue_full = 0;
5030         INIT_LIST_HEAD(&hd->target_reset_list);
5031         INIT_LIST_HEAD(&ioc->sas_device_info_list);
5032         mutex_init(&ioc->sas_device_info_mutex);
5033
5034         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5035
5036         if (ioc->sas_data.ptClear==1) {
5037                 mptbase_sas_persist_operation(
5038                     ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
5039         }
5040
5041         error = scsi_add_host(sh, &ioc->pcidev->dev);
5042         if (error) {
5043                 dprintk(ioc, printk(MYIOC_s_ERR_FMT
5044                   "scsi_add_host failed\n", ioc->name));
5045                 goto out_mptsas_probe;
5046         }
5047
5048         /* older firmware doesn't support expander events */
5049         if ((ioc->facts.HeaderVersion >> 8) < 0xE)
5050                 ioc->old_sas_discovery_protocal = 1;
5051         mptsas_scan_sas_topology(ioc);
5052         mptsas_fw_event_on(ioc);
5053         return 0;
5054
5055  out_mptsas_probe:
5056
5057         mptscsih_remove(pdev);
5058         return error;
5059 }
5060
5061 void
5062 mptsas_shutdown(struct pci_dev *pdev)
5063 {
5064         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
5065
5066         mptsas_fw_event_off(ioc);
5067         mptsas_cleanup_fw_event_q(ioc);
5068 }
5069
5070 static void __devexit mptsas_remove(struct pci_dev *pdev)
5071 {
5072         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
5073         struct mptsas_portinfo *p, *n;
5074         int i;
5075
5076         mptsas_shutdown(pdev);
5077
5078         mptsas_del_device_components(ioc);
5079
5080         ioc->sas_discovery_ignore_events = 1;
5081         sas_remove_host(ioc->sh);
5082
5083         mutex_lock(&ioc->sas_topology_mutex);
5084         list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
5085                 list_del(&p->list);
5086                 for (i = 0 ; i < p->num_phys ; i++)
5087                         mptsas_port_delete(ioc, p->phy_info[i].port_details);
5088
5089                 kfree(p->phy_info);
5090                 kfree(p);
5091         }
5092         mutex_unlock(&ioc->sas_topology_mutex);
5093         ioc->hba_port_info = NULL;
5094         mptscsih_remove(pdev);
5095 }
5096
5097 static struct pci_device_id mptsas_pci_table[] = {
5098         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
5099                 PCI_ANY_ID, PCI_ANY_ID },
5100         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
5101                 PCI_ANY_ID, PCI_ANY_ID },
5102         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
5103                 PCI_ANY_ID, PCI_ANY_ID },
5104         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
5105                 PCI_ANY_ID, PCI_ANY_ID },
5106         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
5107                 PCI_ANY_ID, PCI_ANY_ID },
5108         {0}     /* Terminating entry */
5109 };
5110 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
5111
5112
5113 static struct pci_driver mptsas_driver = {
5114         .name           = "mptsas",
5115         .id_table       = mptsas_pci_table,
5116         .probe          = mptsas_probe,
5117         .remove         = __devexit_p(mptsas_remove),
5118         .shutdown       = mptsas_shutdown,
5119 #ifdef CONFIG_PM
5120         .suspend        = mptscsih_suspend,
5121         .resume         = mptscsih_resume,
5122 #endif
5123 };
5124
5125 static int __init
5126 mptsas_init(void)
5127 {
5128         int error;
5129
5130         show_mptmod_ver(my_NAME, my_VERSION);
5131
5132         mptsas_transport_template =
5133             sas_attach_transport(&mptsas_transport_functions);
5134         if (!mptsas_transport_template)
5135                 return -ENODEV;
5136
5137         mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
5138         mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
5139         mptsasInternalCtx =
5140                 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
5141         mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
5142         mptsasDeviceResetCtx =
5143                 mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
5144
5145         mpt_event_register(mptsasDoneCtx, mptsas_event_process);
5146         mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
5147
5148         error = pci_register_driver(&mptsas_driver);
5149         if (error)
5150                 sas_release_transport(mptsas_transport_template);
5151
5152         return error;
5153 }
5154
5155 static void __exit
5156 mptsas_exit(void)
5157 {
5158         pci_unregister_driver(&mptsas_driver);
5159         sas_release_transport(mptsas_transport_template);
5160
5161         mpt_reset_deregister(mptsasDoneCtx);
5162         mpt_event_deregister(mptsasDoneCtx);
5163
5164         mpt_deregister(mptsasMgmtCtx);
5165         mpt_deregister(mptsasInternalCtx);
5166         mpt_deregister(mptsasTaskCtx);
5167         mpt_deregister(mptsasDoneCtx);
5168         mpt_deregister(mptsasDeviceResetCtx);
5169 }
5170
5171 module_init(mptsas_init);
5172 module_exit(mptsas_exit);