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