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 %d, sas_addr (0x%llx)\n",
3268                     ioc->name, port->port_identifier,
3269                     (unsigned long long)expander_sas_address);
3270                 sas_port_delete(port);
3271                 mptsas_port_delete(ioc, port_details);
3272         }
3273  out:
3274 
3275         printk(MYIOC_s_INFO_FMT "delete expander: num_phys %d, "
3276             "sas_addr (0x%llx)\n",  ioc->name, port_info->num_phys,
3277             (unsigned long long)expander_sas_address);
3278 
3279         /*
3280          * free link
3281          */
3282         list_del(&port_info->list);
3283         kfree(port_info->phy_info);
3284         kfree(port_info);
3285 }
3286 
3287 
3288 /**
3289  * mptsas_send_expander_event - expanders events
3290  * @ioc: Pointer to MPT_ADAPTER structure
3291  * @expander_data: event data
3292  *
3293  *
3294  * This function handles adding, removing, and refreshing
3295  * device handles within the expander objects.
3296  */
3297 static void
3298 mptsas_send_expander_event(struct fw_event_work *fw_event)
3299 {
3300         MPT_ADAPTER *ioc;
3301         MpiEventDataSasExpanderStatusChange_t *expander_data;
3302         struct mptsas_portinfo *port_info;
3303         __le64 sas_address;
3304         int i;
3305 
3306         ioc = fw_event->ioc;
3307         expander_data = (MpiEventDataSasExpanderStatusChange_t *)
3308             fw_event->event_data;
3309         memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3310         port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3311 
3312         if (expander_data->ReasonCode == MPI_EVENT_SAS_EXP_RC_ADDED) {
3313                 if (port_info) {
3314                         for (i = 0; i < port_info->num_phys; i++) {
3315                                 port_info->phy_info[i].portinfo = port_info;
3316                                 port_info->phy_info[i].handle =
3317                                     le16_to_cpu(expander_data->DevHandle);
3318                                 port_info->phy_info[i].identify.sas_address =
3319                                     le64_to_cpu(sas_address);
3320                                 port_info->phy_info[i].identify.handle_parent =
3321                                     le16_to_cpu(expander_data->ParentDevHandle);
3322                         }
3323                         mptsas_expander_refresh(ioc, port_info);
3324                 } else if (!port_info && expander_data->NumPhys)
3325                         mptsas_expander_event_add(ioc, expander_data);
3326         } else if (expander_data->ReasonCode ==
3327             MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING)
3328                 mptsas_expander_delete(ioc, port_info, 0);
3329 
3330         mptsas_free_fw_event(ioc, fw_event);
3331 }
3332 
3333 
3334 /**
3335  * mptsas_expander_add -
3336  * @ioc: Pointer to MPT_ADAPTER structure
3337  * @handle:
3338  *
3339  */
3340 struct mptsas_portinfo *
3341 mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
3342 {
3343         struct mptsas_portinfo buffer, *port_info;
3344         int i;
3345 
3346         if ((mptsas_sas_expander_pg0(ioc, &buffer,
3347             (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3348             MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)))
3349                 return NULL;
3350 
3351         port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_ATOMIC);
3352         if (!port_info) {
3353                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3354                 "%s: exit at line=%d\n", ioc->name,
3355                 __func__, __LINE__));
3356                 return NULL;
3357         }
3358         port_info->num_phys = buffer.num_phys;
3359         port_info->phy_info = buffer.phy_info;
3360         for (i = 0; i < port_info->num_phys; i++)
3361                 port_info->phy_info[i].portinfo = port_info;
3362         mutex_lock(&ioc->sas_topology_mutex);
3363         list_add_tail(&port_info->list, &ioc->sas_topology);
3364         mutex_unlock(&ioc->sas_topology_mutex);
3365         printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3366             "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3367             (unsigned long long)buffer.phy_info[0].identify.sas_address);
3368         mptsas_expander_refresh(ioc, port_info);
3369         return port_info;
3370 }
3371 
3372 static void
3373 mptsas_send_link_status_event(struct fw_event_work *fw_event)
3374 {
3375         MPT_ADAPTER *ioc;
3376         MpiEventDataSasPhyLinkStatus_t *link_data;
3377         struct mptsas_portinfo *port_info;
3378         struct mptsas_phyinfo *phy_info = NULL;
3379         __le64 sas_address;
3380         u8 phy_num;
3381         u8 link_rate;
3382 
3383         ioc = fw_event->ioc;
3384         link_data = (MpiEventDataSasPhyLinkStatus_t *)fw_event->event_data;
3385 
3386         memcpy(&sas_address, &link_data->SASAddress, sizeof(__le64));
3387         sas_address = le64_to_cpu(sas_address);
3388         link_rate = link_data->LinkRates >> 4;
3389         phy_num = link_data->PhyNum;
3390 
3391         port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3392         if (port_info) {
3393                 phy_info = &port_info->phy_info[phy_num];
3394                 if (phy_info)
3395                         phy_info->negotiated_link_rate = link_rate;
3396         }
3397 
3398         if (link_rate == MPI_SAS_IOUNIT0_RATE_1_5 ||
3399             link_rate == MPI_SAS_IOUNIT0_RATE_3_0) {
3400 
3401                 if (!port_info) {
3402                         if (ioc->old_sas_discovery_protocal) {
3403                                 port_info = mptsas_expander_add(ioc,
3404                                         le16_to_cpu(link_data->DevHandle));
3405                                 if (port_info)
3406                                         goto out;
3407                         }
3408                         goto out;
3409                 }
3410 
3411                 if (port_info == ioc->hba_port_info)
3412                         mptsas_probe_hba_phys(ioc);
3413                 else
3414                         mptsas_expander_refresh(ioc, port_info);
3415         } else if (phy_info && phy_info->phy) {
3416                 if (link_rate ==  MPI_SAS_IOUNIT0_RATE_PHY_DISABLED)
3417                         phy_info->phy->negotiated_linkrate =
3418                             SAS_PHY_DISABLED;
3419                 else if (link_rate ==
3420                     MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION)
3421                         phy_info->phy->negotiated_linkrate =
3422                             SAS_LINK_RATE_FAILED;
3423                 else
3424                         phy_info->phy->negotiated_linkrate =
3425                             SAS_LINK_RATE_UNKNOWN;
3426         }
3427  out:
3428         mptsas_free_fw_event(ioc, fw_event);
3429 }
3430 
3431 static void
3432 mptsas_not_responding_devices(MPT_ADAPTER *ioc)
3433 {
3434         struct mptsas_portinfo buffer, *port_info;
3435         struct mptsas_device_info       *sas_info;
3436         struct mptsas_devinfo sas_device;
3437         u32     handle;
3438         VirtTarget *vtarget = NULL;
3439         struct mptsas_phyinfo *phy_info;
3440         u8 found_expander;
3441         int retval, retry_count;
3442         unsigned long flags;
3443 
3444         mpt_findImVolumes(ioc);
3445 
3446         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3447         if (ioc->ioc_reset_in_progress) {
3448                 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3449                    "%s: exiting due to a parallel reset \n", ioc->name,
3450                     __func__));
3451                 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3452                 return;
3453         }
3454         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3455 
3456         /* devices, logical volumes */
3457         mutex_lock(&ioc->sas_device_info_mutex);
3458  redo_device_scan:
3459         list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) {
3460                 if (sas_info->is_cached)
3461                         continue;
3462                 if (!sas_info->is_logical_volume) {
3463                         sas_device.handle = 0;
3464                         retry_count = 0;
3465 retry_page:
3466                         retval = mptsas_sas_device_pg0(ioc, &sas_device,
3467                                 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID
3468                                 << MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3469                                 (sas_info->fw.channel << 8) +
3470                                 sas_info->fw.id);
3471 
3472                         if (sas_device.handle)
3473                                 continue;
3474                         if (retval == -EBUSY) {
3475                                 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3476                                 if (ioc->ioc_reset_in_progress) {
3477                                         dfailprintk(ioc,
3478                                         printk(MYIOC_s_DEBUG_FMT
3479                                         "%s: exiting due to reset\n",
3480                                         ioc->name, __func__));
3481                                         spin_unlock_irqrestore
3482                                         (&ioc->taskmgmt_lock, flags);
3483                                         mutex_unlock(&ioc->
3484                                         sas_device_info_mutex);
3485                                         return;
3486                                 }
3487                                 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
3488                                 flags);
3489                         }
3490 
3491                         if (retval && (retval != -ENODEV)) {
3492                                 if (retry_count < 10) {
3493                                         retry_count++;
3494                                         goto retry_page;
3495                                 } else {
3496                                         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3497                                         "%s: Config page retry exceeded retry "
3498                                         "count deleting device 0x%llx\n",
3499                                         ioc->name, __func__,
3500                                         sas_info->sas_address));
3501                                 }
3502                         }
3503 
3504                         /* delete device */
3505                         vtarget = mptsas_find_vtarget(ioc,
3506                                 sas_info->fw.channel, sas_info->fw.id);
3507 
3508                         if (vtarget)
3509                                 vtarget->deleted = 1;
3510 
3511                         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3512                                         sas_info->sas_address);
3513 
3514                         if (phy_info) {
3515                                 mptsas_del_end_device(ioc, phy_info);
3516                                 goto redo_device_scan;
3517                         }
3518                 } else
3519                         mptsas_volume_delete(ioc, sas_info->fw.id);
3520         }
3521         mutex_unlock(&ioc->sas_device_info_mutex);
3522 
3523         /* expanders */
3524         mutex_lock(&ioc->sas_topology_mutex);
3525  redo_expander_scan:
3526         list_for_each_entry(port_info, &ioc->sas_topology, list) {
3527 
3528                 if (port_info->phy_info &&
3529                     (!(port_info->phy_info[0].identify.device_info &
3530                     MPI_SAS_DEVICE_INFO_SMP_TARGET)))
3531                         continue;
3532                 found_expander = 0;
3533                 handle = 0xFFFF;
3534                 while (!mptsas_sas_expander_pg0(ioc, &buffer,
3535                     (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3536                      MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle) &&
3537                     !found_expander) {
3538 
3539                         handle = buffer.phy_info[0].handle;
3540                         if (buffer.phy_info[0].identify.sas_address ==
3541                             port_info->phy_info[0].identify.sas_address) {
3542                                 found_expander = 1;
3543                         }
3544                         kfree(buffer.phy_info);
3545                 }
3546 
3547                 if (!found_expander) {
3548                         mptsas_expander_delete(ioc, port_info, 0);
3549                         goto redo_expander_scan;
3550                 }
3551         }
3552         mutex_unlock(&ioc->sas_topology_mutex);
3553 }
3554 
3555 /**
3556  *      mptsas_probe_expanders - adding expanders
3557  *      @ioc: Pointer to MPT_ADAPTER structure
3558  *
3559  **/
3560 static void
3561 mptsas_probe_expanders(MPT_ADAPTER *ioc)
3562 {
3563         struct mptsas_portinfo buffer, *port_info;
3564         u32                     handle;
3565         int i;
3566 
3567         handle = 0xFFFF;
3568         while (!mptsas_sas_expander_pg0(ioc, &buffer,
3569             (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3570              MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)) {
3571 
3572                 handle = buffer.phy_info[0].handle;
3573                 port_info = mptsas_find_portinfo_by_sas_address(ioc,
3574                     buffer.phy_info[0].identify.sas_address);
3575 
3576                 if (port_info) {
3577                         /* refreshing handles */
3578                         for (i = 0; i < buffer.num_phys; i++) {
3579                                 port_info->phy_info[i].handle = handle;
3580                                 port_info->phy_info[i].identify.handle_parent =
3581                                     buffer.phy_info[0].identify.handle_parent;
3582                         }
3583                         mptsas_expander_refresh(ioc, port_info);
3584                         kfree(buffer.phy_info);
3585                         continue;
3586                 }
3587 
3588                 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3589                 if (!port_info) {
3590                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3591                         "%s: exit at line=%d\n", ioc->name,
3592                         __func__, __LINE__));
3593                         return;
3594                 }
3595                 port_info->num_phys = buffer.num_phys;
3596                 port_info->phy_info = buffer.phy_info;
3597                 for (i = 0; i < port_info->num_phys; i++)
3598                         port_info->phy_info[i].portinfo = port_info;
3599                 mutex_lock(&ioc->sas_topology_mutex);
3600                 list_add_tail(&port_info->list, &ioc->sas_topology);
3601                 mutex_unlock(&ioc->sas_topology_mutex);
3602                 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3603                     "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3604             (unsigned long long)buffer.phy_info[0].identify.sas_address);
3605                 mptsas_expander_refresh(ioc, port_info);
3606         }
3607 }
3608 
3609 static void
3610 mptsas_probe_devices(MPT_ADAPTER *ioc)
3611 {
3612         u16 handle;
3613         struct mptsas_devinfo sas_device;
3614         struct mptsas_phyinfo *phy_info;
3615 
3616         handle = 0xFFFF;
3617         while (!(mptsas_sas_device_pg0(ioc, &sas_device,
3618             MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
3619 
3620                 handle = sas_device.handle;
3621 
3622                 if ((sas_device.device_info &
3623                      (MPI_SAS_DEVICE_INFO_SSP_TARGET |
3624                       MPI_SAS_DEVICE_INFO_STP_TARGET |
3625                       MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0)
3626                         continue;
3627 
3628                 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3629                 if (!phy_info)
3630                         continue;
3631 
3632                 if (mptsas_get_rphy(phy_info))
3633                         continue;
3634 
3635                 mptsas_add_end_device(ioc, phy_info);
3636         }
3637 }
3638 
3639 /**
3640  *      mptsas_scan_sas_topology -
3641  *      @ioc: Pointer to MPT_ADAPTER structure
3642  *      @sas_address:
3643  *
3644  **/
3645 static void
3646 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
3647 {
3648         struct scsi_device *sdev;
3649         int i;
3650 
3651         mptsas_probe_hba_phys(ioc);
3652         mptsas_probe_expanders(ioc);
3653         mptsas_probe_devices(ioc);
3654 
3655         /*
3656           Reporting RAID volumes.
3657         */
3658         if (!ioc->ir_firmware || !ioc->raid_data.pIocPg2 ||
3659             !ioc->raid_data.pIocPg2->NumActiveVolumes)
3660                 return;
3661         for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
3662                 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
3663                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
3664                 if (sdev) {
3665                         scsi_device_put(sdev);
3666                         continue;
3667                 }
3668                 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
3669                     "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
3670                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID);
3671                 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
3672                     ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
3673         }
3674 }
3675 
3676 
3677 static void
3678 mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
3679 {
3680         MPT_ADAPTER *ioc;
3681         EventDataQueueFull_t *qfull_data;
3682         struct mptsas_device_info *sas_info;
3683         struct scsi_device      *sdev;
3684         int depth;
3685         int id = -1;
3686         int channel = -1;
3687         int fw_id, fw_channel;
3688         u16 current_depth;
3689 
3690 
3691         ioc = fw_event->ioc;
3692         qfull_data = (EventDataQueueFull_t *)fw_event->event_data;
3693         fw_id = qfull_data->TargetID;
3694         fw_channel = qfull_data->Bus;
3695         current_depth = le16_to_cpu(qfull_data->CurrentDepth);
3696 
3697         /* if hidden raid component, look for the volume id */
3698         mutex_lock(&ioc->sas_device_info_mutex);
3699         if (mptscsih_is_phys_disk(ioc, fw_channel, fw_id)) {
3700                 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
3701                     list) {
3702                         if (sas_info->is_cached ||
3703                             sas_info->is_logical_volume)
3704                                 continue;
3705                         if (sas_info->is_hidden_raid_component &&
3706                             (sas_info->fw.channel == fw_channel &&
3707                             sas_info->fw.id == fw_id)) {
3708                                 id = sas_info->volume_id;
3709                                 channel = MPTSAS_RAID_CHANNEL;
3710                                 goto out;
3711                         }
3712                 }
3713         } else {
3714                 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
3715                     list) {
3716                         if (sas_info->is_cached ||
3717                             sas_info->is_hidden_raid_component ||
3718                             sas_info->is_logical_volume)
3719                                 continue;
3720                         if (sas_info->fw.channel == fw_channel &&
3721                             sas_info->fw.id == fw_id) {
3722                                 id = sas_info->os.id;
3723                                 channel = sas_info->os.channel;
3724                                 goto out;
3725                         }
3726                 }
3727 
3728         }
3729 
3730  out:
3731         mutex_unlock(&ioc->sas_device_info_mutex);
3732 
3733         if (id != -1) {
3734                 shost_for_each_device(sdev, ioc->sh) {
3735                         if (sdev->id == id && sdev->channel == channel) {
3736                                 if (current_depth > sdev->queue_depth) {
3737                                         sdev_printk(KERN_INFO, sdev,
3738                                             "strange observation, the queue "
3739                                             "depth is (%d) meanwhile fw queue "
3740                                             "depth (%d)\n", sdev->queue_depth,
3741                                             current_depth);
3742                                         continue;
3743                                 }
3744                                 depth = scsi_track_queue_full(sdev,
3745                                     current_depth - 1);
3746                                 if (depth > 0)
3747                                         sdev_printk(KERN_INFO, sdev,
3748                                         "Queue depth reduced to (%d)\n",
3749                                            depth);
3750                                 else if (depth < 0)
3751                                         sdev_printk(KERN_INFO, sdev,
3752                                         "Tagged Command Queueing is being "
3753                                         "disabled\n");
3754                                 else if (depth == 0)
3755                                         sdev_printk(KERN_INFO, sdev,
3756                                         "Queue depth not changed yet\n");
3757                         }
3758                 }
3759         }
3760 
3761         mptsas_free_fw_event(ioc, fw_event);
3762 }
3763 
3764 
3765 static struct mptsas_phyinfo *
3766 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
3767 {
3768         struct mptsas_portinfo *port_info;
3769         struct mptsas_phyinfo *phy_info = NULL;
3770         int i;
3771 
3772         mutex_lock(&ioc->sas_topology_mutex);
3773         list_for_each_entry(port_info, &ioc->sas_topology, list) {
3774                 for (i = 0; i < port_info->num_phys; i++) {
3775                         if (!mptsas_is_end_device(
3776                                 &port_info->phy_info[i].attached))
3777                                 continue;
3778                         if (port_info->phy_info[i].attached.sas_address
3779                             != sas_address)
3780                                 continue;
3781                         phy_info = &port_info->phy_info[i];
3782                         break;
3783                 }
3784         }
3785         mutex_unlock(&ioc->sas_topology_mutex);
3786         return phy_info;
3787 }
3788 
3789 /**
3790  *      mptsas_find_phyinfo_by_phys_disk_num -
3791  *      @ioc: Pointer to MPT_ADAPTER structure
3792  *      @phys_disk_num:
3793  *      @channel:
3794  *      @id:
3795  *
3796  **/
3797 static struct mptsas_phyinfo *
3798 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
3799         u8 channel, u8 id)
3800 {
3801         struct mptsas_phyinfo *phy_info = NULL;
3802         struct mptsas_portinfo *port_info;
3803         RaidPhysDiskPage1_t *phys_disk = NULL;
3804         int num_paths;
3805         u64 sas_address = 0;
3806         int i;
3807 
3808         phy_info = NULL;
3809         if (!ioc->raid_data.pIocPg3)
3810                 return NULL;
3811         /* dual port support */
3812         num_paths = mpt_raid_phys_disk_get_num_paths(ioc, phys_disk_num);
3813         if (!num_paths)
3814                 goto out;
3815         phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
3816            (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
3817         if (!phys_disk)
3818                 goto out;
3819         mpt_raid_phys_disk_pg1(ioc, phys_disk_num, phys_disk);
3820         for (i = 0; i < num_paths; i++) {
3821                 if ((phys_disk->Path[i].Flags & 1) != 0)
3822                         /* entry no longer valid */
3823                         continue;
3824                 if ((id == phys_disk->Path[i].PhysDiskID) &&
3825                     (channel == phys_disk->Path[i].PhysDiskBus)) {
3826                         memcpy(&sas_address, &phys_disk->Path[i].WWID,
3827                                 sizeof(u64));
3828                         phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3829                                         sas_address);
3830                         goto out;
3831                 }
3832         }
3833 
3834  out:
3835         kfree(phys_disk);
3836         if (phy_info)
3837                 return phy_info;
3838 
3839         /*
3840          * Extra code to handle RAID0 case, where the sas_address is not updated
3841          * in phys_disk_page_1 when hotswapped
3842          */
3843         mutex_lock(&ioc->sas_topology_mutex);
3844         list_for_each_entry(port_info, &ioc->sas_topology, list) {
3845                 for (i = 0; i < port_info->num_phys && !phy_info; i++) {
3846                         if (!mptsas_is_end_device(
3847                                 &port_info->phy_info[i].attached))
3848                                 continue;
3849                         if (port_info->phy_info[i].attached.phys_disk_num == ~0)
3850                                 continue;
3851                         if ((port_info->phy_info[i].attached.phys_disk_num ==
3852                             phys_disk_num) &&
3853                             (port_info->phy_info[i].attached.id == id) &&
3854                             (port_info->phy_info[i].attached.channel ==
3855                              channel))
3856                                 phy_info = &port_info->phy_info[i];
3857                 }
3858         }
3859         mutex_unlock(&ioc->sas_topology_mutex);
3860         return phy_info;
3861 }
3862 
3863 static void
3864 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
3865 {
3866         int rc;
3867 
3868         sdev->no_uld_attach = data ? 1 : 0;
3869         rc = scsi_device_reprobe(sdev);
3870 }
3871 
3872 static void
3873 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
3874 {
3875         starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
3876                         mptsas_reprobe_lun);
3877 }
3878 
3879 static void
3880 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
3881 {
3882         CONFIGPARMS                     cfg;
3883         ConfigPageHeader_t              hdr;
3884         dma_addr_t                      dma_handle;
3885         pRaidVolumePage0_t              buffer = NULL;
3886         RaidPhysDiskPage0_t             phys_disk;
3887         int                             i;
3888         struct mptsas_phyinfo   *phy_info;
3889         struct mptsas_devinfo           sas_device;
3890 
3891         memset(&cfg, 0 , sizeof(CONFIGPARMS));
3892         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
3893         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
3894         cfg.pageAddr = (channel << 8) + id;
3895         cfg.cfghdr.hdr = &hdr;
3896         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3897 
3898         if (mpt_config(ioc, &cfg) != 0)
3899                 goto out;
3900 
3901         if (!hdr.PageLength)
3902                 goto out;
3903 
3904         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
3905             &dma_handle);
3906 
3907         if (!buffer)
3908                 goto out;
3909 
3910         cfg.physAddr = dma_handle;
3911         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3912 
3913         if (mpt_config(ioc, &cfg) != 0)
3914                 goto out;
3915 
3916         if (!(buffer->VolumeStatus.Flags &
3917             MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
3918                 goto out;
3919 
3920         if (!buffer->NumPhysDisks)
3921                 goto out;
3922 
3923         for (i = 0; i < buffer->NumPhysDisks; i++) {
3924 
3925                 if (mpt_raid_phys_disk_pg0(ioc,
3926                     buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
3927                         continue;
3928 
3929                 if (mptsas_sas_device_pg0(ioc, &sas_device,
3930                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
3931                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3932                         (phys_disk.PhysDiskBus << 8) +
3933                         phys_disk.PhysDiskID))
3934                         continue;
3935 
3936                 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3937                     sas_device.sas_address);
3938                 mptsas_add_end_device(ioc, phy_info);
3939         }
3940 
3941  out:
3942         if (buffer)
3943                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
3944                     dma_handle);
3945 }
3946 /*
3947  * Work queue thread to handle SAS hotplug events
3948  */
3949 static void
3950 mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
3951     struct mptsas_hotplug_event *hot_plug_info)
3952 {
3953         struct mptsas_phyinfo *phy_info;
3954         struct scsi_target * starget;
3955         struct mptsas_devinfo sas_device;
3956         VirtTarget *vtarget;
3957         int i;
3958 
3959         switch (hot_plug_info->event_type) {
3960 
3961         case MPTSAS_ADD_PHYSDISK:
3962 
3963                 if (!ioc->raid_data.pIocPg2)
3964                         break;
3965 
3966                 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
3967                         if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID ==
3968                             hot_plug_info->id) {
3969                                 printk(MYIOC_s_WARN_FMT "firmware bug: unable "
3970                                     "to add hidden disk - target_id matchs "
3971                                     "volume_id\n", ioc->name);
3972                                 mptsas_free_fw_event(ioc, fw_event);
3973                                 return;
3974                         }
3975                 }
3976                 mpt_findImVolumes(ioc);
3977 
3978         case MPTSAS_ADD_DEVICE:
3979                 memset(&sas_device, 0, sizeof(struct mptsas_devinfo));
3980                 mptsas_sas_device_pg0(ioc, &sas_device,
3981                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
3982                     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3983                     (hot_plug_info->channel << 8) +
3984                     hot_plug_info->id);
3985 
3986                 if (!sas_device.handle)
3987                         return;
3988 
3989                 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3990                 if (!phy_info)
3991                         break;
3992 
3993                 if (mptsas_get_rphy(phy_info))
3994                         break;
3995 
3996                 mptsas_add_end_device(ioc, phy_info);
3997                 break;
3998 
3999         case MPTSAS_DEL_DEVICE:
4000                 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4001                     hot_plug_info->sas_address);
4002                 mptsas_del_end_device(ioc, phy_info);
4003                 break;
4004 
4005         case MPTSAS_DEL_PHYSDISK:
4006 
4007                 mpt_findImVolumes(ioc);
4008 
4009                 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
4010                                 ioc, hot_plug_info->phys_disk_num,
4011                                 hot_plug_info->channel,
4012                                 hot_plug_info->id);
4013                 mptsas_del_end_device(ioc, phy_info);
4014                 break;
4015 
4016         case MPTSAS_ADD_PHYSDISK_REPROBE:
4017 
4018                 if (mptsas_sas_device_pg0(ioc, &sas_device,
4019                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4020                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4021                     (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4022                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4023                         "%s: fw_id=%d exit at line=%d\n", ioc->name,
4024                                  __func__, hot_plug_info->id, __LINE__));
4025                         break;
4026                 }
4027 
4028                 phy_info = mptsas_find_phyinfo_by_sas_address(
4029                     ioc, sas_device.sas_address);
4030 
4031                 if (!phy_info) {
4032                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4033                                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4034                                  __func__, hot_plug_info->id, __LINE__));
4035                         break;
4036                 }
4037 
4038                 starget = mptsas_get_starget(phy_info);
4039                 if (!starget) {
4040                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4041                                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4042                                  __func__, hot_plug_info->id, __LINE__));
4043                         break;
4044                 }
4045 
4046                 vtarget = starget->hostdata;
4047                 if (!vtarget) {
4048                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4049                                 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4050                                  __func__, hot_plug_info->id, __LINE__));
4051                         break;
4052                 }
4053 
4054                 mpt_findImVolumes(ioc);
4055 
4056                 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Hidding: "
4057                     "fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4058                     ioc->name, hot_plug_info->channel, hot_plug_info->id,
4059                     hot_plug_info->phys_disk_num, (unsigned long long)
4060                     sas_device.sas_address);
4061 
4062                 vtarget->id = hot_plug_info->phys_disk_num;
4063                 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
4064                 phy_info->attached.phys_disk_num = hot_plug_info->phys_disk_num;
4065                 mptsas_reprobe_target(starget, 1);
4066                 break;
4067 
4068         case MPTSAS_DEL_PHYSDISK_REPROBE:
4069 
4070                 if (mptsas_sas_device_pg0(ioc, &sas_device,
4071                     (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4072                      MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4073                         (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4074                                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4075                                     "%s: fw_id=%d exit at line=%d\n",
4076                                     ioc->name, __func__,
4077                                     hot_plug_info->id, __LINE__));
4078                         break;
4079                 }
4080 
4081                 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4082                                 sas_device.sas_address);
4083                 if (!phy_info) {
4084                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4085                             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4086                          __func__, hot_plug_info->id, __LINE__));
4087                         break;
4088                 }
4089 
4090                 starget = mptsas_get_starget(phy_info);
4091                 if (!starget) {
4092                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4093                             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4094                          __func__, hot_plug_info->id, __LINE__));
4095                         break;
4096                 }
4097 
4098                 vtarget = starget->hostdata;
4099                 if (!vtarget) {
4100                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4101                             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4102                          __func__, hot_plug_info->id, __LINE__));
4103                         break;
4104                 }
4105 
4106                 if (!(vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)) {
4107                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4108                             "%s: fw_id=%d exit at line=%d\n", ioc->name,
4109                          __func__, hot_plug_info->id, __LINE__));
4110                         break;
4111                 }
4112 
4113                 mpt_findImVolumes(ioc);
4114 
4115                 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Exposing:"
4116                     " fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4117                     ioc->name, hot_plug_info->channel, hot_plug_info->id,
4118                     hot_plug_info->phys_disk_num, (unsigned long long)
4119                     sas_device.sas_address);
4120 
4121                 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
4122                 vtarget->id = hot_plug_info->id;
4123                 phy_info->attached.phys_disk_num = ~0;
4124                 mptsas_reprobe_target(starget, 0);
4125                 mptsas_add_device_component_by_fw(ioc,
4126                     hot_plug_info->channel, hot_plug_info->id);
4127                 break;
4128 
4129         case MPTSAS_ADD_RAID:
4130 
4131                 mpt_findImVolumes(ioc);
4132                 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4133                     "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4134                     hot_plug_info->id);
4135                 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4136                     hot_plug_info->id, 0);
4137                 break;
4138 
4139         case MPTSAS_DEL_RAID:
4140 
4141                 mpt_findImVolumes(ioc);
4142                 printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4143                     "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4144                     hot_plug_info->id);
4145                 scsi_remove_device(hot_plug_info->sdev);
4146                 scsi_device_put(hot_plug_info->sdev);
4147                 break;
4148 
4149         case MPTSAS_ADD_INACTIVE_VOLUME:
4150 
4151                 mpt_findImVolumes(ioc);
4152                 mptsas_adding_inactive_raid_components(ioc,
4153                     hot_plug_info->channel, hot_plug_info->id);
4154                 break;
4155 
4156         default:
4157                 break;
4158         }
4159 
4160         mptsas_free_fw_event(ioc, fw_event);
4161 }
4162 
4163 static void
4164 mptsas_send_sas_event(struct fw_event_work *fw_event)
4165 {
4166         MPT_ADAPTER *ioc;
4167         struct mptsas_hotplug_event hot_plug_info;
4168         EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
4169         u32 device_info;
4170         u64 sas_address;
4171 
4172         ioc = fw_event->ioc;
4173         sas_event_data = (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
4174             fw_event->event_data;
4175         device_info = le32_to_cpu(sas_event_data->DeviceInfo);
4176 
4177         if ((device_info &
4178                 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
4179                 MPI_SAS_DEVICE_INFO_STP_TARGET |
4180                 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0) {
4181                 mptsas_free_fw_event(ioc, fw_event);
4182                 return;
4183         }
4184 
4185         if (sas_event_data->ReasonCode ==
4186                 MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED) {
4187                 mptbase_sas_persist_operation(ioc,
4188                 MPI_SAS_OP_CLEAR_NOT_PRESENT);
4189                 mptsas_free_fw_event(ioc, fw_event);
4190                 return;
4191         }
4192 
4193         switch (sas_event_data->ReasonCode) {
4194         case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
4195         case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
4196                 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4197                 hot_plug_info.handle = le16_to_cpu(sas_event_data->DevHandle);
4198                 hot_plug_info.channel = sas_event_data->Bus;
4199                 hot_plug_info.id = sas_event_data->TargetID;
4200                 hot_plug_info.phy_id = sas_event_data->PhyNum;
4201                 memcpy(&sas_address, &sas_event_data->SASAddress,
4202                     sizeof(u64));
4203                 hot_plug_info.sas_address = le64_to_cpu(sas_address);
4204                 hot_plug_info.device_info = device_info;
4205                 if (sas_event_data->ReasonCode &
4206                     MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
4207                         hot_plug_info.event_type = MPTSAS_ADD_DEVICE;
4208                 else
4209                         hot_plug_info.event_type = MPTSAS_DEL_DEVICE;
4210                 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4211                 break;
4212 
4213         case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
4214                 mptbase_sas_persist_operation(ioc,
4215                     MPI_SAS_OP_CLEAR_NOT_PRESENT);
4216                 mptsas_free_fw_event(ioc, fw_event);
4217                 break;
4218 
4219         case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
4220         /* TODO */
4221         case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
4222         /* TODO */
4223         default:
4224                 mptsas_free_fw_event(ioc, fw_event);
4225                 break;
4226         }
4227 }
4228 
4229 static void
4230 mptsas_send_raid_event(struct fw_event_work *fw_event)
4231 {
4232         MPT_ADAPTER *ioc;
4233         EVENT_DATA_RAID *raid_event_data;
4234         struct mptsas_hotplug_event hot_plug_info;
4235         int status;
4236         int state;
4237         struct scsi_device *sdev = NULL;
4238         VirtDevice *vdevice = NULL;
4239         RaidPhysDiskPage0_t phys_disk;
4240 
4241         ioc = fw_event->ioc;
4242         raid_event_data = (EVENT_DATA_RAID *)fw_event->event_data;
4243         status = le32_to_cpu(raid_event_data->SettingsStatus);
4244         state = (status >> 8) & 0xff;
4245 
4246         memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4247         hot_plug_info.id = raid_event_data->VolumeID;
4248         hot_plug_info.channel = raid_event_data->VolumeBus;
4249         hot_plug_info.phys_disk_num = raid_event_data->PhysDiskNum;
4250 
4251         if (raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_DELETED ||
4252             raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_CREATED ||
4253             raid_event_data->ReasonCode ==
4254             MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED) {
4255                 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
4256                     hot_plug_info.id, 0);
4257                 hot_plug_info.sdev = sdev;
4258                 if (sdev)
4259                         vdevice = sdev->hostdata;
4260         }
4261 
4262         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4263             "ReasonCode=%02x\n", ioc->name, __func__,
4264             raid_event_data->ReasonCode));
4265 
4266         switch (raid_event_data->ReasonCode) {
4267         case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4268                 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK_REPROBE;
4269                 break;
4270         case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4271                 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK_REPROBE;
4272                 break;
4273         case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4274                 switch (state) {
4275                 case MPI_PD_STATE_ONLINE:
4276                 case MPI_PD_STATE_NOT_COMPATIBLE:
4277                         mpt_raid_phys_disk_pg0(ioc,
4278                             raid_event_data->PhysDiskNum, &phys_disk);
4279                         hot_plug_info.id = phys_disk.PhysDiskID;
4280                         hot_plug_info.channel = phys_disk.PhysDiskBus;
4281                         hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4282                         break;
4283                 case MPI_PD_STATE_FAILED:
4284                 case MPI_PD_STATE_MISSING:
4285                 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
4286                 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
4287                 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
4288                         hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4289                         break;
4290                 default:
4291                         break;
4292                 }
4293                 break;
4294         case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4295                 if (!sdev)
4296                         break;
4297                 vdevice->vtarget->deleted = 1; /* block IO */
4298                 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4299                 break;
4300         case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4301                 if (sdev) {
4302                         scsi_device_put(sdev);
4303                         break;
4304                 }
4305                 hot_plug_info.event_type = MPTSAS_ADD_RAID;
4306                 break;
4307         case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4308                 if (!(status & MPI_RAIDVOL0_STATUS_FLAG_ENABLED)) {
4309                         if (!sdev)
4310                                 break;
4311                         vdevice->vtarget->deleted = 1; /* block IO */
4312                         hot_plug_info.event_type = MPTSAS_DEL_RAID;
4313                         break;
4314                 }
4315                 switch (state) {
4316                 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
4317                 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
4318                         if (!sdev)
4319                                 break;
4320                         vdevice->vtarget->deleted = 1; /* block IO */
4321                         hot_plug_info.event_type = MPTSAS_DEL_RAID;
4322                         break;
4323                 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
4324                 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
4325                         if (sdev) {
4326                                 scsi_device_put(sdev);
4327                                 break;
4328                         }
4329                         hot_plug_info.event_type = MPTSAS_ADD_RAID;
4330                         break;
4331                 default:
4332                         break;
4333                 }
4334                 break;
4335         default:
4336                 break;
4337         }
4338 
4339         if (hot_plug_info.event_type != MPTSAS_IGNORE_EVENT)
4340                 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4341         else
4342                 mptsas_free_fw_event(ioc, fw_event);
4343 }
4344 
4345 /**
4346  *      mptsas_issue_tm - send mptsas internal tm request
4347  *      @ioc: Pointer to MPT_ADAPTER structure
4348  *      @type: Task Management type
4349  *      @channel: channel number for task management
4350  *      @id: Logical Target ID for reset (if appropriate)
4351  *      @lun: Logical unit for reset (if appropriate)
4352  *      @task_context: Context for the task to be aborted
4353  *      @timeout: timeout for task management control
4354  *
4355  *      return 0 on success and -1 on failure:
4356  *
4357  */
4358 static int
4359 mptsas_issue_tm(MPT_ADAPTER *ioc, u8 type, u8 channel, u8 id, u64 lun,
4360         int task_context, ulong timeout, u8 *issue_reset)
4361 {
4362         MPT_FRAME_HDR   *mf;
4363         SCSITaskMgmt_t  *pScsiTm;
4364         int              retval;
4365         unsigned long    timeleft;
4366 
4367         *issue_reset = 0;
4368         mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
4369         if (mf == NULL) {
4370                 retval = -1; /* return failure */
4371                 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "TaskMgmt request: no "
4372                     "msg frames!!\n", ioc->name));
4373                 goto out;
4374         }
4375 
4376         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request: mr = %p, "
4377             "task_type = 0x%02X,\n\t timeout = %ld, fw_channel = %d, "
4378             "fw_id = %d, lun = %lld,\n\t task_context = 0x%x\n", ioc->name, mf,
4379              type, timeout, channel, id, (unsigned long long)lun,
4380              task_context));
4381 
4382         pScsiTm = (SCSITaskMgmt_t *) mf;
4383         memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
4384         pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
4385         pScsiTm->TaskType = type;
4386         pScsiTm->MsgFlags = 0;
4387         pScsiTm->TargetID = id;
4388         pScsiTm->Bus = channel;
4389         pScsiTm->ChainOffset = 0;
4390         pScsiTm->Reserved = 0;
4391         pScsiTm->Reserved1 = 0;
4392         pScsiTm->TaskMsgContext = task_context;
4393         int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
4394 
4395         INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4396         CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
4397         retval = 0;
4398         mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
4399 
4400         /* Now wait for the command to complete */
4401         timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
4402             timeout*HZ);
4403         if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
4404                 retval = -1; /* return failure */
4405                 dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
4406                     "TaskMgmt request: TIMED OUT!(mr=%p)\n", ioc->name, mf));
4407                 mpt_free_msg_frame(ioc, mf);
4408                 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
4409                         goto out;
4410                 *issue_reset = 1;
4411                 goto out;
4412         }
4413 
4414         if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
4415                 retval = -1; /* return failure */
4416                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4417                     "TaskMgmt request: failed with no reply\n", ioc->name));
4418                 goto out;
4419         }
4420 
4421  out:
4422         CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4423         return retval;
4424 }
4425 
4426 /**
4427  *      mptsas_broadcast_primative_work - Handle broadcast primitives
4428  *      @work: work queue payload containing info describing the event
4429  *
4430  *      this will be handled in workqueue context.
4431  */
4432 static void
4433 mptsas_broadcast_primative_work(struct fw_event_work *fw_event)
4434 {
4435         MPT_ADAPTER *ioc = fw_event->ioc;
4436         MPT_FRAME_HDR   *mf;
4437         VirtDevice      *vdevice;
4438         int                     ii;
4439         struct scsi_cmnd        *sc;
4440         SCSITaskMgmtReply_t     *pScsiTmReply;
4441         u8                      issue_reset;
4442         int                     task_context;
4443         u8                      channel, id;
4444         int                      lun;
4445         u32                      termination_count;
4446         u32                      query_count;
4447 
4448         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4449             "%s - enter\n", ioc->name, __func__));
4450 
4451         mutex_lock(&ioc->taskmgmt_cmds.mutex);
4452         if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
4453                 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4454                 mptsas_requeue_fw_event(ioc, fw_event, 1000);
4455                 return;
4456         }
4457 
4458         issue_reset = 0;
4459         termination_count = 0;
4460         query_count = 0;
4461         mpt_findImVolumes(ioc);
4462         pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
4463 
4464         for (ii = 0; ii < ioc->req_depth; ii++) {
4465                 if (ioc->fw_events_off)
4466                         goto out;
4467                 sc = mptscsih_get_scsi_lookup(ioc, ii);
4468                 if (!sc)
4469                         continue;
4470                 mf = MPT_INDEX_2_MFPTR(ioc, ii);
4471                 if (!mf)
4472                         continue;
4473                 task_context = mf->u.frame.hwhdr.msgctxu.MsgContext;
4474                 vdevice = sc->device->hostdata;
4475                 if (!vdevice || !vdevice->vtarget)
4476                         continue;
4477                 if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
4478                         continue; /* skip hidden raid components */
4479                 if (vdevice->vtarget->raidVolume)
4480                         continue; /* skip hidden raid components */
4481                 channel = vdevice->vtarget->channel;
4482                 id = vdevice->vtarget->id;
4483                 lun = vdevice->lun;
4484                 if (mptsas_issue_tm(ioc, MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK,
4485                     channel, id, (u64)lun, task_context, 30, &issue_reset))
4486                         goto out;
4487                 query_count++;
4488                 termination_count +=
4489                     le32_to_cpu(pScsiTmReply->TerminationCount);
4490                 if ((pScsiTmReply->IOCStatus == MPI_IOCSTATUS_SUCCESS) &&
4491                     (pScsiTmReply->ResponseCode ==
4492                     MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
4493                     pScsiTmReply->ResponseCode ==
4494                     MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
4495                         continue;
4496                 if (mptsas_issue_tm(ioc,
4497                     MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET,
4498                     channel, id, (u64)lun, 0, 30, &issue_reset))
4499                         goto out;
4500                 termination_count +=
4501                     le32_to_cpu(pScsiTmReply->TerminationCount);
4502         }
4503 
4504  out:
4505         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4506             "%s - exit, query_count = %d termination_count = %d\n",
4507             ioc->name, __func__, query_count, termination_count));
4508 
4509         ioc->broadcast_aen_busy = 0;
4510         mpt_clear_taskmgmt_in_progress_flag(ioc);
4511         mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4512 
4513         if (issue_reset) {
4514                 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
4515                     ioc->name, __func__);
4516                 mpt_HardResetHandler(ioc, CAN_SLEEP);
4517         }
4518         mptsas_free_fw_event(ioc, fw_event);
4519 }
4520 
4521 /*
4522  * mptsas_send_ir2_event - handle exposing hidden disk when
4523  * an inactive raid volume is added
4524  *
4525  * @ioc: Pointer to MPT_ADAPTER structure
4526  * @ir2_data
4527  *
4528  */
4529 static void
4530 mptsas_send_ir2_event(struct fw_event_work *fw_event)
4531 {
4532         MPT_ADAPTER     *ioc;
4533         struct mptsas_hotplug_event hot_plug_info;
4534         MPI_EVENT_DATA_IR2      *ir2_data;
4535         u8 reasonCode;
4536         RaidPhysDiskPage0_t phys_disk;
4537 
4538         ioc = fw_event->ioc;
4539         ir2_data = (MPI_EVENT_DATA_IR2 *)fw_event->event_data;
4540         reasonCode = ir2_data->ReasonCode;
4541 
4542         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4543             "ReasonCode=%02x\n", ioc->name, __func__, reasonCode));
4544 
4545         memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4546         hot_plug_info.id = ir2_data->TargetID;
4547         hot_plug_info.channel = ir2_data->Bus;
4548         switch (reasonCode) {
4549         case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
4550                 hot_plug_info.event_type = MPTSAS_ADD_INACTIVE_VOLUME;
4551                 break;
4552         case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
4553                 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4554                 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4555                 break;
4556         case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
4557                 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4558                 mpt_raid_phys_disk_pg0(ioc,
4559                     ir2_data->PhysDiskNum, &phys_disk);
4560                 hot_plug_info.id = phys_disk.PhysDiskID;
4561                 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4562                 break;
4563         default:
4564                 mptsas_free_fw_event(ioc, fw_event);
4565                 return;
4566         }
4567         mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4568 }
4569 
4570 static int
4571 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
4572 {
4573         u32 event = le32_to_cpu(reply->Event);
4574         int sz, event_data_sz;
4575         struct fw_event_work *fw_event;
4576         unsigned long delay;
4577 
4578         /* events turned off due to host reset or driver unloading */
4579         if (ioc->fw_events_off)
4580                 return 0;
4581 
4582         delay = msecs_to_jiffies(1);
4583         switch (event) {
4584         case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
4585         {
4586                 EVENT_DATA_SAS_BROADCAST_PRIMITIVE *broadcast_event_data =
4587                     (EVENT_DATA_SAS_BROADCAST_PRIMITIVE *)reply->Data;
4588                 if (broadcast_event_data->Primitive !=
4589                     MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
4590                         return 0;
4591                 if (ioc->broadcast_aen_busy)
4592                         return 0;
4593                 ioc->broadcast_aen_busy = 1;
4594                 break;
4595         }
4596         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
4597         {
4598                 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data =
4599                     (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data;
4600 
4601                 if (sas_event_data->ReasonCode ==
4602                     MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) {
4603                         mptsas_target_reset_queue(ioc, sas_event_data);
4604                         return 0;
4605                 }
4606                 break;
4607         }
4608         case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
4609         {
4610                 MpiEventDataSasExpanderStatusChange_t *expander_data =
4611                     (MpiEventDataSasExpanderStatusChange_t *)reply->Data;
4612 
4613                 if (ioc->old_sas_discovery_protocal)
4614                         return 0;
4615 
4616                 if (expander_data->ReasonCode ==
4617                     MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING &&
4618                     ioc->device_missing_delay)
4619                         delay = HZ * ioc->device_missing_delay;
4620                 break;
4621         }
4622         case MPI_EVENT_SAS_DISCOVERY:
4623         {
4624                 u32 discovery_status;
4625                 EventDataSasDiscovery_t *discovery_data =
4626                     (EventDataSasDiscovery_t *)reply->Data;
4627 
4628                 discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus);
4629                 ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0;
4630                 if (ioc->old_sas_discovery_protocal && !discovery_status)
4631                         mptsas_queue_rescan(ioc);
4632                 return 0;
4633         }
4634         case MPI_EVENT_INTEGRATED_RAID:
4635         case MPI_EVENT_PERSISTENT_TABLE_FULL:
4636         case MPI_EVENT_IR2:
4637         case MPI_EVENT_SAS_PHY_LINK_STATUS:
4638         case MPI_EVENT_QUEUE_FULL:
4639                 break;
4640         default:
4641                 return 0;
4642         }
4643 
4644         event_data_sz = ((reply->MsgLength * 4) -
4645             offsetof(EventNotificationReply_t, Data));
4646         sz = offsetof(struct fw_event_work, event_data) + event_data_sz;
4647         fw_event = kzalloc(sz, GFP_ATOMIC);
4648         if (!fw_event) {
4649                 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name,
4650                  __func__, __LINE__);
4651                 return 0;
4652         }
4653         memcpy(fw_event->event_data, reply->Data, event_data_sz);
4654         fw_event->event = event;
4655         fw_event->ioc = ioc;
4656         mptsas_add_fw_event(ioc, fw_event, delay);
4657         return 0;
4658 }
4659 
4660 /* Delete a volume when no longer listed in ioc pg2
4661  */
4662 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id)
4663 {
4664         struct scsi_device *sdev;
4665         int i;
4666 
4667         sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, id, 0);
4668         if (!sdev)
4669                 return;
4670         if (!ioc->raid_data.pIocPg2)
4671                 goto out;
4672         if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
4673                 goto out;
4674         for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
4675                 if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id)
4676                         goto release_sdev;
4677  out:
4678         printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4679             "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL, id);
4680         scsi_remove_device(sdev);
4681  release_sdev:
4682         scsi_device_put(sdev);
4683 }
4684 
4685 static int
4686 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
4687 {
4688         struct Scsi_Host        *sh;
4689         MPT_SCSI_HOST           *hd;
4690         MPT_ADAPTER             *ioc;
4691         unsigned long            flags;
4692         int                      ii;
4693         int                      numSGE = 0;
4694         int                      scale;
4695         int                      ioc_cap;
4696         int                     error=0;
4697         int                     r;
4698 
4699         r = mpt_attach(pdev,id);
4700         if (r)
4701                 return r;
4702 
4703         ioc = pci_get_drvdata(pdev);
4704         mptsas_fw_event_off(ioc);
4705         ioc->DoneCtx = mptsasDoneCtx;
4706         ioc->TaskCtx = mptsasTaskCtx;
4707         ioc->InternalCtx = mptsasInternalCtx;
4708 
4709         /*  Added sanity check on readiness of the MPT adapter.
4710          */
4711         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
4712                 printk(MYIOC_s_WARN_FMT
4713                   "Skipping because it's not operational!\n",
4714                   ioc->name);
4715                 error = -ENODEV;
4716                 goto out_mptsas_probe;
4717         }
4718 
4719         if (!ioc->active) {
4720                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
4721                   ioc->name);
4722                 error = -ENODEV;
4723                 goto out_mptsas_probe;
4724         }
4725 
4726         /*  Sanity check - ensure at least 1 port is INITIATOR capable
4727          */
4728         ioc_cap = 0;
4729         for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
4730                 if (ioc->pfacts[ii].ProtocolFlags &
4731                                 MPI_PORTFACTS_PROTOCOL_INITIATOR)
4732                         ioc_cap++;
4733         }
4734 
4735         if (!ioc_cap) {
4736                 printk(MYIOC_s_WARN_FMT
4737                         "Skipping ioc=%p because SCSI Initiator mode "
4738                         "is NOT enabled!\n", ioc->name, ioc);
4739                 return 0;
4740         }
4741 
4742         sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
4743         if (!sh) {
4744                 printk(MYIOC_s_WARN_FMT
4745                         "Unable to register controller with SCSI subsystem\n",
4746                         ioc->name);
4747                 error = -1;
4748                 goto out_mptsas_probe;
4749         }
4750 
4751         spin_lock_irqsave(&ioc->FreeQlock, flags);
4752 
4753         /* Attach the SCSI Host to the IOC structure
4754          */
4755         ioc->sh = sh;
4756 
4757         sh->io_port = 0;
4758         sh->n_io_port = 0;
4759         sh->irq = 0;
4760 
4761         /* set 16 byte cdb's */
4762         sh->max_cmd_len = 16;
4763 
4764         sh->max_id = ioc->pfacts[0].PortSCSIID;
4765         sh->max_lun = max_lun;
4766 
4767         sh->transportt = mptsas_transport_template;
4768 
4769         /* Required entry.
4770          */
4771         sh->unique_id = ioc->id;
4772 
4773         INIT_LIST_HEAD(&ioc->sas_topology);
4774         mutex_init(&ioc->sas_topology_mutex);
4775         mutex_init(&ioc->sas_discovery_mutex);
4776         mutex_init(&ioc->sas_mgmt.mutex);
4777         init_completion(&ioc->sas_mgmt.done);
4778 
4779         /* Verify that we won't exceed the maximum
4780          * number of chain buffers
4781          * We can optimize:  ZZ = req_sz/sizeof(SGE)
4782          * For 32bit SGE's:
4783          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
4784          *               + (req_sz - 64)/sizeof(SGE)
4785          * A slightly different algorithm is required for
4786          * 64bit SGEs.
4787          */
4788         scale = ioc->req_sz/ioc->SGE_size;
4789         if (ioc->sg_addr_size == sizeof(u64)) {
4790                 numSGE = (scale - 1) *
4791                   (ioc->facts.MaxChainDepth-1) + scale +
4792                   (ioc->req_sz - 60) / ioc->SGE_size;
4793         } else {
4794                 numSGE = 1 + (scale - 1) *
4795                   (ioc->facts.MaxChainDepth-1) + scale +
4796                   (ioc->req_sz - 64) / ioc->SGE_size;
4797         }
4798 
4799         if (numSGE < sh->sg_tablesize) {
4800                 /* Reset this value */
4801                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4802                   "Resetting sg_tablesize to %d from %d\n",
4803                   ioc->name, numSGE, sh->sg_tablesize));
4804                 sh->sg_tablesize = numSGE;
4805         }
4806 
4807         hd = shost_priv(sh);
4808         hd->ioc = ioc;
4809 
4810         /* SCSI needs scsi_cmnd lookup table!
4811          * (with size equal to req_depth*PtrSz!)
4812          */
4813         ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
4814         if (!ioc->ScsiLookup) {
4815                 error = -ENOMEM;
4816                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4817                 goto out_mptsas_probe;
4818         }
4819         spin_lock_init(&ioc->scsi_lookup_lock);
4820 
4821         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
4822                  ioc->name, ioc->ScsiLookup));
4823 
4824         /* Clear the TM flags
4825          */
4826         hd->abortSCpnt = NULL;
4827 
4828         /* Clear the pointer used to store
4829          * single-threaded commands, i.e., those
4830          * issued during a bus scan, dv and
4831          * configuration pages.
4832          */
4833         hd->cmdPtr = NULL;
4834 
4835         /* Initialize this SCSI Hosts' timers
4836          * To use, set the timer expires field
4837          * and add_timer
4838          */
4839         init_timer(&hd->timer);
4840         hd->timer.data = (unsigned long) hd;
4841         hd->timer.function = mptscsih_timer_expired;
4842 
4843         ioc->sas_data.ptClear = mpt_pt_clear;
4844 
4845         hd->last_queue_full = 0;
4846         INIT_LIST_HEAD(&hd->target_reset_list);
4847         INIT_LIST_HEAD(&ioc->sas_device_info_list);
4848         mutex_init(&ioc->sas_device_info_mutex);
4849 
4850         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4851 
4852         if (ioc->sas_data.ptClear==1) {
4853                 mptbase_sas_persist_operation(
4854                     ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
4855         }
4856 
4857         error = scsi_add_host(sh, &ioc->pcidev->dev);
4858         if (error) {
4859                 dprintk(ioc, printk(MYIOC_s_ERR_FMT
4860                   "scsi_add_host failed\n", ioc->name));
4861                 goto out_mptsas_probe;
4862         }
4863 
4864         /* older firmware doesn't support expander events */
4865         if ((ioc->facts.HeaderVersion >> 8) < 0xE)
4866                 ioc->old_sas_discovery_protocal = 1;
4867         mptsas_scan_sas_topology(ioc);
4868         mptsas_fw_event_on(ioc);
4869         return 0;
4870 
4871  out_mptsas_probe:
4872 
4873         mptscsih_remove(pdev);
4874         return error;
4875 }
4876 
4877 void
4878 mptsas_shutdown(struct pci_dev *pdev)
4879 {
4880         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
4881 
4882         mptsas_fw_event_off(ioc);
4883         mptsas_cleanup_fw_event_q(ioc);
4884 }
4885 
4886 static void __devexit mptsas_remove(struct pci_dev *pdev)
4887 {
4888         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
4889         struct mptsas_portinfo *p, *n;
4890         int i;
4891 
4892         mptsas_shutdown(pdev);
4893 
4894         mptsas_del_device_components(ioc);
4895 
4896         ioc->sas_discovery_ignore_events = 1;
4897         sas_remove_host(ioc->sh);
4898 
4899         mutex_lock(&ioc->sas_topology_mutex);
4900         list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
4901                 list_del(&p->list);
4902                 for (i = 0 ; i < p->num_phys ; i++)
4903                         mptsas_port_delete(ioc, p->phy_info[i].port_details);
4904 
4905                 kfree(p->phy_info);
4906                 kfree(p);
4907         }
4908         mutex_unlock(&ioc->sas_topology_mutex);
4909         ioc->hba_port_info = NULL;
4910         mptscsih_remove(pdev);
4911 }
4912 
4913 static struct pci_device_id mptsas_pci_table[] = {
4914         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
4915                 PCI_ANY_ID, PCI_ANY_ID },
4916         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
4917                 PCI_ANY_ID, PCI_ANY_ID },
4918         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
4919                 PCI_ANY_ID, PCI_ANY_ID },
4920         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
4921                 PCI_ANY_ID, PCI_ANY_ID },
4922         { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
4923                 PCI_ANY_ID, PCI_ANY_ID },
4924         {0}     /* Terminating entry */
4925 };
4926 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
4927 
4928 
4929 static struct pci_driver mptsas_driver = {
4930         .name           = "mptsas",
4931         .id_table       = mptsas_pci_table,
4932         .probe          = mptsas_probe,
4933         .remove         = __devexit_p(mptsas_remove),
4934         .shutdown       = mptsas_shutdown,
4935 #ifdef CONFIG_PM
4936         .suspend        = mptscsih_suspend,
4937         .resume         = mptscsih_resume,
4938 #endif
4939 };
4940 
4941 static int __init
4942 mptsas_init(void)
4943 {
4944         int error;
4945 
4946         show_mptmod_ver(my_NAME, my_VERSION);
4947 
4948         mptsas_transport_template =
4949             sas_attach_transport(&mptsas_transport_functions);
4950         if (!mptsas_transport_template)
4951                 return -ENODEV;
4952 
4953         mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
4954         mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
4955         mptsasInternalCtx =
4956                 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
4957         mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
4958         mptsasDeviceResetCtx =
4959                 mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
4960 
4961         mpt_event_register(mptsasDoneCtx, mptsas_event_process);
4962         mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
4963 
4964         error = pci_register_driver(&mptsas_driver);
4965         if (error)
4966                 sas_release_transport(mptsas_transport_template);
4967 
4968         return error;
4969 }
4970 
4971 static void __exit
4972 mptsas_exit(void)
4973 {
4974         pci_unregister_driver(&mptsas_driver);
4975         sas_release_transport(mptsas_transport_template);
4976 
4977         mpt_reset_deregister(mptsasDoneCtx);
4978         mpt_event_deregister(mptsasDoneCtx);
4979 
4980         mpt_deregister(mptsasMgmtCtx);
4981         mpt_deregister(mptsasInternalCtx);
4982         mpt_deregister(mptsasTaskCtx);
4983         mpt_deregister(mptsasDoneCtx);
4984         mpt_deregister(mptsasDeviceResetCtx);
4985 }
4986 
4987 module_init(mptsas_init);
4988 module_exit(mptsas_exit);
4989 
  This page was automatically generated by the LXR engine.