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.
6 * Copyright (c) 1999-2008 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com)
9 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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.
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.
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.
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
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
44 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46 #include <linux/module.h>
47 #include <linux/kernel.h>
48 #include <linux/slab.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/jiffies.h>
52 #include <linux/workqueue.h>
53 #include <linux/delay.h> /* for mdelay */
55 #include <scsi/scsi.h>
56 #include <scsi/scsi_cmnd.h>
57 #include <scsi/scsi_device.h>
58 #include <scsi/scsi_host.h>
59 #include <scsi/scsi_transport_sas.h>
60 #include <scsi/scsi_transport.h>
61 #include <scsi/scsi_dbg.h>
68 #define my_NAME "Fusion MPT SAS Host driver"
69 #define my_VERSION MPT_LINUX_VERSION_COMMON
70 #define MYNAM "mptsas"
73 * Reserved channel for integrated raid
75 #define MPTSAS_RAID_CHANNEL 1
77 #define SAS_CONFIG_PAGE_TIMEOUT 30
78 MODULE_AUTHOR(MODULEAUTHOR);
79 MODULE_DESCRIPTION(my_NAME);
80 MODULE_LICENSE("GPL");
81 MODULE_VERSION(my_VERSION);
83 static int mpt_pt_clear;
84 module_param(mpt_pt_clear, int, 0);
85 MODULE_PARM_DESC(mpt_pt_clear,
86 " Clear persistency table: enable=1 "
87 "(default=MPTSCSIH_PT_CLEAR=0)");
89 /* scsi-mid layer global parmeter is max_report_luns, which is 511 */
90 #define MPTSAS_MAX_LUN (16895)
91 static int max_lun = MPTSAS_MAX_LUN;
92 module_param(max_lun, int, 0);
93 MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
95 static u8 mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
96 static u8 mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
97 static u8 mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */
98 static u8 mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS;
99 static u8 mptsasDeviceResetCtx = MPT_MAX_PROTOCOL_DRIVERS;
101 static void mptsas_firmware_event_work(struct work_struct *work);
102 static void mptsas_send_sas_event(struct fw_event_work *fw_event);
103 static void mptsas_send_raid_event(struct fw_event_work *fw_event);
104 static void mptsas_send_ir2_event(struct fw_event_work *fw_event);
105 static void mptsas_parse_device_info(struct sas_identify *identify,
106 struct mptsas_devinfo *device_info);
107 static inline void mptsas_set_rphy(MPT_ADAPTER *ioc,
108 struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy);
109 static struct mptsas_phyinfo *mptsas_find_phyinfo_by_sas_address
110 (MPT_ADAPTER *ioc, u64 sas_address);
111 static int mptsas_sas_device_pg0(MPT_ADAPTER *ioc,
112 struct mptsas_devinfo *device_info, u32 form, u32 form_specific);
113 static int mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc,
114 struct mptsas_enclosure *enclosure, u32 form, u32 form_specific);
115 static int mptsas_add_end_device(MPT_ADAPTER *ioc,
116 struct mptsas_phyinfo *phy_info);
117 static void mptsas_del_end_device(MPT_ADAPTER *ioc,
118 struct mptsas_phyinfo *phy_info);
119 static void mptsas_send_link_status_event(struct fw_event_work *fw_event);
120 static struct mptsas_portinfo *mptsas_find_portinfo_by_sas_address
121 (MPT_ADAPTER *ioc, u64 sas_address);
122 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
123 struct mptsas_portinfo *port_info, u8 force);
124 static void mptsas_send_expander_event(struct fw_event_work *fw_event);
125 static void mptsas_not_responding_devices(MPT_ADAPTER *ioc);
126 static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
127 static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event);
128 static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
129 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
130 void mptsas_schedule_target_reset(void *ioc);
132 static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
133 MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
135 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
136 "---- IO UNIT PAGE 0 ------------\n", ioc->name));
137 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
138 ioc->name, le16_to_cpu(phy_data->AttachedDeviceHandle)));
139 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Controller Handle=0x%X\n",
140 ioc->name, le16_to_cpu(phy_data->ControllerDevHandle)));
141 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port=0x%X\n",
142 ioc->name, phy_data->Port));
143 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port Flags=0x%X\n",
144 ioc->name, phy_data->PortFlags));
145 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Flags=0x%X\n",
146 ioc->name, phy_data->PhyFlags));
147 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
148 ioc->name, phy_data->NegotiatedLinkRate));
149 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
150 "Controller PHY Device Info=0x%X\n", ioc->name,
151 le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
152 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DiscoveryStatus=0x%X\n\n",
153 ioc->name, le32_to_cpu(phy_data->DiscoveryStatus)));
156 static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
160 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
162 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
163 "---- SAS PHY PAGE 0 ------------\n", ioc->name));
164 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
165 "Attached Device Handle=0x%X\n", ioc->name,
166 le16_to_cpu(pg0->AttachedDevHandle)));
167 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
168 ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
169 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
170 "Attached PHY Identifier=0x%X\n", ioc->name,
171 pg0->AttachedPhyIdentifier));
172 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Attached Device Info=0x%X\n",
173 ioc->name, le32_to_cpu(pg0->AttachedDeviceInfo)));
174 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
175 ioc->name, pg0->ProgrammedLinkRate));
176 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Change Count=0x%X\n",
177 ioc->name, pg0->ChangeCount));
178 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Info=0x%X\n\n",
179 ioc->name, le32_to_cpu(pg0->PhyInfo)));
182 static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
184 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
185 "---- SAS PHY PAGE 1 ------------\n", ioc->name));
186 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Invalid Dword Count=0x%x\n",
187 ioc->name, pg1->InvalidDwordCount));
188 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
189 "Running Disparity Error Count=0x%x\n", ioc->name,
190 pg1->RunningDisparityErrorCount));
191 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
192 "Loss Dword Synch Count=0x%x\n", ioc->name,
193 pg1->LossDwordSynchCount));
194 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
195 "PHY Reset Problem Count=0x%x\n\n", ioc->name,
196 pg1->PhyResetProblemCount));
199 static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
203 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
205 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
206 "---- SAS DEVICE PAGE 0 ---------\n", ioc->name));
207 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
208 ioc->name, le16_to_cpu(pg0->DevHandle)));
209 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Handle=0x%X\n",
210 ioc->name, le16_to_cpu(pg0->ParentDevHandle)));
211 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Enclosure Handle=0x%X\n",
212 ioc->name, le16_to_cpu(pg0->EnclosureHandle)));
213 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Slot=0x%X\n",
214 ioc->name, le16_to_cpu(pg0->Slot)));
215 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
216 ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
217 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Target ID=0x%X\n",
218 ioc->name, pg0->TargetID));
219 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Bus=0x%X\n",
220 ioc->name, pg0->Bus));
221 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Phy Num=0x%X\n",
222 ioc->name, pg0->PhyNum));
223 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Access Status=0x%X\n",
224 ioc->name, le16_to_cpu(pg0->AccessStatus)));
225 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Device Info=0x%X\n",
226 ioc->name, le32_to_cpu(pg0->DeviceInfo)));
227 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Flags=0x%X\n",
228 ioc->name, le16_to_cpu(pg0->Flags)));
229 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n\n",
230 ioc->name, pg0->PhysicalPort));
233 static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
235 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
236 "---- SAS EXPANDER PAGE 1 ------------\n", ioc->name));
237 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n",
238 ioc->name, pg1->PhysicalPort));
239 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Identifier=0x%X\n",
240 ioc->name, pg1->PhyIdentifier));
241 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
242 ioc->name, pg1->NegotiatedLinkRate));
243 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
244 ioc->name, pg1->ProgrammedLinkRate));
245 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hardware Link Rate=0x%X\n",
246 ioc->name, pg1->HwLinkRate));
247 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Owner Device Handle=0x%X\n",
248 ioc->name, le16_to_cpu(pg1->OwnerDevHandle)));
249 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
250 "Attached Device Handle=0x%X\n\n", ioc->name,
251 le16_to_cpu(pg1->AttachedDevHandle)));
254 /* inhibit sas firmware event handling */
256 mptsas_fw_event_off(MPT_ADAPTER *ioc)
260 spin_lock_irqsave(&ioc->fw_event_lock, flags);
261 ioc->fw_events_off = 1;
262 ioc->sas_discovery_quiesce_io = 0;
263 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
267 /* enable sas firmware event handling */
269 mptsas_fw_event_on(MPT_ADAPTER *ioc)
273 spin_lock_irqsave(&ioc->fw_event_lock, flags);
274 ioc->fw_events_off = 0;
275 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
278 /* queue a sas firmware event */
280 mptsas_add_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
285 spin_lock_irqsave(&ioc->fw_event_lock, flags);
286 list_add_tail(&fw_event->list, &ioc->fw_event_list);
287 INIT_DELAYED_WORK(&fw_event->work, mptsas_firmware_event_work);
288 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: add (fw_event=0x%p)\n",
289 ioc->name, __func__, fw_event));
290 queue_delayed_work(ioc->fw_event_q, &fw_event->work,
292 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
295 /* requeue a sas firmware event */
297 mptsas_requeue_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
301 spin_lock_irqsave(&ioc->fw_event_lock, flags);
302 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: reschedule task "
303 "(fw_event=0x%p)\n", ioc->name, __func__, fw_event));
305 queue_delayed_work(ioc->fw_event_q, &fw_event->work,
306 msecs_to_jiffies(delay));
307 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
310 /* free memory assoicated to a sas firmware event */
312 mptsas_free_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event)
316 spin_lock_irqsave(&ioc->fw_event_lock, flags);
317 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: kfree (fw_event=0x%p)\n",
318 ioc->name, __func__, fw_event));
319 list_del(&fw_event->list);
321 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
324 /* walk the firmware event queue, and either stop or wait for
325 * outstanding events to complete */
327 mptsas_cleanup_fw_event_q(MPT_ADAPTER *ioc)
329 struct fw_event_work *fw_event, *next;
330 struct mptsas_target_reset_event *target_reset_list, *n;
331 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
333 /* flush the target_reset_list */
334 if (!list_empty(&hd->target_reset_list)) {
335 list_for_each_entry_safe(target_reset_list, n,
336 &hd->target_reset_list, list) {
337 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
338 "%s: removing target reset for id=%d\n",
340 target_reset_list->sas_event_data.TargetID));
341 list_del(&target_reset_list->list);
342 kfree(target_reset_list);
346 if (list_empty(&ioc->fw_event_list) ||
347 !ioc->fw_event_q || in_interrupt())
350 list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) {
351 if (cancel_delayed_work(&fw_event->work))
352 mptsas_free_fw_event(ioc, fw_event);
357 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
359 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
360 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
363 static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
365 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
366 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
370 * mptsas_find_portinfo_by_handle
372 * This function should be called with the sas_topology_mutex already held
374 static struct mptsas_portinfo *
375 mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
377 struct mptsas_portinfo *port_info, *rc=NULL;
380 list_for_each_entry(port_info, &ioc->sas_topology, list)
381 for (i = 0; i < port_info->num_phys; i++)
382 if (port_info->phy_info[i].identify.handle == handle) {
391 * mptsas_find_portinfo_by_sas_address -
392 * @ioc: Pointer to MPT_ADAPTER structure
395 * This function should be called with the sas_topology_mutex already held
398 static struct mptsas_portinfo *
399 mptsas_find_portinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
401 struct mptsas_portinfo *port_info, *rc = NULL;
404 if (sas_address >= ioc->hba_port_sas_addr &&
405 sas_address < (ioc->hba_port_sas_addr +
406 ioc->hba_port_num_phy))
407 return ioc->hba_port_info;
409 mutex_lock(&ioc->sas_topology_mutex);
410 list_for_each_entry(port_info, &ioc->sas_topology, list)
411 for (i = 0; i < port_info->num_phys; i++)
412 if (port_info->phy_info[i].identify.sas_address ==
418 mutex_unlock(&ioc->sas_topology_mutex);
423 * Returns true if there is a scsi end device
426 mptsas_is_end_device(struct mptsas_devinfo * attached)
428 if ((attached->sas_address) &&
429 (attached->device_info &
430 MPI_SAS_DEVICE_INFO_END_DEVICE) &&
431 ((attached->device_info &
432 MPI_SAS_DEVICE_INFO_SSP_TARGET) |
433 (attached->device_info &
434 MPI_SAS_DEVICE_INFO_STP_TARGET) |
435 (attached->device_info &
436 MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
444 mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
446 struct mptsas_portinfo *port_info;
447 struct mptsas_phyinfo *phy_info;
453 port_info = port_details->port_info;
454 phy_info = port_info->phy_info;
456 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d "
457 "bitmask=0x%016llX\n", ioc->name, __func__, port_details,
458 port_details->num_phys, (unsigned long long)
459 port_details->phy_bitmask));
461 for (i = 0; i < port_info->num_phys; i++, phy_info++) {
462 if(phy_info->port_details != port_details)
464 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
465 mptsas_set_rphy(ioc, phy_info, NULL);
466 phy_info->port_details = NULL;
471 static inline struct sas_rphy *
472 mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
474 if (phy_info->port_details)
475 return phy_info->port_details->rphy;
481 mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
483 if (phy_info->port_details) {
484 phy_info->port_details->rphy = rphy;
485 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
490 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
491 &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
492 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
493 ioc->name, rphy, rphy->dev.release));
497 static inline struct sas_port *
498 mptsas_get_port(struct mptsas_phyinfo *phy_info)
500 if (phy_info->port_details)
501 return phy_info->port_details->port;
507 mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_port *port)
509 if (phy_info->port_details)
510 phy_info->port_details->port = port;
513 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
514 &port->dev, MYIOC_s_FMT "add:", ioc->name));
515 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "port=%p release=%p\n",
516 ioc->name, port, port->dev.release));
520 static inline struct scsi_target *
521 mptsas_get_starget(struct mptsas_phyinfo *phy_info)
523 if (phy_info->port_details)
524 return phy_info->port_details->starget;
530 mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
533 if (phy_info->port_details)
534 phy_info->port_details->starget = starget;
538 * mptsas_add_device_component -
539 * @ioc: Pointer to MPT_ADAPTER structure
540 * @channel: fw mapped id's
547 mptsas_add_device_component(MPT_ADAPTER *ioc, u8 channel, u8 id,
548 u64 sas_address, u32 device_info, u16 slot, u64 enclosure_logical_id)
550 struct mptsas_device_info *sas_info, *next;
551 struct scsi_device *sdev;
552 struct scsi_target *starget;
553 struct sas_rphy *rphy;
556 * Delete all matching devices out of the list
558 mutex_lock(&ioc->sas_device_info_mutex);
559 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
561 if (!sas_info->is_logical_volume &&
562 (sas_info->sas_address == sas_address ||
563 (sas_info->fw.channel == channel &&
564 sas_info->fw.id == id))) {
565 list_del(&sas_info->list);
570 sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
575 * Set Firmware mapping
577 sas_info->fw.id = id;
578 sas_info->fw.channel = channel;
580 sas_info->sas_address = sas_address;
581 sas_info->device_info = device_info;
582 sas_info->slot = slot;
583 sas_info->enclosure_logical_id = enclosure_logical_id;
584 INIT_LIST_HEAD(&sas_info->list);
585 list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
590 shost_for_each_device(sdev, ioc->sh) {
591 starget = scsi_target(sdev);
592 rphy = dev_to_rphy(starget->dev.parent);
593 if (rphy->identify.sas_address == sas_address) {
594 sas_info->os.id = starget->id;
595 sas_info->os.channel = starget->channel;
600 mutex_unlock(&ioc->sas_device_info_mutex);
605 * mptsas_add_device_component_by_fw -
606 * @ioc: Pointer to MPT_ADAPTER structure
607 * @channel: fw mapped id's
612 mptsas_add_device_component_by_fw(MPT_ADAPTER *ioc, u8 channel, u8 id)
614 struct mptsas_devinfo sas_device;
615 struct mptsas_enclosure enclosure_info;
618 rc = mptsas_sas_device_pg0(ioc, &sas_device,
619 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
620 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
621 (channel << 8) + id);
625 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
626 mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
627 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
628 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
629 sas_device.handle_enclosure);
631 mptsas_add_device_component(ioc, sas_device.channel,
632 sas_device.id, sas_device.sas_address, sas_device.device_info,
633 sas_device.slot, enclosure_info.enclosure_logical_id);
637 * mptsas_add_device_component_starget_ir - Handle Integrated RAID, adding each individual device to list
638 * @ioc: Pointer to MPT_ADAPTER structure
639 * @channel: fw mapped id's
644 mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc,
645 struct scsi_target *starget)
648 ConfigPageHeader_t hdr;
649 dma_addr_t dma_handle;
650 pRaidVolumePage0_t buffer = NULL;
652 RaidPhysDiskPage0_t phys_disk;
653 struct mptsas_device_info *sas_info, *next;
655 memset(&cfg, 0 , sizeof(CONFIGPARMS));
656 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
657 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
658 /* assumption that all volumes on channel = 0 */
659 cfg.pageAddr = starget->id;
660 cfg.cfghdr.hdr = &hdr;
661 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
662 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
664 if (mpt_config(ioc, &cfg) != 0)
670 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
676 cfg.physAddr = dma_handle;
677 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
679 if (mpt_config(ioc, &cfg) != 0)
682 if (!buffer->NumPhysDisks)
686 * Adding entry for hidden components
688 for (i = 0; i < buffer->NumPhysDisks; i++) {
690 if (mpt_raid_phys_disk_pg0(ioc,
691 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
694 mptsas_add_device_component_by_fw(ioc, phys_disk.PhysDiskBus,
695 phys_disk.PhysDiskID);
697 mutex_lock(&ioc->sas_device_info_mutex);
698 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
700 if (!sas_info->is_logical_volume &&
701 (sas_info->fw.channel == phys_disk.PhysDiskBus &&
702 sas_info->fw.id == phys_disk.PhysDiskID)) {
703 sas_info->is_hidden_raid_component = 1;
704 sas_info->volume_id = starget->id;
707 mutex_unlock(&ioc->sas_device_info_mutex);
712 * Delete all matching devices out of the list
714 mutex_lock(&ioc->sas_device_info_mutex);
715 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
717 if (sas_info->is_logical_volume && sas_info->fw.id ==
719 list_del(&sas_info->list);
724 sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
726 sas_info->fw.id = starget->id;
727 sas_info->os.id = starget->id;
728 sas_info->os.channel = starget->channel;
729 sas_info->is_logical_volume = 1;
730 INIT_LIST_HEAD(&sas_info->list);
731 list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
733 mutex_unlock(&ioc->sas_device_info_mutex);
737 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
742 * mptsas_add_device_component_starget -
743 * @ioc: Pointer to MPT_ADAPTER structure
748 mptsas_add_device_component_starget(MPT_ADAPTER *ioc,
749 struct scsi_target *starget)
752 struct sas_rphy *rphy;
753 struct mptsas_phyinfo *phy_info = NULL;
754 struct mptsas_enclosure enclosure_info;
756 rphy = dev_to_rphy(starget->dev.parent);
757 vtarget = starget->hostdata;
758 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
759 rphy->identify.sas_address);
763 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
764 mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
765 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
766 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
767 phy_info->attached.handle_enclosure);
769 mptsas_add_device_component(ioc, phy_info->attached.channel,
770 phy_info->attached.id, phy_info->attached.sas_address,
771 phy_info->attached.device_info,
772 phy_info->attached.slot, enclosure_info.enclosure_logical_id);
776 * mptsas_del_device_component_by_os - Once a device has been removed, we mark the entry in the list as being cached
777 * @ioc: Pointer to MPT_ADAPTER structure
778 * @channel: os mapped id's
783 mptsas_del_device_component_by_os(MPT_ADAPTER *ioc, u8 channel, u8 id)
785 struct mptsas_device_info *sas_info, *next;
790 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
792 if (sas_info->os.channel == channel && sas_info->os.id == id)
793 sas_info->is_cached = 1;
798 * mptsas_del_device_components - Cleaning the list
799 * @ioc: Pointer to MPT_ADAPTER structure
803 mptsas_del_device_components(MPT_ADAPTER *ioc)
805 struct mptsas_device_info *sas_info, *next;
807 mutex_lock(&ioc->sas_device_info_mutex);
808 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
810 list_del(&sas_info->list);
813 mutex_unlock(&ioc->sas_device_info_mutex);
818 * mptsas_setup_wide_ports
820 * Updates for new and existing narrow/wide port configuration
821 * in the sas_topology
824 mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
826 struct mptsas_portinfo_details * port_details;
827 struct mptsas_phyinfo *phy_info, *phy_info_cmp;
831 mutex_lock(&ioc->sas_topology_mutex);
833 phy_info = port_info->phy_info;
834 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
835 if (phy_info->attached.handle)
837 port_details = phy_info->port_details;
840 if (port_details->num_phys < 2)
843 * Removing a phy from a port, letting the last
844 * phy be removed by firmware events.
846 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
847 "%s: [%p]: deleting phy = %d\n",
848 ioc->name, __func__, port_details, i));
849 port_details->num_phys--;
850 port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
851 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
853 devtprintk(ioc, dev_printk(KERN_DEBUG,
854 &phy_info->phy->dev, MYIOC_s_FMT
855 "delete phy %d, phy-obj (0x%p)\n", ioc->name,
856 phy_info->phy_id, phy_info->phy));
857 sas_port_delete_phy(port_details->port, phy_info->phy);
859 phy_info->port_details = NULL;
863 * Populate and refresh the tree
865 phy_info = port_info->phy_info;
866 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
867 sas_address = phy_info->attached.sas_address;
868 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "phy_id=%d sas_address=0x%018llX\n",
869 ioc->name, i, (unsigned long long)sas_address));
872 port_details = phy_info->port_details;
877 port_details = kzalloc(sizeof(struct
878 mptsas_portinfo_details), GFP_KERNEL);
881 port_details->num_phys = 1;
882 port_details->port_info = port_info;
883 if (phy_info->phy_id < 64 )
884 port_details->phy_bitmask |=
885 (1 << phy_info->phy_id);
886 phy_info->sas_port_add_phy=1;
887 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tForming port\n\t\t"
888 "phy_id=%d sas_address=0x%018llX\n",
889 ioc->name, i, (unsigned long long)sas_address));
890 phy_info->port_details = port_details;
893 if (i == port_info->num_phys - 1)
895 phy_info_cmp = &port_info->phy_info[i + 1];
896 for (j = i + 1 ; j < port_info->num_phys ; j++,
898 if (!phy_info_cmp->attached.sas_address)
900 if (sas_address != phy_info_cmp->attached.sas_address)
902 if (phy_info_cmp->port_details == port_details )
904 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
905 "\t\tphy_id=%d sas_address=0x%018llX\n",
906 ioc->name, j, (unsigned long long)
907 phy_info_cmp->attached.sas_address));
908 if (phy_info_cmp->port_details) {
910 mptsas_get_rphy(phy_info_cmp);
912 mptsas_get_port(phy_info_cmp);
913 port_details->starget =
914 mptsas_get_starget(phy_info_cmp);
915 port_details->num_phys =
916 phy_info_cmp->port_details->num_phys;
917 if (!phy_info_cmp->port_details->num_phys)
918 kfree(phy_info_cmp->port_details);
920 phy_info_cmp->sas_port_add_phy=1;
922 * Adding a phy to a port
924 phy_info_cmp->port_details = port_details;
925 if (phy_info_cmp->phy_id < 64 )
926 port_details->phy_bitmask |=
927 (1 << phy_info_cmp->phy_id);
928 port_details->num_phys++;
934 for (i = 0; i < port_info->num_phys; i++) {
935 port_details = port_info->phy_info[i].port_details;
938 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
939 "%s: [%p]: phy_id=%02d num_phys=%02d "
940 "bitmask=0x%016llX\n", ioc->name, __func__,
941 port_details, i, port_details->num_phys,
942 (unsigned long long)port_details->phy_bitmask));
943 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n",
944 ioc->name, port_details->port, port_details->rphy));
946 dsaswideprintk(ioc, printk("\n"));
947 mutex_unlock(&ioc->sas_topology_mutex);
951 * csmisas_find_vtarget
959 mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
961 struct scsi_device *sdev;
963 VirtTarget *vtarget = NULL;
965 shost_for_each_device(sdev, ioc->sh) {
966 vdevice = sdev->hostdata;
967 if ((vdevice == NULL) ||
968 (vdevice->vtarget == NULL))
970 if ((vdevice->vtarget->tflags &
971 MPT_TARGET_FLAGS_RAID_COMPONENT ||
972 vdevice->vtarget->raidVolume))
974 if (vdevice->vtarget->id == id &&
975 vdevice->vtarget->channel == channel)
976 vtarget = vdevice->vtarget;
982 mptsas_queue_device_delete(MPT_ADAPTER *ioc,
983 MpiEventDataSasDeviceStatusChange_t *sas_event_data)
985 struct fw_event_work *fw_event;
988 sz = offsetof(struct fw_event_work, event_data) +
989 sizeof(MpiEventDataSasDeviceStatusChange_t);
990 fw_event = kzalloc(sz, GFP_ATOMIC);
992 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
993 ioc->name, __func__, __LINE__);
996 memcpy(fw_event->event_data, sas_event_data,
997 sizeof(MpiEventDataSasDeviceStatusChange_t));
998 fw_event->event = MPI_EVENT_SAS_DEVICE_STATUS_CHANGE;
1000 mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
1004 mptsas_queue_rescan(MPT_ADAPTER *ioc)
1006 struct fw_event_work *fw_event;
1009 sz = offsetof(struct fw_event_work, event_data);
1010 fw_event = kzalloc(sz, GFP_ATOMIC);
1012 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
1013 ioc->name, __func__, __LINE__);
1016 fw_event->event = -1;
1017 fw_event->ioc = ioc;
1018 mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
1023 * mptsas_target_reset
1025 * Issues TARGET_RESET to end device using handshaking method
1031 * Returns (1) success
1036 mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
1039 SCSITaskMgmt_t *pScsiTm;
1040 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0)
1044 mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
1046 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1047 "%s, no msg frames @%d!!\n", ioc->name,
1048 __func__, __LINE__));
1052 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1055 /* Format the Request
1057 pScsiTm = (SCSITaskMgmt_t *) mf;
1058 memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
1059 pScsiTm->TargetID = id;
1060 pScsiTm->Bus = channel;
1061 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1062 pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
1063 pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
1065 DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
1067 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1068 "TaskMgmt type=%d (sas device delete) fw_channel = %d fw_id = %d)\n",
1069 ioc->name, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, channel, id));
1071 mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
1077 mpt_clear_taskmgmt_in_progress_flag(ioc);
1082 mptsas_block_io_sdev(struct scsi_device *sdev, void *data)
1084 scsi_device_set_state(sdev, SDEV_BLOCK);
1088 mptsas_block_io_starget(struct scsi_target *starget)
1091 starget_for_each_device(starget, NULL, mptsas_block_io_sdev);
1095 * mptsas_target_reset_queue
1097 * Receive request for TARGET_RESET after recieving an firmware
1098 * event NOT_RESPONDING_EVENT, then put command in link list
1099 * and queue if task_queue already in use.
1106 mptsas_target_reset_queue(MPT_ADAPTER *ioc,
1107 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1109 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
1110 VirtTarget *vtarget = NULL;
1111 struct mptsas_target_reset_event *target_reset_list;
1114 id = sas_event_data->TargetID;
1115 channel = sas_event_data->Bus;
1117 vtarget = mptsas_find_vtarget(ioc, channel, id);
1119 mptsas_block_io_starget(vtarget->starget);
1120 vtarget->deleted = 1; /* block IO */
1123 target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event),
1125 if (!target_reset_list) {
1126 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1127 "%s, failed to allocate mem @%d..!!\n",
1128 ioc->name, __func__, __LINE__));
1132 memcpy(&target_reset_list->sas_event_data, sas_event_data,
1133 sizeof(*sas_event_data));
1134 list_add_tail(&target_reset_list->list, &hd->target_reset_list);
1136 target_reset_list->time_count = jiffies;
1138 if (mptsas_target_reset(ioc, channel, id)) {
1139 target_reset_list->target_reset_issued = 1;
1144 * mptsas_schedule_target_reset- send pending target reset
1145 * @iocp: per adapter object
1147 * This function will delete scheduled target reset from the list and
1148 * try to send next target reset. This will be called from completion
1149 * context of any Task managment command.
1153 mptsas_schedule_target_reset(void *iocp)
1155 MPT_ADAPTER *ioc = (MPT_ADAPTER *)(iocp);
1156 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
1157 struct list_head *head = &hd->target_reset_list;
1158 struct mptsas_target_reset_event *target_reset_list;
1161 * issue target reset to next device in the queue
1164 head = &hd->target_reset_list;
1165 if (list_empty(head))
1168 target_reset_list = list_entry(head->next,
1169 struct mptsas_target_reset_event, list);
1171 id = target_reset_list->sas_event_data.TargetID;
1172 channel = target_reset_list->sas_event_data.Bus;
1173 target_reset_list->time_count = jiffies;
1175 if (mptsas_target_reset(ioc, channel, id))
1176 target_reset_list->target_reset_issued = 1;
1182 * mptsas_taskmgmt_complete - complete SAS task management function
1183 * @ioc: Pointer to MPT_ADAPTER structure
1185 * Completion for TARGET_RESET after NOT_RESPONDING_EVENT, enable work
1186 * queue to finish off removing device from upper layers. then send next
1187 * TARGET_RESET in the queue.
1190 mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
1192 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
1193 struct list_head *head = &hd->target_reset_list;
1195 struct mptsas_target_reset_event *target_reset_list;
1196 SCSITaskMgmtReply_t *pScsiTmReply;
1198 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt completed: "
1199 "(mf = %p, mr = %p)\n", ioc->name, mf, mr));
1201 pScsiTmReply = (SCSITaskMgmtReply_t *)mr;
1203 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1204 "\tTaskMgmt completed: fw_channel = %d, fw_id = %d,\n"
1205 "\ttask_type = 0x%02X, iocstatus = 0x%04X "
1206 "loginfo = 0x%08X,\n\tresponse_code = 0x%02X, "
1207 "term_cmnds = %d\n", ioc->name,
1208 pScsiTmReply->Bus, pScsiTmReply->TargetID,
1209 pScsiTmReply->TaskType,
1210 le16_to_cpu(pScsiTmReply->IOCStatus),
1211 le32_to_cpu(pScsiTmReply->IOCLogInfo),
1212 pScsiTmReply->ResponseCode,
1213 le32_to_cpu(pScsiTmReply->TerminationCount)));
1215 if (pScsiTmReply->ResponseCode)
1216 mptscsih_taskmgmt_response_code(ioc,
1217 pScsiTmReply->ResponseCode);
1220 if (pScsiTmReply && (pScsiTmReply->TaskType ==
1221 MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK || pScsiTmReply->TaskType ==
1222 MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET)) {
1223 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
1224 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
1225 memcpy(ioc->taskmgmt_cmds.reply, mr,
1226 min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
1227 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
1228 ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
1229 complete(&ioc->taskmgmt_cmds.done);
1235 mpt_clear_taskmgmt_in_progress_flag(ioc);
1237 if (list_empty(head))
1240 target_reset_list = list_entry(head->next,
1241 struct mptsas_target_reset_event, list);
1243 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1244 "TaskMgmt: completed (%d seconds)\n",
1245 ioc->name, jiffies_to_msecs(jiffies -
1246 target_reset_list->time_count)/1000));
1248 id = pScsiTmReply->TargetID;
1249 channel = pScsiTmReply->Bus;
1250 target_reset_list->time_count = jiffies;
1253 * retry target reset
1255 if (!target_reset_list->target_reset_issued) {
1256 if (mptsas_target_reset(ioc, channel, id))
1257 target_reset_list->target_reset_issued = 1;
1262 * enable work queue to remove device from upper layers
1264 list_del(&target_reset_list->list);
1265 if (!ioc->fw_events_off)
1266 mptsas_queue_device_delete(ioc,
1267 &target_reset_list->sas_event_data);
1270 ioc->schedule_target_reset(ioc);
1276 * mptscsih_ioc_reset
1283 mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1288 rc = mptscsih_ioc_reset(ioc, reset_phase);
1289 if ((ioc->bus_type != SAS) || (!rc))
1292 hd = shost_priv(ioc->sh);
1296 switch (reset_phase) {
1297 case MPT_IOC_SETUP_RESET:
1298 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1299 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
1300 mptsas_fw_event_off(ioc);
1302 case MPT_IOC_PRE_RESET:
1303 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1304 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
1306 case MPT_IOC_POST_RESET:
1307 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1308 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
1309 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
1310 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_DID_IOCRESET;
1311 complete(&ioc->sas_mgmt.done);
1313 mptsas_cleanup_fw_event_q(ioc);
1314 mptsas_queue_rescan(ioc);
1326 * enum device_state -
1327 * @DEVICE_RETRY: need to retry the TUR
1328 * @DEVICE_ERROR: TUR return error, don't add device
1329 * @DEVICE_READY: device can be added
1339 mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
1340 u32 form, u32 form_specific)
1342 ConfigExtendedPageHeader_t hdr;
1344 SasEnclosurePage0_t *buffer;
1345 dma_addr_t dma_handle;
1347 __le64 le_identifier;
1349 memset(&hdr, 0, sizeof(hdr));
1350 hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
1352 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1353 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
1355 cfg.cfghdr.ehdr = &hdr;
1357 cfg.pageAddr = form + form_specific;
1358 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1359 cfg.dir = 0; /* read */
1360 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
1362 error = mpt_config(ioc, &cfg);
1365 if (!hdr.ExtPageLength) {
1370 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1377 cfg.physAddr = dma_handle;
1378 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1380 error = mpt_config(ioc, &cfg);
1382 goto out_free_consistent;
1384 /* save config data */
1385 memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
1386 enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
1387 enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
1388 enclosure->flags = le16_to_cpu(buffer->Flags);
1389 enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
1390 enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
1391 enclosure->start_id = buffer->StartTargetID;
1392 enclosure->start_channel = buffer->StartBus;
1393 enclosure->sep_id = buffer->SEPTargetID;
1394 enclosure->sep_channel = buffer->SEPBus;
1396 out_free_consistent:
1397 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1398 buffer, dma_handle);
1404 * mptsas_add_end_device - report a new end device to sas transport layer
1405 * @ioc: Pointer to MPT_ADAPTER structure
1406 * @phy_info: decribes attached device
1408 * return (0) success (1) failure
1412 mptsas_add_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1414 struct sas_rphy *rphy;
1415 struct sas_port *port;
1416 struct sas_identify identify;
1421 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1422 "%s: exit at line=%d\n", ioc->name,
1423 __func__, __LINE__));
1427 fw_id = phy_info->attached.id;
1429 if (mptsas_get_rphy(phy_info)) {
1430 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1431 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1432 __func__, fw_id, __LINE__));
1436 port = mptsas_get_port(phy_info);
1438 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1439 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1440 __func__, fw_id, __LINE__));
1444 if (phy_info->attached.device_info &
1445 MPI_SAS_DEVICE_INFO_SSP_TARGET)
1447 if (phy_info->attached.device_info &
1448 MPI_SAS_DEVICE_INFO_STP_TARGET)
1450 if (phy_info->attached.device_info &
1451 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1454 printk(MYIOC_s_INFO_FMT "attaching %s device: fw_channel %d, fw_id %d,"
1455 " phy %d, sas_addr 0x%llx\n", ioc->name, ds,
1456 phy_info->attached.channel, phy_info->attached.id,
1457 phy_info->attached.phy_id, (unsigned long long)
1458 phy_info->attached.sas_address);
1460 mptsas_parse_device_info(&identify, &phy_info->attached);
1461 rphy = sas_end_device_alloc(port);
1463 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1464 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1465 __func__, fw_id, __LINE__));
1466 return 5; /* non-fatal: an rphy can be added later */
1469 rphy->identify = identify;
1470 if (sas_rphy_add(rphy)) {
1471 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1472 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1473 __func__, fw_id, __LINE__));
1474 sas_rphy_free(rphy);
1477 mptsas_set_rphy(ioc, phy_info, rphy);
1482 * mptsas_del_end_device - report a deleted end device to sas transport layer
1483 * @ioc: Pointer to MPT_ADAPTER structure
1484 * @phy_info: decribes attached device
1488 mptsas_del_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1490 struct sas_rphy *rphy;
1491 struct sas_port *port;
1492 struct mptsas_portinfo *port_info;
1493 struct mptsas_phyinfo *phy_info_parent;
1502 fw_id = phy_info->attached.id;
1503 sas_address = phy_info->attached.sas_address;
1505 if (!phy_info->port_details) {
1506 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1507 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1508 __func__, fw_id, __LINE__));
1511 rphy = mptsas_get_rphy(phy_info);
1513 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1514 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1515 __func__, fw_id, __LINE__));
1519 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_INITIATOR
1520 || phy_info->attached.device_info
1521 & MPI_SAS_DEVICE_INFO_SMP_INITIATOR
1522 || phy_info->attached.device_info
1523 & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1525 if (phy_info->attached.device_info &
1526 MPI_SAS_DEVICE_INFO_SSP_TARGET)
1528 if (phy_info->attached.device_info &
1529 MPI_SAS_DEVICE_INFO_STP_TARGET)
1531 if (phy_info->attached.device_info &
1532 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1535 dev_printk(KERN_DEBUG, &rphy->dev, MYIOC_s_FMT
1536 "removing %s device: fw_channel %d, fw_id %d, phy %d,"
1537 "sas_addr 0x%llx\n", ioc->name, ds, phy_info->attached.channel,
1538 phy_info->attached.id, phy_info->attached.phy_id,
1539 (unsigned long long) sas_address);
1541 port = mptsas_get_port(phy_info);
1543 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1544 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1545 __func__, fw_id, __LINE__));
1548 port_info = phy_info->portinfo;
1549 phy_info_parent = port_info->phy_info;
1550 for (i = 0; i < port_info->num_phys; i++, phy_info_parent++) {
1551 if (!phy_info_parent->phy)
1553 if (phy_info_parent->attached.sas_address !=
1556 dev_printk(KERN_DEBUG, &phy_info_parent->phy->dev,
1557 MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n",
1558 ioc->name, phy_info_parent->phy_id,
1559 phy_info_parent->phy);
1560 sas_port_delete_phy(port, phy_info_parent->phy);
1563 dev_printk(KERN_DEBUG, &port->dev, MYIOC_s_FMT
1564 "delete port %d, sas_addr (0x%llx)\n", ioc->name,
1565 port->port_identifier, (unsigned long long)sas_address);
1566 sas_port_delete(port);
1567 mptsas_set_port(ioc, phy_info, NULL);
1568 mptsas_port_delete(ioc, phy_info->port_details);
1571 struct mptsas_phyinfo *
1572 mptsas_refreshing_device_handles(MPT_ADAPTER *ioc,
1573 struct mptsas_devinfo *sas_device)
1575 struct mptsas_phyinfo *phy_info;
1576 struct mptsas_portinfo *port_info;
1579 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
1580 sas_device->sas_address);
1583 port_info = phy_info->portinfo;
1586 mutex_lock(&ioc->sas_topology_mutex);
1587 for (i = 0; i < port_info->num_phys; i++) {
1588 if (port_info->phy_info[i].attached.sas_address !=
1589 sas_device->sas_address)
1591 port_info->phy_info[i].attached.channel = sas_device->channel;
1592 port_info->phy_info[i].attached.id = sas_device->id;
1593 port_info->phy_info[i].attached.sas_address =
1594 sas_device->sas_address;
1595 port_info->phy_info[i].attached.handle = sas_device->handle;
1596 port_info->phy_info[i].attached.handle_parent =
1597 sas_device->handle_parent;
1598 port_info->phy_info[i].attached.handle_enclosure =
1599 sas_device->handle_enclosure;
1601 mutex_unlock(&ioc->sas_topology_mutex);
1607 * mptsas_firmware_event_work - work thread for processing fw events
1608 * @work: work queue payload containing info describing the event
1613 mptsas_firmware_event_work(struct work_struct *work)
1615 struct fw_event_work *fw_event =
1616 container_of(work, struct fw_event_work, work.work);
1617 MPT_ADAPTER *ioc = fw_event->ioc;
1619 /* special rescan topology handling */
1620 if (fw_event->event == -1) {
1621 if (ioc->in_rescan) {
1622 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1623 "%s: rescan ignored as it is in progress\n",
1624 ioc->name, __func__));
1627 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: rescan after "
1628 "reset\n", ioc->name, __func__));
1630 mptsas_not_responding_devices(ioc);
1631 mptsas_scan_sas_topology(ioc);
1633 mptsas_free_fw_event(ioc, fw_event);
1634 mptsas_fw_event_on(ioc);
1638 /* events handling turned off during host reset */
1639 if (ioc->fw_events_off) {
1640 mptsas_free_fw_event(ioc, fw_event);
1644 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: fw_event=(0x%p), "
1645 "event = (0x%02x)\n", ioc->name, __func__, fw_event,
1646 (fw_event->event & 0xFF)));
1648 switch (fw_event->event) {
1649 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1650 mptsas_send_sas_event(fw_event);
1652 case MPI_EVENT_INTEGRATED_RAID:
1653 mptsas_send_raid_event(fw_event);
1656 mptsas_send_ir2_event(fw_event);
1658 case MPI_EVENT_PERSISTENT_TABLE_FULL:
1659 mptbase_sas_persist_operation(ioc,
1660 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1661 mptsas_free_fw_event(ioc, fw_event);
1663 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
1664 mptsas_broadcast_primative_work(fw_event);
1666 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
1667 mptsas_send_expander_event(fw_event);
1669 case MPI_EVENT_SAS_PHY_LINK_STATUS:
1670 mptsas_send_link_status_event(fw_event);
1672 case MPI_EVENT_QUEUE_FULL:
1673 mptsas_handle_queue_full_event(fw_event);
1681 mptsas_slave_configure(struct scsi_device *sdev)
1683 struct Scsi_Host *host = sdev->host;
1684 MPT_SCSI_HOST *hd = shost_priv(host);
1685 MPT_ADAPTER *ioc = hd->ioc;
1686 VirtDevice *vdevice = sdev->hostdata;
1688 if (vdevice->vtarget->deleted) {
1689 sdev_printk(KERN_INFO, sdev, "clearing deleted flag\n");
1690 vdevice->vtarget->deleted = 0;
1694 * RAID volumes placed beyond the last expected port.
1695 * Ignore sending sas mode pages in that case..
1697 if (sdev->channel == MPTSAS_RAID_CHANNEL) {
1698 mptsas_add_device_component_starget_ir(ioc, scsi_target(sdev));
1702 sas_read_port_mode_page(sdev);
1704 mptsas_add_device_component_starget(ioc, scsi_target(sdev));
1707 return mptscsih_slave_configure(sdev);
1711 mptsas_target_alloc(struct scsi_target *starget)
1713 struct Scsi_Host *host = dev_to_shost(&starget->dev);
1714 MPT_SCSI_HOST *hd = shost_priv(host);
1715 VirtTarget *vtarget;
1717 struct sas_rphy *rphy;
1718 struct mptsas_portinfo *p;
1720 MPT_ADAPTER *ioc = hd->ioc;
1722 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
1726 vtarget->starget = starget;
1727 vtarget->ioc_id = ioc->id;
1728 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
1733 * RAID volumes placed beyond the last expected port.
1735 if (starget->channel == MPTSAS_RAID_CHANNEL) {
1736 if (!ioc->raid_data.pIocPg2) {
1740 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
1741 if (id == ioc->raid_data.pIocPg2->
1742 RaidVolume[i].VolumeID) {
1743 channel = ioc->raid_data.pIocPg2->
1744 RaidVolume[i].VolumeBus;
1747 vtarget->raidVolume = 1;
1751 rphy = dev_to_rphy(starget->dev.parent);
1752 mutex_lock(&ioc->sas_topology_mutex);
1753 list_for_each_entry(p, &ioc->sas_topology, list) {
1754 for (i = 0; i < p->num_phys; i++) {
1755 if (p->phy_info[i].attached.sas_address !=
1756 rphy->identify.sas_address)
1758 id = p->phy_info[i].attached.id;
1759 channel = p->phy_info[i].attached.channel;
1760 mptsas_set_starget(&p->phy_info[i], starget);
1763 * Exposing hidden raid components
1765 if (mptscsih_is_phys_disk(ioc, channel, id)) {
1766 id = mptscsih_raid_id_to_num(ioc,
1769 MPT_TARGET_FLAGS_RAID_COMPONENT;
1770 p->phy_info[i].attached.phys_disk_num = id;
1772 mutex_unlock(&ioc->sas_topology_mutex);
1776 mutex_unlock(&ioc->sas_topology_mutex);
1783 vtarget->channel = channel;
1784 starget->hostdata = vtarget;
1789 mptsas_target_destroy(struct scsi_target *starget)
1791 struct Scsi_Host *host = dev_to_shost(&starget->dev);
1792 MPT_SCSI_HOST *hd = shost_priv(host);
1793 struct sas_rphy *rphy;
1794 struct mptsas_portinfo *p;
1796 MPT_ADAPTER *ioc = hd->ioc;
1797 VirtTarget *vtarget;
1799 if (!starget->hostdata)
1802 vtarget = starget->hostdata;
1804 mptsas_del_device_component_by_os(ioc, starget->channel,
1808 if (starget->channel == MPTSAS_RAID_CHANNEL)
1811 rphy = dev_to_rphy(starget->dev.parent);
1812 list_for_each_entry(p, &ioc->sas_topology, list) {
1813 for (i = 0; i < p->num_phys; i++) {
1814 if (p->phy_info[i].attached.sas_address !=
1815 rphy->identify.sas_address)
1818 starget_printk(KERN_INFO, starget, MYIOC_s_FMT
1819 "delete device: fw_channel %d, fw_id %d, phy %d, "
1820 "sas_addr 0x%llx\n", ioc->name,
1821 p->phy_info[i].attached.channel,
1822 p->phy_info[i].attached.id,
1823 p->phy_info[i].attached.phy_id, (unsigned long long)
1824 p->phy_info[i].attached.sas_address);
1826 mptsas_set_starget(&p->phy_info[i], NULL);
1831 vtarget->starget = NULL;
1832 kfree(starget->hostdata);
1833 starget->hostdata = NULL;
1838 mptsas_slave_alloc(struct scsi_device *sdev)
1840 struct Scsi_Host *host = sdev->host;
1841 MPT_SCSI_HOST *hd = shost_priv(host);
1842 struct sas_rphy *rphy;
1843 struct mptsas_portinfo *p;
1844 VirtDevice *vdevice;
1845 struct scsi_target *starget;
1847 MPT_ADAPTER *ioc = hd->ioc;
1849 vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
1851 printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
1852 ioc->name, sizeof(VirtDevice));
1855 starget = scsi_target(sdev);
1856 vdevice->vtarget = starget->hostdata;
1858 if (sdev->channel == MPTSAS_RAID_CHANNEL)
1861 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
1862 mutex_lock(&ioc->sas_topology_mutex);
1863 list_for_each_entry(p, &ioc->sas_topology, list) {
1864 for (i = 0; i < p->num_phys; i++) {
1865 if (p->phy_info[i].attached.sas_address !=
1866 rphy->identify.sas_address)
1868 vdevice->lun = sdev->lun;
1870 * Exposing hidden raid components
1872 if (mptscsih_is_phys_disk(ioc,
1873 p->phy_info[i].attached.channel,
1874 p->phy_info[i].attached.id))
1875 sdev->no_uld_attach = 1;
1876 mutex_unlock(&ioc->sas_topology_mutex);
1880 mutex_unlock(&ioc->sas_topology_mutex);
1886 vdevice->vtarget->num_luns++;
1887 sdev->hostdata = vdevice;
1892 mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1896 VirtDevice *vdevice = SCpnt->device->hostdata;
1898 if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
1899 SCpnt->result = DID_NO_CONNECT << 16;
1904 hd = shost_priv(SCpnt->device->host);
1907 if (ioc->sas_discovery_quiesce_io)
1908 return SCSI_MLQUEUE_HOST_BUSY;
1910 if (ioc->debug_level & MPT_DEBUG_SCSI)
1911 scsi_print_command(SCpnt);
1913 return mptscsih_qcmd(SCpnt,done);
1917 * mptsas_mptsas_eh_timed_out - resets the scsi_cmnd timeout
1918 * if the device under question is currently in the
1919 * device removal delay.
1920 * @sc: scsi command that the midlayer is about to time out
1923 static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc)
1927 VirtDevice *vdevice;
1928 enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED;
1930 hd = shost_priv(sc->device->host);
1932 printk(KERN_ERR MYNAM ": %s: Can't locate host! (sc=%p)\n",
1938 if (ioc->bus_type != SAS) {
1939 printk(KERN_ERR MYNAM ": %s: Wrong bus type (sc=%p)\n",
1944 vdevice = sc->device->hostdata;
1945 if (vdevice && vdevice->vtarget && (vdevice->vtarget->inDMD
1946 || vdevice->vtarget->deleted)) {
1947 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: target removed "
1948 "or in device removal delay (sc=%p)\n",
1949 ioc->name, __func__, sc));
1950 rc = BLK_EH_RESET_TIMER;
1959 static struct scsi_host_template mptsas_driver_template = {
1960 .module = THIS_MODULE,
1961 .proc_name = "mptsas",
1962 .proc_info = mptscsih_proc_info,
1963 .name = "MPT SAS Host",
1964 .info = mptscsih_info,
1965 .queuecommand = mptsas_qcmd,
1966 .target_alloc = mptsas_target_alloc,
1967 .slave_alloc = mptsas_slave_alloc,
1968 .slave_configure = mptsas_slave_configure,
1969 .target_destroy = mptsas_target_destroy,
1970 .slave_destroy = mptscsih_slave_destroy,
1971 .change_queue_depth = mptscsih_change_queue_depth,
1972 .eh_abort_handler = mptscsih_abort,
1973 .eh_device_reset_handler = mptscsih_dev_reset,
1974 .eh_bus_reset_handler = mptscsih_bus_reset,
1975 .eh_host_reset_handler = mptscsih_host_reset,
1976 .bios_param = mptscsih_bios_param,
1977 .can_queue = MPT_SAS_CAN_QUEUE,
1979 .sg_tablesize = MPT_SCSI_SG_DEPTH,
1980 .max_sectors = 8192,
1982 .use_clustering = ENABLE_CLUSTERING,
1983 .shost_attrs = mptscsih_host_attrs,
1986 static int mptsas_get_linkerrors(struct sas_phy *phy)
1988 MPT_ADAPTER *ioc = phy_to_ioc(phy);
1989 ConfigExtendedPageHeader_t hdr;
1991 SasPhyPage1_t *buffer;
1992 dma_addr_t dma_handle;
1995 /* FIXME: only have link errors on local phys */
1996 if (!scsi_is_sas_phy_local(phy))
1999 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
2000 hdr.ExtPageLength = 0;
2001 hdr.PageNumber = 1 /* page number 1*/;
2004 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2005 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2007 cfg.cfghdr.ehdr = &hdr;
2009 cfg.pageAddr = phy->identify.phy_identifier;
2010 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2011 cfg.dir = 0; /* read */
2012 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2014 error = mpt_config(ioc, &cfg);
2017 if (!hdr.ExtPageLength)
2020 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2025 cfg.physAddr = dma_handle;
2026 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2028 error = mpt_config(ioc, &cfg);
2030 goto out_free_consistent;
2032 mptsas_print_phy_pg1(ioc, buffer);
2034 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
2035 phy->running_disparity_error_count =
2036 le32_to_cpu(buffer->RunningDisparityErrorCount);
2037 phy->loss_of_dword_sync_count =
2038 le32_to_cpu(buffer->LossDwordSynchCount);
2039 phy->phy_reset_problem_count =
2040 le32_to_cpu(buffer->PhyResetProblemCount);
2042 out_free_consistent:
2043 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2044 buffer, dma_handle);
2048 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2049 MPT_FRAME_HDR *reply)
2051 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2052 if (reply != NULL) {
2053 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_RF_VALID;
2054 memcpy(ioc->sas_mgmt.reply, reply,
2055 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
2058 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
2059 ioc->sas_mgmt.status &= ~MPT_MGMT_STATUS_PENDING;
2060 complete(&ioc->sas_mgmt.done);
2066 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
2068 MPT_ADAPTER *ioc = phy_to_ioc(phy);
2069 SasIoUnitControlRequest_t *req;
2070 SasIoUnitControlReply_t *reply;
2073 unsigned long timeleft;
2074 int error = -ERESTARTSYS;
2076 /* FIXME: fusion doesn't allow non-local phy reset */
2077 if (!scsi_is_sas_phy_local(phy))
2080 /* not implemented for expanders */
2081 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
2084 if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
2087 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2093 hdr = (MPIHeader_t *) mf;
2094 req = (SasIoUnitControlRequest_t *)mf;
2095 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
2096 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
2097 req->MsgContext = hdr->MsgContext;
2098 req->Operation = hard_reset ?
2099 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
2100 req->PhyNum = phy->identify.phy_identifier;
2102 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2103 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2105 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
2107 if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2109 mpt_free_msg_frame(ioc, mf);
2110 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2113 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2117 /* a reply frame is expected */
2118 if ((ioc->sas_mgmt.status &
2119 MPT_MGMT_STATUS_RF_VALID) == 0) {
2124 /* process the completed Reply Message Frame */
2125 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
2126 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
2127 printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
2128 ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo);
2136 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2137 mutex_unlock(&ioc->sas_mgmt.mutex);
2143 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
2145 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2147 struct mptsas_portinfo *p;
2148 struct mptsas_enclosure enclosure_info;
2149 u64 enclosure_handle;
2151 mutex_lock(&ioc->sas_topology_mutex);
2152 list_for_each_entry(p, &ioc->sas_topology, list) {
2153 for (i = 0; i < p->num_phys; i++) {
2154 if (p->phy_info[i].attached.sas_address ==
2155 rphy->identify.sas_address) {
2156 enclosure_handle = p->phy_info[i].
2157 attached.handle_enclosure;
2162 mutex_unlock(&ioc->sas_topology_mutex);
2166 mutex_unlock(&ioc->sas_topology_mutex);
2167 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
2168 error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
2169 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
2170 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
2172 *identifier = enclosure_info.enclosure_logical_id;
2177 mptsas_get_bay_identifier(struct sas_rphy *rphy)
2179 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2180 struct mptsas_portinfo *p;
2183 mutex_lock(&ioc->sas_topology_mutex);
2184 list_for_each_entry(p, &ioc->sas_topology, list) {
2185 for (i = 0; i < p->num_phys; i++) {
2186 if (p->phy_info[i].attached.sas_address ==
2187 rphy->identify.sas_address) {
2188 rc = p->phy_info[i].attached.slot;
2195 mutex_unlock(&ioc->sas_topology_mutex);
2199 static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
2200 struct request *req)
2202 MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
2204 SmpPassthroughRequest_t *smpreq;
2205 struct request *rsp = req->next_rq;
2208 unsigned long timeleft;
2210 dma_addr_t dma_addr_in = 0;
2211 dma_addr_t dma_addr_out = 0;
2212 u64 sas_address = 0;
2215 printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n",
2216 ioc->name, __func__);
2220 /* do we need to support multiple segments? */
2221 if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
2222 printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
2223 ioc->name, __func__, req->bio->bi_vcnt, blk_rq_bytes(req),
2224 rsp->bio->bi_vcnt, blk_rq_bytes(rsp));
2228 ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2232 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2238 smpreq = (SmpPassthroughRequest_t *)mf;
2239 memset(smpreq, 0, sizeof(*smpreq));
2241 smpreq->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
2242 smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2245 sas_address = rphy->identify.sas_address;
2247 struct mptsas_portinfo *port_info;
2249 mutex_lock(&ioc->sas_topology_mutex);
2250 port_info = ioc->hba_port_info;
2251 if (port_info && port_info->phy_info)
2253 port_info->phy_info[0].phy->identify.sas_address;
2254 mutex_unlock(&ioc->sas_topology_mutex);
2257 *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2260 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2263 flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2264 MPI_SGE_FLAGS_END_OF_BUFFER |
2265 MPI_SGE_FLAGS_DIRECTION)
2266 << MPI_SGE_FLAGS_SHIFT;
2267 flagsLength |= (blk_rq_bytes(req) - 4);
2269 dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
2270 blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
2273 ioc->add_sge(psge, flagsLength, dma_addr_out);
2274 psge += ioc->SGE_size;
2277 flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2278 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2279 MPI_SGE_FLAGS_IOC_TO_HOST |
2280 MPI_SGE_FLAGS_END_OF_BUFFER;
2282 flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2283 flagsLength |= blk_rq_bytes(rsp) + 4;
2284 dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio),
2285 blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
2288 ioc->add_sge(psge, flagsLength, dma_addr_in);
2290 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2291 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2293 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2294 if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2296 mpt_free_msg_frame(ioc, mf);
2298 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2301 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2306 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2307 SmpPassthroughReply_t *smprep;
2309 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2310 memcpy(req->sense, smprep, sizeof(*smprep));
2311 req->sense_len = sizeof(*smprep);
2313 rsp->resid_len -= smprep->ResponseDataLength;
2315 printk(MYIOC_s_ERR_FMT
2316 "%s: smp passthru reply failed to be returned\n",
2317 ioc->name, __func__);
2322 pci_unmap_single(ioc->pcidev, dma_addr_out, blk_rq_bytes(req),
2323 PCI_DMA_BIDIRECTIONAL);
2325 pci_unmap_single(ioc->pcidev, dma_addr_in, blk_rq_bytes(rsp),
2326 PCI_DMA_BIDIRECTIONAL);
2329 mpt_free_msg_frame(ioc, mf);
2331 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2332 mutex_unlock(&ioc->sas_mgmt.mutex);
2337 static struct sas_function_template mptsas_transport_functions = {
2338 .get_linkerrors = mptsas_get_linkerrors,
2339 .get_enclosure_identifier = mptsas_get_enclosure_identifier,
2340 .get_bay_identifier = mptsas_get_bay_identifier,
2341 .phy_reset = mptsas_phy_reset,
2342 .smp_handler = mptsas_smp_handler,
2345 static struct scsi_transport_template *mptsas_transport_template;
2348 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
2350 ConfigExtendedPageHeader_t hdr;
2352 SasIOUnitPage0_t *buffer;
2353 dma_addr_t dma_handle;
2356 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
2357 hdr.ExtPageLength = 0;
2361 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2362 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2364 cfg.cfghdr.ehdr = &hdr;
2367 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2368 cfg.dir = 0; /* read */
2369 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2371 error = mpt_config(ioc, &cfg);
2374 if (!hdr.ExtPageLength) {
2379 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2386 cfg.physAddr = dma_handle;
2387 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2389 error = mpt_config(ioc, &cfg);
2391 goto out_free_consistent;
2393 port_info->num_phys = buffer->NumPhys;
2394 port_info->phy_info = kcalloc(port_info->num_phys,
2395 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2396 if (!port_info->phy_info) {
2398 goto out_free_consistent;
2401 ioc->nvdata_version_persistent =
2402 le16_to_cpu(buffer->NvdataVersionPersistent);
2403 ioc->nvdata_version_default =
2404 le16_to_cpu(buffer->NvdataVersionDefault);
2406 for (i = 0; i < port_info->num_phys; i++) {
2407 mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
2408 port_info->phy_info[i].phy_id = i;
2409 port_info->phy_info[i].port_id =
2410 buffer->PhyData[i].Port;
2411 port_info->phy_info[i].negotiated_link_rate =
2412 buffer->PhyData[i].NegotiatedLinkRate;
2413 port_info->phy_info[i].portinfo = port_info;
2414 port_info->phy_info[i].handle =
2415 le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
2418 out_free_consistent:
2419 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2420 buffer, dma_handle);
2426 mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
2428 ConfigExtendedPageHeader_t hdr;
2430 SasIOUnitPage1_t *buffer;
2431 dma_addr_t dma_handle;
2433 u8 device_missing_delay;
2435 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
2436 memset(&cfg, 0, sizeof(CONFIGPARMS));
2438 cfg.cfghdr.ehdr = &hdr;
2439 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2440 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2441 cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2442 cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2443 cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
2444 cfg.cfghdr.ehdr->PageNumber = 1;
2446 error = mpt_config(ioc, &cfg);
2449 if (!hdr.ExtPageLength) {
2454 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2461 cfg.physAddr = dma_handle;
2462 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2464 error = mpt_config(ioc, &cfg);
2466 goto out_free_consistent;
2468 ioc->io_missing_delay =
2469 le16_to_cpu(buffer->IODeviceMissingDelay);
2470 device_missing_delay = buffer->ReportDeviceMissingDelay;
2471 ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
2472 (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
2473 device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
2475 out_free_consistent:
2476 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2477 buffer, dma_handle);
2483 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2484 u32 form, u32 form_specific)
2486 ConfigExtendedPageHeader_t hdr;
2488 SasPhyPage0_t *buffer;
2489 dma_addr_t dma_handle;
2492 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
2493 hdr.ExtPageLength = 0;
2497 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2498 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2500 cfg.cfghdr.ehdr = &hdr;
2501 cfg.dir = 0; /* read */
2502 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2504 /* Get Phy Pg 0 for each Phy. */
2506 cfg.pageAddr = form + form_specific;
2507 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2509 error = mpt_config(ioc, &cfg);
2513 if (!hdr.ExtPageLength) {
2518 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2525 cfg.physAddr = dma_handle;
2526 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2528 error = mpt_config(ioc, &cfg);
2530 goto out_free_consistent;
2532 mptsas_print_phy_pg0(ioc, buffer);
2534 phy_info->hw_link_rate = buffer->HwLinkRate;
2535 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2536 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2537 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2539 out_free_consistent:
2540 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2541 buffer, dma_handle);
2547 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
2548 u32 form, u32 form_specific)
2550 ConfigExtendedPageHeader_t hdr;
2552 SasDevicePage0_t *buffer;
2553 dma_addr_t dma_handle;
2557 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
2558 hdr.ExtPageLength = 0;
2562 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2563 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
2565 cfg.cfghdr.ehdr = &hdr;
2566 cfg.pageAddr = form + form_specific;
2568 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2569 cfg.dir = 0; /* read */
2570 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2572 memset(device_info, 0, sizeof(struct mptsas_devinfo));
2573 error = mpt_config(ioc, &cfg);
2576 if (!hdr.ExtPageLength) {
2581 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2588 cfg.physAddr = dma_handle;
2589 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2591 error = mpt_config(ioc, &cfg);
2593 if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2595 goto out_free_consistent;
2599 goto out_free_consistent;
2601 mptsas_print_device_pg0(ioc, buffer);
2603 memset(device_info, 0, sizeof(struct mptsas_devinfo));
2604 device_info->handle = le16_to_cpu(buffer->DevHandle);
2605 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
2606 device_info->handle_enclosure =
2607 le16_to_cpu(buffer->EnclosureHandle);
2608 device_info->slot = le16_to_cpu(buffer->Slot);
2609 device_info->phy_id = buffer->PhyNum;
2610 device_info->port_id = buffer->PhysicalPort;
2611 device_info->id = buffer->TargetID;
2612 device_info->phys_disk_num = ~0;
2613 device_info->channel = buffer->Bus;
2614 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2615 device_info->sas_address = le64_to_cpu(sas_address);
2616 device_info->device_info =
2617 le32_to_cpu(buffer->DeviceInfo);
2618 device_info->flags = le16_to_cpu(buffer->Flags);
2620 out_free_consistent:
2621 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2622 buffer, dma_handle);
2628 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
2629 u32 form, u32 form_specific)
2631 ConfigExtendedPageHeader_t hdr;
2633 SasExpanderPage0_t *buffer;
2634 dma_addr_t dma_handle;
2638 memset(port_info, 0, sizeof(struct mptsas_portinfo));
2639 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
2640 hdr.ExtPageLength = 0;
2644 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2645 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2647 cfg.cfghdr.ehdr = &hdr;
2649 cfg.pageAddr = form + form_specific;
2650 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2651 cfg.dir = 0; /* read */
2652 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2654 memset(port_info, 0, sizeof(struct mptsas_portinfo));
2655 error = mpt_config(ioc, &cfg);
2659 if (!hdr.ExtPageLength) {
2664 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2671 cfg.physAddr = dma_handle;
2672 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2674 error = mpt_config(ioc, &cfg);
2675 if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2677 goto out_free_consistent;
2681 goto out_free_consistent;
2683 /* save config data */
2684 port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1;
2685 port_info->phy_info = kcalloc(port_info->num_phys,
2686 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2687 if (!port_info->phy_info) {
2689 goto out_free_consistent;
2692 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2693 for (i = 0; i < port_info->num_phys; i++) {
2694 port_info->phy_info[i].portinfo = port_info;
2695 port_info->phy_info[i].handle =
2696 le16_to_cpu(buffer->DevHandle);
2697 port_info->phy_info[i].identify.sas_address =
2698 le64_to_cpu(sas_address);
2699 port_info->phy_info[i].identify.handle_parent =
2700 le16_to_cpu(buffer->ParentDevHandle);
2703 out_free_consistent:
2704 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2705 buffer, dma_handle);
2711 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2712 u32 form, u32 form_specific)
2714 ConfigExtendedPageHeader_t hdr;
2716 SasExpanderPage1_t *buffer;
2717 dma_addr_t dma_handle;
2720 hdr.PageVersion = MPI_SASEXPANDER1_PAGEVERSION;
2721 hdr.ExtPageLength = 0;
2725 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2726 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2728 cfg.cfghdr.ehdr = &hdr;
2730 cfg.pageAddr = form + form_specific;
2731 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2732 cfg.dir = 0; /* read */
2733 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2735 error = mpt_config(ioc, &cfg);
2739 if (!hdr.ExtPageLength) {
2744 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2751 cfg.physAddr = dma_handle;
2752 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2754 error = mpt_config(ioc, &cfg);
2756 if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2758 goto out_free_consistent;
2762 goto out_free_consistent;
2765 mptsas_print_expander_pg1(ioc, buffer);
2767 /* save config data */
2768 phy_info->phy_id = buffer->PhyIdentifier;
2769 phy_info->port_id = buffer->PhysicalPort;
2770 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
2771 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2772 phy_info->hw_link_rate = buffer->HwLinkRate;
2773 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2774 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2776 out_free_consistent:
2777 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2778 buffer, dma_handle);
2783 struct rep_manu_request{
2790 struct rep_manu_reply{
2791 u8 smp_frame_type; /* 0x41 */
2792 u8 function; /* 0x01 */
2795 u16 expander_change_count;
2800 u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
2801 u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
2802 u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
2803 u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
2805 u8 component_revision_id;
2807 u8 vendor_specific[8];
2811 * mptsas_exp_repmanufacture_info -
2812 * @ioc: per adapter object
2813 * @sas_address: expander sas address
2814 * @edev: the sas_expander_device object
2816 * Fills in the sas_expander_device object when SMP port is created.
2818 * Returns 0 for success, non-zero for failure.
2821 mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
2822 u64 sas_address, struct sas_expander_device *edev)
2825 SmpPassthroughRequest_t *smpreq;
2826 SmpPassthroughReply_t *smprep;
2827 struct rep_manu_reply *manufacture_reply;
2828 struct rep_manu_request *manufacture_request;
2831 unsigned long timeleft;
2833 unsigned long flags;
2834 void *data_out = NULL;
2835 dma_addr_t data_out_dma = 0;
2838 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2839 if (ioc->ioc_reset_in_progress) {
2840 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2841 printk(MYIOC_s_INFO_FMT "%s: host reset in progress!\n",
2842 __func__, ioc->name);
2845 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2847 ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2851 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2857 smpreq = (SmpPassthroughRequest_t *)mf;
2858 memset(smpreq, 0, sizeof(*smpreq));
2860 sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
2862 data_out = pci_alloc_consistent(ioc->pcidev, sz, &data_out_dma);
2864 printk(KERN_ERR "Memory allocation failure at %s:%d/%s()!\n",
2865 __FILE__, __LINE__, __func__);
2870 manufacture_request = data_out;
2871 manufacture_request->smp_frame_type = 0x40;
2872 manufacture_request->function = 1;
2873 manufacture_request->reserved = 0;
2874 manufacture_request->request_length = 0;
2876 smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2877 smpreq->PhysicalPort = 0xFF;
2878 *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2879 smpreq->RequestDataLength = sizeof(struct rep_manu_request);
2882 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2884 flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2885 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2886 MPI_SGE_FLAGS_HOST_TO_IOC |
2887 MPI_SGE_FLAGS_END_OF_BUFFER;
2888 flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2889 flagsLength |= sizeof(struct rep_manu_request);
2891 ioc->add_sge(psge, flagsLength, data_out_dma);
2892 psge += ioc->SGE_size;
2894 flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2895 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2896 MPI_SGE_FLAGS_IOC_TO_HOST |
2897 MPI_SGE_FLAGS_END_OF_BUFFER;
2898 flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2899 flagsLength |= sizeof(struct rep_manu_reply);
2900 ioc->add_sge(psge, flagsLength, data_out_dma +
2901 sizeof(struct rep_manu_request));
2903 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2904 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2906 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2907 if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2909 mpt_free_msg_frame(ioc, mf);
2911 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2914 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2920 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2923 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2924 if (le16_to_cpu(smprep->ResponseDataLength) !=
2925 sizeof(struct rep_manu_reply))
2928 manufacture_reply = data_out + sizeof(struct rep_manu_request);
2929 strncpy(edev->vendor_id, manufacture_reply->vendor_id,
2930 SAS_EXPANDER_VENDOR_ID_LEN);
2931 strncpy(edev->product_id, manufacture_reply->product_id,
2932 SAS_EXPANDER_PRODUCT_ID_LEN);
2933 strncpy(edev->product_rev, manufacture_reply->product_rev,
2934 SAS_EXPANDER_PRODUCT_REV_LEN);
2935 edev->level = manufacture_reply->sas_format;
2936 if (manufacture_reply->sas_format) {
2937 strncpy(edev->component_vendor_id,
2938 manufacture_reply->component_vendor_id,
2939 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
2940 tmp = (u8 *)&manufacture_reply->component_id;
2941 edev->component_id = tmp[0] << 8 | tmp[1];
2942 edev->component_revision_id =
2943 manufacture_reply->component_revision_id;
2946 printk(MYIOC_s_ERR_FMT
2947 "%s: smp passthru reply failed to be returned\n",
2948 ioc->name, __func__);
2953 pci_free_consistent(ioc->pcidev, sz, data_out, data_out_dma);
2956 mpt_free_msg_frame(ioc, mf);
2958 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2959 mutex_unlock(&ioc->sas_mgmt.mutex);
2965 mptsas_parse_device_info(struct sas_identify *identify,
2966 struct mptsas_devinfo *device_info)
2970 identify->sas_address = device_info->sas_address;
2971 identify->phy_identifier = device_info->phy_id;
2974 * Fill in Phy Initiator Port Protocol.
2975 * Bits 6:3, more than one bit can be set, fall through cases.
2977 protocols = device_info->device_info & 0x78;
2978 identify->initiator_port_protocols = 0;
2979 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
2980 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
2981 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
2982 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
2983 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
2984 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
2985 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
2986 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
2989 * Fill in Phy Target Port Protocol.
2990 * Bits 10:7, more than one bit can be set, fall through cases.
2992 protocols = device_info->device_info & 0x780;
2993 identify->target_port_protocols = 0;
2994 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
2995 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
2996 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
2997 identify->target_port_protocols |= SAS_PROTOCOL_STP;
2998 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
2999 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
3000 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
3001 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
3004 * Fill in Attached device type.
3006 switch (device_info->device_info &
3007 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
3008 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
3009 identify->device_type = SAS_PHY_UNUSED;
3011 case MPI_SAS_DEVICE_INFO_END_DEVICE:
3012 identify->device_type = SAS_END_DEVICE;
3014 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
3015 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
3017 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
3018 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
3023 static int mptsas_probe_one_phy(struct device *dev,
3024 struct mptsas_phyinfo *phy_info, int index, int local)
3027 struct sas_phy *phy;
3028 struct sas_port *port;
3030 VirtTarget *vtarget;
3037 if (!phy_info->phy) {
3038 phy = sas_phy_alloc(dev, index);
3044 phy = phy_info->phy;
3046 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
3049 * Set Negotiated link rate.
3051 switch (phy_info->negotiated_link_rate) {
3052 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
3053 phy->negotiated_linkrate = SAS_PHY_DISABLED;
3055 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
3056 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
3058 case MPI_SAS_IOUNIT0_RATE_1_5:
3059 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
3061 case MPI_SAS_IOUNIT0_RATE_3_0:
3062 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
3064 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
3065 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
3067 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
3072 * Set Max hardware link rate.
3074 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
3075 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
3076 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
3078 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
3079 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
3086 * Set Max programmed link rate.
3088 switch (phy_info->programmed_link_rate &
3089 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
3090 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
3091 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
3093 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
3094 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
3101 * Set Min hardware link rate.
3103 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
3104 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
3105 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
3107 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
3108 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
3115 * Set Min programmed link rate.
3117 switch (phy_info->programmed_link_rate &
3118 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
3119 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
3120 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
3122 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
3123 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
3129 if (!phy_info->phy) {
3131 error = sas_phy_add(phy);
3136 phy_info->phy = phy;
3139 if (!phy_info->attached.handle ||
3140 !phy_info->port_details)
3143 port = mptsas_get_port(phy_info);
3144 ioc = phy_to_ioc(phy_info->phy);
3146 if (phy_info->sas_port_add_phy) {
3149 port = sas_port_alloc_num(dev);
3154 error = sas_port_add(port);
3156 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3157 "%s: exit at line=%d\n", ioc->name,
3158 __func__, __LINE__));
3161 mptsas_set_port(ioc, phy_info, port);
3162 devtprintk(ioc, dev_printk(KERN_DEBUG, &port->dev,
3163 MYIOC_s_FMT "add port %d, sas_addr (0x%llx)\n",
3164 ioc->name, port->port_identifier,
3165 (unsigned long long)phy_info->
3166 attached.sas_address));
3168 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3169 "sas_port_add_phy: phy_id=%d\n",
3170 ioc->name, phy_info->phy_id));
3171 sas_port_add_phy(port, phy_info->phy);
3172 phy_info->sas_port_add_phy = 0;
3173 devtprintk(ioc, dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3174 MYIOC_s_FMT "add phy %d, phy-obj (0x%p)\n", ioc->name,
3175 phy_info->phy_id, phy_info->phy));
3177 if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
3179 struct sas_rphy *rphy;
3180 struct device *parent;
3181 struct sas_identify identify;
3183 parent = dev->parent->parent;
3185 * Let the hotplug_work thread handle processing
3186 * the adding/removing of devices that occur
3187 * after start of day.
3189 if (mptsas_is_end_device(&phy_info->attached) &&
3190 phy_info->attached.handle_parent) {
3194 mptsas_parse_device_info(&identify, &phy_info->attached);
3195 if (scsi_is_host_device(parent)) {
3196 struct mptsas_portinfo *port_info;
3199 port_info = ioc->hba_port_info;
3201 for (i = 0; i < port_info->num_phys; i++)
3202 if (port_info->phy_info[i].identify.sas_address ==
3203 identify.sas_address) {
3204 sas_port_mark_backlink(port);
3208 } else if (scsi_is_sas_rphy(parent)) {
3209 struct sas_rphy *parent_rphy = dev_to_rphy(parent);
3210 if (identify.sas_address ==
3211 parent_rphy->identify.sas_address) {
3212 sas_port_mark_backlink(port);
3217 switch (identify.device_type) {
3218 case SAS_END_DEVICE:
3219 rphy = sas_end_device_alloc(port);
3221 case SAS_EDGE_EXPANDER_DEVICE:
3222 case SAS_FANOUT_EXPANDER_DEVICE:
3223 rphy = sas_expander_alloc(port, identify.device_type);
3230 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3231 "%s: exit at line=%d\n", ioc->name,
3232 __func__, __LINE__));
3236 rphy->identify = identify;
3237 error = sas_rphy_add(rphy);
3239 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3240 "%s: exit at line=%d\n", ioc->name,
3241 __func__, __LINE__));
3242 sas_rphy_free(rphy);
3245 mptsas_set_rphy(ioc, phy_info, rphy);
3246 if (identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
3247 identify.device_type == SAS_FANOUT_EXPANDER_DEVICE)
3248 mptsas_exp_repmanufacture_info(ioc,
3249 identify.sas_address,
3250 rphy_to_expander_device(rphy));
3253 /* If the device exists,verify it wasn't previously flagged
3254 as a missing device. If so, clear it */
3255 vtarget = mptsas_find_vtarget(ioc,
3256 phy_info->attached.channel,
3257 phy_info->attached.id);
3258 if (vtarget && vtarget->inDMD) {
3259 printk(KERN_INFO "Device returned, unsetting inDMD\n");
3268 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
3270 struct mptsas_portinfo *port_info, *hba;
3271 int error = -ENOMEM, i;
3273 hba = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3277 error = mptsas_sas_io_unit_pg0(ioc, hba);
3279 goto out_free_port_info;
3281 mptsas_sas_io_unit_pg1(ioc);
3282 mutex_lock(&ioc->sas_topology_mutex);
3283 port_info = ioc->hba_port_info;
3285 ioc->hba_port_info = port_info = hba;
3286 ioc->hba_port_num_phy = port_info->num_phys;
3287 list_add_tail(&port_info->list, &ioc->sas_topology);
3289 for (i = 0; i < hba->num_phys; i++) {
3290 port_info->phy_info[i].negotiated_link_rate =
3291 hba->phy_info[i].negotiated_link_rate;
3292 port_info->phy_info[i].handle =
3293 hba->phy_info[i].handle;
3294 port_info->phy_info[i].port_id =
3295 hba->phy_info[i].port_id;
3297 kfree(hba->phy_info);
3301 mutex_unlock(&ioc->sas_topology_mutex);
3302 #if defined(CPQ_CIM)
3303 ioc->num_ports = port_info->num_phys;
3305 for (i = 0; i < port_info->num_phys; i++) {
3306 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
3307 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
3308 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
3309 port_info->phy_info[i].identify.handle =
3310 port_info->phy_info[i].handle;
3311 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
3312 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3313 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3314 port_info->phy_info[i].identify.handle);
3315 if (!ioc->hba_port_sas_addr)
3316 ioc->hba_port_sas_addr =
3317 port_info->phy_info[i].identify.sas_address;
3318 port_info->phy_info[i].identify.phy_id =
3319 port_info->phy_info[i].phy_id = i;
3320 if (port_info->phy_info[i].attached.handle)
3321 mptsas_sas_device_pg0(ioc,
3322 &port_info->phy_info[i].attached,
3323 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3324 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3325 port_info->phy_info[i].attached.handle);
3328 mptsas_setup_wide_ports(ioc, port_info);
3330 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3331 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
3332 &port_info->phy_info[i], ioc->sas_index, 1);
3343 mptsas_expander_refresh(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
3345 struct mptsas_portinfo *parent;
3346 struct device *parent_dev;
3347 struct sas_rphy *rphy;
3349 u64 sas_address; /* expander sas address */
3352 handle = port_info->phy_info[0].handle;
3353 sas_address = port_info->phy_info[0].identify.sas_address;
3354 for (i = 0; i < port_info->num_phys; i++) {
3355 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
3356 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
3357 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + handle);
3359 mptsas_sas_device_pg0(ioc,
3360 &port_info->phy_info[i].identify,
3361 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3362 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3363 port_info->phy_info[i].identify.handle);
3364 port_info->phy_info[i].identify.phy_id =
3365 port_info->phy_info[i].phy_id;
3367 if (port_info->phy_info[i].attached.handle) {
3368 mptsas_sas_device_pg0(ioc,
3369 &port_info->phy_info[i].attached,
3370 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3371 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3372 port_info->phy_info[i].attached.handle);
3373 port_info->phy_info[i].attached.phy_id =
3374 port_info->phy_info[i].phy_id;
3378 mutex_lock(&ioc->sas_topology_mutex);
3379 parent = mptsas_find_portinfo_by_handle(ioc,
3380 port_info->phy_info[0].identify.handle_parent);
3382 mutex_unlock(&ioc->sas_topology_mutex);
3385 for (i = 0, parent_dev = NULL; i < parent->num_phys && !parent_dev;
3387 if (parent->phy_info[i].attached.sas_address == sas_address) {
3388 rphy = mptsas_get_rphy(&parent->phy_info[i]);
3389 parent_dev = &rphy->dev;
3392 mutex_unlock(&ioc->sas_topology_mutex);
3394 mptsas_setup_wide_ports(ioc, port_info);
3395 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3396 mptsas_probe_one_phy(parent_dev, &port_info->phy_info[i],
3401 mptsas_expander_event_add(MPT_ADAPTER *ioc,
3402 MpiEventDataSasExpanderStatusChange_t *expander_data)
3404 struct mptsas_portinfo *port_info;
3408 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3411 port_info->num_phys = (expander_data->NumPhys) ?
3412 expander_data->NumPhys : 1;
3413 port_info->phy_info = kcalloc(port_info->num_phys,
3414 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
3415 if (!port_info->phy_info)
3417 memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3418 for (i = 0; i < port_info->num_phys; i++) {
3419 port_info->phy_info[i].portinfo = port_info;
3420 port_info->phy_info[i].handle =
3421 le16_to_cpu(expander_data->DevHandle);
3422 port_info->phy_info[i].identify.sas_address =
3423 le64_to_cpu(sas_address);
3424 port_info->phy_info[i].identify.handle_parent =
3425 le16_to_cpu(expander_data->ParentDevHandle);
3428 mutex_lock(&ioc->sas_topology_mutex);
3429 list_add_tail(&port_info->list, &ioc->sas_topology);
3430 mutex_unlock(&ioc->sas_topology_mutex);
3432 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3433 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3434 (unsigned long long)sas_address);
3436 mptsas_expander_refresh(ioc, port_info);
3440 * mptsas_delete_expander_siblings - remove siblings attached to expander
3441 * @ioc: Pointer to MPT_ADAPTER structure
3442 * @parent: the parent port_info object
3443 * @expander: the expander port_info object
3446 mptsas_delete_expander_siblings(MPT_ADAPTER *ioc, struct mptsas_portinfo
3447 *parent, struct mptsas_portinfo *expander)
3449 struct mptsas_phyinfo *phy_info;
3450 struct mptsas_portinfo *port_info;
3451 struct sas_rphy *rphy;
3454 phy_info = expander->phy_info;
3455 for (i = 0; i < expander->num_phys; i++, phy_info++) {
3456 rphy = mptsas_get_rphy(phy_info);
3459 if (rphy->identify.device_type == SAS_END_DEVICE)
3460 mptsas_del_end_device(ioc, phy_info);
3463 phy_info = expander->phy_info;
3464 for (i = 0; i < expander->num_phys; i++, phy_info++) {
3465 rphy = mptsas_get_rphy(phy_info);
3468 if (rphy->identify.device_type ==
3469 MPI_SAS_DEVICE_INFO_EDGE_EXPANDER ||
3470 rphy->identify.device_type ==
3471 MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
3472 port_info = mptsas_find_portinfo_by_sas_address(ioc,
3473 rphy->identify.sas_address);
3476 if (port_info == parent) /* backlink rphy */
3479 Delete this expander even if the expdevpage is exists
3480 because the parent expander is already deleted
3482 mptsas_expander_delete(ioc, port_info, 1);
3489 * mptsas_expander_delete - remove this expander
3490 * @ioc: Pointer to MPT_ADAPTER structure
3491 * @port_info: expander port_info struct
3492 * @force: Flag to forcefully delete the expander
3496 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
3497 struct mptsas_portinfo *port_info, u8 force)
3500 struct mptsas_portinfo *parent;
3502 u64 expander_sas_address;
3503 struct mptsas_phyinfo *phy_info;
3504 struct mptsas_portinfo buffer;
3505 struct mptsas_portinfo_details *port_details;
3506 struct sas_port *port;
3511 /* see if expander is still there before deleting */
3512 mptsas_sas_expander_pg0(ioc, &buffer,
3513 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3514 MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
3515 port_info->phy_info[0].identify.handle);
3517 if (buffer.num_phys) {
3518 kfree(buffer.phy_info);
3525 * Obtain the port_info instance to the parent port
3527 port_details = NULL;
3528 expander_sas_address =
3529 port_info->phy_info[0].identify.sas_address;
3530 parent = mptsas_find_portinfo_by_handle(ioc,
3531 port_info->phy_info[0].identify.handle_parent);
3532 mptsas_delete_expander_siblings(ioc, parent, port_info);
3537 * Delete rphys in the parent that point
3540 phy_info = parent->phy_info;
3542 for (i = 0; i < parent->num_phys; i++, phy_info++) {
3545 if (phy_info->attached.sas_address !=
3546 expander_sas_address)
3549 port = mptsas_get_port(phy_info);
3550 port_details = phy_info->port_details;
3552 dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3553 MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n", ioc->name,
3554 phy_info->phy_id, phy_info->phy);
3555 sas_port_delete_phy(port, phy_info->phy);
3558 dev_printk(KERN_DEBUG, &port->dev,
3559 MYIOC_s_FMT "delete port %d, sas_addr (0x%llx)\n",
3560 ioc->name, port->port_identifier,
3561 (unsigned long long)expander_sas_address);
3562 sas_port_delete(port);
3563 mptsas_port_delete(ioc, port_details);
3567 printk(MYIOC_s_INFO_FMT "delete expander: num_phys %d, "
3568 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3569 (unsigned long long)expander_sas_address);
3574 list_del(&port_info->list);
3575 kfree(port_info->phy_info);
3581 * mptsas_send_expander_event - expanders events
3582 * @ioc: Pointer to MPT_ADAPTER structure
3583 * @expander_data: event data
3586 * This function handles adding, removing, and refreshing
3587 * device handles within the expander objects.
3590 mptsas_send_expander_event(struct fw_event_work *fw_event)
3593 MpiEventDataSasExpanderStatusChange_t *expander_data;
3594 struct mptsas_portinfo *port_info;
3598 ioc = fw_event->ioc;
3599 expander_data = (MpiEventDataSasExpanderStatusChange_t *)
3600 fw_event->event_data;
3601 memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3602 sas_address = le64_to_cpu(sas_address);
3603 port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3605 if (expander_data->ReasonCode == MPI_EVENT_SAS_EXP_RC_ADDED) {
3607 for (i = 0; i < port_info->num_phys; i++) {
3608 port_info->phy_info[i].portinfo = port_info;
3609 port_info->phy_info[i].handle =
3610 le16_to_cpu(expander_data->DevHandle);
3611 port_info->phy_info[i].identify.sas_address =
3612 le64_to_cpu(sas_address);
3613 port_info->phy_info[i].identify.handle_parent =
3614 le16_to_cpu(expander_data->ParentDevHandle);
3616 mptsas_expander_refresh(ioc, port_info);
3617 } else if (!port_info && expander_data->NumPhys)
3618 mptsas_expander_event_add(ioc, expander_data);
3619 } else if (expander_data->ReasonCode ==
3620 MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING)
3621 mptsas_expander_delete(ioc, port_info, 0);
3623 mptsas_free_fw_event(ioc, fw_event);
3628 * mptsas_expander_add -
3629 * @ioc: Pointer to MPT_ADAPTER structure
3633 struct mptsas_portinfo *
3634 mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
3636 struct mptsas_portinfo buffer, *port_info;
3639 if ((mptsas_sas_expander_pg0(ioc, &buffer,
3640 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3641 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)))
3644 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_ATOMIC);
3646 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3647 "%s: exit at line=%d\n", ioc->name,
3648 __func__, __LINE__));
3651 port_info->num_phys = buffer.num_phys;
3652 port_info->phy_info = buffer.phy_info;
3653 for (i = 0; i < port_info->num_phys; i++)
3654 port_info->phy_info[i].portinfo = port_info;
3655 mutex_lock(&ioc->sas_topology_mutex);
3656 list_add_tail(&port_info->list, &ioc->sas_topology);
3657 mutex_unlock(&ioc->sas_topology_mutex);
3658 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3659 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3660 (unsigned long long)buffer.phy_info[0].identify.sas_address);
3661 mptsas_expander_refresh(ioc, port_info);
3666 mptsas_send_link_status_event(struct fw_event_work *fw_event)
3669 MpiEventDataSasPhyLinkStatus_t *link_data;
3670 struct mptsas_portinfo *port_info;
3671 struct mptsas_phyinfo *phy_info = NULL;
3676 ioc = fw_event->ioc;
3677 link_data = (MpiEventDataSasPhyLinkStatus_t *)fw_event->event_data;
3679 memcpy(&sas_address, &link_data->SASAddress, sizeof(__le64));
3680 sas_address = le64_to_cpu(sas_address);
3681 link_rate = link_data->LinkRates >> 4;
3682 phy_num = link_data->PhyNum;
3684 port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3686 phy_info = &port_info->phy_info[phy_num];
3688 phy_info->negotiated_link_rate = link_rate;
3691 if (link_rate == MPI_SAS_IOUNIT0_RATE_1_5 ||
3692 link_rate == MPI_SAS_IOUNIT0_RATE_3_0) {
3695 if (ioc->old_sas_discovery_protocal) {
3696 port_info = mptsas_expander_add(ioc,
3697 le16_to_cpu(link_data->DevHandle));
3704 if (port_info == ioc->hba_port_info)
3705 mptsas_probe_hba_phys(ioc);
3707 mptsas_expander_refresh(ioc, port_info);
3708 } else if (phy_info && phy_info->phy) {
3709 if (link_rate == MPI_SAS_IOUNIT0_RATE_PHY_DISABLED)
3710 phy_info->phy->negotiated_linkrate =
3712 else if (link_rate ==
3713 MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION)
3714 phy_info->phy->negotiated_linkrate =
3715 SAS_LINK_RATE_FAILED;
3717 phy_info->phy->negotiated_linkrate =
3718 SAS_LINK_RATE_UNKNOWN;
3719 if (ioc->device_missing_delay &&
3720 mptsas_is_end_device(&phy_info->attached)) {
3721 struct scsi_device *sdev;
3722 VirtDevice *vdevice;
3724 id = phy_info->attached.id;
3725 channel = phy_info->attached.channel;
3726 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3727 "Link down for fw_id %d:fw_channel %d\n",
3728 ioc->name, phy_info->attached.id,
3729 phy_info->attached.channel));
3731 shost_for_each_device(sdev, ioc->sh) {
3732 vdevice = sdev->hostdata;
3733 if ((vdevice == NULL) ||
3734 (vdevice->vtarget == NULL))
3736 if ((vdevice->vtarget->tflags &
3737 MPT_TARGET_FLAGS_RAID_COMPONENT ||
3738 vdevice->vtarget->raidVolume))
3740 if (vdevice->vtarget->id == id &&
3741 vdevice->vtarget->channel ==
3744 printk(MYIOC_s_DEBUG_FMT
3745 "SDEV OUTSTANDING CMDS"
3747 sdev->device_busy));
3754 mptsas_free_fw_event(ioc, fw_event);
3758 mptsas_not_responding_devices(MPT_ADAPTER *ioc)
3760 struct mptsas_portinfo buffer, *port_info;
3761 struct mptsas_device_info *sas_info;
3762 struct mptsas_devinfo sas_device;
3764 VirtTarget *vtarget = NULL;
3765 struct mptsas_phyinfo *phy_info;
3767 int retval, retry_count;
3768 unsigned long flags;
3770 mpt_findImVolumes(ioc);
3772 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3773 if (ioc->ioc_reset_in_progress) {
3774 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3775 "%s: exiting due to a parallel reset \n", ioc->name,
3777 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3780 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3782 /* devices, logical volumes */
3783 mutex_lock(&ioc->sas_device_info_mutex);
3785 list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) {
3786 if (sas_info->is_cached)
3788 if (!sas_info->is_logical_volume) {
3789 sas_device.handle = 0;
3792 retval = mptsas_sas_device_pg0(ioc, &sas_device,
3793 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID
3794 << MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3795 (sas_info->fw.channel << 8) +
3798 if (sas_device.handle)
3800 if (retval == -EBUSY) {
3801 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3802 if (ioc->ioc_reset_in_progress) {
3804 printk(MYIOC_s_DEBUG_FMT
3805 "%s: exiting due to reset\n",
3806 ioc->name, __func__));
3807 spin_unlock_irqrestore
3808 (&ioc->taskmgmt_lock, flags);
3810 sas_device_info_mutex);
3813 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
3817 if (retval && (retval != -ENODEV)) {
3818 if (retry_count < 10) {
3822 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3823 "%s: Config page retry exceeded retry "
3824 "count deleting device 0x%llx\n",
3825 ioc->name, __func__,
3826 sas_info->sas_address));
3831 vtarget = mptsas_find_vtarget(ioc,
3832 sas_info->fw.channel, sas_info->fw.id);
3835 vtarget->deleted = 1;
3837 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3838 sas_info->sas_address);
3841 mptsas_del_end_device(ioc, phy_info);
3842 goto redo_device_scan;
3845 mptsas_volume_delete(ioc, sas_info->fw.id);
3847 mutex_unlock(&ioc->sas_device_info_mutex);
3850 mutex_lock(&ioc->sas_topology_mutex);
3852 list_for_each_entry(port_info, &ioc->sas_topology, list) {
3854 if (port_info->phy_info &&
3855 (!(port_info->phy_info[0].identify.device_info &
3856 MPI_SAS_DEVICE_INFO_SMP_TARGET)))
3860 while (!mptsas_sas_expander_pg0(ioc, &buffer,
3861 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3862 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle) &&
3865 handle = buffer.phy_info[0].handle;
3866 if (buffer.phy_info[0].identify.sas_address ==
3867 port_info->phy_info[0].identify.sas_address) {
3870 kfree(buffer.phy_info);
3873 if (!found_expander) {
3874 mptsas_expander_delete(ioc, port_info, 0);
3875 goto redo_expander_scan;
3878 mutex_unlock(&ioc->sas_topology_mutex);
3882 * mptsas_probe_expanders - adding expanders
3883 * @ioc: Pointer to MPT_ADAPTER structure
3887 mptsas_probe_expanders(MPT_ADAPTER *ioc)
3889 struct mptsas_portinfo buffer, *port_info;
3894 while (!mptsas_sas_expander_pg0(ioc, &buffer,
3895 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3896 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)) {
3898 handle = buffer.phy_info[0].handle;
3899 port_info = mptsas_find_portinfo_by_sas_address(ioc,
3900 buffer.phy_info[0].identify.sas_address);
3903 /* refreshing handles */
3904 for (i = 0; i < buffer.num_phys; i++) {
3905 port_info->phy_info[i].handle = handle;
3906 port_info->phy_info[i].identify.handle_parent =
3907 buffer.phy_info[0].identify.handle_parent;
3909 mptsas_expander_refresh(ioc, port_info);
3910 kfree(buffer.phy_info);
3914 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3916 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3917 "%s: exit at line=%d\n", ioc->name,
3918 __func__, __LINE__));
3921 port_info->num_phys = buffer.num_phys;
3922 port_info->phy_info = buffer.phy_info;
3923 for (i = 0; i < port_info->num_phys; i++)
3924 port_info->phy_info[i].portinfo = port_info;
3925 mutex_lock(&ioc->sas_topology_mutex);
3926 list_add_tail(&port_info->list, &ioc->sas_topology);
3927 mutex_unlock(&ioc->sas_topology_mutex);
3928 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3929 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3930 (unsigned long long)buffer.phy_info[0].identify.sas_address);
3931 mptsas_expander_refresh(ioc, port_info);
3936 mptsas_probe_devices(MPT_ADAPTER *ioc)
3939 struct mptsas_devinfo sas_device;
3940 struct mptsas_phyinfo *phy_info;
3943 while (!(mptsas_sas_device_pg0(ioc, &sas_device,
3944 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
3946 handle = sas_device.handle;
3948 if ((sas_device.device_info &
3949 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
3950 MPI_SAS_DEVICE_INFO_STP_TARGET |
3951 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0)
3954 /* If there is no FW B_T mapping for this device then continue
3956 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
3957 || !(sas_device.flags &
3958 MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
3961 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3965 if (mptsas_get_rphy(phy_info))
3968 mptsas_add_end_device(ioc, phy_info);
3973 * mptsas_scan_sas_topology -
3974 * @ioc: Pointer to MPT_ADAPTER structure
3979 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
3981 struct scsi_device *sdev;
3984 mptsas_probe_hba_phys(ioc);
3985 mptsas_probe_expanders(ioc);
3986 mptsas_probe_devices(ioc);
3989 Reporting RAID volumes.
3991 if (!ioc->ir_firmware || !ioc->raid_data.pIocPg2 ||
3992 !ioc->raid_data.pIocPg2->NumActiveVolumes)
3994 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
3995 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
3996 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
3998 scsi_device_put(sdev);
4001 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4002 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4003 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID);
4004 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4005 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
4011 mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
4014 EventDataQueueFull_t *qfull_data;
4015 struct mptsas_device_info *sas_info;
4016 struct scsi_device *sdev;
4020 int fw_id, fw_channel;
4024 ioc = fw_event->ioc;
4025 qfull_data = (EventDataQueueFull_t *)fw_event->event_data;
4026 fw_id = qfull_data->TargetID;
4027 fw_channel = qfull_data->Bus;
4028 current_depth = le16_to_cpu(qfull_data->CurrentDepth);
4030 /* if hidden raid component, look for the volume id */
4031 mutex_lock(&ioc->sas_device_info_mutex);
4032 if (mptscsih_is_phys_disk(ioc, fw_channel, fw_id)) {
4033 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
4035 if (sas_info->is_cached ||
4036 sas_info->is_logical_volume)
4038 if (sas_info->is_hidden_raid_component &&
4039 (sas_info->fw.channel == fw_channel &&
4040 sas_info->fw.id == fw_id)) {
4041 id = sas_info->volume_id;
4042 channel = MPTSAS_RAID_CHANNEL;
4047 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
4049 if (sas_info->is_cached ||
4050 sas_info->is_hidden_raid_component ||
4051 sas_info->is_logical_volume)
4053 if (sas_info->fw.channel == fw_channel &&
4054 sas_info->fw.id == fw_id) {
4055 id = sas_info->os.id;
4056 channel = sas_info->os.channel;
4064 mutex_unlock(&ioc->sas_device_info_mutex);
4067 shost_for_each_device(sdev, ioc->sh) {
4068 if (sdev->id == id && sdev->channel == channel) {
4069 if (current_depth > sdev->queue_depth) {
4070 sdev_printk(KERN_INFO, sdev,
4071 "strange observation, the queue "
4072 "depth is (%d) meanwhile fw queue "
4073 "depth (%d)\n", sdev->queue_depth,
4077 depth = scsi_track_queue_full(sdev,
4080 sdev_printk(KERN_INFO, sdev,
4081 "Queue depth reduced to (%d)\n",
4084 sdev_printk(KERN_INFO, sdev,
4085 "Tagged Command Queueing is being "
4087 else if (depth == 0)
4088 sdev_printk(KERN_INFO, sdev,
4089 "Queue depth not changed yet\n");
4094 mptsas_free_fw_event(ioc, fw_event);
4098 static struct mptsas_phyinfo *
4099 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
4101 struct mptsas_portinfo *port_info;
4102 struct mptsas_phyinfo *phy_info = NULL;
4105 mutex_lock(&ioc->sas_topology_mutex);
4106 list_for_each_entry(port_info, &ioc->sas_topology, list) {
4107 for (i = 0; i < port_info->num_phys; i++) {
4108 if (!mptsas_is_end_device(
4109 &port_info->phy_info[i].attached))
4111 if (port_info->phy_info[i].attached.sas_address
4114 phy_info = &port_info->phy_info[i];
4118 mutex_unlock(&ioc->sas_topology_mutex);
4123 * mptsas_find_phyinfo_by_phys_disk_num -
4124 * @ioc: Pointer to MPT_ADAPTER structure
4130 static struct mptsas_phyinfo *
4131 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
4134 struct mptsas_phyinfo *phy_info = NULL;
4135 struct mptsas_portinfo *port_info;
4136 RaidPhysDiskPage1_t *phys_disk = NULL;
4138 u64 sas_address = 0;
4142 if (!ioc->raid_data.pIocPg3)
4144 /* dual port support */
4145 num_paths = mpt_raid_phys_disk_get_num_paths(ioc, phys_disk_num);
4148 phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
4149 (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
4152 mpt_raid_phys_disk_pg1(ioc, phys_disk_num, phys_disk);
4153 for (i = 0; i < num_paths; i++) {
4154 if ((phys_disk->Path[i].Flags & 1) != 0)
4155 /* entry no longer valid */
4157 if ((id == phys_disk->Path[i].PhysDiskID) &&
4158 (channel == phys_disk->Path[i].PhysDiskBus)) {
4159 memcpy(&sas_address, &phys_disk->Path[i].WWID,
4161 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4173 * Extra code to handle RAID0 case, where the sas_address is not updated
4174 * in phys_disk_page_1 when hotswapped
4176 mutex_lock(&ioc->sas_topology_mutex);
4177 list_for_each_entry(port_info, &ioc->sas_topology, list) {
4178 for (i = 0; i < port_info->num_phys && !phy_info; i++) {
4179 if (!mptsas_is_end_device(
4180 &port_info->phy_info[i].attached))
4182 if (port_info->phy_info[i].attached.phys_disk_num == ~0)
4184 if ((port_info->phy_info[i].attached.phys_disk_num ==
4186 (port_info->phy_info[i].attached.id == id) &&
4187 (port_info->phy_info[i].attached.channel ==
4189 phy_info = &port_info->phy_info[i];
4192 mutex_unlock(&ioc->sas_topology_mutex);
4197 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
4201 sdev->no_uld_attach = data ? 1 : 0;
4202 rc = scsi_device_reprobe(sdev);
4206 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
4208 starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
4209 mptsas_reprobe_lun);
4213 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
4216 ConfigPageHeader_t hdr;
4217 dma_addr_t dma_handle;
4218 pRaidVolumePage0_t buffer = NULL;
4219 RaidPhysDiskPage0_t phys_disk;
4221 struct mptsas_phyinfo *phy_info;
4222 struct mptsas_devinfo sas_device;
4224 memset(&cfg, 0 , sizeof(CONFIGPARMS));
4225 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4226 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
4227 cfg.pageAddr = (channel << 8) + id;
4228 cfg.cfghdr.hdr = &hdr;
4229 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4230 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
4232 if (mpt_config(ioc, &cfg) != 0)
4235 if (!hdr.PageLength)
4238 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4244 cfg.physAddr = dma_handle;
4245 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4247 if (mpt_config(ioc, &cfg) != 0)
4250 if (!(buffer->VolumeStatus.Flags &
4251 MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
4254 if (!buffer->NumPhysDisks)
4257 for (i = 0; i < buffer->NumPhysDisks; i++) {
4259 if (mpt_raid_phys_disk_pg0(ioc,
4260 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
4263 if (mptsas_sas_device_pg0(ioc, &sas_device,
4264 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4265 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4266 (phys_disk.PhysDiskBus << 8) +
4267 phys_disk.PhysDiskID))
4270 /* If there is no FW B_T mapping for this device then continue
4272 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4273 || !(sas_device.flags &
4274 MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4278 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4279 sas_device.sas_address);
4280 mptsas_add_end_device(ioc, phy_info);
4285 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4289 * Work queue thread to handle SAS hotplug events
4292 mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
4293 struct mptsas_hotplug_event *hot_plug_info)
4295 struct mptsas_phyinfo *phy_info;
4296 struct scsi_target * starget;
4297 struct mptsas_devinfo sas_device;
4298 VirtTarget *vtarget;
4300 struct mptsas_portinfo *port_info;
4302 switch (hot_plug_info->event_type) {
4304 case MPTSAS_ADD_PHYSDISK:
4306 if (!ioc->raid_data.pIocPg2)
4309 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
4310 if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID ==
4311 hot_plug_info->id) {
4312 printk(MYIOC_s_WARN_FMT "firmware bug: unable "
4313 "to add hidden disk - target_id matchs "
4314 "volume_id\n", ioc->name);
4315 mptsas_free_fw_event(ioc, fw_event);
4319 mpt_findImVolumes(ioc);
4321 case MPTSAS_ADD_DEVICE:
4322 memset(&sas_device, 0, sizeof(struct mptsas_devinfo));
4323 mptsas_sas_device_pg0(ioc, &sas_device,
4324 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4325 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4326 (hot_plug_info->channel << 8) +
4329 /* If there is no FW B_T mapping for this device then break
4331 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4332 || !(sas_device.flags &
4333 MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4336 if (!sas_device.handle)
4339 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
4340 /* Only For SATA Device ADD */
4341 if (!phy_info && (sas_device.device_info &
4342 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) {
4343 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4344 "%s %d SATA HOT PLUG: "
4345 "parent handle of device %x\n", ioc->name,
4346 __func__, __LINE__, sas_device.handle_parent));
4347 port_info = mptsas_find_portinfo_by_handle(ioc,
4348 sas_device.handle_parent);
4350 if (port_info == ioc->hba_port_info)
4351 mptsas_probe_hba_phys(ioc);
4353 mptsas_expander_refresh(ioc, port_info);
4355 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4356 "%s %d port info is NULL\n",
4357 ioc->name, __func__, __LINE__));
4360 phy_info = mptsas_refreshing_device_handles
4365 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4366 "%s %d phy info is NULL\n",
4367 ioc->name, __func__, __LINE__));
4371 if (mptsas_get_rphy(phy_info))
4374 mptsas_add_end_device(ioc, phy_info);
4377 case MPTSAS_DEL_DEVICE:
4378 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4379 hot_plug_info->sas_address);
4380 mptsas_del_end_device(ioc, phy_info);
4383 case MPTSAS_DEL_PHYSDISK:
4385 mpt_findImVolumes(ioc);
4387 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
4388 ioc, hot_plug_info->phys_disk_num,
4389 hot_plug_info->channel,
4391 mptsas_del_end_device(ioc, phy_info);
4394 case MPTSAS_ADD_PHYSDISK_REPROBE:
4396 if (mptsas_sas_device_pg0(ioc, &sas_device,
4397 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4398 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4399 (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4400 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4401 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4402 __func__, hot_plug_info->id, __LINE__));
4406 /* If there is no FW B_T mapping for this device then break
4408 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4409 || !(sas_device.flags &
4410 MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4413 phy_info = mptsas_find_phyinfo_by_sas_address(
4414 ioc, sas_device.sas_address);
4417 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4418 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4419 __func__, hot_plug_info->id, __LINE__));
4423 starget = mptsas_get_starget(phy_info);
4425 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4426 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4427 __func__, hot_plug_info->id, __LINE__));
4431 vtarget = starget->hostdata;
4433 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4434 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4435 __func__, hot_plug_info->id, __LINE__));
4439 mpt_findImVolumes(ioc);
4441 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Hidding: "
4442 "fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4443 ioc->name, hot_plug_info->channel, hot_plug_info->id,
4444 hot_plug_info->phys_disk_num, (unsigned long long)
4445 sas_device.sas_address);
4447 vtarget->id = hot_plug_info->phys_disk_num;
4448 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
4449 phy_info->attached.phys_disk_num = hot_plug_info->phys_disk_num;
4450 mptsas_reprobe_target(starget, 1);
4453 case MPTSAS_DEL_PHYSDISK_REPROBE:
4455 if (mptsas_sas_device_pg0(ioc, &sas_device,
4456 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4457 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4458 (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4459 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4460 "%s: fw_id=%d exit at line=%d\n",
4461 ioc->name, __func__,
4462 hot_plug_info->id, __LINE__));
4466 /* If there is no FW B_T mapping for this device then break
4468 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4469 || !(sas_device.flags &
4470 MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4473 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4474 sas_device.sas_address);
4476 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4477 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4478 __func__, hot_plug_info->id, __LINE__));
4482 starget = mptsas_get_starget(phy_info);
4484 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4485 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4486 __func__, hot_plug_info->id, __LINE__));
4490 vtarget = starget->hostdata;
4492 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4493 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4494 __func__, hot_plug_info->id, __LINE__));
4498 if (!(vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)) {
4499 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4500 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4501 __func__, hot_plug_info->id, __LINE__));
4505 mpt_findImVolumes(ioc);
4507 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Exposing:"
4508 " fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4509 ioc->name, hot_plug_info->channel, hot_plug_info->id,
4510 hot_plug_info->phys_disk_num, (unsigned long long)
4511 sas_device.sas_address);
4513 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
4514 vtarget->id = hot_plug_info->id;
4515 phy_info->attached.phys_disk_num = ~0;
4516 mptsas_reprobe_target(starget, 0);
4517 mptsas_add_device_component_by_fw(ioc,
4518 hot_plug_info->channel, hot_plug_info->id);
4521 case MPTSAS_ADD_RAID:
4523 mpt_findImVolumes(ioc);
4524 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4525 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4527 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4528 hot_plug_info->id, 0);
4531 case MPTSAS_DEL_RAID:
4533 mpt_findImVolumes(ioc);
4534 printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4535 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4537 scsi_remove_device(hot_plug_info->sdev);
4538 scsi_device_put(hot_plug_info->sdev);
4541 case MPTSAS_ADD_INACTIVE_VOLUME:
4543 mpt_findImVolumes(ioc);
4544 mptsas_adding_inactive_raid_components(ioc,
4545 hot_plug_info->channel, hot_plug_info->id);
4552 mptsas_free_fw_event(ioc, fw_event);
4556 mptsas_send_sas_event(struct fw_event_work *fw_event)
4559 struct mptsas_hotplug_event hot_plug_info;
4560 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
4564 ioc = fw_event->ioc;
4565 sas_event_data = (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
4566 fw_event->event_data;
4567 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
4570 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
4571 MPI_SAS_DEVICE_INFO_STP_TARGET |
4572 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0) {
4573 mptsas_free_fw_event(ioc, fw_event);
4577 if (sas_event_data->ReasonCode ==
4578 MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED) {
4579 mptbase_sas_persist_operation(ioc,
4580 MPI_SAS_OP_CLEAR_NOT_PRESENT);
4581 mptsas_free_fw_event(ioc, fw_event);
4585 switch (sas_event_data->ReasonCode) {
4586 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
4587 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
4588 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4589 hot_plug_info.handle = le16_to_cpu(sas_event_data->DevHandle);
4590 hot_plug_info.channel = sas_event_data->Bus;
4591 hot_plug_info.id = sas_event_data->TargetID;
4592 hot_plug_info.phy_id = sas_event_data->PhyNum;
4593 memcpy(&sas_address, &sas_event_data->SASAddress,
4595 hot_plug_info.sas_address = le64_to_cpu(sas_address);
4596 hot_plug_info.device_info = device_info;
4597 if (sas_event_data->ReasonCode &
4598 MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
4599 hot_plug_info.event_type = MPTSAS_ADD_DEVICE;
4601 hot_plug_info.event_type = MPTSAS_DEL_DEVICE;
4602 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4605 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
4606 mptbase_sas_persist_operation(ioc,
4607 MPI_SAS_OP_CLEAR_NOT_PRESENT);
4608 mptsas_free_fw_event(ioc, fw_event);
4611 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
4613 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
4616 mptsas_free_fw_event(ioc, fw_event);
4622 mptsas_send_raid_event(struct fw_event_work *fw_event)
4625 EVENT_DATA_RAID *raid_event_data;
4626 struct mptsas_hotplug_event hot_plug_info;
4629 struct scsi_device *sdev = NULL;
4630 VirtDevice *vdevice = NULL;
4631 RaidPhysDiskPage0_t phys_disk;
4633 ioc = fw_event->ioc;
4634 raid_event_data = (EVENT_DATA_RAID *)fw_event->event_data;
4635 status = le32_to_cpu(raid_event_data->SettingsStatus);
4636 state = (status >> 8) & 0xff;
4638 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4639 hot_plug_info.id = raid_event_data->VolumeID;
4640 hot_plug_info.channel = raid_event_data->VolumeBus;
4641 hot_plug_info.phys_disk_num = raid_event_data->PhysDiskNum;
4643 if (raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_DELETED ||
4644 raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_CREATED ||
4645 raid_event_data->ReasonCode ==
4646 MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED) {
4647 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
4648 hot_plug_info.id, 0);
4649 hot_plug_info.sdev = sdev;
4651 vdevice = sdev->hostdata;
4654 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4655 "ReasonCode=%02x\n", ioc->name, __func__,
4656 raid_event_data->ReasonCode));
4658 switch (raid_event_data->ReasonCode) {
4659 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4660 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK_REPROBE;
4662 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4663 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK_REPROBE;
4665 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4667 case MPI_PD_STATE_ONLINE:
4668 case MPI_PD_STATE_NOT_COMPATIBLE:
4669 mpt_raid_phys_disk_pg0(ioc,
4670 raid_event_data->PhysDiskNum, &phys_disk);
4671 hot_plug_info.id = phys_disk.PhysDiskID;
4672 hot_plug_info.channel = phys_disk.PhysDiskBus;
4673 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4675 case MPI_PD_STATE_FAILED:
4676 case MPI_PD_STATE_MISSING:
4677 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
4678 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
4679 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
4680 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4686 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4689 vdevice->vtarget->deleted = 1; /* block IO */
4690 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4692 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4694 scsi_device_put(sdev);
4697 hot_plug_info.event_type = MPTSAS_ADD_RAID;
4699 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4700 if (!(status & MPI_RAIDVOL0_STATUS_FLAG_ENABLED)) {
4703 vdevice->vtarget->deleted = 1; /* block IO */
4704 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4708 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
4709 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
4712 vdevice->vtarget->deleted = 1; /* block IO */
4713 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4715 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
4716 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
4718 scsi_device_put(sdev);
4721 hot_plug_info.event_type = MPTSAS_ADD_RAID;
4731 if (hot_plug_info.event_type != MPTSAS_IGNORE_EVENT)
4732 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4734 mptsas_free_fw_event(ioc, fw_event);
4738 * mptsas_issue_tm - send mptsas internal tm request
4739 * @ioc: Pointer to MPT_ADAPTER structure
4740 * @type: Task Management type
4741 * @channel: channel number for task management
4742 * @id: Logical Target ID for reset (if appropriate)
4743 * @lun: Logical unit for reset (if appropriate)
4744 * @task_context: Context for the task to be aborted
4745 * @timeout: timeout for task management control
4747 * return 0 on success and -1 on failure:
4751 mptsas_issue_tm(MPT_ADAPTER *ioc, u8 type, u8 channel, u8 id, u64 lun,
4752 int task_context, ulong timeout, u8 *issue_reset)
4755 SCSITaskMgmt_t *pScsiTm;
4757 unsigned long timeleft;
4760 mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
4762 retval = -1; /* return failure */
4763 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "TaskMgmt request: no "
4764 "msg frames!!\n", ioc->name));
4768 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request: mr = %p, "
4769 "task_type = 0x%02X,\n\t timeout = %ld, fw_channel = %d, "
4770 "fw_id = %d, lun = %lld,\n\t task_context = 0x%x\n", ioc->name, mf,
4771 type, timeout, channel, id, (unsigned long long)lun,
4774 pScsiTm = (SCSITaskMgmt_t *) mf;
4775 memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
4776 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
4777 pScsiTm->TaskType = type;
4778 pScsiTm->MsgFlags = 0;
4779 pScsiTm->TargetID = id;
4780 pScsiTm->Bus = channel;
4781 pScsiTm->ChainOffset = 0;
4782 pScsiTm->Reserved = 0;
4783 pScsiTm->Reserved1 = 0;
4784 pScsiTm->TaskMsgContext = task_context;
4785 int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
4787 INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4788 CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
4790 mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
4792 /* Now wait for the command to complete */
4793 timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
4795 if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
4796 retval = -1; /* return failure */
4797 dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
4798 "TaskMgmt request: TIMED OUT!(mr=%p)\n", ioc->name, mf));
4799 mpt_free_msg_frame(ioc, mf);
4800 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
4806 if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
4807 retval = -1; /* return failure */
4808 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4809 "TaskMgmt request: failed with no reply\n", ioc->name));
4814 CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4819 * mptsas_broadcast_primative_work - Handle broadcast primitives
4820 * @work: work queue payload containing info describing the event
4822 * this will be handled in workqueue context.
4825 mptsas_broadcast_primative_work(struct fw_event_work *fw_event)
4827 MPT_ADAPTER *ioc = fw_event->ioc;
4829 VirtDevice *vdevice;
4831 struct scsi_cmnd *sc;
4832 SCSITaskMgmtReply_t *pScsiTmReply;
4837 u32 termination_count;
4840 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4841 "%s - enter\n", ioc->name, __func__));
4843 mutex_lock(&ioc->taskmgmt_cmds.mutex);
4844 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
4845 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4846 mptsas_requeue_fw_event(ioc, fw_event, 1000);
4851 termination_count = 0;
4853 mpt_findImVolumes(ioc);
4854 pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
4856 for (ii = 0; ii < ioc->req_depth; ii++) {
4857 if (ioc->fw_events_off)
4859 sc = mptscsih_get_scsi_lookup(ioc, ii);
4862 mf = MPT_INDEX_2_MFPTR(ioc, ii);
4865 task_context = mf->u.frame.hwhdr.msgctxu.MsgContext;
4866 vdevice = sc->device->hostdata;
4867 if (!vdevice || !vdevice->vtarget)
4869 if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
4870 continue; /* skip hidden raid components */
4871 if (vdevice->vtarget->raidVolume)
4872 continue; /* skip hidden raid components */
4873 channel = vdevice->vtarget->channel;
4874 id = vdevice->vtarget->id;
4876 if (mptsas_issue_tm(ioc, MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK,
4877 channel, id, (u64)lun, task_context, 30, &issue_reset))
4880 termination_count +=
4881 le32_to_cpu(pScsiTmReply->TerminationCount);
4882 if ((pScsiTmReply->IOCStatus == MPI_IOCSTATUS_SUCCESS) &&
4883 (pScsiTmReply->ResponseCode ==
4884 MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
4885 pScsiTmReply->ResponseCode ==
4886 MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
4888 if (mptsas_issue_tm(ioc,
4889 MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET,
4890 channel, id, (u64)lun, 0, 30, &issue_reset))
4892 termination_count +=
4893 le32_to_cpu(pScsiTmReply->TerminationCount);
4897 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4898 "%s - exit, query_count = %d termination_count = %d\n",
4899 ioc->name, __func__, query_count, termination_count));
4901 ioc->broadcast_aen_busy = 0;
4902 mpt_clear_taskmgmt_in_progress_flag(ioc);
4903 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4906 printk(MYIOC_s_WARN_FMT
4907 "Issuing Reset from %s!! doorbell=0x%08x\n",
4908 ioc->name, __func__, mpt_GetIocState(ioc, 0));
4909 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
4911 mptsas_free_fw_event(ioc, fw_event);
4915 * mptsas_send_ir2_event - handle exposing hidden disk when
4916 * an inactive raid volume is added
4918 * @ioc: Pointer to MPT_ADAPTER structure
4923 mptsas_send_ir2_event(struct fw_event_work *fw_event)
4926 struct mptsas_hotplug_event hot_plug_info;
4927 MPI_EVENT_DATA_IR2 *ir2_data;
4929 RaidPhysDiskPage0_t phys_disk;
4931 ioc = fw_event->ioc;
4932 ir2_data = (MPI_EVENT_DATA_IR2 *)fw_event->event_data;
4933 reasonCode = ir2_data->ReasonCode;
4935 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4936 "ReasonCode=%02x\n", ioc->name, __func__, reasonCode));
4938 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4939 hot_plug_info.id = ir2_data->TargetID;
4940 hot_plug_info.channel = ir2_data->Bus;
4941 switch (reasonCode) {
4942 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
4943 hot_plug_info.event_type = MPTSAS_ADD_INACTIVE_VOLUME;
4945 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
4946 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4947 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4949 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
4950 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4951 mpt_raid_phys_disk_pg0(ioc,
4952 ir2_data->PhysDiskNum, &phys_disk);
4953 hot_plug_info.id = phys_disk.PhysDiskID;
4954 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4957 mptsas_free_fw_event(ioc, fw_event);
4960 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4964 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
4966 u32 event = le32_to_cpu(reply->Event);
4967 int sz, event_data_sz;
4968 struct fw_event_work *fw_event;
4969 unsigned long delay;
4971 if (ioc->bus_type != SAS)
4974 /* events turned off due to host reset or driver unloading */
4975 if (ioc->fw_events_off)
4978 delay = msecs_to_jiffies(1);
4980 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
4982 EVENT_DATA_SAS_BROADCAST_PRIMITIVE *broadcast_event_data =
4983 (EVENT_DATA_SAS_BROADCAST_PRIMITIVE *)reply->Data;
4984 if (broadcast_event_data->Primitive !=
4985 MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
4987 if (ioc->broadcast_aen_busy)
4989 ioc->broadcast_aen_busy = 1;
4992 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
4994 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data =
4995 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data;
4997 ioc_stat = le16_to_cpu(reply->IOCStatus);
4999 if (sas_event_data->ReasonCode ==
5000 MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) {
5001 mptsas_target_reset_queue(ioc, sas_event_data);
5004 if (sas_event_data->ReasonCode ==
5005 MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
5006 ioc->device_missing_delay &&
5007 (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)) {
5008 VirtTarget *vtarget = NULL;
5010 u32 log_info = le32_to_cpu(reply->IOCLogInfo);
5012 id = sas_event_data->TargetID;
5013 channel = sas_event_data->Bus;
5015 vtarget = mptsas_find_vtarget(ioc, channel, id);
5017 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5018 "LogInfo (0x%x) available for "
5019 "INTERNAL_DEVICE_RESET"
5020 "fw_id %d fw_channel %d\n", ioc->name,
5021 log_info, id, channel));
5022 if (vtarget->raidVolume) {
5023 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5024 "Skipping Raid Volume for inDMD\n",
5027 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5028 "Setting device flag inDMD\n",
5039 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
5041 MpiEventDataSasExpanderStatusChange_t *expander_data =
5042 (MpiEventDataSasExpanderStatusChange_t *)reply->Data;
5044 if (ioc->old_sas_discovery_protocal)
5047 if (expander_data->ReasonCode ==
5048 MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING &&
5049 ioc->device_missing_delay)
5050 delay = HZ * ioc->device_missing_delay;
5053 case MPI_EVENT_SAS_DISCOVERY:
5055 u32 discovery_status;
5056 EventDataSasDiscovery_t *discovery_data =
5057 (EventDataSasDiscovery_t *)reply->Data;
5059 discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus);
5060 ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0;
5061 if (ioc->old_sas_discovery_protocal && !discovery_status)
5062 mptsas_queue_rescan(ioc);
5065 case MPI_EVENT_INTEGRATED_RAID:
5066 case MPI_EVENT_PERSISTENT_TABLE_FULL:
5068 case MPI_EVENT_SAS_PHY_LINK_STATUS:
5069 case MPI_EVENT_QUEUE_FULL:
5075 event_data_sz = ((reply->MsgLength * 4) -
5076 offsetof(EventNotificationReply_t, Data));
5077 sz = offsetof(struct fw_event_work, event_data) + event_data_sz;
5078 fw_event = kzalloc(sz, GFP_ATOMIC);
5080 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name,
5081 __func__, __LINE__);
5084 memcpy(fw_event->event_data, reply->Data, event_data_sz);
5085 fw_event->event = event;
5086 fw_event->ioc = ioc;
5087 mptsas_add_fw_event(ioc, fw_event, delay);
5091 /* Delete a volume when no longer listed in ioc pg2
5093 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id)
5095 struct scsi_device *sdev;
5098 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, id, 0);
5101 if (!ioc->raid_data.pIocPg2)
5103 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
5105 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
5106 if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id)
5109 printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
5110 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL, id);
5111 scsi_remove_device(sdev);
5113 scsi_device_put(sdev);
5117 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5119 struct Scsi_Host *sh;
5122 unsigned long flags;
5130 r = mpt_attach(pdev,id);
5134 ioc = pci_get_drvdata(pdev);
5135 mptsas_fw_event_off(ioc);
5136 ioc->DoneCtx = mptsasDoneCtx;
5137 ioc->TaskCtx = mptsasTaskCtx;
5138 ioc->InternalCtx = mptsasInternalCtx;
5139 ioc->schedule_target_reset = &mptsas_schedule_target_reset;
5140 /* Added sanity check on readiness of the MPT adapter.
5142 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
5143 printk(MYIOC_s_WARN_FMT
5144 "Skipping because it's not operational!\n",
5147 goto out_mptsas_probe;
5151 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
5154 goto out_mptsas_probe;
5157 /* Sanity check - ensure at least 1 port is INITIATOR capable
5160 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
5161 if (ioc->pfacts[ii].ProtocolFlags &
5162 MPI_PORTFACTS_PROTOCOL_INITIATOR)
5167 printk(MYIOC_s_WARN_FMT
5168 "Skipping ioc=%p because SCSI Initiator mode "
5169 "is NOT enabled!\n", ioc->name, ioc);
5173 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
5175 printk(MYIOC_s_WARN_FMT
5176 "Unable to register controller with SCSI subsystem\n",
5179 goto out_mptsas_probe;
5182 spin_lock_irqsave(&ioc->FreeQlock, flags);
5184 /* Attach the SCSI Host to the IOC structure
5192 /* set 16 byte cdb's */
5193 sh->max_cmd_len = 16;
5194 sh->can_queue = min_t(int, ioc->req_depth - 10, sh->can_queue);
5196 sh->max_lun = max_lun;
5197 sh->transportt = mptsas_transport_template;
5201 sh->unique_id = ioc->id;
5203 INIT_LIST_HEAD(&ioc->sas_topology);
5204 mutex_init(&ioc->sas_topology_mutex);
5205 mutex_init(&ioc->sas_discovery_mutex);
5206 mutex_init(&ioc->sas_mgmt.mutex);
5207 init_completion(&ioc->sas_mgmt.done);
5209 /* Verify that we won't exceed the maximum
5210 * number of chain buffers
5211 * We can optimize: ZZ = req_sz/sizeof(SGE)
5213 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
5214 * + (req_sz - 64)/sizeof(SGE)
5215 * A slightly different algorithm is required for
5218 scale = ioc->req_sz/ioc->SGE_size;
5219 if (ioc->sg_addr_size == sizeof(u64)) {
5220 numSGE = (scale - 1) *
5221 (ioc->facts.MaxChainDepth-1) + scale +
5222 (ioc->req_sz - 60) / ioc->SGE_size;
5224 numSGE = 1 + (scale - 1) *
5225 (ioc->facts.MaxChainDepth-1) + scale +
5226 (ioc->req_sz - 64) / ioc->SGE_size;
5229 if (numSGE < sh->sg_tablesize) {
5230 /* Reset this value */
5231 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5232 "Resetting sg_tablesize to %d from %d\n",
5233 ioc->name, numSGE, sh->sg_tablesize));
5234 sh->sg_tablesize = numSGE;
5237 hd = shost_priv(sh);
5240 /* SCSI needs scsi_cmnd lookup table!
5241 * (with size equal to req_depth*PtrSz!)
5243 ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
5244 if (!ioc->ScsiLookup) {
5246 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5247 goto out_mptsas_probe;
5249 spin_lock_init(&ioc->scsi_lookup_lock);
5251 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
5252 ioc->name, ioc->ScsiLookup));
5254 ioc->sas_data.ptClear = mpt_pt_clear;
5256 hd->last_queue_full = 0;
5257 INIT_LIST_HEAD(&hd->target_reset_list);
5258 INIT_LIST_HEAD(&ioc->sas_device_info_list);
5259 mutex_init(&ioc->sas_device_info_mutex);
5261 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5263 if (ioc->sas_data.ptClear==1) {
5264 mptbase_sas_persist_operation(
5265 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
5268 error = scsi_add_host(sh, &ioc->pcidev->dev);
5270 dprintk(ioc, printk(MYIOC_s_ERR_FMT
5271 "scsi_add_host failed\n", ioc->name));
5272 goto out_mptsas_probe;
5275 /* older firmware doesn't support expander events */
5276 if ((ioc->facts.HeaderVersion >> 8) < 0xE)
5277 ioc->old_sas_discovery_protocal = 1;
5278 mptsas_scan_sas_topology(ioc);
5279 mptsas_fw_event_on(ioc);
5284 mptscsih_remove(pdev);
5289 mptsas_shutdown(struct pci_dev *pdev)
5291 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
5293 mptsas_fw_event_off(ioc);
5294 mptsas_cleanup_fw_event_q(ioc);
5297 static void __devexit mptsas_remove(struct pci_dev *pdev)
5299 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
5300 struct mptsas_portinfo *p, *n;
5304 printk(MYIOC_s_INFO_FMT "IOC is in Target mode\n", ioc->name);
5309 mptsas_shutdown(pdev);
5311 mptsas_del_device_components(ioc);
5313 ioc->sas_discovery_ignore_events = 1;
5314 sas_remove_host(ioc->sh);
5316 mutex_lock(&ioc->sas_topology_mutex);
5317 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
5319 for (i = 0 ; i < p->num_phys ; i++)
5320 mptsas_port_delete(ioc, p->phy_info[i].port_details);
5325 mutex_unlock(&ioc->sas_topology_mutex);
5326 ioc->hba_port_info = NULL;
5327 mptscsih_remove(pdev);
5330 static struct pci_device_id mptsas_pci_table[] = {
5331 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
5332 PCI_ANY_ID, PCI_ANY_ID },
5333 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
5334 PCI_ANY_ID, PCI_ANY_ID },
5335 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
5336 PCI_ANY_ID, PCI_ANY_ID },
5337 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
5338 PCI_ANY_ID, PCI_ANY_ID },
5339 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
5340 PCI_ANY_ID, PCI_ANY_ID },
5341 {0} /* Terminating entry */
5343 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
5346 static struct pci_driver mptsas_driver = {
5348 .id_table = mptsas_pci_table,
5349 .probe = mptsas_probe,
5350 .remove = __devexit_p(mptsas_remove),
5351 .shutdown = mptsas_shutdown,
5353 .suspend = mptscsih_suspend,
5354 .resume = mptscsih_resume,
5363 show_mptmod_ver(my_NAME, my_VERSION);
5365 mptsas_transport_template =
5366 sas_attach_transport(&mptsas_transport_functions);
5367 if (!mptsas_transport_template)
5369 mptsas_transport_template->eh_timed_out = mptsas_eh_timed_out;
5371 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER,
5372 "mptscsih_io_done");
5373 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER,
5374 "mptscsih_taskmgmt_complete");
5376 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER,
5377 "mptscsih_scandv_complete");
5378 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER,
5379 "mptsas_mgmt_done");
5380 mptsasDeviceResetCtx =
5381 mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER,
5382 "mptsas_taskmgmt_complete");
5384 mpt_event_register(mptsasDoneCtx, mptsas_event_process);
5385 mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
5387 error = pci_register_driver(&mptsas_driver);
5389 sas_release_transport(mptsas_transport_template);
5397 pci_unregister_driver(&mptsas_driver);
5398 sas_release_transport(mptsas_transport_template);
5400 mpt_reset_deregister(mptsasDoneCtx);
5401 mpt_event_deregister(mptsasDoneCtx);
5403 mpt_deregister(mptsasMgmtCtx);
5404 mpt_deregister(mptsasInternalCtx);
5405 mpt_deregister(mptsasTaskCtx);
5406 mpt_deregister(mptsasDoneCtx);
5407 mpt_deregister(mptsasDeviceResetCtx);
5410 module_init(mptsas_init);
5411 module_exit(mptsas_exit);