Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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 MODULE_AUTHOR(MODULEAUTHOR);
 76 MODULE_DESCRIPTION(my_NAME);
 77 MODULE_LICENSE("GPL");
 78 MODULE_VERSION(my_VERSION);
 79 
 80 static int mpt_pt_clear;
 81 module_param(mpt_pt_clear, int, 0);
 82 MODULE_PARM_DESC(mpt_pt_clear,
 83                 " Clear persistency table: enable=1  "
 84                 "(default=MPTSCSIH_PT_CLEAR=0)");
 85 
 86 /* scsi-mid layer global parmeter is max_report_luns, which is 511 */
 87 #define MPTSAS_MAX_LUN (16895)
 88 static int max_lun = MPTSAS_MAX_LUN;
 89 module_param(max_lun, int, 0);
 90 MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
 91 
 92 static u8       mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
 93 static u8       mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
 94 static u8       mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */
 95 static u8       mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS;
 96 static u8       mptsasDeviceResetCtx = MPT_MAX_PROTOCOL_DRIVERS;
 97 
 98 static void mptsas_firmware_event_work(struct work_struct *work);
 99 static void mptsas_send_sas_event(struct fw_event_work *fw_event);
100 static void mptsas_send_raid_event(struct fw_event_work *fw_event);
101 static void mptsas_send_ir2_event(struct fw_event_work *fw_event);
102 static void mptsas_parse_device_info(struct sas_identify *identify,
103                 struct mptsas_devinfo *device_info);
104 static inline void mptsas_set_rphy(MPT_ADAPTER *ioc,
105                 struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy);
106 static struct mptsas_phyinfo    *mptsas_find_phyinfo_by_sas_address
107                 (MPT_ADAPTER *ioc, u64 sas_address);
108 static int mptsas_sas_device_pg0(MPT_ADAPTER *ioc,
109         struct mptsas_devinfo *device_info, u32 form, u32 form_specific);
110 static int mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc,
111         struct mptsas_enclosure *enclosure, u32 form, u32 form_specific);
112 static int mptsas_add_end_device(MPT_ADAPTER *ioc,
113         struct mptsas_phyinfo *phy_info);
114 static void mptsas_del_end_device(MPT_ADAPTER *ioc,
115         struct mptsas_phyinfo *phy_info);
116 static void mptsas_send_link_status_event(struct fw_event_work *fw_event);
117 static struct mptsas_portinfo   *mptsas_find_portinfo_by_sas_address
118                 (MPT_ADAPTER *ioc, u64 sas_address);
119 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
120                 struct mptsas_portinfo *port_info, u8 force);
121 static void mptsas_send_expander_event(struct fw_event_work *fw_event);
122 static void mptsas_not_responding_devices(MPT_ADAPTER *ioc);
123 static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
124 static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event);
125 static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
126 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
127 
128 static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
129                                         MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
130 {
131         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
132             "---- IO UNIT PAGE 0 ------------\n", ioc->name));
133         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
134             ioc->name, le16_to_cpu(phy_data->AttachedDeviceHandle)));
135         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Controller Handle=0x%X\n",
136             ioc->name, le16_to_cpu(phy_data->ControllerDevHandle)));
137         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port=0x%X\n",
138             ioc->name, phy_data->Port));
139         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port Flags=0x%X\n",
140             ioc->name, phy_data->PortFlags));
141         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Flags=0x%X\n",
142             ioc->name, phy_data->PhyFlags));
143         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
144             ioc->name, phy_data->NegotiatedLinkRate));
145         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
146             "Controller PHY Device Info=0x%X\n", ioc->name,
147             le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
148         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DiscoveryStatus=0x%X\n\n",
149             ioc->name, le32_to_cpu(phy_data->DiscoveryStatus)));
150 }
151 
152 static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
153 {
154         __le64 sas_address;
155 
156         memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
157 
158         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
159             "---- SAS PHY PAGE 0 ------------\n", ioc->name));
160         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
161             "Attached Device Handle=0x%X\n", ioc->name,
162             le16_to_cpu(pg0->AttachedDevHandle)));
163         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
164             ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
165         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
166             "Attached PHY Identifier=0x%X\n", ioc->name,
167             pg0->AttachedPhyIdentifier));
168         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Attached Device Info=0x%X\n",
169             ioc->name, le32_to_cpu(pg0->AttachedDeviceInfo)));
170         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
171             ioc->name,  pg0->ProgrammedLinkRate));
172         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Change Count=0x%X\n",
173             ioc->name, pg0->ChangeCount));
174         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Info=0x%X\n\n",
175             ioc->name, le32_to_cpu(pg0->PhyInfo)));
176 }
177 
178 static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
179 {
180         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
181             "---- SAS PHY PAGE 1 ------------\n", ioc->name));
182         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Invalid Dword Count=0x%x\n",
183             ioc->name,  pg1->InvalidDwordCount));
184         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
185             "Running Disparity Error Count=0x%x\n", ioc->name,
186             pg1->RunningDisparityErrorCount));
187         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
188             "Loss Dword Synch Count=0x%x\n", ioc->name,
189             pg1->LossDwordSynchCount));
190         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
191             "PHY Reset Problem Count=0x%x\n\n", ioc->name,
192             pg1->PhyResetProblemCount));
193 }
194 
195 static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
196 {
197         __le64 sas_address;
198 
199         memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
200 
201         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
202             "---- SAS DEVICE PAGE 0 ---------\n", ioc->name));
203         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
204             ioc->name, le16_to_cpu(pg0->DevHandle)));
205         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Handle=0x%X\n",
206             ioc->name, le16_to_cpu(pg0->ParentDevHandle)));
207         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Enclosure Handle=0x%X\n",
208             ioc->name, le16_to_cpu(pg0->EnclosureHandle)));
209         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Slot=0x%X\n",
210             ioc->name, le16_to_cpu(pg0->Slot)));
211         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
212             ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
213         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Target ID=0x%X\n",
214             ioc->name, pg0->TargetID));
215         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Bus=0x%X\n",
216             ioc->name, pg0->Bus));
217         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Phy Num=0x%X\n",
218             ioc->name, pg0->PhyNum));
219         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Access Status=0x%X\n",
220             ioc->name, le16_to_cpu(pg0->AccessStatus)));
221         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Device Info=0x%X\n",
222             ioc->name, le32_to_cpu(pg0->DeviceInfo)));
223         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Flags=0x%X\n",
224             ioc->name, le16_to_cpu(pg0->Flags)));
225         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n\n",
226             ioc->name, pg0->PhysicalPort));
227 }
228 
229 static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
230 {
231         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
232             "---- SAS EXPANDER PAGE 1 ------------\n", ioc->name));
233         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n",
234             ioc->name, pg1->PhysicalPort));
235         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Identifier=0x%X\n",
236             ioc->name, pg1->PhyIdentifier));
237         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
238             ioc->name, pg1->NegotiatedLinkRate));
239         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
240             ioc->name, pg1->ProgrammedLinkRate));
241         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hardware Link Rate=0x%X\n",
242             ioc->name, pg1->HwLinkRate));
243         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Owner Device Handle=0x%X\n",
244             ioc->name, le16_to_cpu(pg1->OwnerDevHandle)));
245         dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
246             "Attached Device Handle=0x%X\n\n", ioc->name,
247             le16_to_cpu(pg1->AttachedDevHandle)));
248 }
249 
250 /* inhibit sas firmware event handling */
251 static void
252 mptsas_fw_event_off(MPT_ADAPTER *ioc)
253 {
254         unsigned long flags;
255 
256         spin_lock_irqsave(&ioc->fw_event_lock, flags);
257         ioc->fw_events_off = 1;
258         ioc->sas_discovery_quiesce_io = 0;
259         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
260 
261 }
262 
263 /* enable sas firmware event handling */
264 static void
265 mptsas_fw_event_on(MPT_ADAPTER *ioc)
266 {
267         unsigned long flags;
268 
269         spin_lock_irqsave(&ioc->fw_event_lock, flags);
270         ioc->fw_events_off = 0;
271         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
272 }
273 
274 /* queue a sas firmware event */
275 static void
276 mptsas_add_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
277     unsigned long delay)
278 {
279         unsigned long flags;
280 
281         spin_lock_irqsave(&ioc->fw_event_lock, flags);
282         list_add_tail(&fw_event->list, &ioc->fw_event_list);
283         INIT_DELAYED_WORK(&fw_event->work, mptsas_firmware_event_work);
284         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: add (fw_event=0x%p)\n",
285             ioc->name, __func__, fw_event));
286         queue_delayed_work(ioc->fw_event_q, &fw_event->work,
287             delay);
288         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
289 }
290 
291 /* requeue a sas firmware event */
292 static void
293 mptsas_requeue_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
294     unsigned long delay)
295 {
296         unsigned long flags;
297         spin_lock_irqsave(&ioc->fw_event_lock, flags);
298         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: reschedule task "
299             "(fw_event=0x%p)\n", ioc->name, __func__, fw_event));
300         fw_event->retries++;
301         queue_delayed_work(ioc->fw_event_q, &fw_event->work,
302             msecs_to_jiffies(delay));
303         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
304 }
305 
306 /* free memory assoicated to a sas firmware event */
307 static void
308 mptsas_free_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event)
309 {
310         unsigned long flags;
311 
312         spin_lock_irqsave(&ioc->fw_event_lock, flags);
313         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: kfree (fw_event=0x%p)\n",
314             ioc->name, __func__, fw_event));
315         list_del(&fw_event->list);
316         kfree(fw_event);
317         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
318 }
319 
320 /* walk the firmware event queue, and either stop or wait for
321  * outstanding events to complete */
322 static void
323 mptsas_cleanup_fw_event_q(MPT_ADAPTER *ioc)
324 {
325         struct fw_event_work *fw_event, *next;
326         struct mptsas_target_reset_event *target_reset_list, *n;
327         u8      flush_q;
328         MPT_SCSI_HOST   *hd = shost_priv(ioc->sh);
329 
330         /* flush the target_reset_list */
331         if (!list_empty(&hd->target_reset_list)) {
332                 list_for_each_entry_safe(target_reset_list, n,
333                     &hd->target_reset_list, list) {
334                         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
335                             "%s: removing target reset for id=%d\n",
336                             ioc->name, __func__,
337                            target_reset_list->sas_event_data.TargetID));
338                         list_del(&target_reset_list->list);
339                         kfree(target_reset_list);
340                 }
341         }
342 
343         if (list_empty(&ioc->fw_event_list) ||
344              !ioc->fw_event_q || in_interrupt())
345                 return;
346 
347         flush_q = 0;
348         list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) {
349                 if (cancel_delayed_work(&fw_event->work))
350                         mptsas_free_fw_event(ioc, fw_event);
351                 else
352                         flush_q = 1;
353         }
354         if (flush_q)
355                 flush_workqueue(ioc->fw_event_q);
356 }
357 
358 
359 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
360 {
361         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
362         return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
363 }
364 
365 static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
366 {
367         struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
368         return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
369 }
370 
371 /*
372  * mptsas_find_portinfo_by_handle
373  *
374  * This function should be called with the sas_topology_mutex already held
375  */
376 static struct mptsas_portinfo *
377 mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
378 {
379         struct mptsas_portinfo *port_info, *rc=NULL;
380         int i;
381 
382         list_for_each_entry(port_info, &ioc->sas_topology, list)
383                 for (i = 0; i < port_info->num_phys; i++)
384                         if (port_info->phy_info[i].identify.handle == handle) {
385                                 rc = port_info;
386                                 goto out;
387                         }
388  out:
389         return rc;
390 }
391 
392 /**
393  *      mptsas_find_portinfo_by_sas_address -
394  *      @ioc: Pointer to MPT_ADAPTER structure
395  *      @handle:
396  *
397  *      This function should be called with the sas_topology_mutex already held
398  *
399  **/
400 static struct mptsas_portinfo *
401 mptsas_find_portinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
402 {
403         struct mptsas_portinfo *port_info, *rc = NULL;
404         int i;
405 
406         if (sas_address >= ioc->hba_port_sas_addr &&
407             sas_address < (ioc->hba_port_sas_addr +
408             ioc->hba_port_num_phy))
409                 return ioc->hba_port_info;
410 
411         mutex_lock(&ioc->sas_topology_mutex);
412         list_for_each_entry(port_info, &ioc->sas_topology, list)
413                 for (i = 0; i < port_info->num_phys; i++)
414                         if (port_info->phy_info[i].identify.sas_address ==
415                             sas_address) {
416                                 rc = port_info;
417                                 goto out;
418                         }
419  out:
420         mutex_unlock(&ioc->sas_topology_mutex);
421         return rc;
422 }
423 
424 /*
425  * Returns true if there is a scsi end device
426  */
427 static inline int
428 mptsas_is_end_device(struct mptsas_devinfo * attached)
429 {
430         if ((attached->sas_address) &&
431             (attached->device_info &
432             MPI_SAS_DEVICE_INFO_END_DEVICE) &&
433             ((attached->device_info &
434             MPI_SAS_DEVICE_INFO_SSP_TARGET) |
435             (attached->device_info &
436             MPI_SAS_DEVICE_INFO_STP_TARGET) |
437             (attached->device_info &
438             MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
439                 return 1;
440         else
441                 return 0;
442 }
443 
444 /* no mutex */
445 static void
446 mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
447 {
448         struct mptsas_portinfo *port_info;
449         struct mptsas_phyinfo *phy_info;
450         u8      i;
451 
452         if (!port_details)
453                 return;
454 
455         port_info = port_details->port_info;
456         phy_info = port_info->phy_info;
457 
458         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d "
459             "bitmask=0x%016llX\n", ioc->name, __func__, port_details,
460             port_details->num_phys, (unsigned long long)
461             port_details->phy_bitmask));
462 
463         for (i = 0; i < port_info->num_phys; i++, phy_info++) {
464                 if(phy_info->port_details != port_details)
465                         continue;
466                 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
467                 mptsas_set_rphy(ioc, phy_info, NULL);
468                 phy_info->port_details = NULL;
469         }
470         kfree(port_details);
471 }
472 
473 static inline struct sas_rphy *
474 mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
475 {
476         if (phy_info->port_details)
477                 return phy_info->port_details->rphy;
478         else
479                 return NULL;
480 }
481 
482 static inline void
483 mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
484 {
485         if (phy_info->port_details) {
486                 phy_info->port_details->rphy = rphy;
487                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
488                     ioc->name, rphy));
489         }
490 
491         if (rphy) {
492                 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
493                     &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
494                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
495                     ioc->name, rphy, rphy->dev.release));
496         }
497 }
498 
499 static inline struct sas_port *
500 mptsas_get_port(struct mptsas_phyinfo *phy_info)
501 {
502         if (phy_info->port_details)
503                 return phy_info->port_details->port;
504         else
505                 return NULL;
506 }
507 
508 static inline void
509 mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_port *port)
510 {
511         if (phy_info->port_details)
512                 phy_info->port_details->port = port;
513 
514         if (port) {
515                 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
516                     &port->dev, MYIOC_s_FMT "add:", ioc->name));
517                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "port=%p release=%p\n",
518                     ioc->name, port, port->dev.release));
519         }
520 }
521 
522 static inline struct scsi_target *
523 mptsas_get_starget(struct mptsas_phyinfo *phy_info)
524 {
525         if (phy_info->port_details)
526                 return phy_info->port_details->starget;
527         else
528                 return NULL;
529 }
530 
531 static inline void
532 mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
533 starget)
534 {
535         if (phy_info->port_details)
536                 phy_info->port_details->starget = starget;
537 }
538 
539 /**
540  *      mptsas_add_device_component -
541  *      @ioc: Pointer to MPT_ADAPTER structure
542  *      @channel: fw mapped id's
543  *      @id:
544  *      @sas_address:
545  *      @device_info:
546  *
547  **/
548 static void
549 mptsas_add_device_component(MPT_ADAPTER *ioc, u8 channel, u8 id,
550         u64 sas_address, u32 device_info, u16 slot, u64 enclosure_logical_id)
551 {
552         struct mptsas_device_info       *sas_info, *next;
553         struct scsi_device      *sdev;
554         struct scsi_target      *starget;
555         struct sas_rphy *rphy;
556 
557         /*
558          * Delete all matching devices out of the list
559          */
560         mutex_lock(&ioc->sas_device_info_mutex);
561         list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
562             list) {
563                 if (!sas_info->is_logical_volume &&
564                     (sas_info->sas_address == sas_address ||
565                     (sas_info->fw.channel == channel &&
566                      sas_info->fw.id == id))) {
567                         list_del(&sas_info->list);
568                         kfree(sas_info);
569                 }
570         }
571 
572         sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
573         if (!sas_info)
574                 goto out;
575 
576         /*
577          * Set Firmware mapping
578          */
579         sas_info->fw.id = id;
580         sas_info->fw.channel = channel;
581 
582         sas_info->sas_address = sas_address;
583         sas_info->device_info = device_info;
584         sas_info->slot = slot;
585         sas_info->enclosure_logical_id = enclosure_logical_id;
586         INIT_LIST_HEAD(&sas_info->list);
587         list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
588 
589         /*
590          * Set OS mapping
591          */
592         shost_for_each_device(sdev, ioc->sh) {
593                 starget = scsi_target(sdev);
594                 rphy = dev_to_rphy(starget->dev.parent);
595                 if (rphy->identify.sas_address == sas_address) {
596                         sas_info->os.id = starget->id;
597                         sas_info->os.channel = starget->channel;
598                 }
599         }
600 
601  out:
602         mutex_unlock(&ioc->sas_device_info_mutex);
603         return;
604 }
605 
606 /**
607  *      mptsas_add_device_component_by_fw -
608  *      @ioc: Pointer to MPT_ADAPTER structure
609  *      @channel:  fw mapped id's
610  *      @id:
611  *
612  **/
613 static void
614 mptsas_add_device_component_by_fw(MPT_ADAPTER *ioc, u8 channel, u8 id)
615 {
616         struct mptsas_devinfo sas_device;
617         struct mptsas_enclosure enclosure_info;
618         int rc;
619 
620         rc = mptsas_sas_device_pg0(ioc, &sas_device,
621             (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
622              MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
623             (channel << 8) + id);
624         if (rc)
625                 return;
626 
627         memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
628         mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
629             (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
630              MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
631              sas_device.handle_enclosure);
632 
633         mptsas_add_device_component(ioc, sas_device.channel,
634             sas_device.id, sas_device.sas_address, sas_device.device_info,
635             sas_device.slot, enclosure_info.enclosure_logical_id);
636 }
637 
638 /**
639  *      mptsas_add_device_component_starget_ir - Handle Integrated RAID, adding each individual device to list
640  *      @ioc: Pointer to MPT_ADAPTER structure
641  *      @channel: fw mapped id's
642  *      @id:
643  *
644  **/
645 static void
646 mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc,
647                 struct scsi_target *starget)
648 {
649         CONFIGPARMS                     cfg;
650         ConfigPageHeader_t              hdr;
651         dma_addr_t                      dma_handle;
652         pRaidVolumePage0_t              buffer = NULL;
653         int                             i;
654         RaidPhysDiskPage0_t             phys_disk;
655         struct mptsas_device_info       *sas_info, *next;
656 
657         memset(&cfg, 0 , sizeof(CONFIGPARMS));
658         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
659         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
660         /* assumption that all volumes on channel = 0 */
661         cfg.pageAddr = starget->id;
662         cfg.cfghdr.hdr = &hdr;
663         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
664         cfg.timeout = 10;
665 
666         if (mpt_config(ioc, &cfg) != 0)
667                 goto out;
668 
669         if (!hdr.PageLength)
670                 goto out;
671 
672         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
673             &dma_handle);
674 
675         if (!buffer)
676                 goto out;
677 
678         cfg.physAddr = dma_handle;
679         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
680 
681         if (mpt_config(ioc, &cfg) != 0)
682                 goto out;
683 
684         if (!buffer->NumPhysDisks)
685                 goto out;
686 
687         /*
688          * Adding entry for hidden components
689          */
690         for (i = 0; i < buffer->NumPhysDisks; i++) {
691 
692                 if (mpt_raid_phys_disk_pg0(ioc,
693                     buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
694                         continue;
695 
696                 mptsas_add_device_component_by_fw(ioc, phys_disk.PhysDiskBus,
697                     phys_disk.PhysDiskID);
698 
699                 mutex_lock(&ioc->sas_device_info_mutex);
700                 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
701                     list) {
702                         if (!sas_info->is_logical_volume &&
703                             (sas_info->fw.channel == phys_disk.PhysDiskBus &&
704                             sas_info->fw.id == phys_disk.PhysDiskID)) {
705                                 sas_info->is_hidden_raid_component = 1;
706                                 sas_info->volume_id = starget->id;
707                         }
708                 }
709                 mutex_unlock(&ioc->sas_device_info_mutex);
710 
711         }
712 
713         /*
714          * Delete all matching devices out of the list
715          */
716         mutex_lock(&ioc->sas_device_info_mutex);
717         list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
718             list) {
719                 if (sas_info->is_logical_volume && sas_info->fw.id ==
720                     starget->id) {
721                         list_del(&sas_info->list);
722                         kfree(sas_info);
723                 }
724         }
725 
726         sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
727         if (sas_info) {
728                 sas_info->fw.id = starget->id;
729                 sas_info->os.id = starget->id;
730                 sas_info->os.channel = starget->channel;
731                 sas_info->is_logical_volume = 1;
732                 INIT_LIST_HEAD(&sas_info->list);
733                 list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
734         }
735         mutex_unlock(&ioc->sas_device_info_mutex);
736 
737  out:
738         if (buffer)
739                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
740                     dma_handle);
741 }
742 
743 /**
744  *      mptsas_add_device_component_starget -
745  *      @ioc: Pointer to MPT_ADAPTER structure
746  *      @starget:
747  *
748  **/
749 static void
750 mptsas_add_device_component_starget(MPT_ADAPTER *ioc,
751         struct scsi_target *starget)
752 {
753         VirtTarget      *vtarget;
754         struct sas_rphy *rphy;
755         struct mptsas_phyinfo   *phy_info = NULL;
756         struct mptsas_enclosure enclosure_info;
757 
758         rphy = dev_to_rphy(starget->dev.parent);
759         vtarget = starget->hostdata;
760         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
761                         rphy->identify.sas_address);
762         if (!phy_info)
763                 return;
764 
765         memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
766         mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
767                 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
768                 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
769                 phy_info->attached.handle_enclosure);
770 
771         mptsas_add_device_component(ioc, phy_info->attached.channel,
772                 phy_info->attached.id, phy_info->attached.sas_address,
773                 phy_info->attached.device_info,
774                 phy_info->attached.slot, enclosure_info.enclosure_logical_id);
775 }
776 
777 /**
778  *      mptsas_del_device_component_by_os - Once a device has been removed, we mark the entry in the list as being cached
779  *      @ioc: Pointer to MPT_ADAPTER structure
780  *      @channel: os mapped id's
781  *      @id:
782  *
783  **/
784 static void
785 mptsas_del_device_component_by_os(MPT_ADAPTER *ioc, u8 channel, u8 id)
786 {
787         struct mptsas_device_info       *sas_info, *next;
788 
789         /*
790          * Set is_cached flag
791          */
792         list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
793                 list) {
794                 if (sas_info->os.channel == channel && sas_info->os.id == id)
795                         sas_info->is_cached = 1;
796         }
797 }
798 
799 /**
800  *      mptsas_del_device_components - Cleaning the list
801  *      @ioc: Pointer to MPT_ADAPTER structure
802  *
803  **/
804 static void
805 mptsas_del_device_components(MPT_ADAPTER *ioc)
806 {
807         struct mptsas_device_info       *sas_info, *next;
808 
809         mutex_lock(&ioc->sas_device_info_mutex);
810         list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
811                 list) {
812                 list_del(&sas_info->list);
813                 kfree(sas_info);
814         }
815         mutex_unlock(&ioc->sas_device_info_mutex);
816 }
817 
818 
819 /*
820  * mptsas_setup_wide_ports
821  *
822  * Updates for new and existing narrow/wide port configuration
823  * in the sas_topology
824  */
825 static void
826 mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
827 {
828         struct mptsas_portinfo_details * port_details;
829         struct mptsas_phyinfo *phy_info, *phy_info_cmp;
830         u64     sas_address;
831         int     i, j;
832 
833         mutex_lock(&ioc->sas_topology_mutex);
834 
835         phy_info = port_info->phy_info;
836         for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
837                 if (phy_info->attached.handle)
838                         continue;
839                 port_details = phy_info->port_details;
840                 if (!port_details)
841                         continue;
842                 if (port_details->num_phys < 2)
843                         continue;
844                 /*
845                  * Removing a phy from a port, letting the last
846                  * phy be removed by firmware events.
847                  */
848                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
849                     "%s: [%p]: deleting phy = %d\n",
850                     ioc->name, __func__, port_details, i));
851                 port_details->num_phys--;
852                 port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
853                 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
854                 sas_port_delete_phy(port_details->port, phy_info->phy);
855                 phy_info->port_details = NULL;
856         }
857 
858         /*
859          * Populate and refresh the tree
860          */
861         phy_info = port_info->phy_info;
862         for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
863                 sas_address = phy_info->attached.sas_address;
864                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "phy_id=%d sas_address=0x%018llX\n",
865                     ioc->name, i, (unsigned long long)sas_address));
866                 if (!sas_address)
867                         continue;
868                 port_details = phy_info->port_details;
869                 /*
870                  * Forming a port
871                  */
872                 if (!port_details) {
873                         port_details = kzalloc(sizeof(struct
874                                 mptsas_portinfo_details), GFP_KERNEL);
875                         if (!port_details)
876                                 goto out;
877                         port_details->num_phys = 1;
878                         port_details->port_info = port_info;
879                         if (phy_info->phy_id < 64 )
880                                 port_details->phy_bitmask |=
881                                     (1 << phy_info->phy_id);
882                         phy_info->sas_port_add_phy=1;
883                         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tForming port\n\t\t"
884                             "phy_id=%d sas_address=0x%018llX\n",
885                             ioc->name, i, (unsigned long long)sas_address));
886                         phy_info->port_details = port_details;
887                 }
888 
889                 if (i == port_info->num_phys - 1)
890                         continue;
891                 phy_info_cmp = &port_info->phy_info[i + 1];
892                 for (j = i + 1 ; j < port_info->num_phys ; j++,
893                     phy_info_cmp++) {
894                         if (!phy_info_cmp->attached.sas_address)
895                                 continue;
896                         if (sas_address != phy_info_cmp->attached.sas_address)
897                                 continue;
898                         if (phy_info_cmp->port_details == port_details )
899                                 continue;
900                         dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
901                             "\t\tphy_id=%d sas_address=0x%018llX\n",
902                             ioc->name, j, (unsigned long long)
903                             phy_info_cmp->attached.sas_address));
904                         if (phy_info_cmp->port_details) {
905                                 port_details->rphy =
906                                     mptsas_get_rphy(phy_info_cmp);
907                                 port_details->port =
908                                     mptsas_get_port(phy_info_cmp);
909                                 port_details->starget =
910                                     mptsas_get_starget(phy_info_cmp);
911                                 port_details->num_phys =
912                                         phy_info_cmp->port_details->num_phys;
913                                 if (!phy_info_cmp->port_details->num_phys)
914                                         kfree(phy_info_cmp->port_details);
915                         } else
916                                 phy_info_cmp->sas_port_add_phy=1;
917                         /*
918                          * Adding a phy to a port
919                          */
920                         phy_info_cmp->port_details = port_details;
921                         if (phy_info_cmp->phy_id < 64 )
922                                 port_details->phy_bitmask |=
923                                 (1 << phy_info_cmp->phy_id);
924                         port_details->num_phys++;
925                 }
926         }
927 
928  out:
929 
930         for (i = 0; i < port_info->num_phys; i++) {
931                 port_details = port_info->phy_info[i].port_details;
932                 if (!port_details)
933                         continue;
934                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
935                     "%s: [%p]: phy_id=%02d num_phys=%02d "
936                     "bitmask=0x%016llX\n", ioc->name, __func__,
937                     port_details, i, port_details->num_phys,
938                     (unsigned long long)port_details->phy_bitmask));
939                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n",
940                     ioc->name, port_details->port, port_details->rphy));
941         }
942         dsaswideprintk(ioc, printk("\n"));
943         mutex_unlock(&ioc->sas_topology_mutex);
944 }
945 
946 /**
947  * csmisas_find_vtarget
948  *
949  * @ioc
950  * @volume_id
951  * @volume_bus
952  *
953  **/
954 static VirtTarget *
955 mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
956 {
957         struct scsi_device              *sdev;
958         VirtDevice                      *vdevice;
959         VirtTarget                      *vtarget = NULL;
960 
961         shost_for_each_device(sdev, ioc->sh) {
962                 vdevice = sdev->hostdata;
963                 if ((vdevice == NULL) ||
964                         (vdevice->vtarget == NULL))
965                         continue;
966                 if ((vdevice->vtarget->tflags &
967                     MPT_TARGET_FLAGS_RAID_COMPONENT ||
968                     vdevice->vtarget->raidVolume))
969                         continue;
970                 if (vdevice->vtarget->id == id &&
971                         vdevice->vtarget->channel == channel)
972                         vtarget = vdevice->vtarget;
973         }
974         return vtarget;
975 }
976 
977 static void
978 mptsas_queue_device_delete(MPT_ADAPTER *ioc,
979         MpiEventDataSasDeviceStatusChange_t *sas_event_data)
980 {
981         struct fw_event_work *fw_event;
982         int sz;
983 
984         sz = offsetof(struct fw_event_work, event_data) +
985             sizeof(MpiEventDataSasDeviceStatusChange_t);
986         fw_event = kzalloc(sz, GFP_ATOMIC);
987         if (!fw_event) {
988                 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
989                     ioc->name, __func__, __LINE__);
990                 return;
991         }
992         memcpy(fw_event->event_data, sas_event_data,
993             sizeof(MpiEventDataSasDeviceStatusChange_t));
994         fw_event->event = MPI_EVENT_SAS_DEVICE_STATUS_CHANGE;
995         fw_event->ioc = ioc;
996         mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
997 }
998 
999 static void
1000 mptsas_queue_rescan(MPT_ADAPTER *ioc)
1001 {
1002         struct fw_event_work *fw_event;
1003         int sz;
1004 
1005         sz = offsetof(struct fw_event_work, event_data);
1006         fw_event = kzalloc(sz, GFP_ATOMIC);
1007         if (!fw_event) {
1008                 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
1009                     ioc->name, __func__, __LINE__);
1010                 return;
1011         }
1012         fw_event->event = -1;
1013         fw_event->ioc = ioc;
1014         mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
1015 }
1016 
1017 
1018 /**
1019  * mptsas_target_reset
1020  *
1021  * Issues TARGET_RESET to end device using handshaking method
1022  *
1023  * @ioc
1024  * @channel
1025  * @id
1026  *
1027  * Returns (1) success
1028  *         (0) failure
1029  *
1030  **/
1031 static int
1032 mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
1033 {
1034         MPT_FRAME_HDR   *mf;
1035         SCSITaskMgmt_t  *pScsiTm;
1036         if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0)
1037                 return 0;
1038 
1039 
1040         mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
1041         if (mf == NULL) {
1042                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1043                         "%s, no msg frames @%d!!\n", ioc->name,
1044                         __func__, __LINE__));
1045                 goto out_fail;
1046         }
1047 
1048         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1049                 ioc->name, mf));
1050 
1051         /* Format the Request
1052          */
1053         pScsiTm = (SCSITaskMgmt_t *) mf;
1054         memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
1055         pScsiTm->TargetID = id;
1056         pScsiTm->Bus = channel;
1057         pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1058         pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
1059         pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
1060 
1061         DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
1062 
1063         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1064            "TaskMgmt type=%d (sas device delete) fw_channel = %d fw_id = %d)\n",
1065            ioc->name, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, channel, id));
1066 
1067         mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
1068 
1069         return 1;
1070 
1071  out_fail:
1072 
1073         mpt_clear_taskmgmt_in_progress_flag(ioc);
1074         return 0;
1075 }
1076 
1077 /**
1078  * mptsas_target_reset_queue
1079  *
1080  * Receive request for TARGET_RESET after recieving an firmware
1081  * event NOT_RESPONDING_EVENT, then put command in link list
1082  * and queue if task_queue already in use.
1083  *
1084  * @ioc
1085  * @sas_event_data
1086  *
1087  **/
1088 static void
1089 mptsas_target_reset_queue(MPT_ADAPTER *ioc,
1090     EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1091 {
1092         MPT_SCSI_HOST   *hd = shost_priv(ioc->sh);
1093         VirtTarget *vtarget = NULL;
1094         struct mptsas_target_reset_event *target_reset_list;
1095         u8              id, channel;
1096 
1097         id = sas_event_data->TargetID;
1098         channel = sas_event_data->Bus;
1099 
1100         if (!(vtarget = mptsas_find_vtarget(ioc, channel, id)))
1101                 return;
1102 
1103         vtarget->deleted = 1; /* block IO */
1104 
1105         target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event),
1106             GFP_ATOMIC);
1107         if (!target_reset_list) {
1108                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1109                         "%s, failed to allocate mem @%d..!!\n",
1110                         ioc->name, __func__, __LINE__));
1111                 return;
1112         }
1113 
1114         memcpy(&target_reset_list->sas_event_data, sas_event_data,
1115                 sizeof(*sas_event_data));
1116         list_add_tail(&target_reset_list->list, &hd->target_reset_list);
1117 
1118         target_reset_list->time_count = jiffies;
1119 
1120         if (mptsas_target_reset(ioc, channel, id)) {
1121                 target_reset_list->target_reset_issued = 1;
1122         }
1123 }
1124 
1125 /**
1126  *      mptsas_taskmgmt_complete - complete SAS task management function
1127  *      @ioc: Pointer to MPT_ADAPTER structure
1128  *
1129  *      Completion for TARGET_RESET after NOT_RESPONDING_EVENT, enable work
1130  *      queue to finish off removing device from upper layers. then send next
1131  *      TARGET_RESET in the queue.
1132  **/
1133 static int
1134 mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
1135 {
1136         MPT_SCSI_HOST   *hd = shost_priv(ioc->sh);
1137         struct list_head *head = &hd->target_reset_list;
1138         u8              id, channel;
1139         struct mptsas_target_reset_event        *target_reset_list;
1140         SCSITaskMgmtReply_t *pScsiTmReply;
1141 
1142         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt completed: "
1143             "(mf = %p, mr = %p)\n", ioc->name, mf, mr));
1144 
1145         pScsiTmReply = (SCSITaskMgmtReply_t *)mr;
1146         if (pScsiTmReply) {
1147                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1148                     "\tTaskMgmt completed: fw_channel = %d, fw_id = %d,\n"
1149                     "\ttask_type = 0x%02X, iocstatus = 0x%04X "
1150                     "loginfo = 0x%08X,\n\tresponse_code = 0x%02X, "
1151                     "term_cmnds = %d\n", ioc->name,
1152                     pScsiTmReply->Bus, pScsiTmReply->TargetID,
1153                     pScsiTmReply->TaskType,
1154                     le16_to_cpu(pScsiTmReply->IOCStatus),
1155                     le32_to_cpu(pScsiTmReply->IOCLogInfo),
1156                     pScsiTmReply->ResponseCode,
1157                     le32_to_cpu(pScsiTmReply->TerminationCount)));
1158 
1159                 if (pScsiTmReply->ResponseCode)
1160                         mptscsih_taskmgmt_response_code(ioc,
1161                         pScsiTmReply->ResponseCode);
1162         }
1163 
1164         if (pScsiTmReply && (pScsiTmReply->TaskType ==
1165             MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK || pScsiTmReply->TaskType ==
1166              MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET)) {
1167                 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
1168                 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
1169                 memcpy(ioc->taskmgmt_cmds.reply, mr,
1170                     min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
1171                 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
1172                         ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
1173                         complete(&ioc->taskmgmt_cmds.done);
1174                         return 1;
1175                 }
1176                 return 0;
1177         }
1178 
1179         mpt_clear_taskmgmt_in_progress_flag(ioc);
1180 
1181         if (list_empty(head))
1182                 return 1;
1183 
1184         target_reset_list = list_entry(head->next,
1185             struct mptsas_target_reset_event, list);
1186 
1187         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1188             "TaskMgmt: completed (%d seconds)\n",
1189             ioc->name, jiffies_to_msecs(jiffies -
1190             target_reset_list->time_count)/1000));
1191 
1192         id = pScsiTmReply->TargetID;
1193         channel = pScsiTmReply->Bus;
1194         target_reset_list->time_count = jiffies;
1195 
1196         /*
1197          * retry target reset
1198          */
1199         if (!target_reset_list->target_reset_issued) {
1200                 if (mptsas_target_reset(ioc, channel, id))
1201                         target_reset_list->target_reset_issued = 1;
1202                 return 1;
1203         }
1204 
1205         /*
1206          * enable work queue to remove device from upper layers
1207          */
1208         list_del(&target_reset_list->list);
1209         if ((mptsas_find_vtarget(ioc, channel, id)) && !ioc->fw_events_off)
1210                 mptsas_queue_device_delete(ioc,
1211                         &target_reset_list->sas_event_data);
1212 
1213 
1214         /*
1215          * issue target reset to next device in the queue
1216          */
1217 
1218         head = &hd->target_reset_list;
1219         if (list_empty(head))
1220                 return 1;
1221 
1222         target_reset_list = list_entry(head->next, struct mptsas_target_reset_event,
1223             list);
1224 
1225         id = target_reset_list->sas_event_data.TargetID;
1226         channel = target_reset_list->sas_event_data.Bus;
1227         target_reset_list->time_count = jiffies;
1228 
1229         if (mptsas_target_reset(ioc, channel, id))
1230                 target_reset_list->target_reset_issued = 1;
1231 
1232         return 1;
1233 }
1234 
1235 /**
1236  * mptscsih_ioc_reset
1237  *
1238  * @ioc
1239  * @reset_phase
1240  *
1241  **/
1242 static int
1243 mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1244 {
1245         MPT_SCSI_HOST   *hd;
1246         int rc;
1247 
1248         rc = mptscsih_ioc_reset(ioc, reset_phase);
1249         if ((ioc->bus_type != SAS) || (!rc))
1250                 return rc;
1251 
1252         hd = shost_priv(ioc->sh);
1253         if (!hd->ioc)
1254                 goto out;
1255 
1256         switch (reset_phase) {
1257         case MPT_IOC_SETUP_RESET:
1258                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1259                     "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
1260                 mptsas_fw_event_off(ioc);
1261                 break;
1262         case MPT_IOC_PRE_RESET:
1263                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1264                     "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
1265                 break;
1266         case MPT_IOC_POST_RESET:
1267                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1268                     "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
1269                 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
1270                         ioc->sas_mgmt.status |= MPT_MGMT_STATUS_DID_IOCRESET;
1271                         complete(&ioc->sas_mgmt.done);
1272                 }
1273                 mptsas_cleanup_fw_event_q(ioc);
1274                 mptsas_queue_rescan(ioc);
1275                 mptsas_fw_event_on(ioc);
1276                 break;
1277         default:
1278                 break;
1279         }
1280 
1281  out:
1282         return rc;
1283 }
1284 
1285 
1286 /**
1287  * enum device_state -
1288  * @DEVICE_RETRY: need to retry the TUR
1289  * @DEVICE_ERROR: TUR return error, don't add device
1290  * @DEVICE_READY: device can be added
1291  *
1292  */
1293 enum device_state{
1294         DEVICE_RETRY,
1295         DEVICE_ERROR,
1296         DEVICE_READY,
1297 };
1298 
1299 static int
1300 mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
1301                 u32 form, u32 form_specific)
1302 {
1303         ConfigExtendedPageHeader_t hdr;
1304         CONFIGPARMS cfg;
1305         SasEnclosurePage0_t *buffer;
1306         dma_addr_t dma_handle;
1307         int error;
1308         __le64 le_identifier;
1309 
1310         memset(&hdr, 0, sizeof(hdr));
1311         hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
1312         hdr.PageNumber = 0;
1313         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1314         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
1315 
1316         cfg.cfghdr.ehdr = &hdr;
1317         cfg.physAddr = -1;
1318         cfg.pageAddr = form + form_specific;
1319         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1320         cfg.dir = 0;    /* read */
1321         cfg.timeout = 10;
1322 
1323         error = mpt_config(ioc, &cfg);
1324         if (error)
1325                 goto out;
1326         if (!hdr.ExtPageLength) {
1327                 error = -ENXIO;
1328                 goto out;
1329         }
1330 
1331         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1332                         &dma_handle);
1333         if (!buffer) {
1334                 error = -ENOMEM;
1335                 goto out;
1336         }
1337 
1338         cfg.physAddr = dma_handle;
1339         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1340 
1341         error = mpt_config(ioc, &cfg);
1342         if (error)
1343                 goto out_free_consistent;
1344 
1345         /* save config data */
1346         memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
1347         enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
1348         enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
1349         enclosure->flags = le16_to_cpu(buffer->Flags);
1350         enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
1351         enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
1352         enclosure->start_id = buffer->StartTargetID;
1353         enclosure->start_channel = buffer->StartBus;
1354         enclosure->sep_id = buffer->SEPTargetID;
1355         enclosure->sep_channel = buffer->SEPBus;
1356 
1357  out_free_consistent:
1358         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1359                             buffer, dma_handle);
1360  out:
1361         return error;
1362 }
1363 
1364 /**
1365  *      mptsas_add_end_device - report a new end device to sas transport layer
1366  *      @ioc: Pointer to MPT_ADAPTER structure
1367  *      @phy_info: decribes attached device
1368  *
1369  *      return (0) success (1) failure
1370  *
1371  **/
1372 static int
1373 mptsas_add_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1374 {
1375         struct sas_rphy *rphy;
1376         struct sas_port *port;
1377         struct sas_identify identify;
1378         char *ds = NULL;
1379         u8 fw_id;
1380 
1381         if (!phy_info) {
1382                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1383                         "%s: exit at line=%d\n", ioc->name,
1384                          __func__, __LINE__));
1385                 return 1;
1386         }
1387 
1388         fw_id = phy_info->attached.id;
1389 
1390         if (mptsas_get_rphy(phy_info)) {
1391                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1392                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1393                          __func__, fw_id, __LINE__));
1394                 return 2;
1395         }
1396 
1397         port = mptsas_get_port(phy_info);
1398         if (!port) {
1399                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1400                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1401                          __func__, fw_id, __LINE__));
1402                 return 3;
1403         }
1404 
1405         if (phy_info->attached.device_info &
1406             MPI_SAS_DEVICE_INFO_SSP_TARGET)
1407                 ds = "ssp";
1408         if (phy_info->attached.device_info &
1409             MPI_SAS_DEVICE_INFO_STP_TARGET)
1410                 ds = "stp";
1411         if (phy_info->attached.device_info &
1412             MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1413                 ds = "sata";
1414 
1415         printk(MYIOC_s_INFO_FMT "attaching %s device: fw_channel %d, fw_id %d,"
1416             " phy %d, sas_addr 0x%llx\n", ioc->name, ds,
1417             phy_info->attached.channel, phy_info->attached.id,
1418             phy_info->attached.phy_id, (unsigned long long)
1419             phy_info->attached.sas_address);
1420 
1421         mptsas_parse_device_info(&identify, &phy_info->attached);
1422         rphy = sas_end_device_alloc(port);
1423         if (!rphy) {
1424                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1425                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1426                          __func__, fw_id, __LINE__));
1427                 return 5; /* non-fatal: an rphy can be added later */
1428         }
1429 
1430         rphy->identify = identify;
1431         if (sas_rphy_add(rphy)) {
1432                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1433                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1434                          __func__, fw_id, __LINE__));
1435                 sas_rphy_free(rphy);
1436                 return 6;
1437         }
1438         mptsas_set_rphy(ioc, phy_info, rphy);
1439         return 0;
1440 }
1441 
1442 /**
1443  *      mptsas_del_end_device - report a deleted end device to sas transport layer
1444  *      @ioc: Pointer to MPT_ADAPTER structure
1445  *      @phy_info: decribes attached device
1446  *
1447  **/
1448 static void
1449 mptsas_del_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1450 {
1451         struct sas_rphy *rphy;
1452         struct sas_port *port;
1453         struct mptsas_portinfo *port_info;
1454         struct mptsas_phyinfo *phy_info_parent;
1455         int i;
1456         char *ds = NULL;
1457         u8 fw_id;
1458         u64 sas_address;
1459 
1460         if (!phy_info)
1461                 return;
1462 
1463         fw_id = phy_info->attached.id;
1464         sas_address = phy_info->attached.sas_address;
1465 
1466         if (!phy_info->port_details) {
1467                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1468                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1469                          __func__, fw_id, __LINE__));
1470                 return;
1471         }
1472         rphy = mptsas_get_rphy(phy_info);
1473         if (!rphy) {
1474                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1475                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1476                          __func__, fw_id, __LINE__));
1477                 return;
1478         }
1479 
1480         if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_INITIATOR
1481                 || phy_info->attached.device_info
1482                         & MPI_SAS_DEVICE_INFO_SMP_INITIATOR
1483                 || phy_info->attached.device_info
1484                         & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1485                 ds = "initiator";
1486         if (phy_info->attached.device_info &
1487             MPI_SAS_DEVICE_INFO_SSP_TARGET)
1488                 ds = "ssp";
1489         if (phy_info->attached.device_info &
1490             MPI_SAS_DEVICE_INFO_STP_TARGET)
1491                 ds = "stp";
1492         if (phy_info->attached.device_info &
1493             MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1494                 ds = "sata";
1495 
1496         dev_printk(KERN_DEBUG, &rphy->dev, MYIOC_s_FMT
1497             "removing %s device: fw_channel %d, fw_id %d, phy %d,"
1498             "sas_addr 0x%llx\n", ioc->name, ds, phy_info->attached.channel,
1499             phy_info->attached.id, phy_info->attached.phy_id,
1500             (unsigned long long) sas_address);
1501 
1502         port = mptsas_get_port(phy_info);
1503         if (!port) {
1504                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1505                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
1506                          __func__, fw_id, __LINE__));
1507                 return;
1508         }
1509         port_info = phy_info->portinfo;
1510         phy_info_parent = port_info->phy_info;
1511         for (i = 0; i < port_info->num_phys; i++, phy_info_parent++) {
1512                 if (!phy_info_parent->phy)
1513                         continue;
1514                 if (phy_info_parent->attached.sas_address !=
1515                     sas_address)
1516                         continue;
1517                 dev_printk(KERN_DEBUG, &phy_info_parent->phy->dev,
1518                     MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n",
1519                     ioc->name, phy_info_parent->phy_id,
1520                     phy_info_parent->phy);
1521                 sas_port_delete_phy(port, phy_info_parent->phy);
1522         }
1523 
1524         dev_printk(KERN_DEBUG, &port->dev, MYIOC_s_FMT
1525             "delete port %d, sas_addr (0x%llx)\n", ioc->name,
1526              port->port_identifier, (unsigned long long)sas_address);
1527         sas_port_delete(port);
1528         mptsas_set_port(ioc, phy_info, NULL);
1529         mptsas_port_delete(ioc, phy_info->port_details);
1530 }
1531 
1532 struct mptsas_phyinfo *
1533 mptsas_refreshing_device_handles(MPT_ADAPTER *ioc,
1534         struct mptsas_devinfo *sas_device)
1535 {
1536         struct mptsas_phyinfo *phy_info;
1537         struct mptsas_portinfo *port_info;
1538         int i;
1539 
1540         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
1541             sas_device->sas_address);
1542         if (!phy_info)
1543                 goto out;
1544         port_info = phy_info->portinfo;
1545         if (!port_info)
1546                 goto out;
1547         mutex_lock(&ioc->sas_topology_mutex);
1548         for (i = 0; i < port_info->num_phys; i++) {
1549                 if (port_info->phy_info[i].attached.sas_address !=
1550                         sas_device->sas_address)
1551                         continue;
1552                 port_info->phy_info[i].attached.channel = sas_device->channel;
1553                 port_info->phy_info[i].attached.id = sas_device->id;
1554                 port_info->phy_info[i].attached.sas_address =
1555                     sas_device->sas_address;
1556                 port_info->phy_info[i].attached.handle = sas_device->handle;
1557                 port_info->phy_info[i].attached.handle_parent =
1558                     sas_device->handle_parent;
1559                 port_info->phy_info[i].attached.handle_enclosure =
1560                     sas_device->handle_enclosure;
1561         }
1562         mutex_unlock(&ioc->sas_topology_mutex);
1563  out:
1564         return phy_info;
1565 }
1566 
1567 /**
1568  * mptsas_firmware_event_work - work thread for processing fw events
1569  * @work: work queue payload containing info describing the event
1570  * Context: user
1571  *
1572  */
1573 static void
1574 mptsas_firmware_event_work(struct work_struct *work)
1575 {
1576         struct fw_event_work *fw_event =
1577                 container_of(work, struct fw_event_work, work.work);
1578         MPT_ADAPTER *ioc = fw_event->ioc;
1579 
1580         /* special rescan topology handling */
1581         if (fw_event->event == -1) {
1582                 if (ioc->in_rescan) {
1583                         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1584                                 "%s: rescan ignored as it is in progress\n",
1585                                 ioc->name, __func__));
1586                         return;
1587                 }
1588                 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: rescan after "
1589                     "reset\n", ioc->name, __func__));
1590                 ioc->in_rescan = 1;
1591                 mptsas_not_responding_devices(ioc);
1592                 mptsas_scan_sas_topology(ioc);
1593                 ioc->in_rescan = 0;
1594                 mptsas_free_fw_event(ioc, fw_event);
1595                 return;
1596         }
1597 
1598         /* events handling turned off during host reset */
1599         if (ioc->fw_events_off) {
1600                 mptsas_free_fw_event(ioc, fw_event);
1601                 return;
1602         }
1603 
1604         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: fw_event=(0x%p), "
1605             "event = (0x%02x)\n", ioc->name, __func__, fw_event,
1606             (fw_event->event & 0xFF)));
1607 
1608         switch (fw_event->event) {
1609         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1610                 mptsas_send_sas_event(fw_event);
1611                 break;
1612         case MPI_EVENT_INTEGRATED_RAID:
1613                 mptsas_send_raid_event(fw_event);
1614                 break;
1615         case MPI_EVENT_IR2:
1616                 mptsas_send_ir2_event(fw_event);
1617                 break;
1618         case MPI_EVENT_PERSISTENT_TABLE_FULL:
1619                 mptbase_sas_persist_operation(ioc,
1620                     MPI_SAS_OP_CLEAR_NOT_PRESENT);
1621                 mptsas_free_fw_event(ioc, fw_event);
1622                 break;
1623         case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
1624                 mptsas_broadcast_primative_work(fw_event);
1625                 break;
1626         case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
1627                 mptsas_send_expander_event(fw_event);
1628                 break;
1629         case MPI_EVENT_SAS_PHY_LINK_STATUS:
1630                 mptsas_send_link_status_event(fw_event);
1631                 break;
1632         case MPI_EVENT_QUEUE_FULL:
1633                 mptsas_handle_queue_full_event(fw_event);
1634                 break;
1635         }
1636 }
1637 
1638 
1639 
1640 static int
1641 mptsas_slave_configure(struct scsi_device *sdev)
1642 {
1643         struct Scsi_Host        *host = sdev->host;
1644         MPT_SCSI_HOST   *hd = shost_priv(host);
1645         MPT_ADAPTER     *ioc = hd->ioc;
1646         VirtDevice      *vdevice = sdev->hostdata;
1647 
1648         if (vdevice->vtarget->deleted) {
1649                 sdev_printk(KERN_INFO, sdev, "clearing deleted flag\n");
1650                 vdevice->vtarget->deleted = 0;
1651         }
1652 
1653         /*
1654          * RAID volumes placed beyond the last expected port.
1655          * Ignore sending sas mode pages in that case..
1656          */
1657         if (sdev->channel == MPTSAS_RAID_CHANNEL) {
1658                 mptsas_add_device_component_starget_ir(ioc, scsi_target(sdev));
1659                 goto out;
1660         }
1661 
1662         sas_read_port_mode_page(sdev);
1663 
1664         mptsas_add_device_component_starget(ioc, scsi_target(sdev));
1665 
1666  out:
1667         return mptscsih_slave_configure(sdev);
1668 }
1669 
1670 static int
1671 mptsas_target_alloc(struct scsi_target *starget)
1672 {
1673         struct Scsi_Host *host = dev_to_shost(&starget->dev);
1674         MPT_SCSI_HOST           *hd = shost_priv(host);
1675         VirtTarget              *vtarget;
1676         u8                      id, channel;
1677         struct sas_rphy         *rphy;
1678         struct mptsas_portinfo  *p;
1679         int                      i;
1680         MPT_ADAPTER             *ioc = hd->ioc;
1681 
1682         vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
1683         if (!vtarget)
1684                 return -ENOMEM;
1685 
1686         vtarget->starget = starget;
1687         vtarget->ioc_id = ioc->id;
1688         vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
1689         id = starget->id;
1690         channel = 0;
1691 
1692         /*
1693          * RAID volumes placed beyond the last expected port.
1694          */
1695         if (starget->channel == MPTSAS_RAID_CHANNEL) {
1696                 if (!ioc->raid_data.pIocPg2) {
1697                         kfree(vtarget);
1698                         return -ENXIO;
1699                 }
1700                 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
1701                         if (id == ioc->raid_data.pIocPg2->
1702                                         RaidVolume[i].VolumeID) {
1703                                 channel = ioc->raid_data.pIocPg2->
1704                                         RaidVolume[i].VolumeBus;
1705                         }
1706                 }
1707                 vtarget->raidVolume = 1;
1708                 goto out;
1709         }
1710 
1711         rphy = dev_to_rphy(starget->dev.parent);
1712         mutex_lock(&ioc->sas_topology_mutex);
1713         list_for_each_entry(p, &ioc->sas_topology, list) {
1714                 for (i = 0; i < p->num_phys; i++) {
1715                         if (p->phy_info[i].attached.sas_address !=
1716                                         rphy->identify.sas_address)
1717                                 continue;
1718                         id = p->phy_info[i].attached.id;
1719                         channel = p->phy_info[i].attached.channel;
1720                         mptsas_set_starget(&p->phy_info[i], starget);
1721 
1722                         /*
1723                          * Exposing hidden raid components
1724                          */
1725                         if (mptscsih_is_phys_disk(ioc, channel, id)) {
1726                                 id = mptscsih_raid_id_to_num(ioc,
1727                                                 channel, id);
1728                                 vtarget->tflags |=
1729                                     MPT_TARGET_FLAGS_RAID_COMPONENT;
1730                                 p->phy_info[i].attached.phys_disk_num = id;
1731                         }
1732                         mutex_unlock(&ioc->sas_topology_mutex);
1733                         goto out;
1734                 }
1735         }
1736         mutex_unlock(&ioc->sas_topology_mutex);
1737 
1738         kfree(vtarget);
1739         return -ENXIO;
1740 
1741  out:
1742         vtarget->id = id;
1743         vtarget->channel = channel;
1744         starget->hostdata = vtarget;
1745         return 0;
1746 }
1747 
1748 static void
1749 mptsas_target_destroy(struct scsi_target *starget)
1750 {
1751         struct Scsi_Host *host = dev_to_shost(&starget->dev);
1752         MPT_SCSI_HOST           *hd = shost_priv(host);
1753         struct sas_rphy         *rphy;
1754         struct mptsas_portinfo  *p;
1755         int                      i;
1756         MPT_ADAPTER     *ioc = hd->ioc;
1757         VirtTarget      *vtarget;
1758 
1759         if (!starget->hostdata)
1760                 return;
1761 
1762         vtarget = starget->hostdata;
1763 
1764         mptsas_del_device_component_by_os(ioc, starget->channel,
1765             starget->id);
1766 
1767 
1768         if (starget->channel == MPTSAS_RAID_CHANNEL)
1769                 goto out;
1770 
1771         rphy = dev_to_rphy(starget->dev.parent);
1772         list_for_each_entry(p, &ioc->sas_topology, list) {
1773                 for (i = 0; i < p->num_phys; i++) {
1774                         if (p->phy_info[i].attached.sas_address !=
1775                                         rphy->identify.sas_address)
1776                                 continue;
1777 
1778                         starget_printk(KERN_INFO, starget, MYIOC_s_FMT
1779                         "delete device: fw_channel %d, fw_id %d, phy %d, "
1780                         "sas_addr 0x%llx\n", ioc->name,
1781                         p->phy_info[i].attached.channel,
1782                         p->phy_info[i].attached.id,
1783                         p->phy_info[i].attached.phy_id, (unsigned long long)
1784                         p->phy_info[i].attached.sas_address);
1785 
1786                         mptsas_set_starget(&p->phy_info[i], NULL);
1787                 }
1788         }
1789 
1790  out:
1791         vtarget->starget = NULL;
1792         kfree(starget->hostdata);
1793         starget->hostdata = NULL;
1794 }
1795 
1796 
1797 static int
1798 mptsas_slave_alloc(struct scsi_device *sdev)
1799 {
1800         struct Scsi_Host        *host = sdev->host;
1801         MPT_SCSI_HOST           *hd = shost_priv(host);
1802         struct sas_rphy         *rphy;
1803         struct mptsas_portinfo  *p;
1804         VirtDevice              *vdevice;
1805         struct scsi_target      *starget;
1806         int                     i;
1807         MPT_ADAPTER *ioc = hd->ioc;
1808 
1809         vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
1810         if (!vdevice) {
1811                 printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
1812                                 ioc->name, sizeof(VirtDevice));
1813                 return -ENOMEM;
1814         }
1815         starget = scsi_target(sdev);
1816         vdevice->vtarget = starget->hostdata;
1817 
1818         if (sdev->channel == MPTSAS_RAID_CHANNEL)
1819                 goto out;
1820 
1821         rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
1822         mutex_lock(&ioc->sas_topology_mutex);
1823         list_for_each_entry(p, &ioc->sas_topology, list) {
1824                 for (i = 0; i < p->num_phys; i++) {
1825                         if (p->phy_info[i].attached.sas_address !=
1826                                         rphy->identify.sas_address)
1827                                 continue;
1828                         vdevice->lun = sdev->lun;
1829                         /*
1830                          * Exposing hidden raid components
1831                          */
1832                         if (mptscsih_is_phys_disk(ioc,
1833                             p->phy_info[i].attached.channel,
1834                             p->phy_info[i].attached.id))
1835                                 sdev->no_uld_attach = 1;
1836                         mutex_unlock(&ioc->sas_topology_mutex);
1837                         goto out;
1838                 }
1839         }
1840         mutex_unlock(&ioc->sas_topology_mutex);
1841 
1842         kfree(vdevice);
1843         return -ENXIO;
1844 
1845  out:
1846         vdevice->vtarget->num_luns++;
1847         sdev->hostdata = vdevice;
1848         return 0;
1849 }
1850 
1851 static int
1852 mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1853 {
1854         MPT_SCSI_HOST   *hd;
1855         MPT_ADAPTER     *ioc;
1856         VirtDevice      *vdevice = SCpnt->device->hostdata;
1857 
1858         if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
1859                 SCpnt->result = DID_NO_CONNECT << 16;
1860                 done(SCpnt);
1861                 return 0;
1862         }
1863 
1864         hd = shost_priv(SCpnt->device->host);
1865         ioc = hd->ioc;
1866 
1867         if (ioc->sas_discovery_quiesce_io)
1868                 return SCSI_MLQUEUE_HOST_BUSY;
1869 
1870 //      scsi_print_command(SCpnt);
1871 
1872         return mptscsih_qcmd(SCpnt,done);
1873 }
1874 
1875 
1876 static struct scsi_host_template mptsas_driver_template = {
1877         .module                         = THIS_MODULE,
1878         .proc_name                      = "mptsas",
1879         .proc_info                      = mptscsih_proc_info,
1880         .name                           = "MPT SPI Host",
1881         .info                           = mptscsih_info,
1882         .queuecommand                   = mptsas_qcmd,
1883         .target_alloc                   = mptsas_target_alloc,
1884         .slave_alloc                    = mptsas_slave_alloc,
1885         .slave_configure                = mptsas_slave_configure,
1886         .target_destroy                 = mptsas_target_destroy,
1887         .slave_destroy                  = mptscsih_slave_destroy,
1888         .change_queue_depth             = mptscsih_change_queue_depth,
1889         .eh_abort_handler               = mptscsih_abort,
1890         .eh_device_reset_handler        = mptscsih_dev_reset,
1891         .eh_bus_reset_handler           = mptscsih_bus_reset,
1892         .eh_host_reset_handler          = mptscsih_host_reset,
1893         .bios_param                     = mptscsih_bios_param,
1894         .can_queue                      = MPT_FC_CAN_QUEUE,
1895         .this_id                        = -1,
1896         .sg_tablesize                   = MPT_SCSI_SG_DEPTH,
1897         .max_sectors                    = 8192,
1898         .cmd_per_lun                    = 7,
1899         .use_clustering                 = ENABLE_CLUSTERING,
1900         .shost_attrs                    = mptscsih_host_attrs,
1901 };
1902 
1903 static int mptsas_get_linkerrors(struct sas_phy *phy)
1904 {
1905         MPT_ADAPTER *ioc = phy_to_ioc(phy);
1906         ConfigExtendedPageHeader_t hdr;
1907         CONFIGPARMS cfg;
1908         SasPhyPage1_t *buffer;
1909         dma_addr_t dma_handle;
1910         int error;
1911 
1912         /* FIXME: only have link errors on local phys */
1913         if (!scsi_is_sas_phy_local(phy))
1914                 return -EINVAL;
1915 
1916         hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
1917         hdr.ExtPageLength = 0;
1918         hdr.PageNumber = 1 /* page number 1*/;
1919         hdr.Reserved1 = 0;
1920         hdr.Reserved2 = 0;
1921         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1922         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1923 
1924         cfg.cfghdr.ehdr = &hdr;
1925         cfg.physAddr = -1;
1926         cfg.pageAddr = phy->identify.phy_identifier;
1927         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1928         cfg.dir = 0;    /* read */
1929         cfg.timeout = 10;
1930 
1931         error = mpt_config(ioc, &cfg);
1932         if (error)
1933                 return error;
1934         if (!hdr.ExtPageLength)
1935                 return -ENXIO;
1936 
1937         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1938                                       &dma_handle);
1939         if (!buffer)
1940                 return -ENOMEM;
1941 
1942         cfg.physAddr = dma_handle;
1943         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1944 
1945         error = mpt_config(ioc, &cfg);
1946         if (error)
1947                 goto out_free_consistent;
1948 
1949         mptsas_print_phy_pg1(ioc, buffer);
1950 
1951         phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
1952         phy->running_disparity_error_count =
1953                 le32_to_cpu(buffer->RunningDisparityErrorCount);
1954         phy->loss_of_dword_sync_count =
1955                 le32_to_cpu(buffer->LossDwordSynchCount);
1956         phy->phy_reset_problem_count =
1957                 le32_to_cpu(buffer->PhyResetProblemCount);
1958 
1959  out_free_consistent:
1960         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1961                             buffer, dma_handle);
1962         return error;
1963 }
1964 
1965 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
1966                 MPT_FRAME_HDR *reply)
1967 {
1968         ioc->sas_mgmt.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
1969         if (reply != NULL) {
1970                 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_RF_VALID;
1971                 memcpy(ioc->sas_mgmt.reply, reply,
1972                     min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
1973         }
1974 
1975         if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
1976                 ioc->sas_mgmt.status &= ~MPT_MGMT_STATUS_PENDING;
1977                 complete(&ioc->sas_mgmt.done);
1978                 return 1;
1979         }
1980         return 0;
1981 }
1982 
1983 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
1984 {
1985         MPT_ADAPTER *ioc = phy_to_ioc(phy);
1986         SasIoUnitControlRequest_t *req;
1987         SasIoUnitControlReply_t *reply;
1988         MPT_FRAME_HDR *mf;
1989         MPIHeader_t *hdr;
1990         unsigned long timeleft;
1991         int error = -ERESTARTSYS;
1992 
1993         /* FIXME: fusion doesn't allow non-local phy reset */
1994         if (!scsi_is_sas_phy_local(phy))
1995                 return -EINVAL;
1996 
1997         /* not implemented for expanders */
1998         if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
1999                 return -ENXIO;
2000 
2001         if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
2002                 goto out;
2003 
2004         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2005         if (!mf) {
2006                 error = -ENOMEM;
2007                 goto out_unlock;
2008         }
2009 
2010         hdr = (MPIHeader_t *) mf;
2011         req = (SasIoUnitControlRequest_t *)mf;
2012         memset(req, 0, sizeof(SasIoUnitControlRequest_t));
2013         req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
2014         req->MsgContext = hdr->MsgContext;
2015         req->Operation = hard_reset ?
2016                 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
2017         req->PhyNum = phy->identify.phy_identifier;
2018 
2019         INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2020         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2021 
2022         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
2023                         10 * HZ);
2024         if (!timeleft) {
2025                 /* On timeout reset the board */
2026                 mpt_free_msg_frame(ioc, mf);
2027                 mpt_HardResetHandler(ioc, CAN_SLEEP);
2028                 error = -ETIMEDOUT;
2029                 goto out_unlock;
2030         }
2031 
2032         /* a reply frame is expected */
2033         if ((ioc->sas_mgmt.status &
2034             MPT_MGMT_STATUS_RF_VALID) == 0) {
2035                 error = -ENXIO;
2036                 goto out_unlock;
2037         }
2038 
2039         /* process the completed Reply Message Frame */
2040         reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
2041         if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
2042                 printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
2043                     ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo);
2044                 error = -ENXIO;
2045                 goto out_unlock;
2046         }
2047 
2048         error = 0;
2049 
2050  out_unlock:
2051         CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2052         mutex_unlock(&ioc->sas_mgmt.mutex);
2053  out:
2054         return error;
2055 }
2056 
2057 static int
2058 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
2059 {
2060         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2061         int i, error;
2062         struct mptsas_portinfo *p;
2063         struct mptsas_enclosure enclosure_info;
2064         u64 enclosure_handle;
2065 
2066         mutex_lock(&ioc->sas_topology_mutex);
2067         list_for_each_entry(p, &ioc->sas_topology, list) {
2068                 for (i = 0; i < p->num_phys; i++) {
2069                         if (p->phy_info[i].attached.sas_address ==
2070                             rphy->identify.sas_address) {
2071                                 enclosure_handle = p->phy_info[i].
2072                                         attached.handle_enclosure;
2073                                 goto found_info;
2074                         }
2075                 }
2076         }
2077         mutex_unlock(&ioc->sas_topology_mutex);
2078         return -ENXIO;
2079 
2080  found_info:
2081         mutex_unlock(&ioc->sas_topology_mutex);
2082         memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
2083         error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
2084                         (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
2085                          MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
2086         if (!error)
2087                 *identifier = enclosure_info.enclosure_logical_id;
2088         return error;
2089 }
2090 
2091 static int
2092 mptsas_get_bay_identifier(struct sas_rphy *rphy)
2093 {
2094         MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2095         struct mptsas_portinfo *p;
2096         int i, rc;
2097 
2098         mutex_lock(&ioc->sas_topology_mutex);
2099         list_for_each_entry(p, &ioc->sas_topology, list) {
2100                 for (i = 0; i < p->num_phys; i++) {
2101                         if (p->phy_info[i].attached.sas_address ==
2102                             rphy->identify.sas_address) {
2103                                 rc = p->phy_info[i].attached.slot;
2104                                 goto out;
2105                         }
2106                 }
2107         }
2108         rc = -ENXIO;
2109  out:
2110         mutex_unlock(&ioc->sas_topology_mutex);
2111         return rc;
2112 }
2113 
2114 static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
2115                               struct request *req)
2116 {
2117         MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
2118         MPT_FRAME_HDR *mf;
2119         SmpPassthroughRequest_t *smpreq;
2120         struct request *rsp = req->next_rq;
2121         int ret;
2122         int flagsLength;
2123         unsigned long timeleft;
2124         char *psge;
2125         dma_addr_t dma_addr_in = 0;
2126         dma_addr_t dma_addr_out = 0;
2127         u64 sas_address = 0;
2128 
2129         if (!rsp) {
2130                 printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n",
2131                     ioc->name, __func__);
2132                 return -EINVAL;
2133         }
2134 
2135         /* do we need to support multiple segments? */
2136         if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
2137                 printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
2138                     ioc->name, __func__, req->bio->bi_vcnt, blk_rq_bytes(req),
2139                     rsp->bio->bi_vcnt, blk_rq_bytes(rsp));
2140                 return -EINVAL;
2141         }
2142 
2143         ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2144         if (ret)
2145                 goto out;
2146 
2147         mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2148         if (!mf) {
2149                 ret = -ENOMEM;
2150                 goto out_unlock;
2151         }
2152 
2153         smpreq = (SmpPassthroughRequest_t *)mf;
2154         memset(smpreq, 0, sizeof(*smpreq));
2155 
2156         smpreq->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
2157         smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2158 
2159         if (rphy)
2160                 sas_address = rphy->identify.sas_address;
2161         else {
2162                 struct mptsas_portinfo *port_info;
2163 
2164                 mutex_lock(&ioc->sas_topology_mutex);
2165                 port_info = ioc->hba_port_info;
2166                 if (port_info && port_info->phy_info)
2167                         sas_address =
2168                                 port_info->phy_info[0].phy->identify.sas_address;
2169                 mutex_unlock(&ioc->sas_topology_mutex);
2170         }
2171 
2172         *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2173 
2174         psge = (char *)
2175                 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2176 
2177         /* request */
2178         flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2179                        MPI_SGE_FLAGS_END_OF_BUFFER |
2180                        MPI_SGE_FLAGS_DIRECTION)
2181                        << MPI_SGE_FLAGS_SHIFT;
2182         flagsLength |= (blk_rq_bytes(req) - 4);
2183 
2184         dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
2185                                       blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
2186         if (!dma_addr_out)
2187                 goto put_mf;
2188         ioc->add_sge(psge, flagsLength, dma_addr_out);
2189         psge += ioc->SGE_size;
2190 
2191         /* response */
2192         flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2193                 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2194                 MPI_SGE_FLAGS_IOC_TO_HOST |
2195                 MPI_SGE_FLAGS_END_OF_BUFFER;
2196 
2197         flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2198         flagsLength |= blk_rq_bytes(rsp) + 4;
2199         dma_addr_in =  pci_map_single(ioc->pcidev, bio_data(rsp->bio),
2200                                       blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
2201         if (!dma_addr_in)
2202                 goto unmap;
2203         ioc->add_sge(psge, flagsLength, dma_addr_in);
2204 
2205         INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2206         mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2207 
2208         timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2209         if (!timeleft) {
2210                 printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __func__);
2211                 /* On timeout reset the board */
2212                 mpt_HardResetHandler(ioc, CAN_SLEEP);
2213                 ret = -ETIMEDOUT;
2214                 goto unmap;
2215         }
2216         mf = NULL;
2217 
2218         if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2219                 SmpPassthroughReply_t *smprep;
2220 
2221                 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2222                 memcpy(req->sense, smprep, sizeof(*smprep));
2223                 req->sense_len = sizeof(*smprep);
2224                 req->resid_len = 0;
2225                 rsp->resid_len -= smprep->ResponseDataLength;
2226         } else {
2227                 printk(MYIOC_s_ERR_FMT
2228                     "%s: smp passthru reply failed to be returned\n",
2229                     ioc->name, __func__);
2230                 ret = -ENXIO;
2231         }
2232 unmap:
2233         if (dma_addr_out)
2234                 pci_unmap_single(ioc->pcidev, dma_addr_out, blk_rq_bytes(req),
2235                                  PCI_DMA_BIDIRECTIONAL);
2236         if (dma_addr_in)
2237                 pci_unmap_single(ioc->pcidev, dma_addr_in, blk_rq_bytes(rsp),
2238                                  PCI_DMA_BIDIRECTIONAL);
2239 put_mf:
2240         if (mf)
2241                 mpt_free_msg_frame(ioc, mf);
2242 out_unlock:
2243         CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2244         mutex_unlock(&ioc->sas_mgmt.mutex);
2245 out:
2246         return ret;
2247 }
2248 
2249 static struct sas_function_template mptsas_transport_functions = {
2250         .get_linkerrors         = mptsas_get_linkerrors,
2251         .get_enclosure_identifier = mptsas_get_enclosure_identifier,
2252         .get_bay_identifier     = mptsas_get_bay_identifier,
2253         .phy_reset              = mptsas_phy_reset,
2254         .smp_handler            = mptsas_smp_handler,
2255 };
2256 
2257 static struct scsi_transport_template *mptsas_transport_template;
2258 
2259 static int
2260 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
2261 {
2262         ConfigExtendedPageHeader_t hdr;
2263         CONFIGPARMS cfg;
2264         SasIOUnitPage0_t *buffer;
2265         dma_addr_t dma_handle;
2266         int error, i;
2267 
2268         hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
2269         hdr.ExtPageLength = 0;
2270         hdr.PageNumber = 0;
2271         hdr.Reserved1 = 0;
2272         hdr.Reserved2 = 0;
2273         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2274         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2275 
2276         cfg.cfghdr.ehdr = &hdr;
2277         cfg.physAddr = -1;
2278         cfg.pageAddr = 0;
2279         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2280         cfg.dir = 0;    /* read */
2281         cfg.timeout = 10;
2282 
2283         error = mpt_config(ioc, &cfg);
2284         if (error)
2285                 goto out;
2286         if (!hdr.ExtPageLength) {
2287                 error = -ENXIO;
2288                 goto out;
2289         }
2290 
2291         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2292                                             &dma_handle);
2293         if (!buffer) {
2294                 error = -ENOMEM;
2295                 goto out;
2296         }
2297 
2298         cfg.physAddr = dma_handle;
2299         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2300 
2301         error = mpt_config(ioc, &cfg);
2302         if (error)
2303                 goto out_free_consistent;
2304 
2305         port_info->num_phys = buffer->NumPhys;
2306         port_info->phy_info = kcalloc(port_info->num_phys,
2307                 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2308         if (!port_info->phy_info) {
2309                 error = -ENOMEM;
2310                 goto out_free_consistent;
2311         }
2312 
2313         ioc->nvdata_version_persistent =
2314             le16_to_cpu(buffer->NvdataVersionPersistent);
2315         ioc->nvdata_version_default =
2316             le16_to_cpu(buffer->NvdataVersionDefault);
2317 
2318         for (i = 0; i < port_info->num_phys; i++) {
2319                 mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
2320                 port_info->phy_info[i].phy_id = i;
2321                 port_info->phy_info[i].port_id =
2322                     buffer->PhyData[i].Port;
2323                 port_info->phy_info[i].negotiated_link_rate =
2324                     buffer->PhyData[i].NegotiatedLinkRate;
2325                 port_info->phy_info[i].portinfo = port_info;
2326                 port_info->phy_info[i].handle =
2327                     le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
2328         }
2329 
2330  out_free_consistent:
2331         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2332                             buffer, dma_handle);
2333  out:
2334         return error;
2335 }
2336 
2337 static int
2338 mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
2339 {
2340         ConfigExtendedPageHeader_t hdr;
2341         CONFIGPARMS cfg;
2342         SasIOUnitPage1_t *buffer;
2343         dma_addr_t dma_handle;
2344         int error;
2345         u16 device_missing_delay;
2346 
2347         memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
2348         memset(&cfg, 0, sizeof(CONFIGPARMS));
2349 
2350         cfg.cfghdr.ehdr = &hdr;
2351         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2352         cfg.timeout = 10;
2353         cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2354         cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2355         cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
2356         cfg.cfghdr.ehdr->PageNumber = 1;
2357 
2358         error = mpt_config(ioc, &cfg);
2359         if (error)
2360                 goto out;
2361         if (!hdr.ExtPageLength) {
2362                 error = -ENXIO;
2363                 goto out;
2364         }
2365 
2366         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2367                                             &dma_handle);
2368         if (!buffer) {
2369                 error = -ENOMEM;
2370                 goto out;
2371         }
2372 
2373         cfg.physAddr = dma_handle;
2374         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2375 
2376         error = mpt_config(ioc, &cfg);
2377         if (error)
2378                 goto out_free_consistent;
2379 
2380         ioc->io_missing_delay  =
2381             le16_to_cpu(buffer->IODeviceMissingDelay);
2382         device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay);
2383         ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
2384             (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
2385             device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
2386 
2387  out_free_consistent:
2388         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2389                             buffer, dma_handle);
2390  out:
2391         return error;
2392 }
2393 
2394 static int
2395 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2396                 u32 form, u32 form_specific)
2397 {
2398         ConfigExtendedPageHeader_t hdr;
2399         CONFIGPARMS cfg;
2400         SasPhyPage0_t *buffer;
2401         dma_addr_t dma_handle;
2402         int error;
2403 
2404         hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
2405         hdr.ExtPageLength = 0;
2406         hdr.PageNumber = 0;
2407         hdr.Reserved1 = 0;
2408         hdr.Reserved2 = 0;
2409         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2410         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2411 
2412         cfg.cfghdr.ehdr = &hdr;
2413         cfg.dir = 0;    /* read */
2414         cfg.timeout = 10;
2415 
2416         /* Get Phy Pg 0 for each Phy. */
2417         cfg.physAddr = -1;
2418         cfg.pageAddr = form + form_specific;
2419         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2420 
2421         error = mpt_config(ioc, &cfg);
2422         if (error)
2423                 goto out;
2424 
2425         if (!hdr.ExtPageLength) {
2426                 error = -ENXIO;
2427                 goto out;
2428         }
2429 
2430         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2431                                       &dma_handle);
2432         if (!buffer) {
2433                 error = -ENOMEM;
2434                 goto out;
2435         }
2436 
2437         cfg.physAddr = dma_handle;
2438         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2439 
2440         error = mpt_config(ioc, &cfg);
2441         if (error)
2442                 goto out_free_consistent;
2443 
2444         mptsas_print_phy_pg0(ioc, buffer);
2445 
2446         phy_info->hw_link_rate = buffer->HwLinkRate;
2447         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2448         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2449         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2450 
2451  out_free_consistent:
2452         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2453                             buffer, dma_handle);
2454  out:
2455         return error;
2456 }
2457 
2458 static int
2459 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
2460                 u32 form, u32 form_specific)
2461 {
2462         ConfigExtendedPageHeader_t hdr;
2463         CONFIGPARMS cfg;
2464         SasDevicePage0_t *buffer;
2465         dma_addr_t dma_handle;
2466         __le64 sas_address;
2467         int error=0;
2468 
2469         hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
2470         hdr.ExtPageLength = 0;
2471         hdr.PageNumber = 0;
2472         hdr.Reserved1 = 0;
2473         hdr.Reserved2 = 0;
2474         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2475         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
2476 
2477         cfg.cfghdr.ehdr = &hdr;
2478         cfg.pageAddr = form + form_specific;
2479         cfg.physAddr = -1;
2480         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2481         cfg.dir = 0;    /* read */
2482         cfg.timeout = 10;
2483 
2484         memset(device_info, 0, sizeof(struct mptsas_devinfo));
2485         error = mpt_config(ioc, &cfg);
2486         if (error)
2487                 goto out;
2488         if (!hdr.ExtPageLength) {
2489                 error = -ENXIO;
2490                 goto out;
2491         }
2492 
2493         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2494                                       &dma_handle);
2495         if (!buffer) {
2496                 error = -ENOMEM;
2497                 goto out;
2498         }
2499 
2500         cfg.physAddr = dma_handle;
2501         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2502 
2503         error = mpt_config(ioc, &cfg);
2504         if (error)
2505                 goto out_free_consistent;
2506 
2507         mptsas_print_device_pg0(ioc, buffer);
2508 
2509         memset(device_info, 0, sizeof(struct mptsas_devinfo));
2510         device_info->handle = le16_to_cpu(buffer->DevHandle);
2511         device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
2512         device_info->handle_enclosure =
2513             le16_to_cpu(buffer->EnclosureHandle);
2514         device_info->slot = le16_to_cpu(buffer->Slot);
2515         device_info->phy_id = buffer->PhyNum;
2516         device_info->port_id = buffer->PhysicalPort;
2517         device_info->id = buffer->TargetID;
2518         device_info->phys_disk_num = ~0;
2519         device_info->channel = buffer->Bus;
2520         memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2521         device_info->sas_address = le64_to_cpu(sas_address);
2522         device_info->device_info =
2523             le32_to_cpu(buffer->DeviceInfo);
2524 
2525  out_free_consistent:
2526         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2527                             buffer, dma_handle);
2528  out:
2529         return error;
2530 }
2531 
2532 static int
2533 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
2534                 u32 form, u32 form_specific)
2535 {
2536         ConfigExtendedPageHeader_t hdr;
2537         CONFIGPARMS cfg;
2538         SasExpanderPage0_t *buffer;
2539         dma_addr_t dma_handle;
2540         int i, error;
2541         __le64 sas_address;
2542 
2543         memset(port_info, 0, sizeof(struct mptsas_portinfo));
2544         hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
2545         hdr.ExtPageLength = 0;
2546         hdr.PageNumber = 0;
2547         hdr.Reserved1 = 0;
2548         hdr.Reserved2 = 0;
2549         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2550         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2551 
2552         cfg.cfghdr.ehdr = &hdr;
2553         cfg.physAddr = -1;
2554         cfg.pageAddr = form + form_specific;
2555         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2556         cfg.dir = 0;    /* read */
2557         cfg.timeout = 10;
2558 
2559         memset(port_info, 0, sizeof(struct mptsas_portinfo));
2560         error = mpt_config(ioc, &cfg);
2561         if (error)
2562                 goto out;
2563 
2564         if (!hdr.ExtPageLength) {
2565                 error = -ENXIO;
2566                 goto out;
2567         }
2568 
2569         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2570                                       &dma_handle);
2571         if (!buffer) {
2572                 error = -ENOMEM;
2573                 goto out;
2574         }
2575 
2576         cfg.physAddr = dma_handle;
2577         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2578 
2579         error = mpt_config(ioc, &cfg);
2580         if (error)
2581                 goto out_free_consistent;
2582 
2583         if (!buffer->NumPhys) {
2584                 error = -ENODEV;
2585                 goto out_free_consistent;
2586         }
2587 
2588         /* save config data */
2589         port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1;
2590         port_info->phy_info = kcalloc(port_info->num_phys,
2591                 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2592         if (!port_info->phy_info) {
2593                 error = -ENOMEM;
2594                 goto out_free_consistent;
2595         }
2596 
2597         memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2598         for (i = 0; i < port_info->num_phys; i++) {
2599                 port_info->phy_info[i].portinfo = port_info;
2600                 port_info->phy_info[i].handle =
2601                     le16_to_cpu(buffer->DevHandle);
2602                 port_info->phy_info[i].identify.sas_address =
2603                     le64_to_cpu(sas_address);
2604                 port_info->phy_info[i].identify.handle_parent =
2605                     le16_to_cpu(buffer->ParentDevHandle);
2606         }
2607 
2608  out_free_consistent:
2609         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2610                             buffer, dma_handle);
2611  out:
2612         return error;
2613 }
2614 
2615 static int
2616 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2617                 u32 form, u32 form_specific)
2618 {
2619         ConfigExtendedPageHeader_t hdr;
2620         CONFIGPARMS cfg;
2621         SasExpanderPage1_t *buffer;
2622         dma_addr_t dma_handle;
2623         int error=0;
2624 
2625         hdr.PageVersion = MPI_SASEXPANDER1_PAGEVERSION;
2626         hdr.ExtPageLength = 0;
2627         hdr.PageNumber = 1;
2628         hdr.Reserved1 = 0;
2629         hdr.Reserved2 = 0;
2630         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2631         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2632 
2633         cfg.cfghdr.ehdr = &hdr;
2634         cfg.physAddr = -1;
2635         cfg.pageAddr = form + form_specific;
2636         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2637         cfg.dir = 0;    /* read */
2638         cfg.timeout = 10;
2639 
2640         error = mpt_config(ioc, &cfg);
2641         if (error)
2642                 goto out;
2643 
2644         if (!hdr.ExtPageLength) {
2645                 error = -ENXIO;
2646                 goto out;
2647         }
2648 
2649         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2650                                       &dma_handle);
2651         if (!buffer) {
2652                 error = -ENOMEM;
2653                 goto out;
2654         }
2655 
2656         cfg.physAddr = dma_handle;
2657         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2658 
2659         error = mpt_config(ioc, &cfg);
2660 
2661         if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2662                 error = -ENODEV;
2663                 goto out;
2664         }
2665 
2666         if (error)
2667                 goto out_free_consistent;
2668 
2669 
2670         mptsas_print_expander_pg1(ioc, buffer);
2671 
2672         /* save config data */
2673         phy_info->phy_id = buffer->PhyIdentifier;
2674         phy_info->port_id = buffer->PhysicalPort;
2675         phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
2676         phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2677         phy_info->hw_link_rate = buffer->HwLinkRate;
2678         phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2679         phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2680 
2681  out_free_consistent:
2682         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2683                             buffer, dma_handle);
2684  out:
2685         return error;
2686 }
2687 
2688 static void
2689 mptsas_parse_device_info(struct sas_identify *identify,
2690                 struct mptsas_devinfo *device_info)
2691 {
2692         u16 protocols;
2693 
2694         identify->sas_address = device_info->sas_address;
2695         identify->phy_identifier = device_info->phy_id;
2696 
2697         /*
2698          * Fill in Phy Initiator Port Protocol.
2699          * Bits 6:3, more than one bit can be set, fall through cases.
2700          */
2701         protocols = device_info->device_info & 0x78;
2702         identify->initiator_port_protocols = 0;
2703         if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
2704                 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
2705         if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
2706                 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
2707         if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
2708                 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
2709         if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
2710                 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
2711 
2712         /*
2713          * Fill in Phy Target Port Protocol.
2714          * Bits 10:7, more than one bit can be set, fall through cases.
2715          */
2716         protocols = device_info->device_info & 0x780;
2717         identify->target_port_protocols = 0;
2718         if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
2719                 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
2720         if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
2721                 identify->target_port_protocols |= SAS_PROTOCOL_STP;
2722         if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
2723                 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
2724         if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2725                 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
2726 
2727         /*
2728          * Fill in Attached device type.
2729          */
2730         switch (device_info->device_info &
2731                         MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
2732         case MPI_SAS_DEVICE_INFO_NO_DEVICE:
2733                 identify->device_type = SAS_PHY_UNUSED;
2734                 break;
2735         case MPI_SAS_DEVICE_INFO_END_DEVICE:
2736                 identify->device_type = SAS_END_DEVICE;
2737                 break;
2738         case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
2739                 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
2740                 break;
2741         case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
2742                 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
2743                 break;
2744         }
2745 }
2746 
2747 static int mptsas_probe_one_phy(struct device *dev,
2748                 struct mptsas_phyinfo *phy_info, int index, int local)
2749 {
2750         MPT_ADAPTER *ioc;
2751         struct sas_phy *phy;
2752         struct sas_port *port;
2753         int error = 0;
2754 
2755         if (!dev) {
2756                 error = -ENODEV;
2757                 goto out;
2758         }
2759 
2760         if (!phy_info->phy) {
2761                 phy = sas_phy_alloc(dev, index);
2762                 if (!phy) {
2763                         error = -ENOMEM;
2764                         goto out;
2765                 }
2766         } else
2767                 phy = phy_info->phy;
2768 
2769         mptsas_parse_device_info(&phy->identify, &phy_info->identify);
2770 
2771         /*
2772          * Set Negotiated link rate.
2773          */
2774         switch (phy_info->negotiated_link_rate) {
2775         case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
2776                 phy->negotiated_linkrate = SAS_PHY_DISABLED;
2777                 break;
2778         case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
2779                 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
2780                 break;
2781         case MPI_SAS_IOUNIT0_RATE_1_5:
2782                 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
2783                 break;
2784         case MPI_SAS_IOUNIT0_RATE_3_0:
2785                 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
2786                 break;
2787         case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
2788         case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
2789         default:
2790                 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
2791                 break;
2792         }
2793 
2794         /*
2795          * Set Max hardware link rate.
2796          */
2797         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
2798         case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
2799                 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
2800                 break;
2801         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
2802                 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
2803                 break;
2804         default:
2805                 break;
2806         }
2807 
2808         /*
2809          * Set Max programmed link rate.
2810          */
2811         switch (phy_info->programmed_link_rate &
2812                         MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
2813         case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
2814                 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
2815                 break;
2816         case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
2817                 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
2818                 break;
2819         default:
2820                 break;
2821         }
2822 
2823         /*
2824          * Set Min hardware link rate.
2825          */
2826         switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
2827         case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
2828                 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
2829                 break;
2830         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
2831                 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
2832                 break;
2833         default:
2834                 break;
2835         }
2836 
2837         /*
2838          * Set Min programmed link rate.
2839          */
2840         switch (phy_info->programmed_link_rate &
2841                         MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
2842         case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
2843                 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
2844                 break;
2845         case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
2846                 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
2847                 break;
2848         default:
2849                 break;
2850         }
2851 
2852         if (!phy_info->phy) {
2853 
2854                 error = sas_phy_add(phy);
2855                 if (error) {
2856                         sas_phy_free(phy);
2857                         goto out;
2858                 }
2859                 phy_info->phy = phy;
2860         }
2861 
2862         if (!phy_info->attached.handle ||
2863                         !phy_info->port_details)
2864                 goto out;
2865 
2866         port = mptsas_get_port(phy_info);
2867         ioc = phy_to_ioc(phy_info->phy);
2868 
2869         if (phy_info->sas_port_add_phy) {
2870 
2871                 if (!port) {
2872                         port = sas_port_alloc_num(dev);
2873                         if (!port) {
2874                                 error = -ENOMEM;
2875                                 goto out;
2876                         }
2877                         error = sas_port_add(port);
2878                         if (error) {
2879                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2880                                         "%s: exit at line=%d\n", ioc->name,
2881                                         __func__, __LINE__));
2882                                 goto out;
2883                         }
2884                         mptsas_set_port(ioc, phy_info, port);
2885                         devtprintk(ioc, dev_printk(KERN_DEBUG, &port->dev,
2886                             MYIOC_s_FMT "add port %d, sas_addr (0x%llx)\n",
2887                             ioc->name, port->port_identifier,
2888                             (unsigned long long)phy_info->
2889                             attached.sas_address));
2890                 }
2891                 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2892                         "sas_port_add_phy: phy_id=%d\n",
2893                         ioc->name, phy_info->phy_id));
2894                 sas_port_add_phy(port, phy_info->phy);
2895                 phy_info->sas_port_add_phy = 0;
2896                 devtprintk(ioc, dev_printk(KERN_DEBUG, &phy_info->phy->dev,
2897                     MYIOC_s_FMT "add phy %d, phy-obj (0x%p)\n", ioc->name,
2898                      phy_info->phy_id, phy_info->phy));
2899         }
2900         if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
2901 
2902                 struct sas_rphy *rphy;
2903                 struct device *parent;
2904                 struct sas_identify identify;
2905 
2906                 parent = dev->parent->parent;
2907                 /*
2908                  * Let the hotplug_work thread handle processing
2909                  * the adding/removing of devices that occur
2910                  * after start of day.
2911                  */
2912                 if (mptsas_is_end_device(&phy_info->attached) &&
2913                     phy_info->attached.handle_parent) {
2914                         goto out;
2915                 }
2916 
2917                 mptsas_parse_device_info(&identify, &phy_info->attached);
2918                 if (scsi_is_host_device(parent)) {
2919                         struct mptsas_portinfo *port_info;
2920                         int i;
2921 
2922                         port_info = ioc->hba_port_info;
2923 
2924                         for (i = 0; i < port_info->num_phys; i++)
2925                                 if (port_info->phy_info[i].identify.sas_address ==
2926                                     identify.sas_address) {
2927                                         sas_port_mark_backlink(port);
2928                                         goto out;
2929                                 }
2930 
2931                 } else if (scsi_is_sas_rphy(parent)) {
2932                         struct sas_rphy *parent_rphy = dev_to_rphy(parent);
2933                         if (identify.sas_address ==
2934                             parent_rphy->identify.sas_address) {
2935                                 sas_port_mark_backlink(port);
2936                                 goto out;
2937                         }
2938                 }
2939 
2940                 switch (identify.device_type) {
2941                 case SAS_END_DEVICE:
2942                         rphy = sas_end_device_alloc(port);
2943                         break;
2944                 case SAS_EDGE_EXPANDER_DEVICE:
2945                 case SAS_FANOUT_EXPANDER_DEVICE:
2946                         rphy = sas_expander_alloc(port, identify.device_type);
2947                         break;
2948                 default:
2949                         rphy = NULL;
2950                         break;
2951                 }
2952                 if (!rphy) {
2953                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2954                                 "%s: exit at line=%d\n", ioc->name,
2955                                 __func__, __LINE__));
2956                         goto out;
2957                 }
2958 
2959                 rphy->identify = identify;
2960                 error = sas_rphy_add(rphy);
2961                 if (error) {
2962                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2963                                 "%s: exit at line=%d\n", ioc->name,
2964                                 __func__, __LINE__));
2965                         sas_rphy_free(rphy);
2966                         goto out;
2967                 }
2968                 mptsas_set_rphy(ioc, phy_info, rphy);
2969         }
2970 
2971  out:
2972         return error;
2973 }
2974 
2975 static int
2976 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
2977 {
2978         struct mptsas_portinfo *port_info, *hba;
2979         int error = -ENOMEM, i;
2980 
2981         hba = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
2982         if (! hba)
2983                 goto out;
2984 
2985         error = mptsas_sas_io_unit_pg0(ioc, hba);
2986         if (error)
2987                 goto out_free_port_info;
2988 
2989         mptsas_sas_io_unit_pg1(ioc);
2990         mutex_lock(&ioc->sas_topology_mutex);
2991         port_info = ioc->hba_port_info;
2992         if (!port_info) {
2993                 ioc->hba_port_info = port_info = hba;
2994                 ioc->hba_port_num_phy = port_info->num_phys;
2995                 list_add_tail(&port_info->list, &ioc->sas_topology);
2996         } else {
2997                 for (i = 0; i < hba->num_phys; i++) {
2998                         port_info->phy_info[i].negotiated_link_rate =
2999                                 hba->phy_info[i].negotiated_link_rate;
3000                         port_info->phy_info[i].handle =
3001                                 hba->phy_info[i].handle;
3002                         port_info->phy_info[i].port_id =
3003                                 hba->phy_info[i].port_id;
3004                 }
3005                 kfree(hba->phy_info);
3006                 kfree(hba);
3007                 hba = NULL;
3008         }
3009         mutex_unlock(&ioc->sas_topology_mutex);
3010 #if defined(CPQ_CIM)
3011         ioc->num_ports = port_info->num_phys;
3012 #endif
3013         for (i = 0; i < port_info->num_phys; i++) {
3014                 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
3015                         (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
3016                          MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
3017                 port_info->phy_info[i].identify.handle =
3018                     port_info->phy_info[i].handle;
3019                 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
3020                         (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3021                          MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3022                          port_info->phy_info[i].identify.handle);
3023                 if (!ioc->hba_port_sas_addr)
3024                         ioc->hba_port_sas_addr =
3025                             port_info->phy_info[i].identify.sas_address;
3026                 port_info->phy_info[i].identify.phy_id =
3027                     port_info->phy_info[i].phy_id = i;
3028                 if (port_info->phy_info[i].attached.handle)
3029                         mptsas_sas_device_pg0(ioc,
3030                                 &port_info->phy_info[i].attached,
3031                                 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3032                                  MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3033                                 port_info->phy_info[i].attached.handle);
3034         }
3035 
3036         mptsas_setup_wide_ports(ioc, port_info);
3037 
3038         for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3039                 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
3040                     &port_info->phy_info[i], ioc->sas_index, 1);
3041 
3042         return 0;
3043 
3044  out_free_port_info:
3045         kfree(hba);
3046  out:
3047         return error;
3048 }
3049 
3050 static void
3051 mptsas_expander_refresh(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
3052 {
3053         struct mptsas_portinfo *parent;
3054         struct device *parent_dev;
3055         struct sas_rphy *rphy;
3056         int             i;
3057         u64             sas_address; /* expander sas address */
3058         u32             handle;
3059 
3060         handle = port_info->phy_info[0].handle;
3061         sas_address = port_info->phy_info[0].identify.sas_address;
3062         for (i = 0; i < port_info->num_phys; i++) {
3063                 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
3064                     (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
3065                     MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + handle);
3066 
3067                 mptsas_sas_device_pg0(ioc,
3068                     &port_info->phy_info[i].identify,
3069                     (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3070                     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3071                     port_info->phy_info[i].identify.handle);
3072                 port_info->phy_info[i].identify.phy_id =
3073                     port_info->phy_info[i].phy_id;
3074 
3075                 if (port_info->phy_info[i].attached.handle) {
3076                         mptsas_sas_device_pg0(ioc,
3077                             &port_info->phy_info[i].attached,
3078                             (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3079                              MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3080                             port_info->phy_info[i].attached.handle);
3081                         port_info->phy_info[i].attached.phy_id =
3082                             port_info->phy_info[i].phy_id;
3083                 }
3084         }
3085 
3086         mutex_lock(&ioc->sas_topology_mutex);
3087         parent = mptsas_find_portinfo_by_handle(ioc,
3088             port_info->phy_info[0].identify.handle_parent);
3089         if (!parent) {
3090                 mutex_unlock(&ioc->sas_topology_mutex);
3091                 return;
3092         }
3093         for (i = 0, parent_dev = NULL; i < parent->num_phys && !parent_dev;
3094             i++) {
3095                 if (parent->phy_info[i].attached.sas_address == sas_address) {
3096                         rphy = mptsas_get_rphy(&parent->phy_info[i]);
3097                         parent_dev = &rphy->dev;
3098                 }
3099         }
3100         mutex_unlock(&ioc->sas_topology_mutex);
3101 
3102         mptsas_setup_wide_ports(ioc, port_info);
3103         for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3104                 mptsas_probe_one_phy(parent_dev, &port_info->phy_info[i],
3105                     ioc->sas_index, 0);
3106 }
3107 
3108 static void
3109 mptsas_expander_event_add(MPT_ADAPTER *ioc,
3110     MpiEventDataSasExpanderStatusChange_t *expander_data)
3111 {
3112         struct mptsas_portinfo *port_info;
3113         int i;
3114         __le64 sas_address;
3115 
3116         port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3117         if (!port_info)
3118                 BUG();
3119         port_info->num_phys = (expander_data->NumPhys) ?
3120             expander_data->NumPhys : 1;
3121         port_info->phy_info = kcalloc(port_info->num_phys,
3122             sizeof(struct mptsas_phyinfo), GFP_KERNEL);
3123         if (!port_info->phy_info)
3124                 BUG();
3125         memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3126         for (i = 0; i < port_info->num_phys; i++) {
3127                 port_info->phy_info[i].portinfo = port_info;
3128                 port_info->phy_info[i].handle =
3129                     le16_to_cpu(expander_data->DevHandle);
3130                 port_info->phy_info[i].identify.sas_address =
3131                     le64_to_cpu(sas_address);
3132                 port_info->phy_info[i].identify.handle_parent =
3133                     le16_to_cpu(expander_data->ParentDevHandle);
3134         }
3135 
3136         mutex_lock(&ioc->sas_topology_mutex);
3137         list_add_tail(&port_info->list, &ioc->sas_topology);
3138         mutex_unlock(&ioc->sas_topology_mutex);
3139 
3140         printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3141             "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3142             (unsigned long long)sas_address);
3143 
3144         mptsas_expander_refresh(ioc, port_info);
3145 }
3146 
3147 /**
3148  * mptsas_delete_expander_siblings - remove siblings attached to expander
3149  * @ioc: Pointer to MPT_ADAPTER structure
3150  * @parent: the parent port_info object
3151  * @expander: the expander port_info object
3152  **/
3153 static void
3154 mptsas_delete_expander_siblings(MPT_ADAPTER *ioc, struct mptsas_portinfo
3155     *parent, struct mptsas_portinfo *expander)
3156 {
3157         struct mptsas_phyinfo *phy_info;
3158         struct mptsas_portinfo *port_info;
3159         struct sas_rphy *rphy;
3160         int i;
3161 
3162         phy_info = expander->phy_info;
3163         for (i = 0; i < expander->num_phys; i++, phy_info++) {
3164                 rphy = mptsas_get_rphy(phy_info);
3165                 if (!rphy)
3166                         continue;
3167                 if (rphy->identify.device_type == SAS_END_DEVICE)
3168                         mptsas_del_end_device(ioc, phy_info);
3169         }
3170 
3171         phy_info = expander->phy_info;
3172         for (i = 0; i < expander->num_phys; i++, phy_info++) {
3173                 rphy = mptsas_get_rphy(phy_info);
3174                 if (!rphy)
3175                         continue;
3176                 if (rphy->identify.device_type ==
3177                     MPI_SAS_DEVICE_INFO_EDGE_EXPANDER ||
3178                     rphy->identify.device_type ==
3179                     MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
3180                         port_info = mptsas_find_portinfo_by_sas_address(ioc,
3181                             rphy->identify.sas_address);
3182                         if (!port_info)
3183                                 continue;
3184                         if (port_info == parent) /* backlink rphy */
3185                                 continue;
3186                         /*
3187                         Delete this expander even if the expdevpage is exists
3188                         because the parent expander is already deleted
3189                         */
3190                         mptsas_expander_delete(ioc, port_info, 1);
3191                 }
3192         }
3193 }
3194 
3195 
3196 /**
3197  *      mptsas_expander_delete - remove this expander
3198  *      @ioc: Pointer to MPT_ADAPTER structure
3199  *      @port_info: expander port_info struct
3200  *      @force: Flag to forcefully delete the expander
3201  *
3202  **/
3203 
3204 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
3205                 struct mptsas_portinfo *port_info, u8 force)
3206 {
3207 
3208         struct mptsas_portinfo *parent;
3209         int             i;
3210         u64             expander_sas_address;
3211         struct mptsas_phyinfo *phy_info;
3212         struct mptsas_portinfo buffer;
3213         struct mptsas_portinfo_details *port_details;
3214         struct sas_port *port;
3215 
3216         if (!port_info)
3217                 return;
3218 
3219         /* see if expander is still there before deleting */
3220         mptsas_sas_expander_pg0(ioc, &buffer,
3221             (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3222             MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
3223             port_info->phy_info[0].identify.handle);
3224 
3225         if (buffer.num_phys) {
3226                 kfree(buffer.phy_info);
3227                 if (!force)
3228                         return;
3229         }
3230 
3231 
3232         /*
3233          * Obtain the port_info instance to the parent port
3234          */
3235         port_details = NULL;
3236         expander_sas_address =
3237             port_info->phy_info[0].identify.sas_address;
3238         parent = mptsas_find_portinfo_by_handle(ioc,
3239             port_info->phy_info[0].identify.handle_parent);
3240         mptsas_delete_expander_siblings(ioc, parent, port_info);
3241         if (!parent)
3242                 goto out;
3243 
3244         /*
3245          * Delete rphys in the parent that point
3246          * to this expander.
3247          */
3248         phy_info = parent->phy_info;
3249         port = NULL;
3250         for (i = 0; i < parent->num_phys; i++, phy_info++) {
3251                 if (!phy_info->phy)
3252                         continue;
3253                 if (phy_info->attached.sas_address !=
3254                     expander_sas_address)
3255                         continue;
3256                 if (!port) {
3257                         port = mptsas_get_port(phy_info);
3258                         port_details = phy_info->port_details;
3259                 }
3260                 dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3261                     MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n", ioc->name,
3262                     phy_info->phy_id, phy_info->phy);
3263                 sas_port_delete_phy(port, phy_info->phy);
3264         }
3265         if (port) {
3266                 dev_printk(KERN_DEBUG, &port->dev,
3267                     MYIOC_s_FMT "delete port %