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