Merge branch 'for-next'
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / message / fusion / mptsas.c
blob8aefb1829fcd4f2a7514a4eb9d3299cca4fc0bc3
1 /*
2 * linux/drivers/message/fusion/mptsas.c
3 * For use with LSI PCI chip/adapter(s)
4 * running LSI Fusion MPT (Message Passing Technology) firmware.
6 * Copyright (c) 1999-2008 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 */
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.
20 NO WARRANTY
21 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
22 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
23 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
24 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
25 solely responsible for determining the appropriateness of using and
26 distributing the Program and assumes all risks associated with its
27 exercise of rights under this Agreement, including but not limited to
28 the risks and costs of program errors, damage to or loss of data,
29 programs or equipment, and unavailability or interruption of operations.
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>
63 #include "mptbase.h"
64 #include "mptscsih.h"
65 #include "mptsas.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)
158 __le64 sas_address;
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)
201 __le64 sas_address;
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 */
255 static void
256 mptsas_fw_event_off(MPT_ADAPTER *ioc)
258 unsigned long flags;
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 */
268 static void
269 mptsas_fw_event_on(MPT_ADAPTER *ioc)
271 unsigned long flags;
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 */
279 static void
280 mptsas_add_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
281 unsigned long delay)
283 unsigned long flags;
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,
291 delay);
292 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
295 /* requeue a sas firmware event */
296 static void
297 mptsas_requeue_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
298 unsigned long delay)
300 unsigned long flags;
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));
304 fw_event->retries++;
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 */
311 static void
312 mptsas_free_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event)
314 unsigned long flags;
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);
320 kfree(fw_event);
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 */
326 static void
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",
339 ioc->name, __func__,
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())
348 return;
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;
378 int i;
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) {
383 rc = port_info;
384 goto out;
386 out:
387 return rc;
391 * mptsas_find_portinfo_by_sas_address -
392 * @ioc: Pointer to MPT_ADAPTER structure
393 * @handle:
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;
402 int i;
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 ==
413 sas_address) {
414 rc = port_info;
415 goto out;
417 out:
418 mutex_unlock(&ioc->sas_topology_mutex);
419 return rc;
423 * Returns true if there is a scsi end device
425 static inline int
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)))
437 return 1;
438 else
439 return 0;
442 /* no mutex */
443 static void
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;
448 u8 i;
450 if (!port_details)
451 return;
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)
463 continue;
464 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
465 mptsas_set_rphy(ioc, phy_info, NULL);
466 phy_info->port_details = NULL;
468 kfree(port_details);
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;
476 else
477 return NULL;
480 static inline void
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",
486 ioc->name, rphy));
489 if (rphy) {
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;
502 else
503 return NULL;
506 static inline void
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;
512 if (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;
525 else
526 return NULL;
529 static inline void
530 mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
531 starget)
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
541 * @id:
542 * @sas_address:
543 * @device_info:
546 static void
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,
560 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);
566 kfree(sas_info);
570 sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
571 if (!sas_info)
572 goto out;
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);
588 * Set OS mapping
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;
599 out:
600 mutex_unlock(&ioc->sas_device_info_mutex);
601 return;
605 * mptsas_add_device_component_by_fw -
606 * @ioc: Pointer to MPT_ADAPTER structure
607 * @channel: fw mapped id's
608 * @id:
611 static void
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;
616 int rc;
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);
622 if (rc)
623 return;
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
640 * @id:
643 static void
644 mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc,
645 struct scsi_target *starget)
647 CONFIGPARMS cfg;
648 ConfigPageHeader_t hdr;
649 dma_addr_t dma_handle;
650 pRaidVolumePage0_t buffer = NULL;
651 int i;
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)
665 goto out;
667 if (!hdr.PageLength)
668 goto out;
670 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
671 &dma_handle);
673 if (!buffer)
674 goto out;
676 cfg.physAddr = dma_handle;
677 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
679 if (mpt_config(ioc, &cfg) != 0)
680 goto out;
682 if (!buffer->NumPhysDisks)
683 goto out;
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)
692 continue;
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,
699 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,
716 list) {
717 if (sas_info->is_logical_volume && sas_info->fw.id ==
718 starget->id) {
719 list_del(&sas_info->list);
720 kfree(sas_info);
724 sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
725 if (sas_info) {
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);
735 out:
736 if (buffer)
737 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
738 dma_handle);
742 * mptsas_add_device_component_starget -
743 * @ioc: Pointer to MPT_ADAPTER structure
744 * @starget:
747 static void
748 mptsas_add_device_component_starget(MPT_ADAPTER *ioc,
749 struct scsi_target *starget)
751 VirtTarget *vtarget;
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);
760 if (!phy_info)
761 return;
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
779 * @id:
782 static void
783 mptsas_del_device_component_by_os(MPT_ADAPTER *ioc, u8 channel, u8 id)
785 struct mptsas_device_info *sas_info, *next;
788 * Set is_cached flag
790 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
791 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
802 static void
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,
809 list) {
810 list_del(&sas_info->list);
811 kfree(sas_info);
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
823 static void
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;
828 u64 sas_address;
829 int i, j;
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)
836 continue;
837 port_details = phy_info->port_details;
838 if (!port_details)
839 continue;
840 if (port_details->num_phys < 2)
841 continue;
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));
852 if (phy_info->phy) {
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));
870 if (!sas_address)
871 continue;
872 port_details = phy_info->port_details;
874 * Forming a port
876 if (!port_details) {
877 port_details = kzalloc(sizeof(struct
878 mptsas_portinfo_details), GFP_KERNEL);
879 if (!port_details)
880 goto out;
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)
894 continue;
895 phy_info_cmp = &port_info->phy_info[i + 1];
896 for (j = i + 1 ; j < port_info->num_phys ; j++,
897 phy_info_cmp++) {
898 if (!phy_info_cmp->attached.sas_address)
899 continue;
900 if (sas_address != phy_info_cmp->attached.sas_address)
901 continue;
902 if (phy_info_cmp->port_details == port_details )
903 continue;
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) {
909 port_details->rphy =
910 mptsas_get_rphy(phy_info_cmp);
911 port_details->port =
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);
919 } else
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++;
932 out:
934 for (i = 0; i < port_info->num_phys; i++) {
935 port_details = port_info->phy_info[i].port_details;
936 if (!port_details)
937 continue;
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
953 * @ioc
954 * @volume_id
955 * @volume_bus
958 static VirtTarget *
959 mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
961 struct scsi_device *sdev;
962 VirtDevice *vdevice;
963 VirtTarget *vtarget = NULL;
965 shost_for_each_device(sdev, ioc->sh) {
966 vdevice = sdev->hostdata;
967 if ((vdevice == NULL) ||
968 (vdevice->vtarget == NULL))
969 continue;
970 if ((vdevice->vtarget->tflags &
971 MPT_TARGET_FLAGS_RAID_COMPONENT ||
972 vdevice->vtarget->raidVolume))
973 continue;
974 if (vdevice->vtarget->id == id &&
975 vdevice->vtarget->channel == channel)
976 vtarget = vdevice->vtarget;
978 return vtarget;
981 static void
982 mptsas_queue_device_delete(MPT_ADAPTER *ioc,
983 MpiEventDataSasDeviceStatusChange_t *sas_event_data)
985 struct fw_event_work *fw_event;
986 int sz;
988 sz = offsetof(struct fw_event_work, event_data) +
989 sizeof(MpiEventDataSasDeviceStatusChange_t);
990 fw_event = kzalloc(sz, GFP_ATOMIC);
991 if (!fw_event) {
992 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
993 ioc->name, __func__, __LINE__);
994 return;
996 memcpy(fw_event->event_data, sas_event_data,
997 sizeof(MpiEventDataSasDeviceStatusChange_t));
998 fw_event->event = MPI_EVENT_SAS_DEVICE_STATUS_CHANGE;
999 fw_event->ioc = ioc;
1000 mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
1003 static void
1004 mptsas_queue_rescan(MPT_ADAPTER *ioc)
1006 struct fw_event_work *fw_event;
1007 int sz;
1009 sz = offsetof(struct fw_event_work, event_data);
1010 fw_event = kzalloc(sz, GFP_ATOMIC);
1011 if (!fw_event) {
1012 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
1013 ioc->name, __func__, __LINE__);
1014 return;
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
1027 * @ioc
1028 * @channel
1029 * @id
1031 * Returns (1) success
1032 * (0) failure
1035 static int
1036 mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
1038 MPT_FRAME_HDR *mf;
1039 SCSITaskMgmt_t *pScsiTm;
1040 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0)
1041 return 0;
1044 mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
1045 if (mf == NULL) {
1046 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1047 "%s, no msg frames @%d!!\n", ioc->name,
1048 __func__, __LINE__));
1049 goto out_fail;
1052 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1053 ioc->name, mf));
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);
1073 return 1;
1075 out_fail:
1077 mpt_clear_taskmgmt_in_progress_flag(ioc);
1078 return 0;
1081 static void
1082 mptsas_block_io_sdev(struct scsi_device *sdev, void *data)
1084 scsi_device_set_state(sdev, SDEV_BLOCK);
1087 static void
1088 mptsas_block_io_starget(struct scsi_target *starget)
1090 if (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.
1101 * @ioc
1102 * @sas_event_data
1105 static void
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;
1112 u8 id, channel;
1114 id = sas_event_data->TargetID;
1115 channel = sas_event_data->Bus;
1117 vtarget = mptsas_find_vtarget(ioc, channel, id);
1118 if (vtarget) {
1119 mptsas_block_io_starget(vtarget->starget);
1120 vtarget->deleted = 1; /* block IO */
1123 target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event),
1124 GFP_ATOMIC);
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__));
1129 return;
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 management command.
1152 void
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;
1159 u8 id, channel;
1161 * issue target reset to next device in the queue
1164 head = &hd->target_reset_list;
1165 if (list_empty(head))
1166 return;
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;
1177 return;
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.
1189 static int
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;
1194 u8 id, channel;
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;
1202 if (pScsiTmReply) {
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);
1230 return 1;
1232 return 0;
1235 mpt_clear_taskmgmt_in_progress_flag(ioc);
1237 if (list_empty(head))
1238 return 1;
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;
1258 return 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);
1272 return 1;
1276 * mptscsih_ioc_reset
1278 * @ioc
1279 * @reset_phase
1282 static int
1283 mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1285 MPT_SCSI_HOST *hd;
1286 int rc;
1288 rc = mptscsih_ioc_reset(ioc, reset_phase);
1289 if ((ioc->bus_type != SAS) || (!rc))
1290 return rc;
1292 hd = shost_priv(ioc->sh);
1293 if (!hd->ioc)
1294 goto out;
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);
1301 break;
1302 case MPT_IOC_PRE_RESET:
1303 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1304 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
1305 break;
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);
1315 break;
1316 default:
1317 break;
1320 out:
1321 return rc;
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
1332 enum device_state{
1333 DEVICE_RETRY,
1334 DEVICE_ERROR,
1335 DEVICE_READY,
1338 static int
1339 mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
1340 u32 form, u32 form_specific)
1342 ConfigExtendedPageHeader_t hdr;
1343 CONFIGPARMS cfg;
1344 SasEnclosurePage0_t *buffer;
1345 dma_addr_t dma_handle;
1346 int error;
1347 __le64 le_identifier;
1349 memset(&hdr, 0, sizeof(hdr));
1350 hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
1351 hdr.PageNumber = 0;
1352 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1353 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
1355 cfg.cfghdr.ehdr = &hdr;
1356 cfg.physAddr = -1;
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);
1363 if (error)
1364 goto out;
1365 if (!hdr.ExtPageLength) {
1366 error = -ENXIO;
1367 goto out;
1370 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1371 &dma_handle);
1372 if (!buffer) {
1373 error = -ENOMEM;
1374 goto out;
1377 cfg.physAddr = dma_handle;
1378 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1380 error = mpt_config(ioc, &cfg);
1381 if (error)
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);
1399 out:
1400 return error;
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
1411 static int
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;
1417 char *ds = NULL;
1418 u8 fw_id;
1420 if (!phy_info) {
1421 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1422 "%s: exit at line=%d\n", ioc->name,
1423 __func__, __LINE__));
1424 return 1;
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__));
1433 return 2;
1436 port = mptsas_get_port(phy_info);
1437 if (!port) {
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__));
1441 return 3;
1444 if (phy_info->attached.device_info &
1445 MPI_SAS_DEVICE_INFO_SSP_TARGET)
1446 ds = "ssp";
1447 if (phy_info->attached.device_info &
1448 MPI_SAS_DEVICE_INFO_STP_TARGET)
1449 ds = "stp";
1450 if (phy_info->attached.device_info &
1451 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1452 ds = "sata";
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);
1462 if (!rphy) {
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);
1475 return 6;
1477 mptsas_set_rphy(ioc, phy_info, rphy);
1478 return 0;
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
1487 static void
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;
1494 int i;
1495 char *ds = NULL;
1496 u8 fw_id;
1497 u64 sas_address;
1499 if (!phy_info)
1500 return;
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__));
1509 return;
1511 rphy = mptsas_get_rphy(phy_info);
1512 if (!rphy) {
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__));
1516 return;
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)
1524 ds = "initiator";
1525 if (phy_info->attached.device_info &
1526 MPI_SAS_DEVICE_INFO_SSP_TARGET)
1527 ds = "ssp";
1528 if (phy_info->attached.device_info &
1529 MPI_SAS_DEVICE_INFO_STP_TARGET)
1530 ds = "stp";
1531 if (phy_info->attached.device_info &
1532 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1533 ds = "sata";
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);
1542 if (!port) {
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__));
1546 return;
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)
1552 continue;
1553 if (phy_info_parent->attached.sas_address !=
1554 sas_address)
1555 continue;
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;
1577 int i;
1579 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
1580 sas_device->sas_address);
1581 if (!phy_info)
1582 goto out;
1583 port_info = phy_info->portinfo;
1584 if (!port_info)
1585 goto out;
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)
1590 continue;
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);
1602 out:
1603 return phy_info;
1607 * mptsas_firmware_event_work - work thread for processing fw events
1608 * @work: work queue payload containing info describing the event
1609 * Context: user
1612 static void
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__));
1625 return;
1627 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: rescan after "
1628 "reset\n", ioc->name, __func__));
1629 ioc->in_rescan = 1;
1630 mptsas_not_responding_devices(ioc);
1631 mptsas_scan_sas_topology(ioc);
1632 ioc->in_rescan = 0;
1633 mptsas_free_fw_event(ioc, fw_event);
1634 mptsas_fw_event_on(ioc);
1635 return;
1638 /* events handling turned off during host reset */
1639 if (ioc->fw_events_off) {
1640 mptsas_free_fw_event(ioc, fw_event);
1641 return;
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);
1651 break;
1652 case MPI_EVENT_INTEGRATED_RAID:
1653 mptsas_send_raid_event(fw_event);
1654 break;
1655 case MPI_EVENT_IR2:
1656 mptsas_send_ir2_event(fw_event);
1657 break;
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);
1662 break;
1663 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
1664 mptsas_broadcast_primative_work(fw_event);
1665 break;
1666 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
1667 mptsas_send_expander_event(fw_event);
1668 break;
1669 case MPI_EVENT_SAS_PHY_LINK_STATUS:
1670 mptsas_send_link_status_event(fw_event);
1671 break;
1672 case MPI_EVENT_QUEUE_FULL:
1673 mptsas_handle_queue_full_event(fw_event);
1674 break;
1680 static int
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));
1699 goto out;
1702 sas_read_port_mode_page(sdev);
1704 mptsas_add_device_component_starget(ioc, scsi_target(sdev));
1706 out:
1707 return mptscsih_slave_configure(sdev);
1710 static int
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;
1716 u8 id, channel;
1717 struct sas_rphy *rphy;
1718 struct mptsas_portinfo *p;
1719 int i;
1720 MPT_ADAPTER *ioc = hd->ioc;
1722 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
1723 if (!vtarget)
1724 return -ENOMEM;
1726 vtarget->starget = starget;
1727 vtarget->ioc_id = ioc->id;
1728 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
1729 id = starget->id;
1730 channel = 0;
1733 * RAID volumes placed beyond the last expected port.
1735 if (starget->channel == MPTSAS_RAID_CHANNEL) {
1736 if (!ioc->raid_data.pIocPg2) {
1737 kfree(vtarget);
1738 return -ENXIO;
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;
1748 goto out;
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)
1757 continue;
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,
1767 channel, id);
1768 vtarget->tflags |=
1769 MPT_TARGET_FLAGS_RAID_COMPONENT;
1770 p->phy_info[i].attached.phys_disk_num = id;
1772 mutex_unlock(&ioc->sas_topology_mutex);
1773 goto out;
1776 mutex_unlock(&ioc->sas_topology_mutex);
1778 kfree(vtarget);
1779 return -ENXIO;
1781 out:
1782 vtarget->id = id;
1783 vtarget->channel = channel;
1784 starget->hostdata = vtarget;
1785 return 0;
1788 static void
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;
1795 int i;
1796 MPT_ADAPTER *ioc = hd->ioc;
1797 VirtTarget *vtarget;
1799 if (!starget->hostdata)
1800 return;
1802 vtarget = starget->hostdata;
1804 mptsas_del_device_component_by_os(ioc, starget->channel,
1805 starget->id);
1808 if (starget->channel == MPTSAS_RAID_CHANNEL)
1809 goto out;
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)
1816 continue;
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);
1830 out:
1831 vtarget->starget = NULL;
1832 kfree(starget->hostdata);
1833 starget->hostdata = NULL;
1837 static int
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;
1846 int i;
1847 MPT_ADAPTER *ioc = hd->ioc;
1849 vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
1850 if (!vdevice) {
1851 printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
1852 ioc->name, sizeof(VirtDevice));
1853 return -ENOMEM;
1855 starget = scsi_target(sdev);
1856 vdevice->vtarget = starget->hostdata;
1858 if (sdev->channel == MPTSAS_RAID_CHANNEL)
1859 goto out;
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)
1867 continue;
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);
1877 goto out;
1880 mutex_unlock(&ioc->sas_topology_mutex);
1882 kfree(vdevice);
1883 return -ENXIO;
1885 out:
1886 vdevice->vtarget->num_luns++;
1887 sdev->hostdata = vdevice;
1888 return 0;
1891 static int
1892 mptsas_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1894 MPT_SCSI_HOST *hd;
1895 MPT_ADAPTER *ioc;
1896 VirtDevice *vdevice = SCpnt->device->hostdata;
1898 if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
1899 SCpnt->result = DID_NO_CONNECT << 16;
1900 done(SCpnt);
1901 return 0;
1904 hd = shost_priv(SCpnt->device->host);
1905 ioc = hd->ioc;
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);
1916 static DEF_SCSI_QCMD(mptsas_qcmd)
1919 * mptsas_mptsas_eh_timed_out - resets the scsi_cmnd timeout
1920 * if the device under question is currently in the
1921 * device removal delay.
1922 * @sc: scsi command that the midlayer is about to time out
1925 static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc)
1927 MPT_SCSI_HOST *hd;
1928 MPT_ADAPTER *ioc;
1929 VirtDevice *vdevice;
1930 enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED;
1932 hd = shost_priv(sc->device->host);
1933 if (hd == NULL) {
1934 printk(KERN_ERR MYNAM ": %s: Can't locate host! (sc=%p)\n",
1935 __func__, sc);
1936 goto done;
1939 ioc = hd->ioc;
1940 if (ioc->bus_type != SAS) {
1941 printk(KERN_ERR MYNAM ": %s: Wrong bus type (sc=%p)\n",
1942 __func__, sc);
1943 goto done;
1946 vdevice = sc->device->hostdata;
1947 if (vdevice && vdevice->vtarget && (vdevice->vtarget->inDMD
1948 || vdevice->vtarget->deleted)) {
1949 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: target removed "
1950 "or in device removal delay (sc=%p)\n",
1951 ioc->name, __func__, sc));
1952 rc = BLK_EH_RESET_TIMER;
1953 goto done;
1956 done:
1957 return rc;
1961 static struct scsi_host_template mptsas_driver_template = {
1962 .module = THIS_MODULE,
1963 .proc_name = "mptsas",
1964 .proc_info = mptscsih_proc_info,
1965 .name = "MPT SAS Host",
1966 .info = mptscsih_info,
1967 .queuecommand = mptsas_qcmd,
1968 .target_alloc = mptsas_target_alloc,
1969 .slave_alloc = mptsas_slave_alloc,
1970 .slave_configure = mptsas_slave_configure,
1971 .target_destroy = mptsas_target_destroy,
1972 .slave_destroy = mptscsih_slave_destroy,
1973 .change_queue_depth = mptscsih_change_queue_depth,
1974 .eh_abort_handler = mptscsih_abort,
1975 .eh_device_reset_handler = mptscsih_dev_reset,
1976 .eh_bus_reset_handler = mptscsih_bus_reset,
1977 .eh_host_reset_handler = mptscsih_host_reset,
1978 .bios_param = mptscsih_bios_param,
1979 .can_queue = MPT_SAS_CAN_QUEUE,
1980 .this_id = -1,
1981 .sg_tablesize = MPT_SCSI_SG_DEPTH,
1982 .max_sectors = 8192,
1983 .cmd_per_lun = 7,
1984 .use_clustering = ENABLE_CLUSTERING,
1985 .shost_attrs = mptscsih_host_attrs,
1988 static int mptsas_get_linkerrors(struct sas_phy *phy)
1990 MPT_ADAPTER *ioc = phy_to_ioc(phy);
1991 ConfigExtendedPageHeader_t hdr;
1992 CONFIGPARMS cfg;
1993 SasPhyPage1_t *buffer;
1994 dma_addr_t dma_handle;
1995 int error;
1997 /* FIXME: only have link errors on local phys */
1998 if (!scsi_is_sas_phy_local(phy))
1999 return -EINVAL;
2001 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
2002 hdr.ExtPageLength = 0;
2003 hdr.PageNumber = 1 /* page number 1*/;
2004 hdr.Reserved1 = 0;
2005 hdr.Reserved2 = 0;
2006 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2007 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2009 cfg.cfghdr.ehdr = &hdr;
2010 cfg.physAddr = -1;
2011 cfg.pageAddr = phy->identify.phy_identifier;
2012 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2013 cfg.dir = 0; /* read */
2014 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2016 error = mpt_config(ioc, &cfg);
2017 if (error)
2018 return error;
2019 if (!hdr.ExtPageLength)
2020 return -ENXIO;
2022 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2023 &dma_handle);
2024 if (!buffer)
2025 return -ENOMEM;
2027 cfg.physAddr = dma_handle;
2028 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2030 error = mpt_config(ioc, &cfg);
2031 if (error)
2032 goto out_free_consistent;
2034 mptsas_print_phy_pg1(ioc, buffer);
2036 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
2037 phy->running_disparity_error_count =
2038 le32_to_cpu(buffer->RunningDisparityErrorCount);
2039 phy->loss_of_dword_sync_count =
2040 le32_to_cpu(buffer->LossDwordSynchCount);
2041 phy->phy_reset_problem_count =
2042 le32_to_cpu(buffer->PhyResetProblemCount);
2044 out_free_consistent:
2045 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2046 buffer, dma_handle);
2047 return error;
2050 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2051 MPT_FRAME_HDR *reply)
2053 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2054 if (reply != NULL) {
2055 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_RF_VALID;
2056 memcpy(ioc->sas_mgmt.reply, reply,
2057 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
2060 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
2061 ioc->sas_mgmt.status &= ~MPT_MGMT_STATUS_PENDING;
2062 complete(&ioc->sas_mgmt.done);
2063 return 1;
2065 return 0;
2068 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
2070 MPT_ADAPTER *ioc = phy_to_ioc(phy);
2071 SasIoUnitControlRequest_t *req;
2072 SasIoUnitControlReply_t *reply;
2073 MPT_FRAME_HDR *mf;
2074 MPIHeader_t *hdr;
2075 unsigned long timeleft;
2076 int error = -ERESTARTSYS;
2078 /* FIXME: fusion doesn't allow non-local phy reset */
2079 if (!scsi_is_sas_phy_local(phy))
2080 return -EINVAL;
2082 /* not implemented for expanders */
2083 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
2084 return -ENXIO;
2086 if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
2087 goto out;
2089 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2090 if (!mf) {
2091 error = -ENOMEM;
2092 goto out_unlock;
2095 hdr = (MPIHeader_t *) mf;
2096 req = (SasIoUnitControlRequest_t *)mf;
2097 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
2098 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
2099 req->MsgContext = hdr->MsgContext;
2100 req->Operation = hard_reset ?
2101 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
2102 req->PhyNum = phy->identify.phy_identifier;
2104 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2105 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2107 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
2108 10 * HZ);
2109 if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2110 error = -ETIME;
2111 mpt_free_msg_frame(ioc, mf);
2112 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2113 goto out_unlock;
2114 if (!timeleft)
2115 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2116 goto out_unlock;
2119 /* a reply frame is expected */
2120 if ((ioc->sas_mgmt.status &
2121 MPT_MGMT_STATUS_RF_VALID) == 0) {
2122 error = -ENXIO;
2123 goto out_unlock;
2126 /* process the completed Reply Message Frame */
2127 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
2128 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
2129 printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
2130 ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo);
2131 error = -ENXIO;
2132 goto out_unlock;
2135 error = 0;
2137 out_unlock:
2138 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2139 mutex_unlock(&ioc->sas_mgmt.mutex);
2140 out:
2141 return error;
2144 static int
2145 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
2147 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2148 int i, error;
2149 struct mptsas_portinfo *p;
2150 struct mptsas_enclosure enclosure_info;
2151 u64 enclosure_handle;
2153 mutex_lock(&ioc->sas_topology_mutex);
2154 list_for_each_entry(p, &ioc->sas_topology, list) {
2155 for (i = 0; i < p->num_phys; i++) {
2156 if (p->phy_info[i].attached.sas_address ==
2157 rphy->identify.sas_address) {
2158 enclosure_handle = p->phy_info[i].
2159 attached.handle_enclosure;
2160 goto found_info;
2164 mutex_unlock(&ioc->sas_topology_mutex);
2165 return -ENXIO;
2167 found_info:
2168 mutex_unlock(&ioc->sas_topology_mutex);
2169 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
2170 error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
2171 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
2172 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
2173 if (!error)
2174 *identifier = enclosure_info.enclosure_logical_id;
2175 return error;
2178 static int
2179 mptsas_get_bay_identifier(struct sas_rphy *rphy)
2181 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2182 struct mptsas_portinfo *p;
2183 int i, rc;
2185 mutex_lock(&ioc->sas_topology_mutex);
2186 list_for_each_entry(p, &ioc->sas_topology, list) {
2187 for (i = 0; i < p->num_phys; i++) {
2188 if (p->phy_info[i].attached.sas_address ==
2189 rphy->identify.sas_address) {
2190 rc = p->phy_info[i].attached.slot;
2191 goto out;
2195 rc = -ENXIO;
2196 out:
2197 mutex_unlock(&ioc->sas_topology_mutex);
2198 return rc;
2201 static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
2202 struct request *req)
2204 MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
2205 MPT_FRAME_HDR *mf;
2206 SmpPassthroughRequest_t *smpreq;
2207 struct request *rsp = req->next_rq;
2208 int ret;
2209 int flagsLength;
2210 unsigned long timeleft;
2211 char *psge;
2212 dma_addr_t dma_addr_in = 0;
2213 dma_addr_t dma_addr_out = 0;
2214 u64 sas_address = 0;
2216 if (!rsp) {
2217 printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n",
2218 ioc->name, __func__);
2219 return -EINVAL;
2222 /* do we need to support multiple segments? */
2223 if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
2224 printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
2225 ioc->name, __func__, req->bio->bi_vcnt, blk_rq_bytes(req),
2226 rsp->bio->bi_vcnt, blk_rq_bytes(rsp));
2227 return -EINVAL;
2230 ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2231 if (ret)
2232 goto out;
2234 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2235 if (!mf) {
2236 ret = -ENOMEM;
2237 goto out_unlock;
2240 smpreq = (SmpPassthroughRequest_t *)mf;
2241 memset(smpreq, 0, sizeof(*smpreq));
2243 smpreq->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
2244 smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2246 if (rphy)
2247 sas_address = rphy->identify.sas_address;
2248 else {
2249 struct mptsas_portinfo *port_info;
2251 mutex_lock(&ioc->sas_topology_mutex);
2252 port_info = ioc->hba_port_info;
2253 if (port_info && port_info->phy_info)
2254 sas_address =
2255 port_info->phy_info[0].phy->identify.sas_address;
2256 mutex_unlock(&ioc->sas_topology_mutex);
2259 *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2261 psge = (char *)
2262 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2264 /* request */
2265 flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2266 MPI_SGE_FLAGS_END_OF_BUFFER |
2267 MPI_SGE_FLAGS_DIRECTION)
2268 << MPI_SGE_FLAGS_SHIFT;
2269 flagsLength |= (blk_rq_bytes(req) - 4);
2271 dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
2272 blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
2273 if (!dma_addr_out)
2274 goto put_mf;
2275 ioc->add_sge(psge, flagsLength, dma_addr_out);
2276 psge += ioc->SGE_size;
2278 /* response */
2279 flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2280 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2281 MPI_SGE_FLAGS_IOC_TO_HOST |
2282 MPI_SGE_FLAGS_END_OF_BUFFER;
2284 flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2285 flagsLength |= blk_rq_bytes(rsp) + 4;
2286 dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio),
2287 blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
2288 if (!dma_addr_in)
2289 goto unmap;
2290 ioc->add_sge(psge, flagsLength, dma_addr_in);
2292 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2293 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2295 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2296 if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2297 ret = -ETIME;
2298 mpt_free_msg_frame(ioc, mf);
2299 mf = NULL;
2300 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2301 goto unmap;
2302 if (!timeleft)
2303 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2304 goto unmap;
2306 mf = NULL;
2308 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2309 SmpPassthroughReply_t *smprep;
2311 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2312 memcpy(req->sense, smprep, sizeof(*smprep));
2313 req->sense_len = sizeof(*smprep);
2314 req->resid_len = 0;
2315 rsp->resid_len -= smprep->ResponseDataLength;
2316 } else {
2317 printk(MYIOC_s_ERR_FMT
2318 "%s: smp passthru reply failed to be returned\n",
2319 ioc->name, __func__);
2320 ret = -ENXIO;
2322 unmap:
2323 if (dma_addr_out)
2324 pci_unmap_single(ioc->pcidev, dma_addr_out, blk_rq_bytes(req),
2325 PCI_DMA_BIDIRECTIONAL);
2326 if (dma_addr_in)
2327 pci_unmap_single(ioc->pcidev, dma_addr_in, blk_rq_bytes(rsp),
2328 PCI_DMA_BIDIRECTIONAL);
2329 put_mf:
2330 if (mf)
2331 mpt_free_msg_frame(ioc, mf);
2332 out_unlock:
2333 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2334 mutex_unlock(&ioc->sas_mgmt.mutex);
2335 out:
2336 return ret;
2339 static struct sas_function_template mptsas_transport_functions = {
2340 .get_linkerrors = mptsas_get_linkerrors,
2341 .get_enclosure_identifier = mptsas_get_enclosure_identifier,
2342 .get_bay_identifier = mptsas_get_bay_identifier,
2343 .phy_reset = mptsas_phy_reset,
2344 .smp_handler = mptsas_smp_handler,
2347 static struct scsi_transport_template *mptsas_transport_template;
2349 static int
2350 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
2352 ConfigExtendedPageHeader_t hdr;
2353 CONFIGPARMS cfg;
2354 SasIOUnitPage0_t *buffer;
2355 dma_addr_t dma_handle;
2356 int error, i;
2358 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
2359 hdr.ExtPageLength = 0;
2360 hdr.PageNumber = 0;
2361 hdr.Reserved1 = 0;
2362 hdr.Reserved2 = 0;
2363 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2364 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2366 cfg.cfghdr.ehdr = &hdr;
2367 cfg.physAddr = -1;
2368 cfg.pageAddr = 0;
2369 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2370 cfg.dir = 0; /* read */
2371 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2373 error = mpt_config(ioc, &cfg);
2374 if (error)
2375 goto out;
2376 if (!hdr.ExtPageLength) {
2377 error = -ENXIO;
2378 goto out;
2381 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2382 &dma_handle);
2383 if (!buffer) {
2384 error = -ENOMEM;
2385 goto out;
2388 cfg.physAddr = dma_handle;
2389 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2391 error = mpt_config(ioc, &cfg);
2392 if (error)
2393 goto out_free_consistent;
2395 port_info->num_phys = buffer->NumPhys;
2396 port_info->phy_info = kcalloc(port_info->num_phys,
2397 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2398 if (!port_info->phy_info) {
2399 error = -ENOMEM;
2400 goto out_free_consistent;
2403 ioc->nvdata_version_persistent =
2404 le16_to_cpu(buffer->NvdataVersionPersistent);
2405 ioc->nvdata_version_default =
2406 le16_to_cpu(buffer->NvdataVersionDefault);
2408 for (i = 0; i < port_info->num_phys; i++) {
2409 mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
2410 port_info->phy_info[i].phy_id = i;
2411 port_info->phy_info[i].port_id =
2412 buffer->PhyData[i].Port;
2413 port_info->phy_info[i].negotiated_link_rate =
2414 buffer->PhyData[i].NegotiatedLinkRate;
2415 port_info->phy_info[i].portinfo = port_info;
2416 port_info->phy_info[i].handle =
2417 le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
2420 out_free_consistent:
2421 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2422 buffer, dma_handle);
2423 out:
2424 return error;
2427 static int
2428 mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
2430 ConfigExtendedPageHeader_t hdr;
2431 CONFIGPARMS cfg;
2432 SasIOUnitPage1_t *buffer;
2433 dma_addr_t dma_handle;
2434 int error;
2435 u8 device_missing_delay;
2437 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
2438 memset(&cfg, 0, sizeof(CONFIGPARMS));
2440 cfg.cfghdr.ehdr = &hdr;
2441 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2442 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2443 cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2444 cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2445 cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
2446 cfg.cfghdr.ehdr->PageNumber = 1;
2448 error = mpt_config(ioc, &cfg);
2449 if (error)
2450 goto out;
2451 if (!hdr.ExtPageLength) {
2452 error = -ENXIO;
2453 goto out;
2456 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2457 &dma_handle);
2458 if (!buffer) {
2459 error = -ENOMEM;
2460 goto out;
2463 cfg.physAddr = dma_handle;
2464 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2466 error = mpt_config(ioc, &cfg);
2467 if (error)
2468 goto out_free_consistent;
2470 ioc->io_missing_delay =
2471 le16_to_cpu(buffer->IODeviceMissingDelay);
2472 device_missing_delay = buffer->ReportDeviceMissingDelay;
2473 ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
2474 (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
2475 device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
2477 out_free_consistent:
2478 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2479 buffer, dma_handle);
2480 out:
2481 return error;
2484 static int
2485 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2486 u32 form, u32 form_specific)
2488 ConfigExtendedPageHeader_t hdr;
2489 CONFIGPARMS cfg;
2490 SasPhyPage0_t *buffer;
2491 dma_addr_t dma_handle;
2492 int error;
2494 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
2495 hdr.ExtPageLength = 0;
2496 hdr.PageNumber = 0;
2497 hdr.Reserved1 = 0;
2498 hdr.Reserved2 = 0;
2499 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2500 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2502 cfg.cfghdr.ehdr = &hdr;
2503 cfg.dir = 0; /* read */
2504 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2506 /* Get Phy Pg 0 for each Phy. */
2507 cfg.physAddr = -1;
2508 cfg.pageAddr = form + form_specific;
2509 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2511 error = mpt_config(ioc, &cfg);
2512 if (error)
2513 goto out;
2515 if (!hdr.ExtPageLength) {
2516 error = -ENXIO;
2517 goto out;
2520 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2521 &dma_handle);
2522 if (!buffer) {
2523 error = -ENOMEM;
2524 goto out;
2527 cfg.physAddr = dma_handle;
2528 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2530 error = mpt_config(ioc, &cfg);
2531 if (error)
2532 goto out_free_consistent;
2534 mptsas_print_phy_pg0(ioc, buffer);
2536 phy_info->hw_link_rate = buffer->HwLinkRate;
2537 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2538 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2539 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2541 out_free_consistent:
2542 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2543 buffer, dma_handle);
2544 out:
2545 return error;
2548 static int
2549 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
2550 u32 form, u32 form_specific)
2552 ConfigExtendedPageHeader_t hdr;
2553 CONFIGPARMS cfg;
2554 SasDevicePage0_t *buffer;
2555 dma_addr_t dma_handle;
2556 __le64 sas_address;
2557 int error=0;
2559 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
2560 hdr.ExtPageLength = 0;
2561 hdr.PageNumber = 0;
2562 hdr.Reserved1 = 0;
2563 hdr.Reserved2 = 0;
2564 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2565 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
2567 cfg.cfghdr.ehdr = &hdr;
2568 cfg.pageAddr = form + form_specific;
2569 cfg.physAddr = -1;
2570 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2571 cfg.dir = 0; /* read */
2572 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2574 memset(device_info, 0, sizeof(struct mptsas_devinfo));
2575 error = mpt_config(ioc, &cfg);
2576 if (error)
2577 goto out;
2578 if (!hdr.ExtPageLength) {
2579 error = -ENXIO;
2580 goto out;
2583 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2584 &dma_handle);
2585 if (!buffer) {
2586 error = -ENOMEM;
2587 goto out;
2590 cfg.physAddr = dma_handle;
2591 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2593 error = mpt_config(ioc, &cfg);
2595 if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2596 error = -ENODEV;
2597 goto out_free_consistent;
2600 if (error)
2601 goto out_free_consistent;
2603 mptsas_print_device_pg0(ioc, buffer);
2605 memset(device_info, 0, sizeof(struct mptsas_devinfo));
2606 device_info->handle = le16_to_cpu(buffer->DevHandle);
2607 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
2608 device_info->handle_enclosure =
2609 le16_to_cpu(buffer->EnclosureHandle);
2610 device_info->slot = le16_to_cpu(buffer->Slot);
2611 device_info->phy_id = buffer->PhyNum;
2612 device_info->port_id = buffer->PhysicalPort;
2613 device_info->id = buffer->TargetID;
2614 device_info->phys_disk_num = ~0;
2615 device_info->channel = buffer->Bus;
2616 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2617 device_info->sas_address = le64_to_cpu(sas_address);
2618 device_info->device_info =
2619 le32_to_cpu(buffer->DeviceInfo);
2620 device_info->flags = le16_to_cpu(buffer->Flags);
2622 out_free_consistent:
2623 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2624 buffer, dma_handle);
2625 out:
2626 return error;
2629 static int
2630 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
2631 u32 form, u32 form_specific)
2633 ConfigExtendedPageHeader_t hdr;
2634 CONFIGPARMS cfg;
2635 SasExpanderPage0_t *buffer;
2636 dma_addr_t dma_handle;
2637 int i, error;
2638 __le64 sas_address;
2640 memset(port_info, 0, sizeof(struct mptsas_portinfo));
2641 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
2642 hdr.ExtPageLength = 0;
2643 hdr.PageNumber = 0;
2644 hdr.Reserved1 = 0;
2645 hdr.Reserved2 = 0;
2646 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2647 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2649 cfg.cfghdr.ehdr = &hdr;
2650 cfg.physAddr = -1;
2651 cfg.pageAddr = form + form_specific;
2652 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2653 cfg.dir = 0; /* read */
2654 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2656 memset(port_info, 0, sizeof(struct mptsas_portinfo));
2657 error = mpt_config(ioc, &cfg);
2658 if (error)
2659 goto out;
2661 if (!hdr.ExtPageLength) {
2662 error = -ENXIO;
2663 goto out;
2666 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2667 &dma_handle);
2668 if (!buffer) {
2669 error = -ENOMEM;
2670 goto out;
2673 cfg.physAddr = dma_handle;
2674 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2676 error = mpt_config(ioc, &cfg);
2677 if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2678 error = -ENODEV;
2679 goto out_free_consistent;
2682 if (error)
2683 goto out_free_consistent;
2685 /* save config data */
2686 port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1;
2687 port_info->phy_info = kcalloc(port_info->num_phys,
2688 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2689 if (!port_info->phy_info) {
2690 error = -ENOMEM;
2691 goto out_free_consistent;
2694 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2695 for (i = 0; i < port_info->num_phys; i++) {
2696 port_info->phy_info[i].portinfo = port_info;
2697 port_info->phy_info[i].handle =
2698 le16_to_cpu(buffer->DevHandle);
2699 port_info->phy_info[i].identify.sas_address =
2700 le64_to_cpu(sas_address);
2701 port_info->phy_info[i].identify.handle_parent =
2702 le16_to_cpu(buffer->ParentDevHandle);
2705 out_free_consistent:
2706 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2707 buffer, dma_handle);
2708 out:
2709 return error;
2712 static int
2713 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2714 u32 form, u32 form_specific)
2716 ConfigExtendedPageHeader_t hdr;
2717 CONFIGPARMS cfg;
2718 SasExpanderPage1_t *buffer;
2719 dma_addr_t dma_handle;
2720 int error=0;
2722 hdr.PageVersion = MPI_SASEXPANDER1_PAGEVERSION;
2723 hdr.ExtPageLength = 0;
2724 hdr.PageNumber = 1;
2725 hdr.Reserved1 = 0;
2726 hdr.Reserved2 = 0;
2727 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2728 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2730 cfg.cfghdr.ehdr = &hdr;
2731 cfg.physAddr = -1;
2732 cfg.pageAddr = form + form_specific;
2733 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2734 cfg.dir = 0; /* read */
2735 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2737 error = mpt_config(ioc, &cfg);
2738 if (error)
2739 goto out;
2741 if (!hdr.ExtPageLength) {
2742 error = -ENXIO;
2743 goto out;
2746 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2747 &dma_handle);
2748 if (!buffer) {
2749 error = -ENOMEM;
2750 goto out;
2753 cfg.physAddr = dma_handle;
2754 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2756 error = mpt_config(ioc, &cfg);
2758 if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2759 error = -ENODEV;
2760 goto out_free_consistent;
2763 if (error)
2764 goto out_free_consistent;
2767 mptsas_print_expander_pg1(ioc, buffer);
2769 /* save config data */
2770 phy_info->phy_id = buffer->PhyIdentifier;
2771 phy_info->port_id = buffer->PhysicalPort;
2772 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
2773 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2774 phy_info->hw_link_rate = buffer->HwLinkRate;
2775 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2776 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2778 out_free_consistent:
2779 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2780 buffer, dma_handle);
2781 out:
2782 return error;
2785 struct rep_manu_request{
2786 u8 smp_frame_type;
2787 u8 function;
2788 u8 reserved;
2789 u8 request_length;
2792 struct rep_manu_reply{
2793 u8 smp_frame_type; /* 0x41 */
2794 u8 function; /* 0x01 */
2795 u8 function_result;
2796 u8 response_length;
2797 u16 expander_change_count;
2798 u8 reserved0[2];
2799 u8 sas_format:1;
2800 u8 reserved1:7;
2801 u8 reserved2[3];
2802 u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
2803 u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
2804 u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
2805 u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
2806 u16 component_id;
2807 u8 component_revision_id;
2808 u8 reserved3;
2809 u8 vendor_specific[8];
2813 * mptsas_exp_repmanufacture_info -
2814 * @ioc: per adapter object
2815 * @sas_address: expander sas address
2816 * @edev: the sas_expander_device object
2818 * Fills in the sas_expander_device object when SMP port is created.
2820 * Returns 0 for success, non-zero for failure.
2822 static int
2823 mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
2824 u64 sas_address, struct sas_expander_device *edev)
2826 MPT_FRAME_HDR *mf;
2827 SmpPassthroughRequest_t *smpreq;
2828 SmpPassthroughReply_t *smprep;
2829 struct rep_manu_reply *manufacture_reply;
2830 struct rep_manu_request *manufacture_request;
2831 int ret;
2832 int flagsLength;
2833 unsigned long timeleft;
2834 char *psge;
2835 unsigned long flags;
2836 void *data_out = NULL;
2837 dma_addr_t data_out_dma = 0;
2838 u32 sz;
2840 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2841 if (ioc->ioc_reset_in_progress) {
2842 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2843 printk(MYIOC_s_INFO_FMT "%s: host reset in progress!\n",
2844 __func__, ioc->name);
2845 return -EFAULT;
2847 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2849 ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2850 if (ret)
2851 goto out;
2853 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2854 if (!mf) {
2855 ret = -ENOMEM;
2856 goto out_unlock;
2859 smpreq = (SmpPassthroughRequest_t *)mf;
2860 memset(smpreq, 0, sizeof(*smpreq));
2862 sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
2864 data_out = pci_alloc_consistent(ioc->pcidev, sz, &data_out_dma);
2865 if (!data_out) {
2866 printk(KERN_ERR "Memory allocation failure at %s:%d/%s()!\n",
2867 __FILE__, __LINE__, __func__);
2868 ret = -ENOMEM;
2869 goto put_mf;
2872 manufacture_request = data_out;
2873 manufacture_request->smp_frame_type = 0x40;
2874 manufacture_request->function = 1;
2875 manufacture_request->reserved = 0;
2876 manufacture_request->request_length = 0;
2878 smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2879 smpreq->PhysicalPort = 0xFF;
2880 *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2881 smpreq->RequestDataLength = sizeof(struct rep_manu_request);
2883 psge = (char *)
2884 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2886 flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2887 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2888 MPI_SGE_FLAGS_HOST_TO_IOC |
2889 MPI_SGE_FLAGS_END_OF_BUFFER;
2890 flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2891 flagsLength |= sizeof(struct rep_manu_request);
2893 ioc->add_sge(psge, flagsLength, data_out_dma);
2894 psge += ioc->SGE_size;
2896 flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2897 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2898 MPI_SGE_FLAGS_IOC_TO_HOST |
2899 MPI_SGE_FLAGS_END_OF_BUFFER;
2900 flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2901 flagsLength |= sizeof(struct rep_manu_reply);
2902 ioc->add_sge(psge, flagsLength, data_out_dma +
2903 sizeof(struct rep_manu_request));
2905 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2906 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2908 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2909 if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2910 ret = -ETIME;
2911 mpt_free_msg_frame(ioc, mf);
2912 mf = NULL;
2913 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2914 goto out_free;
2915 if (!timeleft)
2916 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2917 goto out_free;
2920 mf = NULL;
2922 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2923 u8 *tmp;
2925 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2926 if (le16_to_cpu(smprep->ResponseDataLength) !=
2927 sizeof(struct rep_manu_reply))
2928 goto out_free;
2930 manufacture_reply = data_out + sizeof(struct rep_manu_request);
2931 strncpy(edev->vendor_id, manufacture_reply->vendor_id,
2932 SAS_EXPANDER_VENDOR_ID_LEN);
2933 strncpy(edev->product_id, manufacture_reply->product_id,
2934 SAS_EXPANDER_PRODUCT_ID_LEN);
2935 strncpy(edev->product_rev, manufacture_reply->product_rev,
2936 SAS_EXPANDER_PRODUCT_REV_LEN);
2937 edev->level = manufacture_reply->sas_format;
2938 if (manufacture_reply->sas_format) {
2939 strncpy(edev->component_vendor_id,
2940 manufacture_reply->component_vendor_id,
2941 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
2942 tmp = (u8 *)&manufacture_reply->component_id;
2943 edev->component_id = tmp[0] << 8 | tmp[1];
2944 edev->component_revision_id =
2945 manufacture_reply->component_revision_id;
2947 } else {
2948 printk(MYIOC_s_ERR_FMT
2949 "%s: smp passthru reply failed to be returned\n",
2950 ioc->name, __func__);
2951 ret = -ENXIO;
2953 out_free:
2954 if (data_out_dma)
2955 pci_free_consistent(ioc->pcidev, sz, data_out, data_out_dma);
2956 put_mf:
2957 if (mf)
2958 mpt_free_msg_frame(ioc, mf);
2959 out_unlock:
2960 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2961 mutex_unlock(&ioc->sas_mgmt.mutex);
2962 out:
2963 return ret;
2966 static void
2967 mptsas_parse_device_info(struct sas_identify *identify,
2968 struct mptsas_devinfo *device_info)
2970 u16 protocols;
2972 identify->sas_address = device_info->sas_address;
2973 identify->phy_identifier = device_info->phy_id;
2976 * Fill in Phy Initiator Port Protocol.
2977 * Bits 6:3, more than one bit can be set, fall through cases.
2979 protocols = device_info->device_info & 0x78;
2980 identify->initiator_port_protocols = 0;
2981 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
2982 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
2983 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
2984 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
2985 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
2986 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
2987 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
2988 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
2991 * Fill in Phy Target Port Protocol.
2992 * Bits 10:7, more than one bit can be set, fall through cases.
2994 protocols = device_info->device_info & 0x780;
2995 identify->target_port_protocols = 0;
2996 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
2997 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
2998 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
2999 identify->target_port_protocols |= SAS_PROTOCOL_STP;
3000 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
3001 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
3002 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
3003 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
3006 * Fill in Attached device type.
3008 switch (device_info->device_info &
3009 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
3010 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
3011 identify->device_type = SAS_PHY_UNUSED;
3012 break;
3013 case MPI_SAS_DEVICE_INFO_END_DEVICE:
3014 identify->device_type = SAS_END_DEVICE;
3015 break;
3016 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
3017 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
3018 break;
3019 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
3020 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
3021 break;
3025 static int mptsas_probe_one_phy(struct device *dev,
3026 struct mptsas_phyinfo *phy_info, int index, int local)
3028 MPT_ADAPTER *ioc;
3029 struct sas_phy *phy;
3030 struct sas_port *port;
3031 int error = 0;
3032 VirtTarget *vtarget;
3034 if (!dev) {
3035 error = -ENODEV;
3036 goto out;
3039 if (!phy_info->phy) {
3040 phy = sas_phy_alloc(dev, index);
3041 if (!phy) {
3042 error = -ENOMEM;
3043 goto out;
3045 } else
3046 phy = phy_info->phy;
3048 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
3051 * Set Negotiated link rate.
3053 switch (phy_info->negotiated_link_rate) {
3054 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
3055 phy->negotiated_linkrate = SAS_PHY_DISABLED;
3056 break;
3057 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
3058 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
3059 break;
3060 case MPI_SAS_IOUNIT0_RATE_1_5:
3061 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
3062 break;
3063 case MPI_SAS_IOUNIT0_RATE_3_0:
3064 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
3065 break;
3066 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
3067 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
3068 default:
3069 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
3070 break;
3074 * Set Max hardware link rate.
3076 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
3077 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
3078 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
3079 break;
3080 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
3081 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
3082 break;
3083 default:
3084 break;
3088 * Set Max programmed link rate.
3090 switch (phy_info->programmed_link_rate &
3091 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
3092 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
3093 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
3094 break;
3095 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
3096 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
3097 break;
3098 default:
3099 break;
3103 * Set Min hardware link rate.
3105 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
3106 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
3107 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
3108 break;
3109 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
3110 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
3111 break;
3112 default:
3113 break;
3117 * Set Min programmed link rate.
3119 switch (phy_info->programmed_link_rate &
3120 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
3121 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
3122 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
3123 break;
3124 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
3125 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
3126 break;
3127 default:
3128 break;
3131 if (!phy_info->phy) {
3133 error = sas_phy_add(phy);
3134 if (error) {
3135 sas_phy_free(phy);
3136 goto out;
3138 phy_info->phy = phy;
3141 if (!phy_info->attached.handle ||
3142 !phy_info->port_details)
3143 goto out;
3145 port = mptsas_get_port(phy_info);
3146 ioc = phy_to_ioc(phy_info->phy);
3148 if (phy_info->sas_port_add_phy) {
3150 if (!port) {
3151 port = sas_port_alloc_num(dev);
3152 if (!port) {
3153 error = -ENOMEM;
3154 goto out;
3156 error = sas_port_add(port);
3157 if (error) {
3158 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3159 "%s: exit at line=%d\n", ioc->name,
3160 __func__, __LINE__));
3161 goto out;
3163 mptsas_set_port(ioc, phy_info, port);
3164 devtprintk(ioc, dev_printk(KERN_DEBUG, &port->dev,
3165 MYIOC_s_FMT "add port %d, sas_addr (0x%llx)\n",
3166 ioc->name, port->port_identifier,
3167 (unsigned long long)phy_info->
3168 attached.sas_address));
3170 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3171 "sas_port_add_phy: phy_id=%d\n",
3172 ioc->name, phy_info->phy_id));
3173 sas_port_add_phy(port, phy_info->phy);
3174 phy_info->sas_port_add_phy = 0;
3175 devtprintk(ioc, dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3176 MYIOC_s_FMT "add phy %d, phy-obj (0x%p)\n", ioc->name,
3177 phy_info->phy_id, phy_info->phy));
3179 if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
3181 struct sas_rphy *rphy;
3182 struct device *parent;
3183 struct sas_identify identify;
3185 parent = dev->parent->parent;
3187 * Let the hotplug_work thread handle processing
3188 * the adding/removing of devices that occur
3189 * after start of day.
3191 if (mptsas_is_end_device(&phy_info->attached) &&
3192 phy_info->attached.handle_parent) {
3193 goto out;
3196 mptsas_parse_device_info(&identify, &phy_info->attached);
3197 if (scsi_is_host_device(parent)) {
3198 struct mptsas_portinfo *port_info;
3199 int i;
3201 port_info = ioc->hba_port_info;
3203 for (i = 0; i < port_info->num_phys; i++)
3204 if (port_info->phy_info[i].identify.sas_address ==
3205 identify.sas_address) {
3206 sas_port_mark_backlink(port);
3207 goto out;
3210 } else if (scsi_is_sas_rphy(parent)) {
3211 struct sas_rphy *parent_rphy = dev_to_rphy(parent);
3212 if (identify.sas_address ==
3213 parent_rphy->identify.sas_address) {
3214 sas_port_mark_backlink(port);
3215 goto out;
3219 switch (identify.device_type) {
3220 case SAS_END_DEVICE:
3221 rphy = sas_end_device_alloc(port);
3222 break;
3223 case SAS_EDGE_EXPANDER_DEVICE:
3224 case SAS_FANOUT_EXPANDER_DEVICE:
3225 rphy = sas_expander_alloc(port, identify.device_type);
3226 break;
3227 default:
3228 rphy = NULL;
3229 break;
3231 if (!rphy) {
3232 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3233 "%s: exit at line=%d\n", ioc->name,
3234 __func__, __LINE__));
3235 goto out;
3238 rphy->identify = identify;
3239 error = sas_rphy_add(rphy);
3240 if (error) {
3241 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3242 "%s: exit at line=%d\n", ioc->name,
3243 __func__, __LINE__));
3244 sas_rphy_free(rphy);
3245 goto out;
3247 mptsas_set_rphy(ioc, phy_info, rphy);
3248 if (identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
3249 identify.device_type == SAS_FANOUT_EXPANDER_DEVICE)
3250 mptsas_exp_repmanufacture_info(ioc,
3251 identify.sas_address,
3252 rphy_to_expander_device(rphy));
3255 /* If the device exists,verify it wasn't previously flagged
3256 as a missing device. If so, clear it */
3257 vtarget = mptsas_find_vtarget(ioc,
3258 phy_info->attached.channel,
3259 phy_info->attached.id);
3260 if (vtarget && vtarget->inDMD) {
3261 printk(KERN_INFO "Device returned, unsetting inDMD\n");
3262 vtarget->inDMD = 0;
3265 out:
3266 return error;
3269 static int
3270 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
3272 struct mptsas_portinfo *port_info, *hba;
3273 int error = -ENOMEM, i;
3275 hba = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3276 if (! hba)
3277 goto out;
3279 error = mptsas_sas_io_unit_pg0(ioc, hba);
3280 if (error)
3281 goto out_free_port_info;
3283 mptsas_sas_io_unit_pg1(ioc);
3284 mutex_lock(&ioc->sas_topology_mutex);
3285 port_info = ioc->hba_port_info;
3286 if (!port_info) {
3287 ioc->hba_port_info = port_info = hba;
3288 ioc->hba_port_num_phy = port_info->num_phys;
3289 list_add_tail(&port_info->list, &ioc->sas_topology);
3290 } else {
3291 for (i = 0; i < hba->num_phys; i++) {
3292 port_info->phy_info[i].negotiated_link_rate =
3293 hba->phy_info[i].negotiated_link_rate;
3294 port_info->phy_info[i].handle =
3295 hba->phy_info[i].handle;
3296 port_info->phy_info[i].port_id =
3297 hba->phy_info[i].port_id;
3299 kfree(hba->phy_info);
3300 kfree(hba);
3301 hba = NULL;
3303 mutex_unlock(&ioc->sas_topology_mutex);
3304 #if defined(CPQ_CIM)
3305 ioc->num_ports = port_info->num_phys;
3306 #endif
3307 for (i = 0; i < port_info->num_phys; i++) {
3308 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
3309 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
3310 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
3311 port_info->phy_info[i].identify.handle =
3312 port_info->phy_info[i].handle;
3313 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
3314 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3315 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3316 port_info->phy_info[i].identify.handle);
3317 if (!ioc->hba_port_sas_addr)
3318 ioc->hba_port_sas_addr =
3319 port_info->phy_info[i].identify.sas_address;
3320 port_info->phy_info[i].identify.phy_id =
3321 port_info->phy_info[i].phy_id = i;
3322 if (port_info->phy_info[i].attached.handle)
3323 mptsas_sas_device_pg0(ioc,
3324 &port_info->phy_info[i].attached,
3325 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3326 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3327 port_info->phy_info[i].attached.handle);
3330 mptsas_setup_wide_ports(ioc, port_info);
3332 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3333 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
3334 &port_info->phy_info[i], ioc->sas_index, 1);
3336 return 0;
3338 out_free_port_info:
3339 kfree(hba);
3340 out:
3341 return error;
3344 static void
3345 mptsas_expander_refresh(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
3347 struct mptsas_portinfo *parent;
3348 struct device *parent_dev;
3349 struct sas_rphy *rphy;
3350 int i;
3351 u64 sas_address; /* expander sas address */
3352 u32 handle;
3354 handle = port_info->phy_info[0].handle;
3355 sas_address = port_info->phy_info[0].identify.sas_address;
3356 for (i = 0; i < port_info->num_phys; i++) {
3357 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
3358 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
3359 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + handle);
3361 mptsas_sas_device_pg0(ioc,
3362 &port_info->phy_info[i].identify,
3363 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3364 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3365 port_info->phy_info[i].identify.handle);
3366 port_info->phy_info[i].identify.phy_id =
3367 port_info->phy_info[i].phy_id;
3369 if (port_info->phy_info[i].attached.handle) {
3370 mptsas_sas_device_pg0(ioc,
3371 &port_info->phy_info[i].attached,
3372 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3373 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3374 port_info->phy_info[i].attached.handle);
3375 port_info->phy_info[i].attached.phy_id =
3376 port_info->phy_info[i].phy_id;
3380 mutex_lock(&ioc->sas_topology_mutex);
3381 parent = mptsas_find_portinfo_by_handle(ioc,
3382 port_info->phy_info[0].identify.handle_parent);
3383 if (!parent) {
3384 mutex_unlock(&ioc->sas_topology_mutex);
3385 return;
3387 for (i = 0, parent_dev = NULL; i < parent->num_phys && !parent_dev;
3388 i++) {
3389 if (parent->phy_info[i].attached.sas_address == sas_address) {
3390 rphy = mptsas_get_rphy(&parent->phy_info[i]);
3391 parent_dev = &rphy->dev;
3394 mutex_unlock(&ioc->sas_topology_mutex);
3396 mptsas_setup_wide_ports(ioc, port_info);
3397 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3398 mptsas_probe_one_phy(parent_dev, &port_info->phy_info[i],
3399 ioc->sas_index, 0);
3402 static void
3403 mptsas_expander_event_add(MPT_ADAPTER *ioc,
3404 MpiEventDataSasExpanderStatusChange_t *expander_data)
3406 struct mptsas_portinfo *port_info;
3407 int i;
3408 __le64 sas_address;
3410 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3411 if (!port_info)
3412 BUG();
3413 port_info->num_phys = (expander_data->NumPhys) ?
3414 expander_data->NumPhys : 1;
3415 port_info->phy_info = kcalloc(port_info->num_phys,
3416 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
3417 if (!port_info->phy_info)
3418 BUG();
3419 memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3420 for (i = 0; i < port_info->num_phys; i++) {
3421 port_info->phy_info[i].portinfo = port_info;
3422 port_info->phy_info[i].handle =
3423 le16_to_cpu(expander_data->DevHandle);
3424 port_info->phy_info[i].identify.sas_address =
3425 le64_to_cpu(sas_address);
3426 port_info->phy_info[i].identify.handle_parent =
3427 le16_to_cpu(expander_data->ParentDevHandle);
3430 mutex_lock(&ioc->sas_topology_mutex);
3431 list_add_tail(&port_info->list, &ioc->sas_topology);
3432 mutex_unlock(&ioc->sas_topology_mutex);
3434 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3435 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3436 (unsigned long long)sas_address);
3438 mptsas_expander_refresh(ioc, port_info);
3442 * mptsas_delete_expander_siblings - remove siblings attached to expander
3443 * @ioc: Pointer to MPT_ADAPTER structure
3444 * @parent: the parent port_info object
3445 * @expander: the expander port_info object
3447 static void
3448 mptsas_delete_expander_siblings(MPT_ADAPTER *ioc, struct mptsas_portinfo
3449 *parent, struct mptsas_portinfo *expander)
3451 struct mptsas_phyinfo *phy_info;
3452 struct mptsas_portinfo *port_info;
3453 struct sas_rphy *rphy;
3454 int i;
3456 phy_info = expander->phy_info;
3457 for (i = 0; i < expander->num_phys; i++, phy_info++) {
3458 rphy = mptsas_get_rphy(phy_info);
3459 if (!rphy)
3460 continue;
3461 if (rphy->identify.device_type == SAS_END_DEVICE)
3462 mptsas_del_end_device(ioc, phy_info);
3465 phy_info = expander->phy_info;
3466 for (i = 0; i < expander->num_phys; i++, phy_info++) {
3467 rphy = mptsas_get_rphy(phy_info);
3468 if (!rphy)
3469 continue;
3470 if (rphy->identify.device_type ==
3471 MPI_SAS_DEVICE_INFO_EDGE_EXPANDER ||
3472 rphy->identify.device_type ==
3473 MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
3474 port_info = mptsas_find_portinfo_by_sas_address(ioc,
3475 rphy->identify.sas_address);
3476 if (!port_info)
3477 continue;
3478 if (port_info == parent) /* backlink rphy */
3479 continue;
3481 Delete this expander even if the expdevpage is exists
3482 because the parent expander is already deleted
3484 mptsas_expander_delete(ioc, port_info, 1);
3491 * mptsas_expander_delete - remove this expander
3492 * @ioc: Pointer to MPT_ADAPTER structure
3493 * @port_info: expander port_info struct
3494 * @force: Flag to forcefully delete the expander
3498 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
3499 struct mptsas_portinfo *port_info, u8 force)
3502 struct mptsas_portinfo *parent;
3503 int i;
3504 u64 expander_sas_address;
3505 struct mptsas_phyinfo *phy_info;
3506 struct mptsas_portinfo buffer;
3507 struct mptsas_portinfo_details *port_details;
3508 struct sas_port *port;
3510 if (!port_info)
3511 return;
3513 /* see if expander is still there before deleting */
3514 mptsas_sas_expander_pg0(ioc, &buffer,
3515 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3516 MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
3517 port_info->phy_info[0].identify.handle);
3519 if (buffer.num_phys) {
3520 kfree(buffer.phy_info);
3521 if (!force)
3522 return;
3527 * Obtain the port_info instance to the parent port
3529 port_details = NULL;
3530 expander_sas_address =
3531 port_info->phy_info[0].identify.sas_address;
3532 parent = mptsas_find_portinfo_by_handle(ioc,
3533 port_info->phy_info[0].identify.handle_parent);
3534 mptsas_delete_expander_siblings(ioc, parent, port_info);
3535 if (!parent)
3536 goto out;
3539 * Delete rphys in the parent that point
3540 * to this expander.
3542 phy_info = parent->phy_info;
3543 port = NULL;
3544 for (i = 0; i < parent->num_phys; i++, phy_info++) {
3545 if (!phy_info->phy)
3546 continue;
3547 if (phy_info->attached.sas_address !=
3548 expander_sas_address)
3549 continue;
3550 if (!port) {
3551 port = mptsas_get_port(phy_info);
3552 port_details = phy_info->port_details;
3554 dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3555 MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n", ioc->name,
3556 phy_info->phy_id, phy_info->phy);
3557 sas_port_delete_phy(port, phy_info->phy);
3559 if (port) {
3560 dev_printk(KERN_DEBUG, &port->dev,
3561 MYIOC_s_FMT "delete port %d, sas_addr (0x%llx)\n",
3562 ioc->name, port->port_identifier,
3563 (unsigned long long)expander_sas_address);
3564 sas_port_delete(port);
3565 mptsas_port_delete(ioc, port_details);
3567 out:
3569 printk(MYIOC_s_INFO_FMT "delete expander: num_phys %d, "
3570 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3571 (unsigned long long)expander_sas_address);
3574 * free link
3576 list_del(&port_info->list);
3577 kfree(port_info->phy_info);
3578 kfree(port_info);
3583 * mptsas_send_expander_event - expanders events
3584 * @ioc: Pointer to MPT_ADAPTER structure
3585 * @expander_data: event data
3588 * This function handles adding, removing, and refreshing
3589 * device handles within the expander objects.
3591 static void
3592 mptsas_send_expander_event(struct fw_event_work *fw_event)
3594 MPT_ADAPTER *ioc;
3595 MpiEventDataSasExpanderStatusChange_t *expander_data;
3596 struct mptsas_portinfo *port_info;
3597 __le64 sas_address;
3598 int i;
3600 ioc = fw_event->ioc;
3601 expander_data = (MpiEventDataSasExpanderStatusChange_t *)
3602 fw_event->event_data;
3603 memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3604 sas_address = le64_to_cpu(sas_address);
3605 port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3607 if (expander_data->ReasonCode == MPI_EVENT_SAS_EXP_RC_ADDED) {
3608 if (port_info) {
3609 for (i = 0; i < port_info->num_phys; i++) {
3610 port_info->phy_info[i].portinfo = port_info;
3611 port_info->phy_info[i].handle =
3612 le16_to_cpu(expander_data->DevHandle);
3613 port_info->phy_info[i].identify.sas_address =
3614 le64_to_cpu(sas_address);
3615 port_info->phy_info[i].identify.handle_parent =
3616 le16_to_cpu(expander_data->ParentDevHandle);
3618 mptsas_expander_refresh(ioc, port_info);
3619 } else if (!port_info && expander_data->NumPhys)
3620 mptsas_expander_event_add(ioc, expander_data);
3621 } else if (expander_data->ReasonCode ==
3622 MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING)
3623 mptsas_expander_delete(ioc, port_info, 0);
3625 mptsas_free_fw_event(ioc, fw_event);
3630 * mptsas_expander_add -
3631 * @ioc: Pointer to MPT_ADAPTER structure
3632 * @handle:
3635 struct mptsas_portinfo *
3636 mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
3638 struct mptsas_portinfo buffer, *port_info;
3639 int i;
3641 if ((mptsas_sas_expander_pg0(ioc, &buffer,
3642 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3643 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)))
3644 return NULL;
3646 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_ATOMIC);
3647 if (!port_info) {
3648 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3649 "%s: exit at line=%d\n", ioc->name,
3650 __func__, __LINE__));
3651 return NULL;
3653 port_info->num_phys = buffer.num_phys;
3654 port_info->phy_info = buffer.phy_info;
3655 for (i = 0; i < port_info->num_phys; i++)
3656 port_info->phy_info[i].portinfo = port_info;
3657 mutex_lock(&ioc->sas_topology_mutex);
3658 list_add_tail(&port_info->list, &ioc->sas_topology);
3659 mutex_unlock(&ioc->sas_topology_mutex);
3660 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3661 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3662 (unsigned long long)buffer.phy_info[0].identify.sas_address);
3663 mptsas_expander_refresh(ioc, port_info);
3664 return port_info;
3667 static void
3668 mptsas_send_link_status_event(struct fw_event_work *fw_event)
3670 MPT_ADAPTER *ioc;
3671 MpiEventDataSasPhyLinkStatus_t *link_data;
3672 struct mptsas_portinfo *port_info;
3673 struct mptsas_phyinfo *phy_info = NULL;
3674 __le64 sas_address;
3675 u8 phy_num;
3676 u8 link_rate;
3678 ioc = fw_event->ioc;
3679 link_data = (MpiEventDataSasPhyLinkStatus_t *)fw_event->event_data;
3681 memcpy(&sas_address, &link_data->SASAddress, sizeof(__le64));
3682 sas_address = le64_to_cpu(sas_address);
3683 link_rate = link_data->LinkRates >> 4;
3684 phy_num = link_data->PhyNum;
3686 port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3687 if (port_info) {
3688 phy_info = &port_info->phy_info[phy_num];
3689 if (phy_info)
3690 phy_info->negotiated_link_rate = link_rate;
3693 if (link_rate == MPI_SAS_IOUNIT0_RATE_1_5 ||
3694 link_rate == MPI_SAS_IOUNIT0_RATE_3_0) {
3696 if (!port_info) {
3697 if (ioc->old_sas_discovery_protocal) {
3698 port_info = mptsas_expander_add(ioc,
3699 le16_to_cpu(link_data->DevHandle));
3700 if (port_info)
3701 goto out;
3703 goto out;
3706 if (port_info == ioc->hba_port_info)
3707 mptsas_probe_hba_phys(ioc);
3708 else
3709 mptsas_expander_refresh(ioc, port_info);
3710 } else if (phy_info && phy_info->phy) {
3711 if (link_rate == MPI_SAS_IOUNIT0_RATE_PHY_DISABLED)
3712 phy_info->phy->negotiated_linkrate =
3713 SAS_PHY_DISABLED;
3714 else if (link_rate ==
3715 MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION)
3716 phy_info->phy->negotiated_linkrate =
3717 SAS_LINK_RATE_FAILED;
3718 else {
3719 phy_info->phy->negotiated_linkrate =
3720 SAS_LINK_RATE_UNKNOWN;
3721 if (ioc->device_missing_delay &&
3722 mptsas_is_end_device(&phy_info->attached)) {
3723 struct scsi_device *sdev;
3724 VirtDevice *vdevice;
3725 u8 channel, id;
3726 id = phy_info->attached.id;
3727 channel = phy_info->attached.channel;
3728 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3729 "Link down for fw_id %d:fw_channel %d\n",
3730 ioc->name, phy_info->attached.id,
3731 phy_info->attached.channel));
3733 shost_for_each_device(sdev, ioc->sh) {
3734 vdevice = sdev->hostdata;
3735 if ((vdevice == NULL) ||
3736 (vdevice->vtarget == NULL))
3737 continue;
3738 if ((vdevice->vtarget->tflags &
3739 MPT_TARGET_FLAGS_RAID_COMPONENT ||
3740 vdevice->vtarget->raidVolume))
3741 continue;
3742 if (vdevice->vtarget->id == id &&
3743 vdevice->vtarget->channel ==
3744 channel)
3745 devtprintk(ioc,
3746 printk(MYIOC_s_DEBUG_FMT
3747 "SDEV OUTSTANDING CMDS"
3748 "%d\n", ioc->name,
3749 sdev->device_busy));
3755 out:
3756 mptsas_free_fw_event(ioc, fw_event);
3759 static void
3760 mptsas_not_responding_devices(MPT_ADAPTER *ioc)
3762 struct mptsas_portinfo buffer, *port_info;
3763 struct mptsas_device_info *sas_info;
3764 struct mptsas_devinfo sas_device;
3765 u32 handle;
3766 VirtTarget *vtarget = NULL;
3767 struct mptsas_phyinfo *phy_info;
3768 u8 found_expander;
3769 int retval, retry_count;
3770 unsigned long flags;
3772 mpt_findImVolumes(ioc);
3774 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3775 if (ioc->ioc_reset_in_progress) {
3776 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3777 "%s: exiting due to a parallel reset \n", ioc->name,
3778 __func__));
3779 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3780 return;
3782 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3784 /* devices, logical volumes */
3785 mutex_lock(&ioc->sas_device_info_mutex);
3786 redo_device_scan:
3787 list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) {
3788 if (sas_info->is_cached)
3789 continue;
3790 if (!sas_info->is_logical_volume) {
3791 sas_device.handle = 0;
3792 retry_count = 0;
3793 retry_page:
3794 retval = mptsas_sas_device_pg0(ioc, &sas_device,
3795 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID
3796 << MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3797 (sas_info->fw.channel << 8) +
3798 sas_info->fw.id);
3800 if (sas_device.handle)
3801 continue;
3802 if (retval == -EBUSY) {
3803 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3804 if (ioc->ioc_reset_in_progress) {
3805 dfailprintk(ioc,
3806 printk(MYIOC_s_DEBUG_FMT
3807 "%s: exiting due to reset\n",
3808 ioc->name, __func__));
3809 spin_unlock_irqrestore
3810 (&ioc->taskmgmt_lock, flags);
3811 mutex_unlock(&ioc->
3812 sas_device_info_mutex);
3813 return;
3815 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
3816 flags);
3819 if (retval && (retval != -ENODEV)) {
3820 if (retry_count < 10) {
3821 retry_count++;
3822 goto retry_page;
3823 } else {
3824 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3825 "%s: Config page retry exceeded retry "
3826 "count deleting device 0x%llx\n",
3827 ioc->name, __func__,
3828 sas_info->sas_address));
3832 /* delete device */
3833 vtarget = mptsas_find_vtarget(ioc,
3834 sas_info->fw.channel, sas_info->fw.id);
3836 if (vtarget)
3837 vtarget->deleted = 1;
3839 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3840 sas_info->sas_address);
3842 if (phy_info) {
3843 mptsas_del_end_device(ioc, phy_info);
3844 goto redo_device_scan;
3846 } else
3847 mptsas_volume_delete(ioc, sas_info->fw.id);
3849 mutex_unlock(&ioc->sas_device_info_mutex);
3851 /* expanders */
3852 mutex_lock(&ioc->sas_topology_mutex);
3853 redo_expander_scan:
3854 list_for_each_entry(port_info, &ioc->sas_topology, list) {
3856 if (port_info->phy_info &&
3857 (!(port_info->phy_info[0].identify.device_info &
3858 MPI_SAS_DEVICE_INFO_SMP_TARGET)))
3859 continue;
3860 found_expander = 0;
3861 handle = 0xFFFF;
3862 while (!mptsas_sas_expander_pg0(ioc, &buffer,
3863 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3864 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle) &&
3865 !found_expander) {
3867 handle = buffer.phy_info[0].handle;
3868 if (buffer.phy_info[0].identify.sas_address ==
3869 port_info->phy_info[0].identify.sas_address) {
3870 found_expander = 1;
3872 kfree(buffer.phy_info);
3875 if (!found_expander) {
3876 mptsas_expander_delete(ioc, port_info, 0);
3877 goto redo_expander_scan;
3880 mutex_unlock(&ioc->sas_topology_mutex);
3884 * mptsas_probe_expanders - adding expanders
3885 * @ioc: Pointer to MPT_ADAPTER structure
3888 static void
3889 mptsas_probe_expanders(MPT_ADAPTER *ioc)
3891 struct mptsas_portinfo buffer, *port_info;
3892 u32 handle;
3893 int i;
3895 handle = 0xFFFF;
3896 while (!mptsas_sas_expander_pg0(ioc, &buffer,
3897 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3898 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)) {
3900 handle = buffer.phy_info[0].handle;
3901 port_info = mptsas_find_portinfo_by_sas_address(ioc,
3902 buffer.phy_info[0].identify.sas_address);
3904 if (port_info) {
3905 /* refreshing handles */
3906 for (i = 0; i < buffer.num_phys; i++) {
3907 port_info->phy_info[i].handle = handle;
3908 port_info->phy_info[i].identify.handle_parent =
3909 buffer.phy_info[0].identify.handle_parent;
3911 mptsas_expander_refresh(ioc, port_info);
3912 kfree(buffer.phy_info);
3913 continue;
3916 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3917 if (!port_info) {
3918 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3919 "%s: exit at line=%d\n", ioc->name,
3920 __func__, __LINE__));
3921 return;
3923 port_info->num_phys = buffer.num_phys;
3924 port_info->phy_info = buffer.phy_info;
3925 for (i = 0; i < port_info->num_phys; i++)
3926 port_info->phy_info[i].portinfo = port_info;
3927 mutex_lock(&ioc->sas_topology_mutex);
3928 list_add_tail(&port_info->list, &ioc->sas_topology);
3929 mutex_unlock(&ioc->sas_topology_mutex);
3930 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3931 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3932 (unsigned long long)buffer.phy_info[0].identify.sas_address);
3933 mptsas_expander_refresh(ioc, port_info);
3937 static void
3938 mptsas_probe_devices(MPT_ADAPTER *ioc)
3940 u16 handle;
3941 struct mptsas_devinfo sas_device;
3942 struct mptsas_phyinfo *phy_info;
3944 handle = 0xFFFF;
3945 while (!(mptsas_sas_device_pg0(ioc, &sas_device,
3946 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
3948 handle = sas_device.handle;
3950 if ((sas_device.device_info &
3951 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
3952 MPI_SAS_DEVICE_INFO_STP_TARGET |
3953 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0)
3954 continue;
3956 /* If there is no FW B_T mapping for this device then continue
3957 * */
3958 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
3959 || !(sas_device.flags &
3960 MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
3961 continue;
3963 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3964 if (!phy_info)
3965 continue;
3967 if (mptsas_get_rphy(phy_info))
3968 continue;
3970 mptsas_add_end_device(ioc, phy_info);
3975 * mptsas_scan_sas_topology -
3976 * @ioc: Pointer to MPT_ADAPTER structure
3977 * @sas_address:
3980 static void
3981 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
3983 struct scsi_device *sdev;
3984 int i;
3986 mptsas_probe_hba_phys(ioc);
3987 mptsas_probe_expanders(ioc);
3988 mptsas_probe_devices(ioc);
3991 Reporting RAID volumes.
3993 if (!ioc->ir_firmware || !ioc->raid_data.pIocPg2 ||
3994 !ioc->raid_data.pIocPg2->NumActiveVolumes)
3995 return;
3996 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
3997 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
3998 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
3999 if (sdev) {
4000 scsi_device_put(sdev);
4001 continue;
4003 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4004 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4005 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID);
4006 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4007 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
4012 static void
4013 mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
4015 MPT_ADAPTER *ioc;
4016 EventDataQueueFull_t *qfull_data;
4017 struct mptsas_device_info *sas_info;
4018 struct scsi_device *sdev;
4019 int depth;
4020 int id = -1;
4021 int channel = -1;
4022 int fw_id, fw_channel;
4023 u16 current_depth;
4026 ioc = fw_event->ioc;
4027 qfull_data = (EventDataQueueFull_t *)fw_event->event_data;
4028 fw_id = qfull_data->TargetID;
4029 fw_channel = qfull_data->Bus;
4030 current_depth = le16_to_cpu(qfull_data->CurrentDepth);
4032 /* if hidden raid component, look for the volume id */
4033 mutex_lock(&ioc->sas_device_info_mutex);
4034 if (mptscsih_is_phys_disk(ioc, fw_channel, fw_id)) {
4035 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
4036 list) {
4037 if (sas_info->is_cached ||
4038 sas_info->is_logical_volume)
4039 continue;
4040 if (sas_info->is_hidden_raid_component &&
4041 (sas_info->fw.channel == fw_channel &&
4042 sas_info->fw.id == fw_id)) {
4043 id = sas_info->volume_id;
4044 channel = MPTSAS_RAID_CHANNEL;
4045 goto out;
4048 } else {
4049 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
4050 list) {
4051 if (sas_info->is_cached ||
4052 sas_info->is_hidden_raid_component ||
4053 sas_info->is_logical_volume)
4054 continue;
4055 if (sas_info->fw.channel == fw_channel &&
4056 sas_info->fw.id == fw_id) {
4057 id = sas_info->os.id;
4058 channel = sas_info->os.channel;
4059 goto out;
4065 out:
4066 mutex_unlock(&ioc->sas_device_info_mutex);
4068 if (id != -1) {
4069 shost_for_each_device(sdev, ioc->sh) {
4070 if (sdev->id == id && sdev->channel == channel) {
4071 if (current_depth > sdev->queue_depth) {
4072 sdev_printk(KERN_INFO, sdev,
4073 "strange observation, the queue "
4074 "depth is (%d) meanwhile fw queue "
4075 "depth (%d)\n", sdev->queue_depth,
4076 current_depth);
4077 continue;
4079 depth = scsi_track_queue_full(sdev,
4080 current_depth - 1);
4081 if (depth > 0)
4082 sdev_printk(KERN_INFO, sdev,
4083 "Queue depth reduced to (%d)\n",
4084 depth);
4085 else if (depth < 0)
4086 sdev_printk(KERN_INFO, sdev,
4087 "Tagged Command Queueing is being "
4088 "disabled\n");
4089 else if (depth == 0)
4090 sdev_printk(KERN_INFO, sdev,
4091 "Queue depth not changed yet\n");
4096 mptsas_free_fw_event(ioc, fw_event);
4100 static struct mptsas_phyinfo *
4101 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
4103 struct mptsas_portinfo *port_info;
4104 struct mptsas_phyinfo *phy_info = NULL;
4105 int i;
4107 mutex_lock(&ioc->sas_topology_mutex);
4108 list_for_each_entry(port_info, &ioc->sas_topology, list) {
4109 for (i = 0; i < port_info->num_phys; i++) {
4110 if (!mptsas_is_end_device(
4111 &port_info->phy_info[i].attached))
4112 continue;
4113 if (port_info->phy_info[i].attached.sas_address
4114 != sas_address)
4115 continue;
4116 phy_info = &port_info->phy_info[i];
4117 break;
4120 mutex_unlock(&ioc->sas_topology_mutex);
4121 return phy_info;
4125 * mptsas_find_phyinfo_by_phys_disk_num -
4126 * @ioc: Pointer to MPT_ADAPTER structure
4127 * @phys_disk_num:
4128 * @channel:
4129 * @id:
4132 static struct mptsas_phyinfo *
4133 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
4134 u8 channel, u8 id)
4136 struct mptsas_phyinfo *phy_info = NULL;
4137 struct mptsas_portinfo *port_info;
4138 RaidPhysDiskPage1_t *phys_disk = NULL;
4139 int num_paths;
4140 u64 sas_address = 0;
4141 int i;
4143 phy_info = NULL;
4144 if (!ioc->raid_data.pIocPg3)
4145 return NULL;
4146 /* dual port support */
4147 num_paths = mpt_raid_phys_disk_get_num_paths(ioc, phys_disk_num);
4148 if (!num_paths)
4149 goto out;
4150 phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
4151 (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
4152 if (!phys_disk)
4153 goto out;
4154 mpt_raid_phys_disk_pg1(ioc, phys_disk_num, phys_disk);
4155 for (i = 0; i < num_paths; i++) {
4156 if ((phys_disk->Path[i].Flags & 1) != 0)
4157 /* entry no longer valid */
4158 continue;
4159 if ((id == phys_disk->Path[i].PhysDiskID) &&
4160 (channel == phys_disk->Path[i].PhysDiskBus)) {
4161 memcpy(&sas_address, &phys_disk->Path[i].WWID,
4162 sizeof(u64));
4163 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4164 sas_address);
4165 goto out;
4169 out:
4170 kfree(phys_disk);
4171 if (phy_info)
4172 return phy_info;
4175 * Extra code to handle RAID0 case, where the sas_address is not updated
4176 * in phys_disk_page_1 when hotswapped
4178 mutex_lock(&ioc->sas_topology_mutex);
4179 list_for_each_entry(port_info, &ioc->sas_topology, list) {
4180 for (i = 0; i < port_info->num_phys && !phy_info; i++) {
4181 if (!mptsas_is_end_device(
4182 &port_info->phy_info[i].attached))
4183 continue;
4184 if (port_info->phy_info[i].attached.phys_disk_num == ~0)
4185 continue;
4186 if ((port_info->phy_info[i].attached.phys_disk_num ==
4187 phys_disk_num) &&
4188 (port_info->phy_info[i].attached.id == id) &&
4189 (port_info->phy_info[i].attached.channel ==
4190 channel))
4191 phy_info = &port_info->phy_info[i];
4194 mutex_unlock(&ioc->sas_topology_mutex);
4195 return phy_info;
4198 static void
4199 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
4201 int rc;
4203 sdev->no_uld_attach = data ? 1 : 0;
4204 rc = scsi_device_reprobe(sdev);
4207 static void
4208 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
4210 starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
4211 mptsas_reprobe_lun);
4214 static void
4215 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
4217 CONFIGPARMS cfg;
4218 ConfigPageHeader_t hdr;
4219 dma_addr_t dma_handle;
4220 pRaidVolumePage0_t buffer = NULL;
4221 RaidPhysDiskPage0_t phys_disk;
4222 int i;
4223 struct mptsas_phyinfo *phy_info;
4224 struct mptsas_devinfo sas_device;
4226 memset(&cfg, 0 , sizeof(CONFIGPARMS));
4227 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4228 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
4229 cfg.pageAddr = (channel << 8) + id;
4230 cfg.cfghdr.hdr = &hdr;
4231 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4232 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
4234 if (mpt_config(ioc, &cfg) != 0)
4235 goto out;
4237 if (!hdr.PageLength)
4238 goto out;
4240 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4241 &dma_handle);
4243 if (!buffer)
4244 goto out;
4246 cfg.physAddr = dma_handle;
4247 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4249 if (mpt_config(ioc, &cfg) != 0)
4250 goto out;
4252 if (!(buffer->VolumeStatus.Flags &
4253 MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
4254 goto out;
4256 if (!buffer->NumPhysDisks)
4257 goto out;
4259 for (i = 0; i < buffer->NumPhysDisks; i++) {
4261 if (mpt_raid_phys_disk_pg0(ioc,
4262 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
4263 continue;
4265 if (mptsas_sas_device_pg0(ioc, &sas_device,
4266 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4267 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4268 (phys_disk.PhysDiskBus << 8) +
4269 phys_disk.PhysDiskID))
4270 continue;
4272 /* If there is no FW B_T mapping for this device then continue
4273 * */
4274 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4275 || !(sas_device.flags &
4276 MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4277 continue;
4280 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4281 sas_device.sas_address);
4282 mptsas_add_end_device(ioc, phy_info);
4285 out:
4286 if (buffer)
4287 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4288 dma_handle);
4291 * Work queue thread to handle SAS hotplug events
4293 static void
4294 mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
4295 struct mptsas_hotplug_event *hot_plug_info)
4297 struct mptsas_phyinfo *phy_info;
4298 struct scsi_target * starget;
4299 struct mptsas_devinfo sas_device;
4300 VirtTarget *vtarget;
4301 int i;
4302 struct mptsas_portinfo *port_info;
4304 switch (hot_plug_info->event_type) {
4306 case MPTSAS_ADD_PHYSDISK:
4308 if (!ioc->raid_data.pIocPg2)
4309 break;
4311 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
4312 if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID ==
4313 hot_plug_info->id) {
4314 printk(MYIOC_s_WARN_FMT "firmware bug: unable "
4315 "to add hidden disk - target_id matchs "
4316 "volume_id\n", ioc->name);
4317 mptsas_free_fw_event(ioc, fw_event);
4318 return;
4321 mpt_findImVolumes(ioc);
4323 case MPTSAS_ADD_DEVICE:
4324 memset(&sas_device, 0, sizeof(struct mptsas_devinfo));
4325 mptsas_sas_device_pg0(ioc, &sas_device,
4326 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4327 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4328 (hot_plug_info->channel << 8) +
4329 hot_plug_info->id);
4331 /* If there is no FW B_T mapping for this device then break
4332 * */
4333 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4334 || !(sas_device.flags &
4335 MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4336 break;
4338 if (!sas_device.handle)
4339 return;
4341 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
4342 /* Only For SATA Device ADD */
4343 if (!phy_info && (sas_device.device_info &
4344 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) {
4345 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4346 "%s %d SATA HOT PLUG: "
4347 "parent handle of device %x\n", ioc->name,
4348 __func__, __LINE__, sas_device.handle_parent));
4349 port_info = mptsas_find_portinfo_by_handle(ioc,
4350 sas_device.handle_parent);
4352 if (port_info == ioc->hba_port_info)
4353 mptsas_probe_hba_phys(ioc);
4354 else if (port_info)
4355 mptsas_expander_refresh(ioc, port_info);
4356 else {
4357 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4358 "%s %d port info is NULL\n",
4359 ioc->name, __func__, __LINE__));
4360 break;
4362 phy_info = mptsas_refreshing_device_handles
4363 (ioc, &sas_device);
4366 if (!phy_info) {
4367 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4368 "%s %d phy info is NULL\n",
4369 ioc->name, __func__, __LINE__));
4370 break;
4373 if (mptsas_get_rphy(phy_info))
4374 break;
4376 mptsas_add_end_device(ioc, phy_info);
4377 break;
4379 case MPTSAS_DEL_DEVICE:
4380 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4381 hot_plug_info->sas_address);
4382 mptsas_del_end_device(ioc, phy_info);
4383 break;
4385 case MPTSAS_DEL_PHYSDISK:
4387 mpt_findImVolumes(ioc);
4389 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
4390 ioc, hot_plug_info->phys_disk_num,
4391 hot_plug_info->channel,
4392 hot_plug_info->id);
4393 mptsas_del_end_device(ioc, phy_info);
4394 break;
4396 case MPTSAS_ADD_PHYSDISK_REPROBE:
4398 if (mptsas_sas_device_pg0(ioc, &sas_device,
4399 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4400 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4401 (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4402 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4403 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4404 __func__, hot_plug_info->id, __LINE__));
4405 break;
4408 /* If there is no FW B_T mapping for this device then break
4409 * */
4410 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4411 || !(sas_device.flags &
4412 MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4413 break;
4415 phy_info = mptsas_find_phyinfo_by_sas_address(
4416 ioc, sas_device.sas_address);
4418 if (!phy_info) {
4419 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4420 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4421 __func__, hot_plug_info->id, __LINE__));
4422 break;
4425 starget = mptsas_get_starget(phy_info);
4426 if (!starget) {
4427 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4428 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4429 __func__, hot_plug_info->id, __LINE__));
4430 break;
4433 vtarget = starget->hostdata;
4434 if (!vtarget) {
4435 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4436 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4437 __func__, hot_plug_info->id, __LINE__));
4438 break;
4441 mpt_findImVolumes(ioc);
4443 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Hidding: "
4444 "fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4445 ioc->name, hot_plug_info->channel, hot_plug_info->id,
4446 hot_plug_info->phys_disk_num, (unsigned long long)
4447 sas_device.sas_address);
4449 vtarget->id = hot_plug_info->phys_disk_num;
4450 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
4451 phy_info->attached.phys_disk_num = hot_plug_info->phys_disk_num;
4452 mptsas_reprobe_target(starget, 1);
4453 break;
4455 case MPTSAS_DEL_PHYSDISK_REPROBE:
4457 if (mptsas_sas_device_pg0(ioc, &sas_device,
4458 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4459 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4460 (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4461 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4462 "%s: fw_id=%d exit at line=%d\n",
4463 ioc->name, __func__,
4464 hot_plug_info->id, __LINE__));
4465 break;
4468 /* If there is no FW B_T mapping for this device then break
4469 * */
4470 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4471 || !(sas_device.flags &
4472 MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4473 break;
4475 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4476 sas_device.sas_address);
4477 if (!phy_info) {
4478 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4479 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4480 __func__, hot_plug_info->id, __LINE__));
4481 break;
4484 starget = mptsas_get_starget(phy_info);
4485 if (!starget) {
4486 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4487 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4488 __func__, hot_plug_info->id, __LINE__));
4489 break;
4492 vtarget = starget->hostdata;
4493 if (!vtarget) {
4494 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4495 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4496 __func__, hot_plug_info->id, __LINE__));
4497 break;
4500 if (!(vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)) {
4501 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4502 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4503 __func__, hot_plug_info->id, __LINE__));
4504 break;
4507 mpt_findImVolumes(ioc);
4509 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Exposing:"
4510 " fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4511 ioc->name, hot_plug_info->channel, hot_plug_info->id,
4512 hot_plug_info->phys_disk_num, (unsigned long long)
4513 sas_device.sas_address);
4515 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
4516 vtarget->id = hot_plug_info->id;
4517 phy_info->attached.phys_disk_num = ~0;
4518 mptsas_reprobe_target(starget, 0);
4519 mptsas_add_device_component_by_fw(ioc,
4520 hot_plug_info->channel, hot_plug_info->id);
4521 break;
4523 case MPTSAS_ADD_RAID:
4525 mpt_findImVolumes(ioc);
4526 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4527 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4528 hot_plug_info->id);
4529 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4530 hot_plug_info->id, 0);
4531 break;
4533 case MPTSAS_DEL_RAID:
4535 mpt_findImVolumes(ioc);
4536 printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4537 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4538 hot_plug_info->id);
4539 scsi_remove_device(hot_plug_info->sdev);
4540 scsi_device_put(hot_plug_info->sdev);
4541 break;
4543 case MPTSAS_ADD_INACTIVE_VOLUME:
4545 mpt_findImVolumes(ioc);
4546 mptsas_adding_inactive_raid_components(ioc,
4547 hot_plug_info->channel, hot_plug_info->id);
4548 break;
4550 default:
4551 break;
4554 mptsas_free_fw_event(ioc, fw_event);
4557 static void
4558 mptsas_send_sas_event(struct fw_event_work *fw_event)
4560 MPT_ADAPTER *ioc;
4561 struct mptsas_hotplug_event hot_plug_info;
4562 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
4563 u32 device_info;
4564 u64 sas_address;
4566 ioc = fw_event->ioc;
4567 sas_event_data = (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
4568 fw_event->event_data;
4569 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
4571 if ((device_info &
4572 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
4573 MPI_SAS_DEVICE_INFO_STP_TARGET |
4574 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0) {
4575 mptsas_free_fw_event(ioc, fw_event);
4576 return;
4579 if (sas_event_data->ReasonCode ==
4580 MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED) {
4581 mptbase_sas_persist_operation(ioc,
4582 MPI_SAS_OP_CLEAR_NOT_PRESENT);
4583 mptsas_free_fw_event(ioc, fw_event);
4584 return;
4587 switch (sas_event_data->ReasonCode) {
4588 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
4589 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
4590 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4591 hot_plug_info.handle = le16_to_cpu(sas_event_data->DevHandle);
4592 hot_plug_info.channel = sas_event_data->Bus;
4593 hot_plug_info.id = sas_event_data->TargetID;
4594 hot_plug_info.phy_id = sas_event_data->PhyNum;
4595 memcpy(&sas_address, &sas_event_data->SASAddress,
4596 sizeof(u64));
4597 hot_plug_info.sas_address = le64_to_cpu(sas_address);
4598 hot_plug_info.device_info = device_info;
4599 if (sas_event_data->ReasonCode &
4600 MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
4601 hot_plug_info.event_type = MPTSAS_ADD_DEVICE;
4602 else
4603 hot_plug_info.event_type = MPTSAS_DEL_DEVICE;
4604 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4605 break;
4607 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
4608 mptbase_sas_persist_operation(ioc,
4609 MPI_SAS_OP_CLEAR_NOT_PRESENT);
4610 mptsas_free_fw_event(ioc, fw_event);
4611 break;
4613 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
4614 /* TODO */
4615 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
4616 /* TODO */
4617 default:
4618 mptsas_free_fw_event(ioc, fw_event);
4619 break;
4623 static void
4624 mptsas_send_raid_event(struct fw_event_work *fw_event)
4626 MPT_ADAPTER *ioc;
4627 EVENT_DATA_RAID *raid_event_data;
4628 struct mptsas_hotplug_event hot_plug_info;
4629 int status;
4630 int state;
4631 struct scsi_device *sdev = NULL;
4632 VirtDevice *vdevice = NULL;
4633 RaidPhysDiskPage0_t phys_disk;
4635 ioc = fw_event->ioc;
4636 raid_event_data = (EVENT_DATA_RAID *)fw_event->event_data;
4637 status = le32_to_cpu(raid_event_data->SettingsStatus);
4638 state = (status >> 8) & 0xff;
4640 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4641 hot_plug_info.id = raid_event_data->VolumeID;
4642 hot_plug_info.channel = raid_event_data->VolumeBus;
4643 hot_plug_info.phys_disk_num = raid_event_data->PhysDiskNum;
4645 if (raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_DELETED ||
4646 raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_CREATED ||
4647 raid_event_data->ReasonCode ==
4648 MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED) {
4649 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
4650 hot_plug_info.id, 0);
4651 hot_plug_info.sdev = sdev;
4652 if (sdev)
4653 vdevice = sdev->hostdata;
4656 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4657 "ReasonCode=%02x\n", ioc->name, __func__,
4658 raid_event_data->ReasonCode));
4660 switch (raid_event_data->ReasonCode) {
4661 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4662 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK_REPROBE;
4663 break;
4664 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4665 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK_REPROBE;
4666 break;
4667 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4668 switch (state) {
4669 case MPI_PD_STATE_ONLINE:
4670 case MPI_PD_STATE_NOT_COMPATIBLE:
4671 mpt_raid_phys_disk_pg0(ioc,
4672 raid_event_data->PhysDiskNum, &phys_disk);
4673 hot_plug_info.id = phys_disk.PhysDiskID;
4674 hot_plug_info.channel = phys_disk.PhysDiskBus;
4675 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4676 break;
4677 case MPI_PD_STATE_FAILED:
4678 case MPI_PD_STATE_MISSING:
4679 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
4680 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
4681 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
4682 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4683 break;
4684 default:
4685 break;
4687 break;
4688 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4689 if (!sdev)
4690 break;
4691 vdevice->vtarget->deleted = 1; /* block IO */
4692 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4693 break;
4694 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4695 if (sdev) {
4696 scsi_device_put(sdev);
4697 break;
4699 hot_plug_info.event_type = MPTSAS_ADD_RAID;
4700 break;
4701 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4702 if (!(status & MPI_RAIDVOL0_STATUS_FLAG_ENABLED)) {
4703 if (!sdev)
4704 break;
4705 vdevice->vtarget->deleted = 1; /* block IO */
4706 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4707 break;
4709 switch (state) {
4710 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
4711 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
4712 if (!sdev)
4713 break;
4714 vdevice->vtarget->deleted = 1; /* block IO */
4715 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4716 break;
4717 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
4718 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
4719 if (sdev) {
4720 scsi_device_put(sdev);
4721 break;
4723 hot_plug_info.event_type = MPTSAS_ADD_RAID;
4724 break;
4725 default:
4726 break;
4728 break;
4729 default:
4730 break;
4733 if (hot_plug_info.event_type != MPTSAS_IGNORE_EVENT)
4734 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4735 else
4736 mptsas_free_fw_event(ioc, fw_event);
4740 * mptsas_issue_tm - send mptsas internal tm request
4741 * @ioc: Pointer to MPT_ADAPTER structure
4742 * @type: Task Management type
4743 * @channel: channel number for task management
4744 * @id: Logical Target ID for reset (if appropriate)
4745 * @lun: Logical unit for reset (if appropriate)
4746 * @task_context: Context for the task to be aborted
4747 * @timeout: timeout for task management control
4749 * return 0 on success and -1 on failure:
4752 static int
4753 mptsas_issue_tm(MPT_ADAPTER *ioc, u8 type, u8 channel, u8 id, u64 lun,
4754 int task_context, ulong timeout, u8 *issue_reset)
4756 MPT_FRAME_HDR *mf;
4757 SCSITaskMgmt_t *pScsiTm;
4758 int retval;
4759 unsigned long timeleft;
4761 *issue_reset = 0;
4762 mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
4763 if (mf == NULL) {
4764 retval = -1; /* return failure */
4765 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "TaskMgmt request: no "
4766 "msg frames!!\n", ioc->name));
4767 goto out;
4770 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request: mr = %p, "
4771 "task_type = 0x%02X,\n\t timeout = %ld, fw_channel = %d, "
4772 "fw_id = %d, lun = %lld,\n\t task_context = 0x%x\n", ioc->name, mf,
4773 type, timeout, channel, id, (unsigned long long)lun,
4774 task_context));
4776 pScsiTm = (SCSITaskMgmt_t *) mf;
4777 memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
4778 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
4779 pScsiTm->TaskType = type;
4780 pScsiTm->MsgFlags = 0;
4781 pScsiTm->TargetID = id;
4782 pScsiTm->Bus = channel;
4783 pScsiTm->ChainOffset = 0;
4784 pScsiTm->Reserved = 0;
4785 pScsiTm->Reserved1 = 0;
4786 pScsiTm->TaskMsgContext = task_context;
4787 int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
4789 INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4790 CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
4791 retval = 0;
4792 mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
4794 /* Now wait for the command to complete */
4795 timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
4796 timeout*HZ);
4797 if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
4798 retval = -1; /* return failure */
4799 dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
4800 "TaskMgmt request: TIMED OUT!(mr=%p)\n", ioc->name, mf));
4801 mpt_free_msg_frame(ioc, mf);
4802 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
4803 goto out;
4804 *issue_reset = 1;
4805 goto out;
4808 if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
4809 retval = -1; /* return failure */
4810 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4811 "TaskMgmt request: failed with no reply\n", ioc->name));
4812 goto out;
4815 out:
4816 CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4817 return retval;
4821 * mptsas_broadcast_primative_work - Handle broadcast primitives
4822 * @work: work queue payload containing info describing the event
4824 * this will be handled in workqueue context.
4826 static void
4827 mptsas_broadcast_primative_work(struct fw_event_work *fw_event)
4829 MPT_ADAPTER *ioc = fw_event->ioc;
4830 MPT_FRAME_HDR *mf;
4831 VirtDevice *vdevice;
4832 int ii;
4833 struct scsi_cmnd *sc;
4834 SCSITaskMgmtReply_t *pScsiTmReply;
4835 u8 issue_reset;
4836 int task_context;
4837 u8 channel, id;
4838 int lun;
4839 u32 termination_count;
4840 u32 query_count;
4842 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4843 "%s - enter\n", ioc->name, __func__));
4845 mutex_lock(&ioc->taskmgmt_cmds.mutex);
4846 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
4847 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4848 mptsas_requeue_fw_event(ioc, fw_event, 1000);
4849 return;
4852 issue_reset = 0;
4853 termination_count = 0;
4854 query_count = 0;
4855 mpt_findImVolumes(ioc);
4856 pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
4858 for (ii = 0; ii < ioc->req_depth; ii++) {
4859 if (ioc->fw_events_off)
4860 goto out;
4861 sc = mptscsih_get_scsi_lookup(ioc, ii);
4862 if (!sc)
4863 continue;
4864 mf = MPT_INDEX_2_MFPTR(ioc, ii);
4865 if (!mf)
4866 continue;
4867 task_context = mf->u.frame.hwhdr.msgctxu.MsgContext;
4868 vdevice = sc->device->hostdata;
4869 if (!vdevice || !vdevice->vtarget)
4870 continue;
4871 if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
4872 continue; /* skip hidden raid components */
4873 if (vdevice->vtarget->raidVolume)
4874 continue; /* skip hidden raid components */
4875 channel = vdevice->vtarget->channel;
4876 id = vdevice->vtarget->id;
4877 lun = vdevice->lun;
4878 if (mptsas_issue_tm(ioc, MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK,
4879 channel, id, (u64)lun, task_context, 30, &issue_reset))
4880 goto out;
4881 query_count++;
4882 termination_count +=
4883 le32_to_cpu(pScsiTmReply->TerminationCount);
4884 if ((pScsiTmReply->IOCStatus == MPI_IOCSTATUS_SUCCESS) &&
4885 (pScsiTmReply->ResponseCode ==
4886 MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
4887 pScsiTmReply->ResponseCode ==
4888 MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
4889 continue;
4890 if (mptsas_issue_tm(ioc,
4891 MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET,
4892 channel, id, (u64)lun, 0, 30, &issue_reset))
4893 goto out;
4894 termination_count +=
4895 le32_to_cpu(pScsiTmReply->TerminationCount);
4898 out:
4899 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4900 "%s - exit, query_count = %d termination_count = %d\n",
4901 ioc->name, __func__, query_count, termination_count));
4903 ioc->broadcast_aen_busy = 0;
4904 mpt_clear_taskmgmt_in_progress_flag(ioc);
4905 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4907 if (issue_reset) {
4908 printk(MYIOC_s_WARN_FMT
4909 "Issuing Reset from %s!! doorbell=0x%08x\n",
4910 ioc->name, __func__, mpt_GetIocState(ioc, 0));
4911 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
4913 mptsas_free_fw_event(ioc, fw_event);
4917 * mptsas_send_ir2_event - handle exposing hidden disk when
4918 * an inactive raid volume is added
4920 * @ioc: Pointer to MPT_ADAPTER structure
4921 * @ir2_data
4924 static void
4925 mptsas_send_ir2_event(struct fw_event_work *fw_event)
4927 MPT_ADAPTER *ioc;
4928 struct mptsas_hotplug_event hot_plug_info;
4929 MPI_EVENT_DATA_IR2 *ir2_data;
4930 u8 reasonCode;
4931 RaidPhysDiskPage0_t phys_disk;
4933 ioc = fw_event->ioc;
4934 ir2_data = (MPI_EVENT_DATA_IR2 *)fw_event->event_data;
4935 reasonCode = ir2_data->ReasonCode;
4937 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4938 "ReasonCode=%02x\n", ioc->name, __func__, reasonCode));
4940 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4941 hot_plug_info.id = ir2_data->TargetID;
4942 hot_plug_info.channel = ir2_data->Bus;
4943 switch (reasonCode) {
4944 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
4945 hot_plug_info.event_type = MPTSAS_ADD_INACTIVE_VOLUME;
4946 break;
4947 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
4948 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4949 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4950 break;
4951 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
4952 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4953 mpt_raid_phys_disk_pg0(ioc,
4954 ir2_data->PhysDiskNum, &phys_disk);
4955 hot_plug_info.id = phys_disk.PhysDiskID;
4956 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4957 break;
4958 default:
4959 mptsas_free_fw_event(ioc, fw_event);
4960 return;
4962 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4965 static int
4966 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
4968 u32 event = le32_to_cpu(reply->Event);
4969 int sz, event_data_sz;
4970 struct fw_event_work *fw_event;
4971 unsigned long delay;
4973 if (ioc->bus_type != SAS)
4974 return 0;
4976 /* events turned off due to host reset or driver unloading */
4977 if (ioc->fw_events_off)
4978 return 0;
4980 delay = msecs_to_jiffies(1);
4981 switch (event) {
4982 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
4984 EVENT_DATA_SAS_BROADCAST_PRIMITIVE *broadcast_event_data =
4985 (EVENT_DATA_SAS_BROADCAST_PRIMITIVE *)reply->Data;
4986 if (broadcast_event_data->Primitive !=
4987 MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
4988 return 0;
4989 if (ioc->broadcast_aen_busy)
4990 return 0;
4991 ioc->broadcast_aen_busy = 1;
4992 break;
4994 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
4996 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data =
4997 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data;
4998 u16 ioc_stat;
4999 ioc_stat = le16_to_cpu(reply->IOCStatus);
5001 if (sas_event_data->ReasonCode ==
5002 MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) {
5003 mptsas_target_reset_queue(ioc, sas_event_data);
5004 return 0;
5006 if (sas_event_data->ReasonCode ==
5007 MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
5008 ioc->device_missing_delay &&
5009 (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)) {
5010 VirtTarget *vtarget = NULL;
5011 u8 id, channel;
5012 u32 log_info = le32_to_cpu(reply->IOCLogInfo);
5014 id = sas_event_data->TargetID;
5015 channel = sas_event_data->Bus;
5017 vtarget = mptsas_find_vtarget(ioc, channel, id);
5018 if (vtarget) {
5019 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5020 "LogInfo (0x%x) available for "
5021 "INTERNAL_DEVICE_RESET"
5022 "fw_id %d fw_channel %d\n", ioc->name,
5023 log_info, id, channel));
5024 if (vtarget->raidVolume) {
5025 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5026 "Skipping Raid Volume for inDMD\n",
5027 ioc->name));
5028 } else {
5029 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5030 "Setting device flag inDMD\n",
5031 ioc->name));
5032 vtarget->inDMD = 1;
5039 break;
5041 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
5043 MpiEventDataSasExpanderStatusChange_t *expander_data =
5044 (MpiEventDataSasExpanderStatusChange_t *)reply->Data;
5046 if (ioc->old_sas_discovery_protocal)
5047 return 0;
5049 if (expander_data->ReasonCode ==
5050 MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING &&
5051 ioc->device_missing_delay)
5052 delay = HZ * ioc->device_missing_delay;
5053 break;
5055 case MPI_EVENT_SAS_DISCOVERY:
5057 u32 discovery_status;
5058 EventDataSasDiscovery_t *discovery_data =
5059 (EventDataSasDiscovery_t *)reply->Data;
5061 discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus);
5062 ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0;
5063 if (ioc->old_sas_discovery_protocal && !discovery_status)
5064 mptsas_queue_rescan(ioc);
5065 return 0;
5067 case MPI_EVENT_INTEGRATED_RAID:
5068 case MPI_EVENT_PERSISTENT_TABLE_FULL:
5069 case MPI_EVENT_IR2:
5070 case MPI_EVENT_SAS_PHY_LINK_STATUS:
5071 case MPI_EVENT_QUEUE_FULL:
5072 break;
5073 default:
5074 return 0;
5077 event_data_sz = ((reply->MsgLength * 4) -
5078 offsetof(EventNotificationReply_t, Data));
5079 sz = offsetof(struct fw_event_work, event_data) + event_data_sz;
5080 fw_event = kzalloc(sz, GFP_ATOMIC);
5081 if (!fw_event) {
5082 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name,
5083 __func__, __LINE__);
5084 return 0;
5086 memcpy(fw_event->event_data, reply->Data, event_data_sz);
5087 fw_event->event = event;
5088 fw_event->ioc = ioc;
5089 mptsas_add_fw_event(ioc, fw_event, delay);
5090 return 0;
5093 /* Delete a volume when no longer listed in ioc pg2
5095 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id)
5097 struct scsi_device *sdev;
5098 int i;
5100 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, id, 0);
5101 if (!sdev)
5102 return;
5103 if (!ioc->raid_data.pIocPg2)
5104 goto out;
5105 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
5106 goto out;
5107 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
5108 if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id)
5109 goto release_sdev;
5110 out:
5111 printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
5112 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL, id);
5113 scsi_remove_device(sdev);
5114 release_sdev:
5115 scsi_device_put(sdev);
5118 static int
5119 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5121 struct Scsi_Host *sh;
5122 MPT_SCSI_HOST *hd;
5123 MPT_ADAPTER *ioc;
5124 unsigned long flags;
5125 int ii;
5126 int numSGE = 0;
5127 int scale;
5128 int ioc_cap;
5129 int error=0;
5130 int r;
5132 r = mpt_attach(pdev,id);
5133 if (r)
5134 return r;
5136 ioc = pci_get_drvdata(pdev);
5137 mptsas_fw_event_off(ioc);
5138 ioc->DoneCtx = mptsasDoneCtx;
5139 ioc->TaskCtx = mptsasTaskCtx;
5140 ioc->InternalCtx = mptsasInternalCtx;
5141 ioc->schedule_target_reset = &mptsas_schedule_target_reset;
5142 /* Added sanity check on readiness of the MPT adapter.
5144 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
5145 printk(MYIOC_s_WARN_FMT
5146 "Skipping because it's not operational!\n",
5147 ioc->name);
5148 error = -ENODEV;
5149 goto out_mptsas_probe;
5152 if (!ioc->active) {
5153 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
5154 ioc->name);
5155 error = -ENODEV;
5156 goto out_mptsas_probe;
5159 /* Sanity check - ensure at least 1 port is INITIATOR capable
5161 ioc_cap = 0;
5162 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
5163 if (ioc->pfacts[ii].ProtocolFlags &
5164 MPI_PORTFACTS_PROTOCOL_INITIATOR)
5165 ioc_cap++;
5168 if (!ioc_cap) {
5169 printk(MYIOC_s_WARN_FMT
5170 "Skipping ioc=%p because SCSI Initiator mode "
5171 "is NOT enabled!\n", ioc->name, ioc);
5172 return 0;
5175 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
5176 if (!sh) {
5177 printk(MYIOC_s_WARN_FMT
5178 "Unable to register controller with SCSI subsystem\n",
5179 ioc->name);
5180 error = -1;
5181 goto out_mptsas_probe;
5184 spin_lock_irqsave(&ioc->FreeQlock, flags);
5186 /* Attach the SCSI Host to the IOC structure
5188 ioc->sh = sh;
5190 sh->io_port = 0;
5191 sh->n_io_port = 0;
5192 sh->irq = 0;
5194 /* set 16 byte cdb's */
5195 sh->max_cmd_len = 16;
5196 sh->can_queue = min_t(int, ioc->req_depth - 10, sh->can_queue);
5197 sh->max_id = -1;
5198 sh->max_lun = max_lun;
5199 sh->transportt = mptsas_transport_template;
5201 /* Required entry.
5203 sh->unique_id = ioc->id;
5205 INIT_LIST_HEAD(&ioc->sas_topology);
5206 mutex_init(&ioc->sas_topology_mutex);
5207 mutex_init(&ioc->sas_discovery_mutex);
5208 mutex_init(&ioc->sas_mgmt.mutex);
5209 init_completion(&ioc->sas_mgmt.done);
5211 /* Verify that we won't exceed the maximum
5212 * number of chain buffers
5213 * We can optimize: ZZ = req_sz/sizeof(SGE)
5214 * For 32bit SGE's:
5215 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
5216 * + (req_sz - 64)/sizeof(SGE)
5217 * A slightly different algorithm is required for
5218 * 64bit SGEs.
5220 scale = ioc->req_sz/ioc->SGE_size;
5221 if (ioc->sg_addr_size == sizeof(u64)) {
5222 numSGE = (scale - 1) *
5223 (ioc->facts.MaxChainDepth-1) + scale +
5224 (ioc->req_sz - 60) / ioc->SGE_size;
5225 } else {
5226 numSGE = 1 + (scale - 1) *
5227 (ioc->facts.MaxChainDepth-1) + scale +
5228 (ioc->req_sz - 64) / ioc->SGE_size;
5231 if (numSGE < sh->sg_tablesize) {
5232 /* Reset this value */
5233 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5234 "Resetting sg_tablesize to %d from %d\n",
5235 ioc->name, numSGE, sh->sg_tablesize));
5236 sh->sg_tablesize = numSGE;
5239 hd = shost_priv(sh);
5240 hd->ioc = ioc;
5242 /* SCSI needs scsi_cmnd lookup table!
5243 * (with size equal to req_depth*PtrSz!)
5245 ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
5246 if (!ioc->ScsiLookup) {
5247 error = -ENOMEM;
5248 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5249 goto out_mptsas_probe;
5251 spin_lock_init(&ioc->scsi_lookup_lock);
5253 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
5254 ioc->name, ioc->ScsiLookup));
5256 ioc->sas_data.ptClear = mpt_pt_clear;
5258 hd->last_queue_full = 0;
5259 INIT_LIST_HEAD(&hd->target_reset_list);
5260 INIT_LIST_HEAD(&ioc->sas_device_info_list);
5261 mutex_init(&ioc->sas_device_info_mutex);
5263 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5265 if (ioc->sas_data.ptClear==1) {
5266 mptbase_sas_persist_operation(
5267 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
5270 error = scsi_add_host(sh, &ioc->pcidev->dev);
5271 if (error) {
5272 dprintk(ioc, printk(MYIOC_s_ERR_FMT
5273 "scsi_add_host failed\n", ioc->name));
5274 goto out_mptsas_probe;
5277 /* older firmware doesn't support expander events */
5278 if ((ioc->facts.HeaderVersion >> 8) < 0xE)
5279 ioc->old_sas_discovery_protocal = 1;
5280 mptsas_scan_sas_topology(ioc);
5281 mptsas_fw_event_on(ioc);
5282 return 0;
5284 out_mptsas_probe:
5286 mptscsih_remove(pdev);
5287 return error;
5290 void
5291 mptsas_shutdown(struct pci_dev *pdev)
5293 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
5295 mptsas_fw_event_off(ioc);
5296 mptsas_cleanup_fw_event_q(ioc);
5299 static void __devexit mptsas_remove(struct pci_dev *pdev)
5301 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
5302 struct mptsas_portinfo *p, *n;
5303 int i;
5305 if (!ioc->sh) {
5306 printk(MYIOC_s_INFO_FMT "IOC is in Target mode\n", ioc->name);
5307 mpt_detach(pdev);
5308 return;
5311 mptsas_shutdown(pdev);
5313 mptsas_del_device_components(ioc);
5315 ioc->sas_discovery_ignore_events = 1;
5316 sas_remove_host(ioc->sh);
5318 mutex_lock(&ioc->sas_topology_mutex);
5319 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
5320 list_del(&p->list);
5321 for (i = 0 ; i < p->num_phys ; i++)
5322 mptsas_port_delete(ioc, p->phy_info[i].port_details);
5324 kfree(p->phy_info);
5325 kfree(p);
5327 mutex_unlock(&ioc->sas_topology_mutex);
5328 ioc->hba_port_info = NULL;
5329 mptscsih_remove(pdev);
5332 static struct pci_device_id mptsas_pci_table[] = {
5333 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
5334 PCI_ANY_ID, PCI_ANY_ID },
5335 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
5336 PCI_ANY_ID, PCI_ANY_ID },
5337 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
5338 PCI_ANY_ID, PCI_ANY_ID },
5339 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
5340 PCI_ANY_ID, PCI_ANY_ID },
5341 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
5342 PCI_ANY_ID, PCI_ANY_ID },
5343 {0} /* Terminating entry */
5345 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
5348 static struct pci_driver mptsas_driver = {
5349 .name = "mptsas",
5350 .id_table = mptsas_pci_table,
5351 .probe = mptsas_probe,
5352 .remove = __devexit_p(mptsas_remove),
5353 .shutdown = mptsas_shutdown,
5354 #ifdef CONFIG_PM
5355 .suspend = mptscsih_suspend,
5356 .resume = mptscsih_resume,
5357 #endif
5360 static int __init
5361 mptsas_init(void)
5363 int error;
5365 show_mptmod_ver(my_NAME, my_VERSION);
5367 mptsas_transport_template =
5368 sas_attach_transport(&mptsas_transport_functions);
5369 if (!mptsas_transport_template)
5370 return -ENODEV;
5371 mptsas_transport_template->eh_timed_out = mptsas_eh_timed_out;
5373 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER,
5374 "mptscsih_io_done");
5375 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER,
5376 "mptscsih_taskmgmt_complete");
5377 mptsasInternalCtx =
5378 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER,
5379 "mptscsih_scandv_complete");
5380 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER,
5381 "mptsas_mgmt_done");
5382 mptsasDeviceResetCtx =
5383 mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER,
5384 "mptsas_taskmgmt_complete");
5386 mpt_event_register(mptsasDoneCtx, mptsas_event_process);
5387 mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
5389 error = pci_register_driver(&mptsas_driver);
5390 if (error)
5391 sas_release_transport(mptsas_transport_template);
5393 return error;
5396 static void __exit
5397 mptsas_exit(void)
5399 pci_unregister_driver(&mptsas_driver);
5400 sas_release_transport(mptsas_transport_template);
5402 mpt_reset_deregister(mptsasDoneCtx);
5403 mpt_event_deregister(mptsasDoneCtx);
5405 mpt_deregister(mptsasMgmtCtx);
5406 mpt_deregister(mptsasInternalCtx);
5407 mpt_deregister(mptsasTaskCtx);
5408 mpt_deregister(mptsasDoneCtx);
5409 mpt_deregister(mptsasDeviceResetCtx);
5412 module_init(mptsas_init);
5413 module_exit(mptsas_exit);