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