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