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