fusion: mptsas, fix lock imbalance
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / message / fusion / mptsas.c
blob55ff25244af44a1f2c51002ce8c78fe3b3b699e1
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/init.h>
49 #include <linux/errno.h>
50 #include <linux/jiffies.h>
51 #include <linux/workqueue.h>
52 #include <linux/delay.h> /* for mdelay */
54 #include <scsi/scsi.h>
55 #include <scsi/scsi_cmnd.h>
56 #include <scsi/scsi_device.h>
57 #include <scsi/scsi_host.h>
58 #include <scsi/scsi_transport_sas.h>
59 #include <scsi/scsi_dbg.h>
61 #include "mptbase.h"
62 #include "mptscsih.h"
63 #include "mptsas.h"
66 #define my_NAME "Fusion MPT SAS Host driver"
67 #define my_VERSION MPT_LINUX_VERSION_COMMON
68 #define MYNAM "mptsas"
71 * Reserved channel for integrated raid
73 #define MPTSAS_RAID_CHANNEL 1
75 MODULE_AUTHOR(MODULEAUTHOR);
76 MODULE_DESCRIPTION(my_NAME);
77 MODULE_LICENSE("GPL");
78 MODULE_VERSION(my_VERSION);
80 static int mpt_pt_clear;
81 module_param(mpt_pt_clear, int, 0);
82 MODULE_PARM_DESC(mpt_pt_clear,
83 " Clear persistency table: enable=1 "
84 "(default=MPTSCSIH_PT_CLEAR=0)");
86 /* scsi-mid layer global parmeter is max_report_luns, which is 511 */
87 #define MPTSAS_MAX_LUN (16895)
88 static int max_lun = MPTSAS_MAX_LUN;
89 module_param(max_lun, int, 0);
90 MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
92 static u8 mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
93 static u8 mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
94 static u8 mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */
95 static u8 mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS;
96 static u8 mptsasDeviceResetCtx = MPT_MAX_PROTOCOL_DRIVERS;
98 static void mptsas_firmware_event_work(struct work_struct *work);
99 static void mptsas_send_sas_event(struct fw_event_work *fw_event);
100 static void mptsas_send_raid_event(struct fw_event_work *fw_event);
101 static void mptsas_send_ir2_event(struct fw_event_work *fw_event);
102 static void mptsas_parse_device_info(struct sas_identify *identify,
103 struct mptsas_devinfo *device_info);
104 static inline void mptsas_set_rphy(MPT_ADAPTER *ioc,
105 struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy);
106 static struct mptsas_phyinfo *mptsas_find_phyinfo_by_sas_address
107 (MPT_ADAPTER *ioc, u64 sas_address);
108 static int mptsas_sas_device_pg0(MPT_ADAPTER *ioc,
109 struct mptsas_devinfo *device_info, u32 form, u32 form_specific);
110 static int mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc,
111 struct mptsas_enclosure *enclosure, u32 form, u32 form_specific);
112 static int mptsas_add_end_device(MPT_ADAPTER *ioc,
113 struct mptsas_phyinfo *phy_info);
114 static void mptsas_del_end_device(MPT_ADAPTER *ioc,
115 struct mptsas_phyinfo *phy_info);
116 static void mptsas_send_link_status_event(struct fw_event_work *fw_event);
117 static struct mptsas_portinfo *mptsas_find_portinfo_by_sas_address
118 (MPT_ADAPTER *ioc, u64 sas_address);
119 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
120 struct mptsas_portinfo *port_info, u8 force);
121 static void mptsas_send_expander_event(struct fw_event_work *fw_event);
122 static void mptsas_not_responding_devices(MPT_ADAPTER *ioc);
123 static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
124 static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event);
125 static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
126 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
128 static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
129 MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
131 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
132 "---- IO UNIT PAGE 0 ------------\n", ioc->name));
133 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
134 ioc->name, le16_to_cpu(phy_data->AttachedDeviceHandle)));
135 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Controller Handle=0x%X\n",
136 ioc->name, le16_to_cpu(phy_data->ControllerDevHandle)));
137 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port=0x%X\n",
138 ioc->name, phy_data->Port));
139 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port Flags=0x%X\n",
140 ioc->name, phy_data->PortFlags));
141 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Flags=0x%X\n",
142 ioc->name, phy_data->PhyFlags));
143 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
144 ioc->name, phy_data->NegotiatedLinkRate));
145 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
146 "Controller PHY Device Info=0x%X\n", ioc->name,
147 le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
148 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DiscoveryStatus=0x%X\n\n",
149 ioc->name, le32_to_cpu(phy_data->DiscoveryStatus)));
152 static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
154 __le64 sas_address;
156 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
158 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
159 "---- SAS PHY PAGE 0 ------------\n", ioc->name));
160 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
161 "Attached Device Handle=0x%X\n", ioc->name,
162 le16_to_cpu(pg0->AttachedDevHandle)));
163 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
164 ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
165 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
166 "Attached PHY Identifier=0x%X\n", ioc->name,
167 pg0->AttachedPhyIdentifier));
168 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Attached Device Info=0x%X\n",
169 ioc->name, le32_to_cpu(pg0->AttachedDeviceInfo)));
170 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
171 ioc->name, pg0->ProgrammedLinkRate));
172 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Change Count=0x%X\n",
173 ioc->name, pg0->ChangeCount));
174 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Info=0x%X\n\n",
175 ioc->name, le32_to_cpu(pg0->PhyInfo)));
178 static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
180 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
181 "---- SAS PHY PAGE 1 ------------\n", ioc->name));
182 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Invalid Dword Count=0x%x\n",
183 ioc->name, pg1->InvalidDwordCount));
184 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
185 "Running Disparity Error Count=0x%x\n", ioc->name,
186 pg1->RunningDisparityErrorCount));
187 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
188 "Loss Dword Synch Count=0x%x\n", ioc->name,
189 pg1->LossDwordSynchCount));
190 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
191 "PHY Reset Problem Count=0x%x\n\n", ioc->name,
192 pg1->PhyResetProblemCount));
195 static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
197 __le64 sas_address;
199 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
201 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
202 "---- SAS DEVICE PAGE 0 ---------\n", ioc->name));
203 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
204 ioc->name, le16_to_cpu(pg0->DevHandle)));
205 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Handle=0x%X\n",
206 ioc->name, le16_to_cpu(pg0->ParentDevHandle)));
207 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Enclosure Handle=0x%X\n",
208 ioc->name, le16_to_cpu(pg0->EnclosureHandle)));
209 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Slot=0x%X\n",
210 ioc->name, le16_to_cpu(pg0->Slot)));
211 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
212 ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
213 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Target ID=0x%X\n",
214 ioc->name, pg0->TargetID));
215 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Bus=0x%X\n",
216 ioc->name, pg0->Bus));
217 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Phy Num=0x%X\n",
218 ioc->name, pg0->PhyNum));
219 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Access Status=0x%X\n",
220 ioc->name, le16_to_cpu(pg0->AccessStatus)));
221 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Device Info=0x%X\n",
222 ioc->name, le32_to_cpu(pg0->DeviceInfo)));
223 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Flags=0x%X\n",
224 ioc->name, le16_to_cpu(pg0->Flags)));
225 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n\n",
226 ioc->name, pg0->PhysicalPort));
229 static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
231 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
232 "---- SAS EXPANDER PAGE 1 ------------\n", ioc->name));
233 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n",
234 ioc->name, pg1->PhysicalPort));
235 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Identifier=0x%X\n",
236 ioc->name, pg1->PhyIdentifier));
237 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
238 ioc->name, pg1->NegotiatedLinkRate));
239 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
240 ioc->name, pg1->ProgrammedLinkRate));
241 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hardware Link Rate=0x%X\n",
242 ioc->name, pg1->HwLinkRate));
243 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Owner Device Handle=0x%X\n",
244 ioc->name, le16_to_cpu(pg1->OwnerDevHandle)));
245 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
246 "Attached Device Handle=0x%X\n\n", ioc->name,
247 le16_to_cpu(pg1->AttachedDevHandle)));
250 /* inhibit sas firmware event handling */
251 static void
252 mptsas_fw_event_off(MPT_ADAPTER *ioc)
254 unsigned long flags;
256 spin_lock_irqsave(&ioc->fw_event_lock, flags);
257 ioc->fw_events_off = 1;
258 ioc->sas_discovery_quiesce_io = 0;
259 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
263 /* enable sas firmware event handling */
264 static void
265 mptsas_fw_event_on(MPT_ADAPTER *ioc)
267 unsigned long flags;
269 spin_lock_irqsave(&ioc->fw_event_lock, flags);
270 ioc->fw_events_off = 0;
271 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
274 /* queue a sas firmware event */
275 static void
276 mptsas_add_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
277 unsigned long delay)
279 unsigned long flags;
281 spin_lock_irqsave(&ioc->fw_event_lock, flags);
282 list_add_tail(&fw_event->list, &ioc->fw_event_list);
283 INIT_DELAYED_WORK(&fw_event->work, mptsas_firmware_event_work);
284 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: add (fw_event=0x%p)\n",
285 ioc->name, __func__, fw_event));
286 queue_delayed_work(ioc->fw_event_q, &fw_event->work,
287 delay);
288 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
291 /* requeue a sas firmware event */
292 static void
293 mptsas_requeue_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
294 unsigned long delay)
296 unsigned long flags;
297 spin_lock_irqsave(&ioc->fw_event_lock, flags);
298 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: reschedule task "
299 "(fw_event=0x%p)\n", ioc->name, __func__, fw_event));
300 fw_event->retries++;
301 queue_delayed_work(ioc->fw_event_q, &fw_event->work,
302 msecs_to_jiffies(delay));
303 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
306 /* free memory assoicated to a sas firmware event */
307 static void
308 mptsas_free_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event)
310 unsigned long flags;
312 spin_lock_irqsave(&ioc->fw_event_lock, flags);
313 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: kfree (fw_event=0x%p)\n",
314 ioc->name, __func__, fw_event));
315 list_del(&fw_event->list);
316 kfree(fw_event);
317 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
320 /* walk the firmware event queue, and either stop or wait for
321 * outstanding events to complete */
322 static void
323 mptsas_cleanup_fw_event_q(MPT_ADAPTER *ioc)
325 struct fw_event_work *fw_event, *next;
326 struct mptsas_target_reset_event *target_reset_list, *n;
327 u8 flush_q;
328 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
330 /* flush the target_reset_list */
331 if (!list_empty(&hd->target_reset_list)) {
332 list_for_each_entry_safe(target_reset_list, n,
333 &hd->target_reset_list, list) {
334 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
335 "%s: removing target reset for id=%d\n",
336 ioc->name, __func__,
337 target_reset_list->sas_event_data.TargetID));
338 list_del(&target_reset_list->list);
339 kfree(target_reset_list);
343 if (list_empty(&ioc->fw_event_list) ||
344 !ioc->fw_event_q || in_interrupt())
345 return;
347 flush_q = 0;
348 list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) {
349 if (cancel_delayed_work(&fw_event->work))
350 mptsas_free_fw_event(ioc, fw_event);
351 else
352 flush_q = 1;
354 if (flush_q)
355 flush_workqueue(ioc->fw_event_q);
359 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
361 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
362 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
365 static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
367 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
368 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
372 * mptsas_find_portinfo_by_handle
374 * This function should be called with the sas_topology_mutex already held
376 static struct mptsas_portinfo *
377 mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
379 struct mptsas_portinfo *port_info, *rc=NULL;
380 int i;
382 list_for_each_entry(port_info, &ioc->sas_topology, list)
383 for (i = 0; i < port_info->num_phys; i++)
384 if (port_info->phy_info[i].identify.handle == handle) {
385 rc = port_info;
386 goto out;
388 out:
389 return rc;
393 * mptsas_find_portinfo_by_sas_address -
394 * @ioc: Pointer to MPT_ADAPTER structure
395 * @handle:
397 * This function should be called with the sas_topology_mutex already held
400 static struct mptsas_portinfo *
401 mptsas_find_portinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
403 struct mptsas_portinfo *port_info, *rc = NULL;
404 int i;
406 if (sas_address >= ioc->hba_port_sas_addr &&
407 sas_address < (ioc->hba_port_sas_addr +
408 ioc->hba_port_num_phy))
409 return ioc->hba_port_info;
411 mutex_lock(&ioc->sas_topology_mutex);
412 list_for_each_entry(port_info, &ioc->sas_topology, list)
413 for (i = 0; i < port_info->num_phys; i++)
414 if (port_info->phy_info[i].identify.sas_address ==
415 sas_address) {
416 rc = port_info;
417 goto out;
419 out:
420 mutex_unlock(&ioc->sas_topology_mutex);
421 return rc;
425 * Returns true if there is a scsi end device
427 static inline int
428 mptsas_is_end_device(struct mptsas_devinfo * attached)
430 if ((attached->sas_address) &&
431 (attached->device_info &
432 MPI_SAS_DEVICE_INFO_END_DEVICE) &&
433 ((attached->device_info &
434 MPI_SAS_DEVICE_INFO_SSP_TARGET) |
435 (attached->device_info &
436 MPI_SAS_DEVICE_INFO_STP_TARGET) |
437 (attached->device_info &
438 MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
439 return 1;
440 else
441 return 0;
444 /* no mutex */
445 static void
446 mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
448 struct mptsas_portinfo *port_info;
449 struct mptsas_phyinfo *phy_info;
450 u8 i;
452 if (!port_details)
453 return;
455 port_info = port_details->port_info;
456 phy_info = port_info->phy_info;
458 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d "
459 "bitmask=0x%016llX\n", ioc->name, __func__, port_details,
460 port_details->num_phys, (unsigned long long)
461 port_details->phy_bitmask));
463 for (i = 0; i < port_info->num_phys; i++, phy_info++) {
464 if(phy_info->port_details != port_details)
465 continue;
466 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
467 mptsas_set_rphy(ioc, phy_info, NULL);
468 phy_info->port_details = NULL;
470 kfree(port_details);
473 static inline struct sas_rphy *
474 mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
476 if (phy_info->port_details)
477 return phy_info->port_details->rphy;
478 else
479 return NULL;
482 static inline void
483 mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
485 if (phy_info->port_details) {
486 phy_info->port_details->rphy = rphy;
487 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
488 ioc->name, rphy));
491 if (rphy) {
492 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
493 &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
494 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
495 ioc->name, rphy, rphy->dev.release));
499 static inline struct sas_port *
500 mptsas_get_port(struct mptsas_phyinfo *phy_info)
502 if (phy_info->port_details)
503 return phy_info->port_details->port;
504 else
505 return NULL;
508 static inline void
509 mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_port *port)
511 if (phy_info->port_details)
512 phy_info->port_details->port = port;
514 if (port) {
515 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
516 &port->dev, MYIOC_s_FMT "add:", ioc->name));
517 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "port=%p release=%p\n",
518 ioc->name, port, port->dev.release));
522 static inline struct scsi_target *
523 mptsas_get_starget(struct mptsas_phyinfo *phy_info)
525 if (phy_info->port_details)
526 return phy_info->port_details->starget;
527 else
528 return NULL;
531 static inline void
532 mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
533 starget)
535 if (phy_info->port_details)
536 phy_info->port_details->starget = starget;
540 * mptsas_add_device_component -
541 * @ioc: Pointer to MPT_ADAPTER structure
542 * @channel: fw mapped id's
543 * @id:
544 * @sas_address:
545 * @device_info:
548 static void
549 mptsas_add_device_component(MPT_ADAPTER *ioc, u8 channel, u8 id,
550 u64 sas_address, u32 device_info, u16 slot, u64 enclosure_logical_id)
552 struct mptsas_device_info *sas_info, *next;
553 struct scsi_device *sdev;
554 struct scsi_target *starget;
555 struct sas_rphy *rphy;
558 * Delete all matching devices out of the list
560 mutex_lock(&ioc->sas_device_info_mutex);
561 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
562 list) {
563 if (!sas_info->is_logical_volume &&
564 (sas_info->sas_address == sas_address ||
565 (sas_info->fw.channel == channel &&
566 sas_info->fw.id == id))) {
567 list_del(&sas_info->list);
568 kfree(sas_info);
572 sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
573 if (!sas_info)
574 goto out;
577 * Set Firmware mapping
579 sas_info->fw.id = id;
580 sas_info->fw.channel = channel;
582 sas_info->sas_address = sas_address;
583 sas_info->device_info = device_info;
584 sas_info->slot = slot;
585 sas_info->enclosure_logical_id = enclosure_logical_id;
586 INIT_LIST_HEAD(&sas_info->list);
587 list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
590 * Set OS mapping
592 shost_for_each_device(sdev, ioc->sh) {
593 starget = scsi_target(sdev);
594 rphy = dev_to_rphy(starget->dev.parent);
595 if (rphy->identify.sas_address == sas_address) {
596 sas_info->os.id = starget->id;
597 sas_info->os.channel = starget->channel;
601 out:
602 mutex_unlock(&ioc->sas_device_info_mutex);
603 return;
607 * mptsas_add_device_component_by_fw -
608 * @ioc: Pointer to MPT_ADAPTER structure
609 * @channel: fw mapped id's
610 * @id:
613 static void
614 mptsas_add_device_component_by_fw(MPT_ADAPTER *ioc, u8 channel, u8 id)
616 struct mptsas_devinfo sas_device;
617 struct mptsas_enclosure enclosure_info;
618 int rc;
620 rc = mptsas_sas_device_pg0(ioc, &sas_device,
621 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
622 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
623 (channel << 8) + id);
624 if (rc)
625 return;
627 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
628 mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
629 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
630 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
631 sas_device.handle_enclosure);
633 mptsas_add_device_component(ioc, sas_device.channel,
634 sas_device.id, sas_device.sas_address, sas_device.device_info,
635 sas_device.slot, enclosure_info.enclosure_logical_id);
639 * mptsas_add_device_component_starget_ir - Handle Integrated RAID, adding each individual device to list
640 * @ioc: Pointer to MPT_ADAPTER structure
641 * @channel: fw mapped id's
642 * @id:
645 static void
646 mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc,
647 struct scsi_target *starget)
649 CONFIGPARMS cfg;
650 ConfigPageHeader_t hdr;
651 dma_addr_t dma_handle;
652 pRaidVolumePage0_t buffer = NULL;
653 int i;
654 RaidPhysDiskPage0_t phys_disk;
655 struct mptsas_device_info *sas_info, *next;
657 memset(&cfg, 0 , sizeof(CONFIGPARMS));
658 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
659 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
660 /* assumption that all volumes on channel = 0 */
661 cfg.pageAddr = starget->id;
662 cfg.cfghdr.hdr = &hdr;
663 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
664 cfg.timeout = 10;
666 if (mpt_config(ioc, &cfg) != 0)
667 goto out;
669 if (!hdr.PageLength)
670 goto out;
672 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
673 &dma_handle);
675 if (!buffer)
676 goto out;
678 cfg.physAddr = dma_handle;
679 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
681 if (mpt_config(ioc, &cfg) != 0)
682 goto out;
684 if (!buffer->NumPhysDisks)
685 goto out;
688 * Adding entry for hidden components
690 for (i = 0; i < buffer->NumPhysDisks; i++) {
692 if (mpt_raid_phys_disk_pg0(ioc,
693 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
694 continue;
696 mptsas_add_device_component_by_fw(ioc, phys_disk.PhysDiskBus,
697 phys_disk.PhysDiskID);
699 mutex_lock(&ioc->sas_device_info_mutex);
700 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
701 list) {
702 if (!sas_info->is_logical_volume &&
703 (sas_info->fw.channel == phys_disk.PhysDiskBus &&
704 sas_info->fw.id == phys_disk.PhysDiskID)) {
705 sas_info->is_hidden_raid_component = 1;
706 sas_info->volume_id = starget->id;
709 mutex_unlock(&ioc->sas_device_info_mutex);
714 * Delete all matching devices out of the list
716 mutex_lock(&ioc->sas_device_info_mutex);
717 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
718 list) {
719 if (sas_info->is_logical_volume && sas_info->fw.id ==
720 starget->id) {
721 list_del(&sas_info->list);
722 kfree(sas_info);
726 sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
727 if (sas_info) {
728 sas_info->fw.id = starget->id;
729 sas_info->os.id = starget->id;
730 sas_info->os.channel = starget->channel;
731 sas_info->is_logical_volume = 1;
732 INIT_LIST_HEAD(&sas_info->list);
733 list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
735 mutex_unlock(&ioc->sas_device_info_mutex);
737 out:
738 if (buffer)
739 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
740 dma_handle);
744 * mptsas_add_device_component_starget -
745 * @ioc: Pointer to MPT_ADAPTER structure
746 * @starget:
749 static void
750 mptsas_add_device_component_starget(MPT_ADAPTER *ioc,
751 struct scsi_target *starget)
753 VirtTarget *vtarget;
754 struct sas_rphy *rphy;
755 struct mptsas_phyinfo *phy_info = NULL;
756 struct mptsas_enclosure enclosure_info;
758 rphy = dev_to_rphy(starget->dev.parent);
759 vtarget = starget->hostdata;
760 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
761 rphy->identify.sas_address);
762 if (!phy_info)
763 return;
765 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
766 mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
767 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
768 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
769 phy_info->attached.handle_enclosure);
771 mptsas_add_device_component(ioc, phy_info->attached.channel,
772 phy_info->attached.id, phy_info->attached.sas_address,
773 phy_info->attached.device_info,
774 phy_info->attached.slot, enclosure_info.enclosure_logical_id);
778 * mptsas_del_device_component_by_os - Once a device has been removed, we mark the entry in the list as being cached
779 * @ioc: Pointer to MPT_ADAPTER structure
780 * @channel: os mapped id's
781 * @id:
784 static void
785 mptsas_del_device_component_by_os(MPT_ADAPTER *ioc, u8 channel, u8 id)
787 struct mptsas_device_info *sas_info, *next;
790 * Set is_cached flag
792 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
793 list) {
794 if (sas_info->os.channel == channel && sas_info->os.id == id)
795 sas_info->is_cached = 1;
800 * mptsas_del_device_components - Cleaning the list
801 * @ioc: Pointer to MPT_ADAPTER structure
804 static void
805 mptsas_del_device_components(MPT_ADAPTER *ioc)
807 struct mptsas_device_info *sas_info, *next;
809 mutex_lock(&ioc->sas_device_info_mutex);
810 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
811 list) {
812 list_del(&sas_info->list);
813 kfree(sas_info);
815 mutex_unlock(&ioc->sas_device_info_mutex);
820 * mptsas_setup_wide_ports
822 * Updates for new and existing narrow/wide port configuration
823 * in the sas_topology
825 static void
826 mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
828 struct mptsas_portinfo_details * port_details;
829 struct mptsas_phyinfo *phy_info, *phy_info_cmp;
830 u64 sas_address;
831 int i, j;
833 mutex_lock(&ioc->sas_topology_mutex);
835 phy_info = port_info->phy_info;
836 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
837 if (phy_info->attached.handle)
838 continue;
839 port_details = phy_info->port_details;
840 if (!port_details)
841 continue;
842 if (port_details->num_phys < 2)
843 continue;
845 * Removing a phy from a port, letting the last
846 * phy be removed by firmware events.
848 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
849 "%s: [%p]: deleting phy = %d\n",
850 ioc->name, __func__, port_details, i));
851 port_details->num_phys--;
852 port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
853 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
854 sas_port_delete_phy(port_details->port, phy_info->phy);
855 phy_info->port_details = NULL;
859 * Populate and refresh the tree
861 phy_info = port_info->phy_info;
862 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
863 sas_address = phy_info->attached.sas_address;
864 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "phy_id=%d sas_address=0x%018llX\n",
865 ioc->name, i, (unsigned long long)sas_address));
866 if (!sas_address)
867 continue;
868 port_details = phy_info->port_details;
870 * Forming a port
872 if (!port_details) {
873 port_details = kzalloc(sizeof(struct
874 mptsas_portinfo_details), GFP_KERNEL);
875 if (!port_details)
876 goto out;
877 port_details->num_phys = 1;
878 port_details->port_info = port_info;
879 if (phy_info->phy_id < 64 )
880 port_details->phy_bitmask |=
881 (1 << phy_info->phy_id);
882 phy_info->sas_port_add_phy=1;
883 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tForming port\n\t\t"
884 "phy_id=%d sas_address=0x%018llX\n",
885 ioc->name, i, (unsigned long long)sas_address));
886 phy_info->port_details = port_details;
889 if (i == port_info->num_phys - 1)
890 continue;
891 phy_info_cmp = &port_info->phy_info[i + 1];
892 for (j = i + 1 ; j < port_info->num_phys ; j++,
893 phy_info_cmp++) {
894 if (!phy_info_cmp->attached.sas_address)
895 continue;
896 if (sas_address != phy_info_cmp->attached.sas_address)
897 continue;
898 if (phy_info_cmp->port_details == port_details )
899 continue;
900 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
901 "\t\tphy_id=%d sas_address=0x%018llX\n",
902 ioc->name, j, (unsigned long long)
903 phy_info_cmp->attached.sas_address));
904 if (phy_info_cmp->port_details) {
905 port_details->rphy =
906 mptsas_get_rphy(phy_info_cmp);
907 port_details->port =
908 mptsas_get_port(phy_info_cmp);
909 port_details->starget =
910 mptsas_get_starget(phy_info_cmp);
911 port_details->num_phys =
912 phy_info_cmp->port_details->num_phys;
913 if (!phy_info_cmp->port_details->num_phys)
914 kfree(phy_info_cmp->port_details);
915 } else
916 phy_info_cmp->sas_port_add_phy=1;
918 * Adding a phy to a port
920 phy_info_cmp->port_details = port_details;
921 if (phy_info_cmp->phy_id < 64 )
922 port_details->phy_bitmask |=
923 (1 << phy_info_cmp->phy_id);
924 port_details->num_phys++;
928 out:
930 for (i = 0; i < port_info->num_phys; i++) {
931 port_details = port_info->phy_info[i].port_details;
932 if (!port_details)
933 continue;
934 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
935 "%s: [%p]: phy_id=%02d num_phys=%02d "
936 "bitmask=0x%016llX\n", ioc->name, __func__,
937 port_details, i, port_details->num_phys,
938 (unsigned long long)port_details->phy_bitmask));
939 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n",
940 ioc->name, port_details->port, port_details->rphy));
942 dsaswideprintk(ioc, printk("\n"));
943 mutex_unlock(&ioc->sas_topology_mutex);
947 * csmisas_find_vtarget
949 * @ioc
950 * @volume_id
951 * @volume_bus
954 static VirtTarget *
955 mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
957 struct scsi_device *sdev;
958 VirtDevice *vdevice;
959 VirtTarget *vtarget = NULL;
961 shost_for_each_device(sdev, ioc->sh) {
962 vdevice = sdev->hostdata;
963 if ((vdevice == NULL) ||
964 (vdevice->vtarget == NULL))
965 continue;
966 if ((vdevice->vtarget->tflags &
967 MPT_TARGET_FLAGS_RAID_COMPONENT ||
968 vdevice->vtarget->raidVolume))
969 continue;
970 if (vdevice->vtarget->id == id &&
971 vdevice->vtarget->channel == channel)
972 vtarget = vdevice->vtarget;
974 return vtarget;
977 static void
978 mptsas_queue_device_delete(MPT_ADAPTER *ioc,
979 MpiEventDataSasDeviceStatusChange_t *sas_event_data)
981 struct fw_event_work *fw_event;
982 int sz;
984 sz = offsetof(struct fw_event_work, event_data) +
985 sizeof(MpiEventDataSasDeviceStatusChange_t);
986 fw_event = kzalloc(sz, GFP_ATOMIC);
987 if (!fw_event) {
988 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
989 ioc->name, __func__, __LINE__);
990 return;
992 memcpy(fw_event->event_data, sas_event_data,
993 sizeof(MpiEventDataSasDeviceStatusChange_t));
994 fw_event->event = MPI_EVENT_SAS_DEVICE_STATUS_CHANGE;
995 fw_event->ioc = ioc;
996 mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
999 static void
1000 mptsas_queue_rescan(MPT_ADAPTER *ioc)
1002 struct fw_event_work *fw_event;
1003 int sz;
1005 sz = offsetof(struct fw_event_work, event_data);
1006 fw_event = kzalloc(sz, GFP_ATOMIC);
1007 if (!fw_event) {
1008 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
1009 ioc->name, __func__, __LINE__);
1010 return;
1012 fw_event->event = -1;
1013 fw_event->ioc = ioc;
1014 mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
1019 * mptsas_target_reset
1021 * Issues TARGET_RESET to end device using handshaking method
1023 * @ioc
1024 * @channel
1025 * @id
1027 * Returns (1) success
1028 * (0) failure
1031 static int
1032 mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
1034 MPT_FRAME_HDR *mf;
1035 SCSITaskMgmt_t *pScsiTm;
1036 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0)
1037 return 0;
1040 mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
1041 if (mf == NULL) {
1042 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1043 "%s, no msg frames @%d!!\n", ioc->name,
1044 __func__, __LINE__));
1045 goto out_fail;
1048 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1049 ioc->name, mf));
1051 /* Format the Request
1053 pScsiTm = (SCSITaskMgmt_t *) mf;
1054 memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
1055 pScsiTm->TargetID = id;
1056 pScsiTm->Bus = channel;
1057 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1058 pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
1059 pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
1061 DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
1063 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1064 "TaskMgmt type=%d (sas device delete) fw_channel = %d fw_id = %d)\n",
1065 ioc->name, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, channel, id));
1067 mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
1069 return 1;
1071 out_fail:
1073 mpt_clear_taskmgmt_in_progress_flag(ioc);
1074 return 0;
1078 * mptsas_target_reset_queue
1080 * Receive request for TARGET_RESET after recieving an firmware
1081 * event NOT_RESPONDING_EVENT, then put command in link list
1082 * and queue if task_queue already in use.
1084 * @ioc
1085 * @sas_event_data
1088 static void
1089 mptsas_target_reset_queue(MPT_ADAPTER *ioc,
1090 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1092 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
1093 VirtTarget *vtarget = NULL;
1094 struct mptsas_target_reset_event *target_reset_list;
1095 u8 id, channel;
1097 id = sas_event_data->TargetID;
1098 channel = sas_event_data->Bus;
1100 if (!(vtarget = mptsas_find_vtarget(ioc, channel, id)))
1101 return;
1103 vtarget->deleted = 1; /* block IO */
1105 target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event),
1106 GFP_ATOMIC);
1107 if (!target_reset_list) {
1108 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1109 "%s, failed to allocate mem @%d..!!\n",
1110 ioc->name, __func__, __LINE__));
1111 return;
1114 memcpy(&target_reset_list->sas_event_data, sas_event_data,
1115 sizeof(*sas_event_data));
1116 list_add_tail(&target_reset_list->list, &hd->target_reset_list);
1118 target_reset_list->time_count = jiffies;
1120 if (mptsas_target_reset(ioc, channel, id)) {
1121 target_reset_list->target_reset_issued = 1;
1126 * mptsas_taskmgmt_complete - complete SAS task management function
1127 * @ioc: Pointer to MPT_ADAPTER structure
1129 * Completion for TARGET_RESET after NOT_RESPONDING_EVENT, enable work
1130 * queue to finish off removing device from upper layers. then send next
1131 * TARGET_RESET in the queue.
1133 static int
1134 mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
1136 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
1137 struct list_head *head = &hd->target_reset_list;
1138 u8 id, channel;
1139 struct mptsas_target_reset_event *target_reset_list;
1140 SCSITaskMgmtReply_t *pScsiTmReply;
1142 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt completed: "
1143 "(mf = %p, mr = %p)\n", ioc->name, mf, mr));
1145 pScsiTmReply = (SCSITaskMgmtReply_t *)mr;
1146 if (pScsiTmReply) {
1147 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1148 "\tTaskMgmt completed: fw_channel = %d, fw_id = %d,\n"
1149 "\ttask_type = 0x%02X, iocstatus = 0x%04X "
1150 "loginfo = 0x%08X,\n\tresponse_code = 0x%02X, "
1151 "term_cmnds = %d\n", ioc->name,
1152 pScsiTmReply->Bus, pScsiTmReply->TargetID,
1153 pScsiTmReply->TaskType,
1154 le16_to_cpu(pScsiTmReply->IOCStatus),
1155 le32_to_cpu(pScsiTmReply->IOCLogInfo),
1156 pScsiTmReply->ResponseCode,
1157 le32_to_cpu(pScsiTmReply->TerminationCount)));
1159 if (pScsiTmReply->ResponseCode)
1160 mptscsih_taskmgmt_response_code(ioc,
1161 pScsiTmReply->ResponseCode);
1164 if (pScsiTmReply && (pScsiTmReply->TaskType ==
1165 MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK || pScsiTmReply->TaskType ==
1166 MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET)) {
1167 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
1168 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
1169 memcpy(ioc->taskmgmt_cmds.reply, mr,
1170 min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
1171 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
1172 ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
1173 complete(&ioc->taskmgmt_cmds.done);
1174 return 1;
1176 return 0;
1179 mpt_clear_taskmgmt_in_progress_flag(ioc);
1181 if (list_empty(head))
1182 return 1;
1184 target_reset_list = list_entry(head->next,
1185 struct mptsas_target_reset_event, list);
1187 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1188 "TaskMgmt: completed (%d seconds)\n",
1189 ioc->name, jiffies_to_msecs(jiffies -
1190 target_reset_list->time_count)/1000));
1192 id = pScsiTmReply->TargetID;
1193 channel = pScsiTmReply->Bus;
1194 target_reset_list->time_count = jiffies;
1197 * retry target reset
1199 if (!target_reset_list->target_reset_issued) {
1200 if (mptsas_target_reset(ioc, channel, id))
1201 target_reset_list->target_reset_issued = 1;
1202 return 1;
1206 * enable work queue to remove device from upper layers
1208 list_del(&target_reset_list->list);
1209 if ((mptsas_find_vtarget(ioc, channel, id)) && !ioc->fw_events_off)
1210 mptsas_queue_device_delete(ioc,
1211 &target_reset_list->sas_event_data);
1215 * issue target reset to next device in the queue
1218 head = &hd->target_reset_list;
1219 if (list_empty(head))
1220 return 1;
1222 target_reset_list = list_entry(head->next, struct mptsas_target_reset_event,
1223 list);
1225 id = target_reset_list->sas_event_data.TargetID;
1226 channel = target_reset_list->sas_event_data.Bus;
1227 target_reset_list->time_count = jiffies;
1229 if (mptsas_target_reset(ioc, channel, id))
1230 target_reset_list->target_reset_issued = 1;
1232 return 1;
1236 * mptscsih_ioc_reset
1238 * @ioc
1239 * @reset_phase
1242 static int
1243 mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1245 MPT_SCSI_HOST *hd;
1246 int rc;
1248 rc = mptscsih_ioc_reset(ioc, reset_phase);
1249 if ((ioc->bus_type != SAS) || (!rc))
1250 return rc;
1252 hd = shost_priv(ioc->sh);
1253 if (!hd->ioc)
1254 goto out;
1256 switch (reset_phase) {
1257 case MPT_IOC_SETUP_RESET:
1258 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1259 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
1260 mptsas_fw_event_off(ioc);
1261 break;
1262 case MPT_IOC_PRE_RESET:
1263 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1264 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
1265 break;
1266 case MPT_IOC_POST_RESET:
1267 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1268 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
1269 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
1270 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_DID_IOCRESET;
1271 complete(&ioc->sas_mgmt.done);
1273 mptsas_cleanup_fw_event_q(ioc);
1274 mptsas_queue_rescan(ioc);
1275 mptsas_fw_event_on(ioc);
1276 break;
1277 default:
1278 break;
1281 out:
1282 return rc;
1287 * enum device_state -
1288 * @DEVICE_RETRY: need to retry the TUR
1289 * @DEVICE_ERROR: TUR return error, don't add device
1290 * @DEVICE_READY: device can be added
1293 enum device_state{
1294 DEVICE_RETRY,
1295 DEVICE_ERROR,
1296 DEVICE_READY,
1299 static int
1300 mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
1301 u32 form, u32 form_specific)
1303 ConfigExtendedPageHeader_t hdr;
1304 CONFIGPARMS cfg;
1305 SasEnclosurePage0_t *buffer;
1306 dma_addr_t dma_handle;
1307 int error;
1308 __le64 le_identifier;
1310 memset(&hdr, 0, sizeof(hdr));
1311 hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
1312 hdr.PageNumber = 0;
1313 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1314 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
1316 cfg.cfghdr.ehdr = &hdr;
1317 cfg.physAddr = -1;
1318 cfg.pageAddr = form + form_specific;
1319 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1320 cfg.dir = 0; /* read */
1321 cfg.timeout = 10;
1323 error = mpt_config(ioc, &cfg);
1324 if (error)
1325 goto out;
1326 if (!hdr.ExtPageLength) {
1327 error = -ENXIO;
1328 goto out;
1331 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1332 &dma_handle);
1333 if (!buffer) {
1334 error = -ENOMEM;
1335 goto out;
1338 cfg.physAddr = dma_handle;
1339 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1341 error = mpt_config(ioc, &cfg);
1342 if (error)
1343 goto out_free_consistent;
1345 /* save config data */
1346 memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
1347 enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
1348 enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
1349 enclosure->flags = le16_to_cpu(buffer->Flags);
1350 enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
1351 enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
1352 enclosure->start_id = buffer->StartTargetID;
1353 enclosure->start_channel = buffer->StartBus;
1354 enclosure->sep_id = buffer->SEPTargetID;
1355 enclosure->sep_channel = buffer->SEPBus;
1357 out_free_consistent:
1358 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1359 buffer, dma_handle);
1360 out:
1361 return error;
1365 * mptsas_add_end_device - report a new end device to sas transport layer
1366 * @ioc: Pointer to MPT_ADAPTER structure
1367 * @phy_info: decribes attached device
1369 * return (0) success (1) failure
1372 static int
1373 mptsas_add_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1375 struct sas_rphy *rphy;
1376 struct sas_port *port;
1377 struct sas_identify identify;
1378 char *ds = NULL;
1379 u8 fw_id;
1381 if (!phy_info) {
1382 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1383 "%s: exit at line=%d\n", ioc->name,
1384 __func__, __LINE__));
1385 return 1;
1388 fw_id = phy_info->attached.id;
1390 if (mptsas_get_rphy(phy_info)) {
1391 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1392 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1393 __func__, fw_id, __LINE__));
1394 return 2;
1397 port = mptsas_get_port(phy_info);
1398 if (!port) {
1399 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1400 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1401 __func__, fw_id, __LINE__));
1402 return 3;
1405 if (phy_info->attached.device_info &
1406 MPI_SAS_DEVICE_INFO_SSP_TARGET)
1407 ds = "ssp";
1408 if (phy_info->attached.device_info &
1409 MPI_SAS_DEVICE_INFO_STP_TARGET)
1410 ds = "stp";
1411 if (phy_info->attached.device_info &
1412 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1413 ds = "sata";
1415 printk(MYIOC_s_INFO_FMT "attaching %s device: fw_channel %d, fw_id %d,"
1416 " phy %d, sas_addr 0x%llx\n", ioc->name, ds,
1417 phy_info->attached.channel, phy_info->attached.id,
1418 phy_info->attached.phy_id, (unsigned long long)
1419 phy_info->attached.sas_address);
1421 mptsas_parse_device_info(&identify, &phy_info->attached);
1422 rphy = sas_end_device_alloc(port);
1423 if (!rphy) {
1424 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1425 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1426 __func__, fw_id, __LINE__));
1427 return 5; /* non-fatal: an rphy can be added later */
1430 rphy->identify = identify;
1431 if (sas_rphy_add(rphy)) {
1432 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1433 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1434 __func__, fw_id, __LINE__));
1435 sas_rphy_free(rphy);
1436 return 6;
1438 mptsas_set_rphy(ioc, phy_info, rphy);
1439 return 0;
1443 * mptsas_del_end_device - report a deleted end device to sas transport layer
1444 * @ioc: Pointer to MPT_ADAPTER structure
1445 * @phy_info: decribes attached device
1448 static void
1449 mptsas_del_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1451 struct sas_rphy *rphy;
1452 struct sas_port *port;
1453 struct mptsas_portinfo *port_info;
1454 struct mptsas_phyinfo *phy_info_parent;
1455 int i;
1456 char *ds = NULL;
1457 u8 fw_id;
1458 u64 sas_address;
1460 if (!phy_info)
1461 return;
1463 fw_id = phy_info->attached.id;
1464 sas_address = phy_info->attached.sas_address;
1466 if (!phy_info->port_details) {
1467 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1468 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1469 __func__, fw_id, __LINE__));
1470 return;
1472 rphy = mptsas_get_rphy(phy_info);
1473 if (!rphy) {
1474 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1475 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1476 __func__, fw_id, __LINE__));
1477 return;
1480 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_INITIATOR
1481 || phy_info->attached.device_info
1482 & MPI_SAS_DEVICE_INFO_SMP_INITIATOR
1483 || phy_info->attached.device_info
1484 & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1485 ds = "initiator";
1486 if (phy_info->attached.device_info &
1487 MPI_SAS_DEVICE_INFO_SSP_TARGET)
1488 ds = "ssp";
1489 if (phy_info->attached.device_info &
1490 MPI_SAS_DEVICE_INFO_STP_TARGET)
1491 ds = "stp";
1492 if (phy_info->attached.device_info &
1493 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1494 ds = "sata";
1496 dev_printk(KERN_DEBUG, &rphy->dev, MYIOC_s_FMT
1497 "removing %s device: fw_channel %d, fw_id %d, phy %d,"
1498 "sas_addr 0x%llx\n", ioc->name, ds, phy_info->attached.channel,
1499 phy_info->attached.id, phy_info->attached.phy_id,
1500 (unsigned long long) sas_address);
1502 port = mptsas_get_port(phy_info);
1503 if (!port) {
1504 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1505 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1506 __func__, fw_id, __LINE__));
1507 return;
1509 port_info = phy_info->portinfo;
1510 phy_info_parent = port_info->phy_info;
1511 for (i = 0; i < port_info->num_phys; i++, phy_info_parent++) {
1512 if (!phy_info_parent->phy)
1513 continue;
1514 if (phy_info_parent->attached.sas_address !=
1515 sas_address)
1516 continue;
1517 dev_printk(KERN_DEBUG, &phy_info_parent->phy->dev,
1518 MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n",
1519 ioc->name, phy_info_parent->phy_id,
1520 phy_info_parent->phy);
1521 sas_port_delete_phy(port, phy_info_parent->phy);
1524 dev_printk(KERN_DEBUG, &port->dev, MYIOC_s_FMT
1525 "delete port %d, sas_addr (0x%llx)\n", ioc->name,
1526 port->port_identifier, (unsigned long long)sas_address);
1527 sas_port_delete(port);
1528 mptsas_set_port(ioc, phy_info, NULL);
1529 mptsas_port_delete(ioc, phy_info->port_details);
1532 struct mptsas_phyinfo *
1533 mptsas_refreshing_device_handles(MPT_ADAPTER *ioc,
1534 struct mptsas_devinfo *sas_device)
1536 struct mptsas_phyinfo *phy_info;
1537 struct mptsas_portinfo *port_info;
1538 int i;
1540 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
1541 sas_device->sas_address);
1542 if (!phy_info)
1543 goto out;
1544 port_info = phy_info->portinfo;
1545 if (!port_info)
1546 goto out;
1547 mutex_lock(&ioc->sas_topology_mutex);
1548 for (i = 0; i < port_info->num_phys; i++) {
1549 if (port_info->phy_info[i].attached.sas_address !=
1550 sas_device->sas_address)
1551 continue;
1552 port_info->phy_info[i].attached.channel = sas_device->channel;
1553 port_info->phy_info[i].attached.id = sas_device->id;
1554 port_info->phy_info[i].attached.sas_address =
1555 sas_device->sas_address;
1556 port_info->phy_info[i].attached.handle = sas_device->handle;
1557 port_info->phy_info[i].attached.handle_parent =
1558 sas_device->handle_parent;
1559 port_info->phy_info[i].attached.handle_enclosure =
1560 sas_device->handle_enclosure;
1562 mutex_unlock(&ioc->sas_topology_mutex);
1563 out:
1564 return phy_info;
1568 * mptsas_firmware_event_work - work thread for processing fw events
1569 * @work: work queue payload containing info describing the event
1570 * Context: user
1573 static void
1574 mptsas_firmware_event_work(struct work_struct *work)
1576 struct fw_event_work *fw_event =
1577 container_of(work, struct fw_event_work, work.work);
1578 MPT_ADAPTER *ioc = fw_event->ioc;
1580 /* special rescan topology handling */
1581 if (fw_event->event == -1) {
1582 if (ioc->in_rescan) {
1583 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1584 "%s: rescan ignored as it is in progress\n",
1585 ioc->name, __func__));
1586 return;
1588 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: rescan after "
1589 "reset\n", ioc->name, __func__));
1590 ioc->in_rescan = 1;
1591 mptsas_not_responding_devices(ioc);
1592 mptsas_scan_sas_topology(ioc);
1593 ioc->in_rescan = 0;
1594 mptsas_free_fw_event(ioc, fw_event);
1595 return;
1598 /* events handling turned off during host reset */
1599 if (ioc->fw_events_off) {
1600 mptsas_free_fw_event(ioc, fw_event);
1601 return;
1604 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: fw_event=(0x%p), "
1605 "event = (0x%02x)\n", ioc->name, __func__, fw_event,
1606 (fw_event->event & 0xFF)));
1608 switch (fw_event->event) {
1609 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1610 mptsas_send_sas_event(fw_event);
1611 break;
1612 case MPI_EVENT_INTEGRATED_RAID:
1613 mptsas_send_raid_event(fw_event);
1614 break;
1615 case MPI_EVENT_IR2:
1616 mptsas_send_ir2_event(fw_event);
1617 break;
1618 case MPI_EVENT_PERSISTENT_TABLE_FULL:
1619 mptbase_sas_persist_operation(ioc,
1620 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1621 mptsas_free_fw_event(ioc, fw_event);
1622 break;
1623 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
1624 mptsas_broadcast_primative_work(fw_event);
1625 break;
1626 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
1627 mptsas_send_expander_event(fw_event);
1628 break;
1629 case MPI_EVENT_SAS_PHY_LINK_STATUS:
1630 mptsas_send_link_status_event(fw_event);
1631 break;
1632 case MPI_EVENT_QUEUE_FULL:
1633 mptsas_handle_queue_full_event(fw_event);
1634 break;
1640 static int
1641 mptsas_slave_configure(struct scsi_device *sdev)
1643 struct Scsi_Host *host = sdev->host;
1644 MPT_SCSI_HOST *hd = shost_priv(host);
1645 MPT_ADAPTER *ioc = hd->ioc;
1646 VirtDevice *vdevice = sdev->hostdata;
1648 if (vdevice->vtarget->deleted) {
1649 sdev_printk(KERN_INFO, sdev, "clearing deleted flag\n");
1650 vdevice->vtarget->deleted = 0;
1654 * RAID volumes placed beyond the last expected port.
1655 * Ignore sending sas mode pages in that case..
1657 if (sdev->channel == MPTSAS_RAID_CHANNEL) {
1658 mptsas_add_device_component_starget_ir(ioc, scsi_target(sdev));
1659 goto out;
1662 sas_read_port_mode_page(sdev);
1664 mptsas_add_device_component_starget(ioc, scsi_target(sdev));
1666 out:
1667 return mptscsih_slave_configure(sdev);
1670 static int
1671 mptsas_target_alloc(struct scsi_target *starget)
1673 struct Scsi_Host *host = dev_to_shost(&starget->dev);
1674 MPT_SCSI_HOST *hd = shost_priv(host);
1675 VirtTarget *vtarget;
1676 u8 id, channel;
1677 struct sas_rphy *rphy;
1678 struct mptsas_portinfo *p;
1679 int i;
1680 MPT_ADAPTER *ioc = hd->ioc;
1682 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
1683 if (!vtarget)
1684 return -ENOMEM;
1686 vtarget->starget = starget;
1687 vtarget->ioc_id = ioc->id;
1688 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
1689 id = starget->id;
1690 channel = 0;
1693 * RAID volumes placed beyond the last expected port.
1695 if (starget->channel == MPTSAS_RAID_CHANNEL) {
1696 if (!ioc->raid_data.pIocPg2) {
1697 kfree(vtarget);
1698 return -ENXIO;
1700 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
1701 if (id == ioc->raid_data.pIocPg2->
1702 RaidVolume[i].VolumeID) {
1703 channel = ioc->raid_data.pIocPg2->
1704 RaidVolume[i].VolumeBus;
1707 vtarget->raidVolume = 1;
1708 goto out;
1711 rphy = dev_to_rphy(starget->dev.parent);
1712 mutex_lock(&ioc->sas_topology_mutex);
1713 list_for_each_entry(p, &ioc->sas_topology, list) {
1714 for (i = 0; i < p->num_phys; i++) {
1715 if (p->phy_info[i].attached.sas_address !=
1716 rphy->identify.sas_address)
1717 continue;
1718 id = p->phy_info[i].attached.id;
1719 channel = p->phy_info[i].attached.channel;
1720 mptsas_set_starget(&p->phy_info[i], starget);
1723 * Exposing hidden raid components
1725 if (mptscsih_is_phys_disk(ioc, channel, id)) {
1726 id = mptscsih_raid_id_to_num(ioc,
1727 channel, id);
1728 vtarget->tflags |=
1729 MPT_TARGET_FLAGS_RAID_COMPONENT;
1730 p->phy_info[i].attached.phys_disk_num = id;
1732 mutex_unlock(&ioc->sas_topology_mutex);
1733 goto out;
1736 mutex_unlock(&ioc->sas_topology_mutex);
1738 kfree(vtarget);
1739 return -ENXIO;
1741 out:
1742 vtarget->id = id;
1743 vtarget->channel = channel;
1744 starget->hostdata = vtarget;
1745 return 0;
1748 static void
1749 mptsas_target_destroy(struct scsi_target *starget)
1751 struct Scsi_Host *host = dev_to_shost(&starget->dev);
1752 MPT_SCSI_HOST *hd = shost_priv(host);
1753 struct sas_rphy *rphy;
1754 struct mptsas_portinfo *p;
1755 int i;
1756 MPT_ADAPTER *ioc = hd->ioc;
1757 VirtTarget *vtarget;
1759 if (!starget->hostdata)
1760 return;
1762 vtarget = starget->hostdata;
1764 mptsas_del_device_component_by_os(ioc, starget->channel,
1765 starget->id);
1768 if (starget->channel == MPTSAS_RAID_CHANNEL)
1769 goto out;
1771 rphy = dev_to_rphy(starget->dev.parent);
1772 list_for_each_entry(p, &ioc->sas_topology, list) {
1773 for (i = 0; i < p->num_phys; i++) {
1774 if (p->phy_info[i].attached.sas_address !=
1775 rphy->identify.sas_address)
1776 continue;
1778 starget_printk(KERN_INFO, starget, MYIOC_s_FMT
1779 "delete device: fw_channel %d, fw_id %d, phy %d, "
1780 "sas_addr 0x%llx\n", ioc->name,
1781 p->phy_info[i].attached.channel,
1782 p->phy_info[i].attached.id,
1783 p->phy_info[i].attached.phy_id, (unsigned long long)
1784 p->phy_info[i].attached.sas_address);
1786 mptsas_set_starget(&p->phy_info[i], NULL);
1790 out:
1791 vtarget->starget = NULL;
1792 kfree(starget->hostdata);
1793 starget->hostdata = NULL;
1797 static int
1798 mptsas_slave_alloc(struct scsi_device *sdev)
1800 struct Scsi_Host *host = sdev->host;
1801 MPT_SCSI_HOST *hd = shost_priv(host);
1802 struct sas_rphy *rphy;
1803 struct mptsas_portinfo *p;
1804 VirtDevice *vdevice;
1805 struct scsi_target *starget;
1806 int i;
1807 MPT_ADAPTER *ioc = hd->ioc;
1809 vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
1810 if (!vdevice) {
1811 printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
1812 ioc->name, sizeof(VirtDevice));
1813 return -ENOMEM;
1815 starget = scsi_target(sdev);
1816 vdevice->vtarget = starget->hostdata;
1818 if (sdev->channel == MPTSAS_RAID_CHANNEL)
1819 goto out;
1821 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
1822 mutex_lock(&ioc->sas_topology_mutex);
1823 list_for_each_entry(p, &ioc->sas_topology, list) {
1824 for (i = 0; i < p->num_phys; i++) {
1825 if (p->phy_info[i].attached.sas_address !=
1826 rphy->identify.sas_address)
1827 continue;
1828 vdevice->lun = sdev->lun;
1830 * Exposing hidden raid components
1832 if (mptscsih_is_phys_disk(ioc,
1833 p->phy_info[i].attached.channel,
1834 p->phy_info[i].attached.id))
1835 sdev->no_uld_attach = 1;
1836 mutex_unlock(&ioc->sas_topology_mutex);
1837 goto out;
1840 mutex_unlock(&ioc->sas_topology_mutex);
1842 kfree(vdevice);
1843 return -ENXIO;
1845 out:
1846 vdevice->vtarget->num_luns++;
1847 sdev->hostdata = vdevice;
1848 return 0;
1851 static int
1852 mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1854 MPT_SCSI_HOST *hd;
1855 MPT_ADAPTER *ioc;
1856 VirtDevice *vdevice = SCpnt->device->hostdata;
1858 if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
1859 SCpnt->result = DID_NO_CONNECT << 16;
1860 done(SCpnt);
1861 return 0;
1864 hd = shost_priv(SCpnt->device->host);
1865 ioc = hd->ioc;
1867 if (ioc->sas_discovery_quiesce_io)
1868 return SCSI_MLQUEUE_HOST_BUSY;
1870 // scsi_print_command(SCpnt);
1872 return mptscsih_qcmd(SCpnt,done);
1876 static struct scsi_host_template mptsas_driver_template = {
1877 .module = THIS_MODULE,
1878 .proc_name = "mptsas",
1879 .proc_info = mptscsih_proc_info,
1880 .name = "MPT SPI Host",
1881 .info = mptscsih_info,
1882 .queuecommand = mptsas_qcmd,
1883 .target_alloc = mptsas_target_alloc,
1884 .slave_alloc = mptsas_slave_alloc,
1885 .slave_configure = mptsas_slave_configure,
1886 .target_destroy = mptsas_target_destroy,
1887 .slave_destroy = mptscsih_slave_destroy,
1888 .change_queue_depth = mptscsih_change_queue_depth,
1889 .eh_abort_handler = mptscsih_abort,
1890 .eh_device_reset_handler = mptscsih_dev_reset,
1891 .eh_bus_reset_handler = mptscsih_bus_reset,
1892 .eh_host_reset_handler = mptscsih_host_reset,
1893 .bios_param = mptscsih_bios_param,
1894 .can_queue = MPT_FC_CAN_QUEUE,
1895 .this_id = -1,
1896 .sg_tablesize = MPT_SCSI_SG_DEPTH,
1897 .max_sectors = 8192,
1898 .cmd_per_lun = 7,
1899 .use_clustering = ENABLE_CLUSTERING,
1900 .shost_attrs = mptscsih_host_attrs,
1903 static int mptsas_get_linkerrors(struct sas_phy *phy)
1905 MPT_ADAPTER *ioc = phy_to_ioc(phy);
1906 ConfigExtendedPageHeader_t hdr;
1907 CONFIGPARMS cfg;
1908 SasPhyPage1_t *buffer;
1909 dma_addr_t dma_handle;
1910 int error;
1912 /* FIXME: only have link errors on local phys */
1913 if (!scsi_is_sas_phy_local(phy))
1914 return -EINVAL;
1916 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
1917 hdr.ExtPageLength = 0;
1918 hdr.PageNumber = 1 /* page number 1*/;
1919 hdr.Reserved1 = 0;
1920 hdr.Reserved2 = 0;
1921 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1922 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1924 cfg.cfghdr.ehdr = &hdr;
1925 cfg.physAddr = -1;
1926 cfg.pageAddr = phy->identify.phy_identifier;
1927 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1928 cfg.dir = 0; /* read */
1929 cfg.timeout = 10;
1931 error = mpt_config(ioc, &cfg);
1932 if (error)
1933 return error;
1934 if (!hdr.ExtPageLength)
1935 return -ENXIO;
1937 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1938 &dma_handle);
1939 if (!buffer)
1940 return -ENOMEM;
1942 cfg.physAddr = dma_handle;
1943 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1945 error = mpt_config(ioc, &cfg);
1946 if (error)
1947 goto out_free_consistent;
1949 mptsas_print_phy_pg1(ioc, buffer);
1951 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
1952 phy->running_disparity_error_count =
1953 le32_to_cpu(buffer->RunningDisparityErrorCount);
1954 phy->loss_of_dword_sync_count =
1955 le32_to_cpu(buffer->LossDwordSynchCount);
1956 phy->phy_reset_problem_count =
1957 le32_to_cpu(buffer->PhyResetProblemCount);
1959 out_free_consistent:
1960 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1961 buffer, dma_handle);
1962 return error;
1965 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
1966 MPT_FRAME_HDR *reply)
1968 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
1969 if (reply != NULL) {
1970 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_RF_VALID;
1971 memcpy(ioc->sas_mgmt.reply, reply,
1972 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
1975 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
1976 ioc->sas_mgmt.status &= ~MPT_MGMT_STATUS_PENDING;
1977 complete(&ioc->sas_mgmt.done);
1978 return 1;
1980 return 0;
1983 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
1985 MPT_ADAPTER *ioc = phy_to_ioc(phy);
1986 SasIoUnitControlRequest_t *req;
1987 SasIoUnitControlReply_t *reply;
1988 MPT_FRAME_HDR *mf;
1989 MPIHeader_t *hdr;
1990 unsigned long timeleft;
1991 int error = -ERESTARTSYS;
1993 /* FIXME: fusion doesn't allow non-local phy reset */
1994 if (!scsi_is_sas_phy_local(phy))
1995 return -EINVAL;
1997 /* not implemented for expanders */
1998 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
1999 return -ENXIO;
2001 if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
2002 goto out;
2004 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2005 if (!mf) {
2006 error = -ENOMEM;
2007 goto out_unlock;
2010 hdr = (MPIHeader_t *) mf;
2011 req = (SasIoUnitControlRequest_t *)mf;
2012 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
2013 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
2014 req->MsgContext = hdr->MsgContext;
2015 req->Operation = hard_reset ?
2016 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
2017 req->PhyNum = phy->identify.phy_identifier;
2019 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2020 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2022 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
2023 10 * HZ);
2024 if (!timeleft) {
2025 /* On timeout reset the board */
2026 mpt_free_msg_frame(ioc, mf);
2027 mpt_HardResetHandler(ioc, CAN_SLEEP);
2028 error = -ETIMEDOUT;
2029 goto out_unlock;
2032 /* a reply frame is expected */
2033 if ((ioc->sas_mgmt.status &
2034 MPT_MGMT_STATUS_RF_VALID) == 0) {
2035 error = -ENXIO;
2036 goto out_unlock;
2039 /* process the completed Reply Message Frame */
2040 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
2041 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
2042 printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
2043 ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo);
2044 error = -ENXIO;
2045 goto out_unlock;
2048 error = 0;
2050 out_unlock:
2051 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2052 mutex_unlock(&ioc->sas_mgmt.mutex);
2053 out:
2054 return error;
2057 static int
2058 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
2060 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2061 int i, error;
2062 struct mptsas_portinfo *p;
2063 struct mptsas_enclosure enclosure_info;
2064 u64 enclosure_handle;
2066 mutex_lock(&ioc->sas_topology_mutex);
2067 list_for_each_entry(p, &ioc->sas_topology, list) {
2068 for (i = 0; i < p->num_phys; i++) {
2069 if (p->phy_info[i].attached.sas_address ==
2070 rphy->identify.sas_address) {
2071 enclosure_handle = p->phy_info[i].
2072 attached.handle_enclosure;
2073 goto found_info;
2077 mutex_unlock(&ioc->sas_topology_mutex);
2078 return -ENXIO;
2080 found_info:
2081 mutex_unlock(&ioc->sas_topology_mutex);
2082 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
2083 error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
2084 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
2085 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
2086 if (!error)
2087 *identifier = enclosure_info.enclosure_logical_id;
2088 return error;
2091 static int
2092 mptsas_get_bay_identifier(struct sas_rphy *rphy)
2094 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2095 struct mptsas_portinfo *p;
2096 int i, rc;
2098 mutex_lock(&ioc->sas_topology_mutex);
2099 list_for_each_entry(p, &ioc->sas_topology, list) {
2100 for (i = 0; i < p->num_phys; i++) {
2101 if (p->phy_info[i].attached.sas_address ==
2102 rphy->identify.sas_address) {
2103 rc = p->phy_info[i].attached.slot;
2104 goto out;
2108 rc = -ENXIO;
2109 out:
2110 mutex_unlock(&ioc->sas_topology_mutex);
2111 return rc;
2114 static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
2115 struct request *req)
2117 MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
2118 MPT_FRAME_HDR *mf;
2119 SmpPassthroughRequest_t *smpreq;
2120 struct request *rsp = req->next_rq;
2121 int ret;
2122 int flagsLength;
2123 unsigned long timeleft;
2124 char *psge;
2125 dma_addr_t dma_addr_in = 0;
2126 dma_addr_t dma_addr_out = 0;
2127 u64 sas_address = 0;
2129 if (!rsp) {
2130 printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n",
2131 ioc->name, __func__);
2132 return -EINVAL;
2135 /* do we need to support multiple segments? */
2136 if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
2137 printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
2138 ioc->name, __func__, req->bio->bi_vcnt, blk_rq_bytes(req),
2139 rsp->bio->bi_vcnt, blk_rq_bytes(rsp));
2140 return -EINVAL;
2143 ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2144 if (ret)
2145 goto out;
2147 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2148 if (!mf) {
2149 ret = -ENOMEM;
2150 goto out_unlock;
2153 smpreq = (SmpPassthroughRequest_t *)mf;
2154 memset(smpreq, 0, sizeof(*smpreq));
2156 smpreq->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
2157 smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2159 if (rphy)
2160 sas_address = rphy->identify.sas_address;
2161 else {
2162 struct mptsas_portinfo *port_info;
2164 mutex_lock(&ioc->sas_topology_mutex);
2165 port_info = ioc->hba_port_info;
2166 if (port_info && port_info->phy_info)
2167 sas_address =
2168 port_info->phy_info[0].phy->identify.sas_address;
2169 mutex_unlock(&ioc->sas_topology_mutex);
2172 *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2174 psge = (char *)
2175 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2177 /* request */
2178 flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2179 MPI_SGE_FLAGS_END_OF_BUFFER |
2180 MPI_SGE_FLAGS_DIRECTION)
2181 << MPI_SGE_FLAGS_SHIFT;
2182 flagsLength |= (blk_rq_bytes(req) - 4);
2184 dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
2185 blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
2186 if (!dma_addr_out)
2187 goto put_mf;
2188 ioc->add_sge(psge, flagsLength, dma_addr_out);
2189 psge += ioc->SGE_size;
2191 /* response */
2192 flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2193 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2194 MPI_SGE_FLAGS_IOC_TO_HOST |
2195 MPI_SGE_FLAGS_END_OF_BUFFER;
2197 flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2198 flagsLength |= blk_rq_bytes(rsp) + 4;
2199 dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio),
2200 blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
2201 if (!dma_addr_in)
2202 goto unmap;
2203 ioc->add_sge(psge, flagsLength, dma_addr_in);
2205 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2206 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2208 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2209 if (!timeleft) {
2210 printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __func__);
2211 /* On timeout reset the board */
2212 mpt_HardResetHandler(ioc, CAN_SLEEP);
2213 ret = -ETIMEDOUT;
2214 goto unmap;
2216 mf = NULL;
2218 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2219 SmpPassthroughReply_t *smprep;
2221 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2222 memcpy(req->sense, smprep, sizeof(*smprep));
2223 req->sense_len = sizeof(*smprep);
2224 req->resid_len = 0;
2225 rsp->resid_len -= smprep->ResponseDataLength;
2226 } else {
2227 printk(MYIOC_s_ERR_FMT
2228 "%s: smp passthru reply failed to be returned\n",
2229 ioc->name, __func__);
2230 ret = -ENXIO;
2232 unmap:
2233 if (dma_addr_out)
2234 pci_unmap_single(ioc->pcidev, dma_addr_out, blk_rq_bytes(req),
2235 PCI_DMA_BIDIRECTIONAL);
2236 if (dma_addr_in)
2237 pci_unmap_single(ioc->pcidev, dma_addr_in, blk_rq_bytes(rsp),
2238 PCI_DMA_BIDIRECTIONAL);
2239 put_mf:
2240 if (mf)
2241 mpt_free_msg_frame(ioc, mf);
2242 out_unlock:
2243 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2244 mutex_unlock(&ioc->sas_mgmt.mutex);
2245 out:
2246 return ret;
2249 static struct sas_function_template mptsas_transport_functions = {
2250 .get_linkerrors = mptsas_get_linkerrors,
2251 .get_enclosure_identifier = mptsas_get_enclosure_identifier,
2252 .get_bay_identifier = mptsas_get_bay_identifier,
2253 .phy_reset = mptsas_phy_reset,
2254 .smp_handler = mptsas_smp_handler,
2257 static struct scsi_transport_template *mptsas_transport_template;
2259 static int
2260 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
2262 ConfigExtendedPageHeader_t hdr;
2263 CONFIGPARMS cfg;
2264 SasIOUnitPage0_t *buffer;
2265 dma_addr_t dma_handle;
2266 int error, i;
2268 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
2269 hdr.ExtPageLength = 0;
2270 hdr.PageNumber = 0;
2271 hdr.Reserved1 = 0;
2272 hdr.Reserved2 = 0;
2273 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2274 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2276 cfg.cfghdr.ehdr = &hdr;
2277 cfg.physAddr = -1;
2278 cfg.pageAddr = 0;
2279 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2280 cfg.dir = 0; /* read */
2281 cfg.timeout = 10;
2283 error = mpt_config(ioc, &cfg);
2284 if (error)
2285 goto out;
2286 if (!hdr.ExtPageLength) {
2287 error = -ENXIO;
2288 goto out;
2291 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2292 &dma_handle);
2293 if (!buffer) {
2294 error = -ENOMEM;
2295 goto out;
2298 cfg.physAddr = dma_handle;
2299 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2301 error = mpt_config(ioc, &cfg);
2302 if (error)
2303 goto out_free_consistent;
2305 port_info->num_phys = buffer->NumPhys;
2306 port_info->phy_info = kcalloc(port_info->num_phys,
2307 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2308 if (!port_info->phy_info) {
2309 error = -ENOMEM;
2310 goto out_free_consistent;
2313 ioc->nvdata_version_persistent =
2314 le16_to_cpu(buffer->NvdataVersionPersistent);
2315 ioc->nvdata_version_default =
2316 le16_to_cpu(buffer->NvdataVersionDefault);
2318 for (i = 0; i < port_info->num_phys; i++) {
2319 mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
2320 port_info->phy_info[i].phy_id = i;
2321 port_info->phy_info[i].port_id =
2322 buffer->PhyData[i].Port;
2323 port_info->phy_info[i].negotiated_link_rate =
2324 buffer->PhyData[i].NegotiatedLinkRate;
2325 port_info->phy_info[i].portinfo = port_info;
2326 port_info->phy_info[i].handle =
2327 le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
2330 out_free_consistent:
2331 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2332 buffer, dma_handle);
2333 out:
2334 return error;
2337 static int
2338 mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
2340 ConfigExtendedPageHeader_t hdr;
2341 CONFIGPARMS cfg;
2342 SasIOUnitPage1_t *buffer;
2343 dma_addr_t dma_handle;
2344 int error;
2345 u16 device_missing_delay;
2347 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
2348 memset(&cfg, 0, sizeof(CONFIGPARMS));
2350 cfg.cfghdr.ehdr = &hdr;
2351 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2352 cfg.timeout = 10;
2353 cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2354 cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2355 cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
2356 cfg.cfghdr.ehdr->PageNumber = 1;
2358 error = mpt_config(ioc, &cfg);
2359 if (error)
2360 goto out;
2361 if (!hdr.ExtPageLength) {
2362 error = -ENXIO;
2363 goto out;
2366 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2367 &dma_handle);
2368 if (!buffer) {
2369 error = -ENOMEM;
2370 goto out;
2373 cfg.physAddr = dma_handle;
2374 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2376 error = mpt_config(ioc, &cfg);
2377 if (error)
2378 goto out_free_consistent;
2380 ioc->io_missing_delay =
2381 le16_to_cpu(buffer->IODeviceMissingDelay);
2382 device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay);
2383 ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
2384 (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
2385 device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
2387 out_free_consistent:
2388 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2389 buffer, dma_handle);
2390 out:
2391 return error;
2394 static int
2395 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2396 u32 form, u32 form_specific)
2398 ConfigExtendedPageHeader_t hdr;
2399 CONFIGPARMS cfg;
2400 SasPhyPage0_t *buffer;
2401 dma_addr_t dma_handle;
2402 int error;
2404 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
2405 hdr.ExtPageLength = 0;
2406 hdr.PageNumber = 0;
2407 hdr.Reserved1 = 0;
2408 hdr.Reserved2 = 0;
2409 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2410 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2412 cfg.cfghdr.ehdr = &hdr;
2413 cfg.dir = 0; /* read */
2414 cfg.timeout = 10;
2416 /* Get Phy Pg 0 for each Phy. */
2417 cfg.physAddr = -1;
2418 cfg.pageAddr = form + form_specific;
2419 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2421 error = mpt_config(ioc, &cfg);
2422 if (error)
2423 goto out;
2425 if (!hdr.ExtPageLength) {
2426 error = -ENXIO;
2427 goto out;
2430 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2431 &dma_handle);
2432 if (!buffer) {
2433 error = -ENOMEM;
2434 goto out;
2437 cfg.physAddr = dma_handle;
2438 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2440 error = mpt_config(ioc, &cfg);
2441 if (error)
2442 goto out_free_consistent;
2444 mptsas_print_phy_pg0(ioc, buffer);
2446 phy_info->hw_link_rate = buffer->HwLinkRate;
2447 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2448 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2449 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2451 out_free_consistent:
2452 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2453 buffer, dma_handle);
2454 out:
2455 return error;
2458 static int
2459 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
2460 u32 form, u32 form_specific)
2462 ConfigExtendedPageHeader_t hdr;
2463 CONFIGPARMS cfg;
2464 SasDevicePage0_t *buffer;
2465 dma_addr_t dma_handle;
2466 __le64 sas_address;
2467 int error=0;
2469 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
2470 hdr.ExtPageLength = 0;
2471 hdr.PageNumber = 0;
2472 hdr.Reserved1 = 0;
2473 hdr.Reserved2 = 0;
2474 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2475 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
2477 cfg.cfghdr.ehdr = &hdr;
2478 cfg.pageAddr = form + form_specific;
2479 cfg.physAddr = -1;
2480 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2481 cfg.dir = 0; /* read */
2482 cfg.timeout = 10;
2484 memset(device_info, 0, sizeof(struct mptsas_devinfo));
2485 error = mpt_config(ioc, &cfg);
2486 if (error)
2487 goto out;
2488 if (!hdr.ExtPageLength) {
2489 error = -ENXIO;
2490 goto out;
2493 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2494 &dma_handle);
2495 if (!buffer) {
2496 error = -ENOMEM;
2497 goto out;
2500 cfg.physAddr = dma_handle;
2501 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2503 error = mpt_config(ioc, &cfg);
2504 if (error)
2505 goto out_free_consistent;
2507 mptsas_print_device_pg0(ioc, buffer);
2509 memset(device_info, 0, sizeof(struct mptsas_devinfo));
2510 device_info->handle = le16_to_cpu(buffer->DevHandle);
2511 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
2512 device_info->handle_enclosure =
2513 le16_to_cpu(buffer->EnclosureHandle);
2514 device_info->slot = le16_to_cpu(buffer->Slot);
2515 device_info->phy_id = buffer->PhyNum;
2516 device_info->port_id = buffer->PhysicalPort;
2517 device_info->id = buffer->TargetID;
2518 device_info->phys_disk_num = ~0;
2519 device_info->channel = buffer->Bus;
2520 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2521 device_info->sas_address = le64_to_cpu(sas_address);
2522 device_info->device_info =
2523 le32_to_cpu(buffer->DeviceInfo);
2525 out_free_consistent:
2526 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2527 buffer, dma_handle);
2528 out:
2529 return error;
2532 static int
2533 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
2534 u32 form, u32 form_specific)
2536 ConfigExtendedPageHeader_t hdr;
2537 CONFIGPARMS cfg;
2538 SasExpanderPage0_t *buffer;
2539 dma_addr_t dma_handle;
2540 int i, error;
2541 __le64 sas_address;
2543 memset(port_info, 0, sizeof(struct mptsas_portinfo));
2544 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
2545 hdr.ExtPageLength = 0;
2546 hdr.PageNumber = 0;
2547 hdr.Reserved1 = 0;
2548 hdr.Reserved2 = 0;
2549 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2550 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2552 cfg.cfghdr.ehdr = &hdr;
2553 cfg.physAddr = -1;
2554 cfg.pageAddr = form + form_specific;
2555 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2556 cfg.dir = 0; /* read */
2557 cfg.timeout = 10;
2559 memset(port_info, 0, sizeof(struct mptsas_portinfo));
2560 error = mpt_config(ioc, &cfg);
2561 if (error)
2562 goto out;
2564 if (!hdr.ExtPageLength) {
2565 error = -ENXIO;
2566 goto out;
2569 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2570 &dma_handle);
2571 if (!buffer) {
2572 error = -ENOMEM;
2573 goto out;
2576 cfg.physAddr = dma_handle;
2577 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2579 error = mpt_config(ioc, &cfg);
2580 if (error)
2581 goto out_free_consistent;
2583 if (!buffer->NumPhys) {
2584 error = -ENODEV;
2585 goto out_free_consistent;
2588 /* save config data */
2589 port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1;
2590 port_info->phy_info = kcalloc(port_info->num_phys,
2591 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2592 if (!port_info->phy_info) {
2593 error = -ENOMEM;
2594 goto out_free_consistent;
2597 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2598 for (i = 0; i < port_info->num_phys; i++) {
2599 port_info->phy_info[i].portinfo = port_info;
2600 port_info->phy_info[i].handle =
2601 le16_to_cpu(buffer->DevHandle);
2602 port_info->phy_info[i].identify.sas_address =
2603 le64_to_cpu(sas_address);
2604 port_info->phy_info[i].identify.handle_parent =
2605 le16_to_cpu(buffer->ParentDevHandle);
2608 out_free_consistent:
2609 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2610 buffer, dma_handle);
2611 out:
2612 return error;
2615 static int
2616 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2617 u32 form, u32 form_specific)
2619 ConfigExtendedPageHeader_t hdr;
2620 CONFIGPARMS cfg;
2621 SasExpanderPage1_t *buffer;
2622 dma_addr_t dma_handle;
2623 int error=0;
2625 hdr.PageVersion = MPI_SASEXPANDER1_PAGEVERSION;
2626 hdr.ExtPageLength = 0;
2627 hdr.PageNumber = 1;
2628 hdr.Reserved1 = 0;
2629 hdr.Reserved2 = 0;
2630 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2631 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2633 cfg.cfghdr.ehdr = &hdr;
2634 cfg.physAddr = -1;
2635 cfg.pageAddr = form + form_specific;
2636 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2637 cfg.dir = 0; /* read */
2638 cfg.timeout = 10;
2640 error = mpt_config(ioc, &cfg);
2641 if (error)
2642 goto out;
2644 if (!hdr.ExtPageLength) {
2645 error = -ENXIO;
2646 goto out;
2649 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2650 &dma_handle);
2651 if (!buffer) {
2652 error = -ENOMEM;
2653 goto out;
2656 cfg.physAddr = dma_handle;
2657 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2659 error = mpt_config(ioc, &cfg);
2661 if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2662 error = -ENODEV;
2663 goto out;
2666 if (error)
2667 goto out_free_consistent;
2670 mptsas_print_expander_pg1(ioc, buffer);
2672 /* save config data */
2673 phy_info->phy_id = buffer->PhyIdentifier;
2674 phy_info->port_id = buffer->PhysicalPort;
2675 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
2676 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2677 phy_info->hw_link_rate = buffer->HwLinkRate;
2678 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2679 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2681 out_free_consistent:
2682 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2683 buffer, dma_handle);
2684 out:
2685 return error;
2688 static void
2689 mptsas_parse_device_info(struct sas_identify *identify,
2690 struct mptsas_devinfo *device_info)
2692 u16 protocols;
2694 identify->sas_address = device_info->sas_address;
2695 identify->phy_identifier = device_info->phy_id;
2698 * Fill in Phy Initiator Port Protocol.
2699 * Bits 6:3, more than one bit can be set, fall through cases.
2701 protocols = device_info->device_info & 0x78;
2702 identify->initiator_port_protocols = 0;
2703 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
2704 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
2705 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
2706 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
2707 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
2708 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
2709 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
2710 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
2713 * Fill in Phy Target Port Protocol.
2714 * Bits 10:7, more than one bit can be set, fall through cases.
2716 protocols = device_info->device_info & 0x780;
2717 identify->target_port_protocols = 0;
2718 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
2719 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
2720 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
2721 identify->target_port_protocols |= SAS_PROTOCOL_STP;
2722 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
2723 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
2724 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2725 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
2728 * Fill in Attached device type.
2730 switch (device_info->device_info &
2731 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
2732 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
2733 identify->device_type = SAS_PHY_UNUSED;
2734 break;
2735 case MPI_SAS_DEVICE_INFO_END_DEVICE:
2736 identify->device_type = SAS_END_DEVICE;
2737 break;
2738 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
2739 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
2740 break;
2741 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
2742 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
2743 break;
2747 static int mptsas_probe_one_phy(struct device *dev,
2748 struct mptsas_phyinfo *phy_info, int index, int local)
2750 MPT_ADAPTER *ioc;
2751 struct sas_phy *phy;
2752 struct sas_port *port;
2753 int error = 0;
2755 if (!dev) {
2756 error = -ENODEV;
2757 goto out;
2760 if (!phy_info->phy) {
2761 phy = sas_phy_alloc(dev, index);
2762 if (!phy) {
2763 error = -ENOMEM;
2764 goto out;
2766 } else
2767 phy = phy_info->phy;
2769 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
2772 * Set Negotiated link rate.
2774 switch (phy_info->negotiated_link_rate) {
2775 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
2776 phy->negotiated_linkrate = SAS_PHY_DISABLED;
2777 break;
2778 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
2779 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
2780 break;
2781 case MPI_SAS_IOUNIT0_RATE_1_5:
2782 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
2783 break;
2784 case MPI_SAS_IOUNIT0_RATE_3_0:
2785 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
2786 break;
2787 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
2788 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
2789 default:
2790 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
2791 break;
2795 * Set Max hardware link rate.
2797 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
2798 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
2799 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
2800 break;
2801 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
2802 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
2803 break;
2804 default:
2805 break;
2809 * Set Max programmed link rate.
2811 switch (phy_info->programmed_link_rate &
2812 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
2813 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
2814 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
2815 break;
2816 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
2817 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
2818 break;
2819 default:
2820 break;
2824 * Set Min hardware link rate.
2826 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
2827 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
2828 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
2829 break;
2830 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
2831 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
2832 break;
2833 default:
2834 break;
2838 * Set Min programmed link rate.
2840 switch (phy_info->programmed_link_rate &
2841 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
2842 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
2843 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
2844 break;
2845 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
2846 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
2847 break;
2848 default:
2849 break;
2852 if (!phy_info->phy) {
2854 error = sas_phy_add(phy);
2855 if (error) {
2856 sas_phy_free(phy);
2857 goto out;
2859 phy_info->phy = phy;
2862 if (!phy_info->attached.handle ||
2863 !phy_info->port_details)
2864 goto out;
2866 port = mptsas_get_port(phy_info);
2867 ioc = phy_to_ioc(phy_info->phy);
2869 if (phy_info->sas_port_add_phy) {
2871 if (!port) {
2872 port = sas_port_alloc_num(dev);
2873 if (!port) {
2874 error = -ENOMEM;
2875 goto out;
2877 error = sas_port_add(port);
2878 if (error) {
2879 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2880 "%s: exit at line=%d\n", ioc->name,
2881 __func__, __LINE__));
2882 goto out;
2884 mptsas_set_port(ioc, phy_info, port);
2885 devtprintk(ioc, dev_printk(KERN_DEBUG, &port->dev,
2886 MYIOC_s_FMT "add port %d, sas_addr (0x%llx)\n",
2887 ioc->name, port->port_identifier,
2888 (unsigned long long)phy_info->
2889 attached.sas_address));
2891 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2892 "sas_port_add_phy: phy_id=%d\n",
2893 ioc->name, phy_info->phy_id));
2894 sas_port_add_phy(port, phy_info->phy);
2895 phy_info->sas_port_add_phy = 0;
2896 devtprintk(ioc, dev_printk(KERN_DEBUG, &phy_info->phy->dev,
2897 MYIOC_s_FMT "add phy %d, phy-obj (0x%p)\n", ioc->name,
2898 phy_info->phy_id, phy_info->phy));
2900 if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
2902 struct sas_rphy *rphy;
2903 struct device *parent;
2904 struct sas_identify identify;
2906 parent = dev->parent->parent;
2908 * Let the hotplug_work thread handle processing
2909 * the adding/removing of devices that occur
2910 * after start of day.
2912 if (mptsas_is_end_device(&phy_info->attached) &&
2913 phy_info->attached.handle_parent) {
2914 goto out;
2917 mptsas_parse_device_info(&identify, &phy_info->attached);
2918 if (scsi_is_host_device(parent)) {
2919 struct mptsas_portinfo *port_info;
2920 int i;
2922 port_info = ioc->hba_port_info;
2924 for (i = 0; i < port_info->num_phys; i++)
2925 if (port_info->phy_info[i].identify.sas_address ==
2926 identify.sas_address) {
2927 sas_port_mark_backlink(port);
2928 goto out;
2931 } else if (scsi_is_sas_rphy(parent)) {
2932 struct sas_rphy *parent_rphy = dev_to_rphy(parent);
2933 if (identify.sas_address ==
2934 parent_rphy->identify.sas_address) {
2935 sas_port_mark_backlink(port);
2936 goto out;
2940 switch (identify.device_type) {
2941 case SAS_END_DEVICE:
2942 rphy = sas_end_device_alloc(port);
2943 break;
2944 case SAS_EDGE_EXPANDER_DEVICE:
2945 case SAS_FANOUT_EXPANDER_DEVICE:
2946 rphy = sas_expander_alloc(port, identify.device_type);
2947 break;
2948 default:
2949 rphy = NULL;
2950 break;
2952 if (!rphy) {
2953 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2954 "%s: exit at line=%d\n", ioc->name,
2955 __func__, __LINE__));
2956 goto out;
2959 rphy->identify = identify;
2960 error = sas_rphy_add(rphy);
2961 if (error) {
2962 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2963 "%s: exit at line=%d\n", ioc->name,
2964 __func__, __LINE__));
2965 sas_rphy_free(rphy);
2966 goto out;
2968 mptsas_set_rphy(ioc, phy_info, rphy);
2971 out:
2972 return error;
2975 static int
2976 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
2978 struct mptsas_portinfo *port_info, *hba;
2979 int error = -ENOMEM, i;
2981 hba = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
2982 if (! hba)
2983 goto out;
2985 error = mptsas_sas_io_unit_pg0(ioc, hba);
2986 if (error)
2987 goto out_free_port_info;
2989 mptsas_sas_io_unit_pg1(ioc);
2990 mutex_lock(&ioc->sas_topology_mutex);
2991 port_info = ioc->hba_port_info;
2992 if (!port_info) {
2993 ioc->hba_port_info = port_info = hba;
2994 ioc->hba_port_num_phy = port_info->num_phys;
2995 list_add_tail(&port_info->list, &ioc->sas_topology);
2996 } else {
2997 for (i = 0; i < hba->num_phys; i++) {
2998 port_info->phy_info[i].negotiated_link_rate =
2999 hba->phy_info[i].negotiated_link_rate;
3000 port_info->phy_info[i].handle =
3001 hba->phy_info[i].handle;
3002 port_info->phy_info[i].port_id =
3003 hba->phy_info[i].port_id;
3005 kfree(hba->phy_info);
3006 kfree(hba);
3007 hba = NULL;
3009 mutex_unlock(&ioc->sas_topology_mutex);
3010 #if defined(CPQ_CIM)
3011 ioc->num_ports = port_info->num_phys;
3012 #endif
3013 for (i = 0; i < port_info->num_phys; i++) {
3014 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
3015 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
3016 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
3017 port_info->phy_info[i].identify.handle =
3018 port_info->phy_info[i].handle;
3019 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
3020 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3021 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3022 port_info->phy_info[i].identify.handle);
3023 if (!ioc->hba_port_sas_addr)
3024 ioc->hba_port_sas_addr =
3025 port_info->phy_info[i].identify.sas_address;
3026 port_info->phy_info[i].identify.phy_id =
3027 port_info->phy_info[i].phy_id = i;
3028 if (port_info->phy_info[i].attached.handle)
3029 mptsas_sas_device_pg0(ioc,
3030 &port_info->phy_info[i].attached,
3031 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3032 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3033 port_info->phy_info[i].attached.handle);
3036 mptsas_setup_wide_ports(ioc, port_info);
3038 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3039 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
3040 &port_info->phy_info[i], ioc->sas_index, 1);
3042 return 0;
3044 out_free_port_info:
3045 kfree(hba);
3046 out:
3047 return error;
3050 static void
3051 mptsas_expander_refresh(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
3053 struct mptsas_portinfo *parent;
3054 struct device *parent_dev;
3055 struct sas_rphy *rphy;
3056 int i;
3057 u64 sas_address; /* expander sas address */
3058 u32 handle;
3060 handle = port_info->phy_info[0].handle;
3061 sas_address = port_info->phy_info[0].identify.sas_address;
3062 for (i = 0; i < port_info->num_phys; i++) {
3063 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
3064 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
3065 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + handle);
3067 mptsas_sas_device_pg0(ioc,
3068 &port_info->phy_info[i].identify,
3069 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3070 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3071 port_info->phy_info[i].identify.handle);
3072 port_info->phy_info[i].identify.phy_id =
3073 port_info->phy_info[i].phy_id;
3075 if (port_info->phy_info[i].attached.handle) {
3076 mptsas_sas_device_pg0(ioc,
3077 &port_info->phy_info[i].attached,
3078 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3079 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3080 port_info->phy_info[i].attached.handle);
3081 port_info->phy_info[i].attached.phy_id =
3082 port_info->phy_info[i].phy_id;
3086 mutex_lock(&ioc->sas_topology_mutex);
3087 parent = mptsas_find_portinfo_by_handle(ioc,
3088 port_info->phy_info[0].identify.handle_parent);
3089 if (!parent) {
3090 mutex_unlock(&ioc->sas_topology_mutex);
3091 return;
3093 for (i = 0, parent_dev = NULL; i < parent->num_phys && !parent_dev;
3094 i++) {
3095 if (parent->phy_info[i].attached.sas_address == sas_address) {
3096 rphy = mptsas_get_rphy(&parent->phy_info[i]);
3097 parent_dev = &rphy->dev;
3100 mutex_unlock(&ioc->sas_topology_mutex);
3102 mptsas_setup_wide_ports(ioc, port_info);
3103 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3104 mptsas_probe_one_phy(parent_dev, &port_info->phy_info[i],
3105 ioc->sas_index, 0);
3108 static void
3109 mptsas_expander_event_add(MPT_ADAPTER *ioc,
3110 MpiEventDataSasExpanderStatusChange_t *expander_data)
3112 struct mptsas_portinfo *port_info;
3113 int i;
3114 __le64 sas_address;
3116 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3117 if (!port_info)
3118 BUG();
3119 port_info->num_phys = (expander_data->NumPhys) ?
3120 expander_data->NumPhys : 1;
3121 port_info->phy_info = kcalloc(port_info->num_phys,
3122 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
3123 if (!port_info->phy_info)
3124 BUG();
3125 memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3126 for (i = 0; i < port_info->num_phys; i++) {
3127 port_info->phy_info[i].portinfo = port_info;
3128 port_info->phy_info[i].handle =
3129 le16_to_cpu(expander_data->DevHandle);
3130 port_info->phy_info[i].identify.sas_address =
3131 le64_to_cpu(sas_address);
3132 port_info->phy_info[i].identify.handle_parent =
3133 le16_to_cpu(expander_data->ParentDevHandle);
3136 mutex_lock(&ioc->sas_topology_mutex);
3137 list_add_tail(&port_info->list, &ioc->sas_topology);
3138 mutex_unlock(&ioc->sas_topology_mutex);
3140 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3141 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3142 (unsigned long long)sas_address);
3144 mptsas_expander_refresh(ioc, port_info);
3148 * mptsas_delete_expander_siblings - remove siblings attached to expander
3149 * @ioc: Pointer to MPT_ADAPTER structure
3150 * @parent: the parent port_info object
3151 * @expander: the expander port_info object
3153 static void
3154 mptsas_delete_expander_siblings(MPT_ADAPTER *ioc, struct mptsas_portinfo
3155 *parent, struct mptsas_portinfo *expander)
3157 struct mptsas_phyinfo *phy_info;
3158 struct mptsas_portinfo *port_info;
3159 struct sas_rphy *rphy;
3160 int i;
3162 phy_info = expander->phy_info;
3163 for (i = 0; i < expander->num_phys; i++, phy_info++) {
3164 rphy = mptsas_get_rphy(phy_info);
3165 if (!rphy)
3166 continue;
3167 if (rphy->identify.device_type == SAS_END_DEVICE)
3168 mptsas_del_end_device(ioc, phy_info);
3171 phy_info = expander->phy_info;
3172 for (i = 0; i < expander->num_phys; i++, phy_info++) {
3173 rphy = mptsas_get_rphy(phy_info);
3174 if (!rphy)
3175 continue;
3176 if (rphy->identify.device_type ==
3177 MPI_SAS_DEVICE_INFO_EDGE_EXPANDER ||
3178 rphy->identify.device_type ==
3179 MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
3180 port_info = mptsas_find_portinfo_by_sas_address(ioc,
3181 rphy->identify.sas_address);
3182 if (!port_info)
3183 continue;
3184 if (port_info == parent) /* backlink rphy */
3185 continue;
3187 Delete this expander even if the expdevpage is exists
3188 because the parent expander is already deleted
3190 mptsas_expander_delete(ioc, port_info, 1);
3197 * mptsas_expander_delete - remove this expander
3198 * @ioc: Pointer to MPT_ADAPTER structure
3199 * @port_info: expander port_info struct
3200 * @force: Flag to forcefully delete the expander
3204 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
3205 struct mptsas_portinfo *port_info, u8 force)
3208 struct mptsas_portinfo *parent;
3209 int i;
3210 u64 expander_sas_address;
3211 struct mptsas_phyinfo *phy_info;
3212 struct mptsas_portinfo buffer;
3213 struct mptsas_portinfo_details *port_details;
3214 struct sas_port *port;
3216 if (!port_info)
3217 return;
3219 /* see if expander is still there before deleting */
3220 mptsas_sas_expander_pg0(ioc, &buffer,
3221 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3222 MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
3223 port_info->phy_info[0].identify.handle);
3225 if (buffer.num_phys) {
3226 kfree(buffer.phy_info);
3227 if (!force)
3228 return;
3233 * Obtain the port_info instance to the parent port
3235 port_details = NULL;
3236 expander_sas_address =
3237 port_info->phy_info[0].identify.sas_address;
3238 parent = mptsas_find_portinfo_by_handle(ioc,
3239 port_info->phy_info[0].identify.handle_parent);
3240 mptsas_delete_expander_siblings(ioc, parent, port_info);
3241 if (!parent)
3242 goto out;
3245 * Delete rphys in the parent that point
3246 * to this expander.
3248 phy_info = parent->phy_info;
3249 port = NULL;
3250 for (i = 0; i < parent->num_phys; i++, phy_info++) {
3251 if (!phy_info->phy)
3252 continue;
3253 if (phy_info->attached.sas_address !=
3254 expander_sas_address)
3255 continue;
3256 if (!port) {
3257 port = mptsas_get_port(phy_info);
3258 port_details = phy_info->port_details;
3260 dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3261 MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n", ioc->name,
3262 phy_info->phy_id, phy_info->phy);
3263 sas_port_delete_phy(port, phy_info->phy);
3265 if (port) {
3266 dev_printk(KERN_DEBUG, &port->dev,
3267 MYIOC_s_FMT "delete port %d, sas_addr (0x%llx)\n",
3268 ioc->name, port->port_identifier,
3269 (unsigned long long)expander_sas_address);
3270 sas_port_delete(port);
3271 mptsas_port_delete(ioc, port_details);
3273 out:
3275 printk(MYIOC_s_INFO_FMT "delete expander: num_phys %d, "
3276 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3277 (unsigned long long)expander_sas_address);
3280 * free link
3282 list_del(&port_info->list);
3283 kfree(port_info->phy_info);
3284 kfree(port_info);
3289 * mptsas_send_expander_event - expanders events
3290 * @ioc: Pointer to MPT_ADAPTER structure
3291 * @expander_data: event data
3294 * This function handles adding, removing, and refreshing
3295 * device handles within the expander objects.
3297 static void
3298 mptsas_send_expander_event(struct fw_event_work *fw_event)
3300 MPT_ADAPTER *ioc;
3301 MpiEventDataSasExpanderStatusChange_t *expander_data;
3302 struct mptsas_portinfo *port_info;
3303 __le64 sas_address;
3304 int i;
3306 ioc = fw_event->ioc;
3307 expander_data = (MpiEventDataSasExpanderStatusChange_t *)
3308 fw_event->event_data;
3309 memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3310 port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3312 if (expander_data->ReasonCode == MPI_EVENT_SAS_EXP_RC_ADDED) {
3313 if (port_info) {
3314 for (i = 0; i < port_info->num_phys; i++) {
3315 port_info->phy_info[i].portinfo = port_info;
3316 port_info->phy_info[i].handle =
3317 le16_to_cpu(expander_data->DevHandle);
3318 port_info->phy_info[i].identify.sas_address =
3319 le64_to_cpu(sas_address);
3320 port_info->phy_info[i].identify.handle_parent =
3321 le16_to_cpu(expander_data->ParentDevHandle);
3323 mptsas_expander_refresh(ioc, port_info);
3324 } else if (!port_info && expander_data->NumPhys)
3325 mptsas_expander_event_add(ioc, expander_data);
3326 } else if (expander_data->ReasonCode ==
3327 MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING)
3328 mptsas_expander_delete(ioc, port_info, 0);
3330 mptsas_free_fw_event(ioc, fw_event);
3335 * mptsas_expander_add -
3336 * @ioc: Pointer to MPT_ADAPTER structure
3337 * @handle:
3340 struct mptsas_portinfo *
3341 mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
3343 struct mptsas_portinfo buffer, *port_info;
3344 int i;
3346 if ((mptsas_sas_expander_pg0(ioc, &buffer,
3347 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3348 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)))
3349 return NULL;
3351 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_ATOMIC);
3352 if (!port_info) {
3353 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3354 "%s: exit at line=%d\n", ioc->name,
3355 __func__, __LINE__));
3356 return NULL;
3358 port_info->num_phys = buffer.num_phys;
3359 port_info->phy_info = buffer.phy_info;
3360 for (i = 0; i < port_info->num_phys; i++)
3361 port_info->phy_info[i].portinfo = port_info;
3362 mutex_lock(&ioc->sas_topology_mutex);
3363 list_add_tail(&port_info->list, &ioc->sas_topology);
3364 mutex_unlock(&ioc->sas_topology_mutex);
3365 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3366 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3367 (unsigned long long)buffer.phy_info[0].identify.sas_address);
3368 mptsas_expander_refresh(ioc, port_info);
3369 return port_info;
3372 static void
3373 mptsas_send_link_status_event(struct fw_event_work *fw_event)
3375 MPT_ADAPTER *ioc;
3376 MpiEventDataSasPhyLinkStatus_t *link_data;
3377 struct mptsas_portinfo *port_info;
3378 struct mptsas_phyinfo *phy_info = NULL;
3379 __le64 sas_address;
3380 u8 phy_num;
3381 u8 link_rate;
3383 ioc = fw_event->ioc;
3384 link_data = (MpiEventDataSasPhyLinkStatus_t *)fw_event->event_data;
3386 memcpy(&sas_address, &link_data->SASAddress, sizeof(__le64));
3387 sas_address = le64_to_cpu(sas_address);
3388 link_rate = link_data->LinkRates >> 4;
3389 phy_num = link_data->PhyNum;
3391 port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3392 if (port_info) {
3393 phy_info = &port_info->phy_info[phy_num];
3394 if (phy_info)
3395 phy_info->negotiated_link_rate = link_rate;
3398 if (link_rate == MPI_SAS_IOUNIT0_RATE_1_5 ||
3399 link_rate == MPI_SAS_IOUNIT0_RATE_3_0) {
3401 if (!port_info) {
3402 if (ioc->old_sas_discovery_protocal) {
3403 port_info = mptsas_expander_add(ioc,
3404 le16_to_cpu(link_data->DevHandle));
3405 if (port_info)
3406 goto out;
3408 goto out;
3411 if (port_info == ioc->hba_port_info)
3412 mptsas_probe_hba_phys(ioc);
3413 else
3414 mptsas_expander_refresh(ioc, port_info);
3415 } else if (phy_info && phy_info->phy) {
3416 if (link_rate == MPI_SAS_IOUNIT0_RATE_PHY_DISABLED)
3417 phy_info->phy->negotiated_linkrate =
3418 SAS_PHY_DISABLED;
3419 else if (link_rate ==
3420 MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION)
3421 phy_info->phy->negotiated_linkrate =
3422 SAS_LINK_RATE_FAILED;
3423 else
3424 phy_info->phy->negotiated_linkrate =
3425 SAS_LINK_RATE_UNKNOWN;
3427 out:
3428 mptsas_free_fw_event(ioc, fw_event);
3431 static void
3432 mptsas_not_responding_devices(MPT_ADAPTER *ioc)
3434 struct mptsas_portinfo buffer, *port_info;
3435 struct mptsas_device_info *sas_info;
3436 struct mptsas_devinfo sas_device;
3437 u32 handle;
3438 VirtTarget *vtarget = NULL;
3439 struct mptsas_phyinfo *phy_info;
3440 u8 found_expander;
3441 int retval, retry_count;
3442 unsigned long flags;
3444 mpt_findImVolumes(ioc);
3446 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3447 if (ioc->ioc_reset_in_progress) {
3448 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3449 "%s: exiting due to a parallel reset \n", ioc->name,
3450 __func__));
3451 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3452 return;
3454 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3456 /* devices, logical volumes */
3457 mutex_lock(&ioc->sas_device_info_mutex);
3458 redo_device_scan:
3459 list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) {
3460 if (sas_info->is_cached)
3461 continue;
3462 if (!sas_info->is_logical_volume) {
3463 sas_device.handle = 0;
3464 retry_count = 0;
3465 retry_page:
3466 retval = mptsas_sas_device_pg0(ioc, &sas_device,
3467 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID
3468 << MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3469 (sas_info->fw.channel << 8) +
3470 sas_info->fw.id);
3472 if (sas_device.handle)
3473 continue;
3474 if (retval == -EBUSY) {
3475 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3476 if (ioc->ioc_reset_in_progress) {
3477 dfailprintk(ioc,
3478 printk(MYIOC_s_DEBUG_FMT
3479 "%s: exiting due to reset\n",
3480 ioc->name, __func__));
3481 spin_unlock_irqrestore
3482 (&ioc->taskmgmt_lock, flags);
3483 mutex_unlock(&ioc->
3484 sas_device_info_mutex);
3485 return;
3487 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
3488 flags);
3491 if (retval && (retval != -ENODEV)) {
3492 if (retry_count < 10) {
3493 retry_count++;
3494 goto retry_page;
3495 } else {
3496 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3497 "%s: Config page retry exceeded retry "
3498 "count deleting device 0x%llx\n",
3499 ioc->name, __func__,
3500 sas_info->sas_address));
3504 /* delete device */
3505 vtarget = mptsas_find_vtarget(ioc,
3506 sas_info->fw.channel, sas_info->fw.id);
3508 if (vtarget)
3509 vtarget->deleted = 1;
3511 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3512 sas_info->sas_address);
3514 if (phy_info) {
3515 mptsas_del_end_device(ioc, phy_info);
3516 goto redo_device_scan;
3518 } else
3519 mptsas_volume_delete(ioc, sas_info->fw.id);
3521 mutex_unlock(&ioc->sas_device_info_mutex);
3523 /* expanders */
3524 mutex_lock(&ioc->sas_topology_mutex);
3525 redo_expander_scan:
3526 list_for_each_entry(port_info, &ioc->sas_topology, list) {
3528 if (port_info->phy_info &&
3529 (!(port_info->phy_info[0].identify.device_info &
3530 MPI_SAS_DEVICE_INFO_SMP_TARGET)))
3531 continue;
3532 found_expander = 0;
3533 handle = 0xFFFF;
3534 while (!mptsas_sas_expander_pg0(ioc, &buffer,
3535 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3536 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle) &&
3537 !found_expander) {
3539 handle = buffer.phy_info[0].handle;
3540 if (buffer.phy_info[0].identify.sas_address ==
3541 port_info->phy_info[0].identify.sas_address) {
3542 found_expander = 1;
3544 kfree(buffer.phy_info);
3547 if (!found_expander) {
3548 mptsas_expander_delete(ioc, port_info, 0);
3549 goto redo_expander_scan;
3552 mutex_unlock(&ioc->sas_topology_mutex);
3556 * mptsas_probe_expanders - adding expanders
3557 * @ioc: Pointer to MPT_ADAPTER structure
3560 static void
3561 mptsas_probe_expanders(MPT_ADAPTER *ioc)
3563 struct mptsas_portinfo buffer, *port_info;
3564 u32 handle;
3565 int i;
3567 handle = 0xFFFF;
3568 while (!mptsas_sas_expander_pg0(ioc, &buffer,
3569 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3570 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)) {
3572 handle = buffer.phy_info[0].handle;
3573 port_info = mptsas_find_portinfo_by_sas_address(ioc,
3574 buffer.phy_info[0].identify.sas_address);
3576 if (port_info) {
3577 /* refreshing handles */
3578 for (i = 0; i < buffer.num_phys; i++) {
3579 port_info->phy_info[i].handle = handle;
3580 port_info->phy_info[i].identify.handle_parent =
3581 buffer.phy_info[0].identify.handle_parent;
3583 mptsas_expander_refresh(ioc, port_info);
3584 kfree(buffer.phy_info);
3585 continue;
3588 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3589 if (!port_info) {
3590 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3591 "%s: exit at line=%d\n", ioc->name,
3592 __func__, __LINE__));
3593 return;
3595 port_info->num_phys = buffer.num_phys;
3596 port_info->phy_info = buffer.phy_info;
3597 for (i = 0; i < port_info->num_phys; i++)
3598 port_info->phy_info[i].portinfo = port_info;
3599 mutex_lock(&ioc->sas_topology_mutex);
3600 list_add_tail(&port_info->list, &ioc->sas_topology);
3601 mutex_unlock(&ioc->sas_topology_mutex);
3602 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3603 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3604 (unsigned long long)buffer.phy_info[0].identify.sas_address);
3605 mptsas_expander_refresh(ioc, port_info);
3609 static void
3610 mptsas_probe_devices(MPT_ADAPTER *ioc)
3612 u16 handle;
3613 struct mptsas_devinfo sas_device;
3614 struct mptsas_phyinfo *phy_info;
3616 handle = 0xFFFF;
3617 while (!(mptsas_sas_device_pg0(ioc, &sas_device,
3618 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
3620 handle = sas_device.handle;
3622 if ((sas_device.device_info &
3623 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
3624 MPI_SAS_DEVICE_INFO_STP_TARGET |
3625 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0)
3626 continue;
3628 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3629 if (!phy_info)
3630 continue;
3632 if (mptsas_get_rphy(phy_info))
3633 continue;
3635 mptsas_add_end_device(ioc, phy_info);
3640 * mptsas_scan_sas_topology -
3641 * @ioc: Pointer to MPT_ADAPTER structure
3642 * @sas_address:
3645 static void
3646 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
3648 struct scsi_device *sdev;
3649 int i;
3651 mptsas_probe_hba_phys(ioc);
3652 mptsas_probe_expanders(ioc);
3653 mptsas_probe_devices(ioc);
3656 Reporting RAID volumes.
3658 if (!ioc->ir_firmware || !ioc->raid_data.pIocPg2 ||
3659 !ioc->raid_data.pIocPg2->NumActiveVolumes)
3660 return;
3661 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
3662 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
3663 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
3664 if (sdev) {
3665 scsi_device_put(sdev);
3666 continue;
3668 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
3669 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
3670 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID);
3671 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
3672 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
3677 static void
3678 mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
3680 MPT_ADAPTER *ioc;
3681 EventDataQueueFull_t *qfull_data;
3682 struct mptsas_device_info *sas_info;
3683 struct scsi_device *sdev;
3684 int depth;
3685 int id = -1;
3686 int channel = -1;
3687 int fw_id, fw_channel;
3688 u16 current_depth;
3691 ioc = fw_event->ioc;
3692 qfull_data = (EventDataQueueFull_t *)fw_event->event_data;
3693 fw_id = qfull_data->TargetID;
3694 fw_channel = qfull_data->Bus;
3695 current_depth = le16_to_cpu(qfull_data->CurrentDepth);
3697 /* if hidden raid component, look for the volume id */
3698 mutex_lock(&ioc->sas_device_info_mutex);
3699 if (mptscsih_is_phys_disk(ioc, fw_channel, fw_id)) {
3700 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
3701 list) {
3702 if (sas_info->is_cached ||
3703 sas_info->is_logical_volume)
3704 continue;
3705 if (sas_info->is_hidden_raid_component &&
3706 (sas_info->fw.channel == fw_channel &&
3707 sas_info->fw.id == fw_id)) {
3708 id = sas_info->volume_id;
3709 channel = MPTSAS_RAID_CHANNEL;
3710 goto out;
3713 } else {
3714 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
3715 list) {
3716 if (sas_info->is_cached ||
3717 sas_info->is_hidden_raid_component ||
3718 sas_info->is_logical_volume)
3719 continue;
3720 if (sas_info->fw.channel == fw_channel &&
3721 sas_info->fw.id == fw_id) {
3722 id = sas_info->os.id;
3723 channel = sas_info->os.channel;
3724 goto out;
3730 out:
3731 mutex_unlock(&ioc->sas_device_info_mutex);
3733 if (id != -1) {
3734 shost_for_each_device(sdev, ioc->sh) {
3735 if (sdev->id == id && sdev->channel == channel) {
3736 if (current_depth > sdev->queue_depth) {
3737 sdev_printk(KERN_INFO, sdev,
3738 "strange observation, the queue "
3739 "depth is (%d) meanwhile fw queue "
3740 "depth (%d)\n", sdev->queue_depth,
3741 current_depth);
3742 continue;
3744 depth = scsi_track_queue_full(sdev,
3745 current_depth - 1);
3746 if (depth > 0)
3747 sdev_printk(KERN_INFO, sdev,
3748 "Queue depth reduced to (%d)\n",
3749 depth);
3750 else if (depth < 0)
3751 sdev_printk(KERN_INFO, sdev,
3752 "Tagged Command Queueing is being "
3753 "disabled\n");
3754 else if (depth == 0)
3755 sdev_printk(KERN_INFO, sdev,
3756 "Queue depth not changed yet\n");
3761 mptsas_free_fw_event(ioc, fw_event);
3765 static struct mptsas_phyinfo *
3766 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
3768 struct mptsas_portinfo *port_info;
3769 struct mptsas_phyinfo *phy_info = NULL;
3770 int i;
3772 mutex_lock(&ioc->sas_topology_mutex);
3773 list_for_each_entry(port_info, &ioc->sas_topology, list) {
3774 for (i = 0; i < port_info->num_phys; i++) {
3775 if (!mptsas_is_end_device(
3776 &port_info->phy_info[i].attached))
3777 continue;
3778 if (port_info->phy_info[i].attached.sas_address
3779 != sas_address)
3780 continue;
3781 phy_info = &port_info->phy_info[i];
3782 break;
3785 mutex_unlock(&ioc->sas_topology_mutex);
3786 return phy_info;
3790 * mptsas_find_phyinfo_by_phys_disk_num -
3791 * @ioc: Pointer to MPT_ADAPTER structure
3792 * @phys_disk_num:
3793 * @channel:
3794 * @id:
3797 static struct mptsas_phyinfo *
3798 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
3799 u8 channel, u8 id)
3801 struct mptsas_phyinfo *phy_info = NULL;
3802 struct mptsas_portinfo *port_info;
3803 RaidPhysDiskPage1_t *phys_disk = NULL;
3804 int num_paths;
3805 u64 sas_address = 0;
3806 int i;
3808 phy_info = NULL;
3809 if (!ioc->raid_data.pIocPg3)
3810 return NULL;
3811 /* dual port support */
3812 num_paths = mpt_raid_phys_disk_get_num_paths(ioc, phys_disk_num);
3813 if (!num_paths)
3814 goto out;
3815 phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
3816 (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
3817 if (!phys_disk)
3818 goto out;
3819 mpt_raid_phys_disk_pg1(ioc, phys_disk_num, phys_disk);
3820 for (i = 0; i < num_paths; i++) {
3821 if ((phys_disk->Path[i].Flags & 1) != 0)
3822 /* entry no longer valid */
3823 continue;
3824 if ((id == phys_disk->Path[i].PhysDiskID) &&
3825 (channel == phys_disk->Path[i].PhysDiskBus)) {
3826 memcpy(&sas_address, &phys_disk->Path[i].WWID,
3827 sizeof(u64));
3828 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3829 sas_address);
3830 goto out;
3834 out:
3835 kfree(phys_disk);
3836 if (phy_info)
3837 return phy_info;
3840 * Extra code to handle RAID0 case, where the sas_address is not updated
3841 * in phys_disk_page_1 when hotswapped
3843 mutex_lock(&ioc->sas_topology_mutex);
3844 list_for_each_entry(port_info, &ioc->sas_topology, list) {
3845 for (i = 0; i < port_info->num_phys && !phy_info; i++) {
3846 if (!mptsas_is_end_device(
3847 &port_info->phy_info[i].attached))
3848 continue;
3849 if (port_info->phy_info[i].attached.phys_disk_num == ~0)
3850 continue;
3851 if ((port_info->phy_info[i].attached.phys_disk_num ==
3852 phys_disk_num) &&
3853 (port_info->phy_info[i].attached.id == id) &&
3854 (port_info->phy_info[i].attached.channel ==
3855 channel))
3856 phy_info = &port_info->phy_info[i];
3859 mutex_unlock(&ioc->sas_topology_mutex);
3860 return phy_info;
3863 static void
3864 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
3866 int rc;
3868 sdev->no_uld_attach = data ? 1 : 0;
3869 rc = scsi_device_reprobe(sdev);
3872 static void
3873 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
3875 starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
3876 mptsas_reprobe_lun);
3879 static void
3880 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
3882 CONFIGPARMS cfg;
3883 ConfigPageHeader_t hdr;
3884 dma_addr_t dma_handle;
3885 pRaidVolumePage0_t buffer = NULL;
3886 RaidPhysDiskPage0_t phys_disk;
3887 int i;
3888 struct mptsas_phyinfo *phy_info;
3889 struct mptsas_devinfo sas_device;
3891 memset(&cfg, 0 , sizeof(CONFIGPARMS));
3892 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
3893 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
3894 cfg.pageAddr = (channel << 8) + id;
3895 cfg.cfghdr.hdr = &hdr;
3896 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3898 if (mpt_config(ioc, &cfg) != 0)
3899 goto out;
3901 if (!hdr.PageLength)
3902 goto out;
3904 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
3905 &dma_handle);
3907 if (!buffer)
3908 goto out;
3910 cfg.physAddr = dma_handle;
3911 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3913 if (mpt_config(ioc, &cfg) != 0)
3914 goto out;
3916 if (!(buffer->VolumeStatus.Flags &
3917 MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
3918 goto out;
3920 if (!buffer->NumPhysDisks)
3921 goto out;
3923 for (i = 0; i < buffer->NumPhysDisks; i++) {
3925 if (mpt_raid_phys_disk_pg0(ioc,
3926 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
3927 continue;
3929 if (mptsas_sas_device_pg0(ioc, &sas_device,
3930 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
3931 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3932 (phys_disk.PhysDiskBus << 8) +
3933 phys_disk.PhysDiskID))
3934 continue;
3936 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3937 sas_device.sas_address);
3938 mptsas_add_end_device(ioc, phy_info);
3941 out:
3942 if (buffer)
3943 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
3944 dma_handle);
3947 * Work queue thread to handle SAS hotplug events
3949 static void
3950 mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
3951 struct mptsas_hotplug_event *hot_plug_info)
3953 struct mptsas_phyinfo *phy_info;
3954 struct scsi_target * starget;
3955 struct mptsas_devinfo sas_device;
3956 VirtTarget *vtarget;
3957 int i;
3959 switch (hot_plug_info->event_type) {
3961 case MPTSAS_ADD_PHYSDISK:
3963 if (!ioc->raid_data.pIocPg2)
3964 break;
3966 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
3967 if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID ==
3968 hot_plug_info->id) {
3969 printk(MYIOC_s_WARN_FMT "firmware bug: unable "
3970 "to add hidden disk - target_id matchs "
3971 "volume_id\n", ioc->name);
3972 mptsas_free_fw_event(ioc, fw_event);
3973 return;
3976 mpt_findImVolumes(ioc);
3978 case MPTSAS_ADD_DEVICE:
3979 memset(&sas_device, 0, sizeof(struct mptsas_devinfo));
3980 mptsas_sas_device_pg0(ioc, &sas_device,
3981 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
3982 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3983 (hot_plug_info->channel << 8) +
3984 hot_plug_info->id);
3986 if (!sas_device.handle)
3987 return;
3989 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3990 if (!phy_info)
3991 break;
3993 if (mptsas_get_rphy(phy_info))
3994 break;
3996 mptsas_add_end_device(ioc, phy_info);
3997 break;
3999 case MPTSAS_DEL_DEVICE:
4000 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4001 hot_plug_info->sas_address);
4002 mptsas_del_end_device(ioc, phy_info);
4003 break;
4005 case MPTSAS_DEL_PHYSDISK:
4007 mpt_findImVolumes(ioc);
4009 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
4010 ioc, hot_plug_info->phys_disk_num,
4011 hot_plug_info->channel,
4012 hot_plug_info->id);
4013 mptsas_del_end_device(ioc, phy_info);
4014 break;
4016 case MPTSAS_ADD_PHYSDISK_REPROBE:
4018 if (mptsas_sas_device_pg0(ioc, &sas_device,
4019 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4020 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4021 (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4022 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4023 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4024 __func__, hot_plug_info->id, __LINE__));
4025 break;
4028 phy_info = mptsas_find_phyinfo_by_sas_address(
4029 ioc, sas_device.sas_address);
4031 if (!phy_info) {
4032 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4033 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4034 __func__, hot_plug_info->id, __LINE__));
4035 break;
4038 starget = mptsas_get_starget(phy_info);
4039 if (!starget) {
4040 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4041 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4042 __func__, hot_plug_info->id, __LINE__));
4043 break;
4046 vtarget = starget->hostdata;
4047 if (!vtarget) {
4048 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4049 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4050 __func__, hot_plug_info->id, __LINE__));
4051 break;
4054 mpt_findImVolumes(ioc);
4056 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Hidding: "
4057 "fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4058 ioc->name, hot_plug_info->channel, hot_plug_info->id,
4059 hot_plug_info->phys_disk_num, (unsigned long long)
4060 sas_device.sas_address);
4062 vtarget->id = hot_plug_info->phys_disk_num;
4063 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
4064 phy_info->attached.phys_disk_num = hot_plug_info->phys_disk_num;
4065 mptsas_reprobe_target(starget, 1);
4066 break;
4068 case MPTSAS_DEL_PHYSDISK_REPROBE:
4070 if (mptsas_sas_device_pg0(ioc, &sas_device,
4071 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4072 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4073 (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4074 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4075 "%s: fw_id=%d exit at line=%d\n",
4076 ioc->name, __func__,
4077 hot_plug_info->id, __LINE__));
4078 break;
4081 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4082 sas_device.sas_address);
4083 if (!phy_info) {
4084 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4085 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4086 __func__, hot_plug_info->id, __LINE__));
4087 break;
4090 starget = mptsas_get_starget(phy_info);
4091 if (!starget) {
4092 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4093 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4094 __func__, hot_plug_info->id, __LINE__));
4095 break;
4098 vtarget = starget->hostdata;
4099 if (!vtarget) {
4100 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4101 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4102 __func__, hot_plug_info->id, __LINE__));
4103 break;
4106 if (!(vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)) {
4107 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4108 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4109 __func__, hot_plug_info->id, __LINE__));
4110 break;
4113 mpt_findImVolumes(ioc);
4115 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Exposing:"
4116 " fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4117 ioc->name, hot_plug_info->channel, hot_plug_info->id,
4118 hot_plug_info->phys_disk_num, (unsigned long long)
4119 sas_device.sas_address);
4121 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
4122 vtarget->id = hot_plug_info->id;
4123 phy_info->attached.phys_disk_num = ~0;
4124 mptsas_reprobe_target(starget, 0);
4125 mptsas_add_device_component_by_fw(ioc,
4126 hot_plug_info->channel, hot_plug_info->id);
4127 break;
4129 case MPTSAS_ADD_RAID:
4131 mpt_findImVolumes(ioc);
4132 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4133 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4134 hot_plug_info->id);
4135 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4136 hot_plug_info->id, 0);
4137 break;
4139 case MPTSAS_DEL_RAID:
4141 mpt_findImVolumes(ioc);
4142 printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4143 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4144 hot_plug_info->id);
4145 scsi_remove_device(hot_plug_info->sdev);
4146 scsi_device_put(hot_plug_info->sdev);
4147 break;
4149 case MPTSAS_ADD_INACTIVE_VOLUME:
4151 mpt_findImVolumes(ioc);
4152 mptsas_adding_inactive_raid_components(ioc,
4153 hot_plug_info->channel, hot_plug_info->id);
4154 break;
4156 default:
4157 break;
4160 mptsas_free_fw_event(ioc, fw_event);
4163 static void
4164 mptsas_send_sas_event(struct fw_event_work *fw_event)
4166 MPT_ADAPTER *ioc;
4167 struct mptsas_hotplug_event hot_plug_info;
4168 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
4169 u32 device_info;
4170 u64 sas_address;
4172 ioc = fw_event->ioc;
4173 sas_event_data = (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
4174 fw_event->event_data;
4175 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
4177 if ((device_info &
4178 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
4179 MPI_SAS_DEVICE_INFO_STP_TARGET |
4180 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0) {
4181 mptsas_free_fw_event(ioc, fw_event);
4182 return;
4185 if (sas_event_data->ReasonCode ==
4186 MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED) {
4187 mptbase_sas_persist_operation(ioc,
4188 MPI_SAS_OP_CLEAR_NOT_PRESENT);
4189 mptsas_free_fw_event(ioc, fw_event);
4190 return;
4193 switch (sas_event_data->ReasonCode) {
4194 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
4195 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
4196 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4197 hot_plug_info.handle = le16_to_cpu(sas_event_data->DevHandle);
4198 hot_plug_info.channel = sas_event_data->Bus;
4199 hot_plug_info.id = sas_event_data->TargetID;
4200 hot_plug_info.phy_id = sas_event_data->PhyNum;
4201 memcpy(&sas_address, &sas_event_data->SASAddress,
4202 sizeof(u64));
4203 hot_plug_info.sas_address = le64_to_cpu(sas_address);
4204 hot_plug_info.device_info = device_info;
4205 if (sas_event_data->ReasonCode &
4206 MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
4207 hot_plug_info.event_type = MPTSAS_ADD_DEVICE;
4208 else
4209 hot_plug_info.event_type = MPTSAS_DEL_DEVICE;
4210 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4211 break;
4213 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
4214 mptbase_sas_persist_operation(ioc,
4215 MPI_SAS_OP_CLEAR_NOT_PRESENT);
4216 mptsas_free_fw_event(ioc, fw_event);
4217 break;
4219 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
4220 /* TODO */
4221 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
4222 /* TODO */
4223 default:
4224 mptsas_free_fw_event(ioc, fw_event);
4225 break;
4229 static void
4230 mptsas_send_raid_event(struct fw_event_work *fw_event)
4232 MPT_ADAPTER *ioc;
4233 EVENT_DATA_RAID *raid_event_data;
4234 struct mptsas_hotplug_event hot_plug_info;
4235 int status;
4236 int state;
4237 struct scsi_device *sdev = NULL;
4238 VirtDevice *vdevice = NULL;
4239 RaidPhysDiskPage0_t phys_disk;
4241 ioc = fw_event->ioc;
4242 raid_event_data = (EVENT_DATA_RAID *)fw_event->event_data;
4243 status = le32_to_cpu(raid_event_data->SettingsStatus);
4244 state = (status >> 8) & 0xff;
4246 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4247 hot_plug_info.id = raid_event_data->VolumeID;
4248 hot_plug_info.channel = raid_event_data->VolumeBus;
4249 hot_plug_info.phys_disk_num = raid_event_data->PhysDiskNum;
4251 if (raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_DELETED ||
4252 raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_CREATED ||
4253 raid_event_data->ReasonCode ==
4254 MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED) {
4255 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
4256 hot_plug_info.id, 0);
4257 hot_plug_info.sdev = sdev;
4258 if (sdev)
4259 vdevice = sdev->hostdata;
4262 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4263 "ReasonCode=%02x\n", ioc->name, __func__,
4264 raid_event_data->ReasonCode));
4266 switch (raid_event_data->ReasonCode) {
4267 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4268 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK_REPROBE;
4269 break;
4270 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4271 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK_REPROBE;
4272 break;
4273 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4274 switch (state) {
4275 case MPI_PD_STATE_ONLINE:
4276 case MPI_PD_STATE_NOT_COMPATIBLE:
4277 mpt_raid_phys_disk_pg0(ioc,
4278 raid_event_data->PhysDiskNum, &phys_disk);
4279 hot_plug_info.id = phys_disk.PhysDiskID;
4280 hot_plug_info.channel = phys_disk.PhysDiskBus;
4281 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4282 break;
4283 case MPI_PD_STATE_FAILED:
4284 case MPI_PD_STATE_MISSING:
4285 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
4286 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
4287 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
4288 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4289 break;
4290 default:
4291 break;
4293 break;
4294 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4295 if (!sdev)
4296 break;
4297 vdevice->vtarget->deleted = 1; /* block IO */
4298 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4299 break;
4300 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4301 if (sdev) {
4302 scsi_device_put(sdev);
4303 break;
4305 hot_plug_info.event_type = MPTSAS_ADD_RAID;
4306 break;
4307 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4308 if (!(status & MPI_RAIDVOL0_STATUS_FLAG_ENABLED)) {
4309 if (!sdev)
4310 break;
4311 vdevice->vtarget->deleted = 1; /* block IO */
4312 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4313 break;
4315 switch (state) {
4316 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
4317 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
4318 if (!sdev)
4319 break;
4320 vdevice->vtarget->deleted = 1; /* block IO */
4321 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4322 break;
4323 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
4324 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
4325 if (sdev) {
4326 scsi_device_put(sdev);
4327 break;
4329 hot_plug_info.event_type = MPTSAS_ADD_RAID;
4330 break;
4331 default:
4332 break;
4334 break;
4335 default:
4336 break;
4339 if (hot_plug_info.event_type != MPTSAS_IGNORE_EVENT)
4340 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4341 else
4342 mptsas_free_fw_event(ioc, fw_event);
4346 * mptsas_issue_tm - send mptsas internal tm request
4347 * @ioc: Pointer to MPT_ADAPTER structure
4348 * @type: Task Management type
4349 * @channel: channel number for task management
4350 * @id: Logical Target ID for reset (if appropriate)
4351 * @lun: Logical unit for reset (if appropriate)
4352 * @task_context: Context for the task to be aborted
4353 * @timeout: timeout for task management control
4355 * return 0 on success and -1 on failure:
4358 static int
4359 mptsas_issue_tm(MPT_ADAPTER *ioc, u8 type, u8 channel, u8 id, u64 lun,
4360 int task_context, ulong timeout, u8 *issue_reset)
4362 MPT_FRAME_HDR *mf;
4363 SCSITaskMgmt_t *pScsiTm;
4364 int retval;
4365 unsigned long timeleft;
4367 *issue_reset = 0;
4368 mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
4369 if (mf == NULL) {
4370 retval = -1; /* return failure */
4371 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "TaskMgmt request: no "
4372 "msg frames!!\n", ioc->name));
4373 goto out;
4376 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request: mr = %p, "
4377 "task_type = 0x%02X,\n\t timeout = %ld, fw_channel = %d, "
4378 "fw_id = %d, lun = %lld,\n\t task_context = 0x%x\n", ioc->name, mf,
4379 type, timeout, channel, id, (unsigned long long)lun,
4380 task_context));
4382 pScsiTm = (SCSITaskMgmt_t *) mf;
4383 memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
4384 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
4385 pScsiTm->TaskType = type;
4386 pScsiTm->MsgFlags = 0;
4387 pScsiTm->TargetID = id;
4388 pScsiTm->Bus = channel;
4389 pScsiTm->ChainOffset = 0;
4390 pScsiTm->Reserved = 0;
4391 pScsiTm->Reserved1 = 0;
4392 pScsiTm->TaskMsgContext = task_context;
4393 int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
4395 INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4396 CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
4397 retval = 0;
4398 mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
4400 /* Now wait for the command to complete */
4401 timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
4402 timeout*HZ);
4403 if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
4404 retval = -1; /* return failure */
4405 dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
4406 "TaskMgmt request: TIMED OUT!(mr=%p)\n", ioc->name, mf));
4407 mpt_free_msg_frame(ioc, mf);
4408 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
4409 goto out;
4410 *issue_reset = 1;
4411 goto out;
4414 if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
4415 retval = -1; /* return failure */
4416 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4417 "TaskMgmt request: failed with no reply\n", ioc->name));
4418 goto out;
4421 out:
4422 CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4423 return retval;
4427 * mptsas_broadcast_primative_work - Handle broadcast primitives
4428 * @work: work queue payload containing info describing the event
4430 * this will be handled in workqueue context.
4432 static void
4433 mptsas_broadcast_primative_work(struct fw_event_work *fw_event)
4435 MPT_ADAPTER *ioc = fw_event->ioc;
4436 MPT_FRAME_HDR *mf;
4437 VirtDevice *vdevice;
4438 int ii;
4439 struct scsi_cmnd *sc;
4440 SCSITaskMgmtReply_t *pScsiTmReply;
4441 u8 issue_reset;
4442 int task_context;
4443 u8 channel, id;
4444 int lun;
4445 u32 termination_count;
4446 u32 query_count;
4448 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4449 "%s - enter\n", ioc->name, __func__));
4451 mutex_lock(&ioc->taskmgmt_cmds.mutex);
4452 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
4453 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4454 mptsas_requeue_fw_event(ioc, fw_event, 1000);
4455 return;
4458 issue_reset = 0;
4459 termination_count = 0;
4460 query_count = 0;
4461 mpt_findImVolumes(ioc);
4462 pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
4464 for (ii = 0; ii < ioc->req_depth; ii++) {
4465 if (ioc->fw_events_off)
4466 goto out;
4467 sc = mptscsih_get_scsi_lookup(ioc, ii);
4468 if (!sc)
4469 continue;
4470 mf = MPT_INDEX_2_MFPTR(ioc, ii);
4471 if (!mf)
4472 continue;
4473 task_context = mf->u.frame.hwhdr.msgctxu.MsgContext;
4474 vdevice = sc->device->hostdata;
4475 if (!vdevice || !vdevice->vtarget)
4476 continue;
4477 if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
4478 continue; /* skip hidden raid components */
4479 if (vdevice->vtarget->raidVolume)
4480 continue; /* skip hidden raid components */
4481 channel = vdevice->vtarget->channel;
4482 id = vdevice->vtarget->id;
4483 lun = vdevice->lun;
4484 if (mptsas_issue_tm(ioc, MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK,
4485 channel, id, (u64)lun, task_context, 30, &issue_reset))
4486 goto out;
4487 query_count++;
4488 termination_count +=
4489 le32_to_cpu(pScsiTmReply->TerminationCount);
4490 if ((pScsiTmReply->IOCStatus == MPI_IOCSTATUS_SUCCESS) &&
4491 (pScsiTmReply->ResponseCode ==
4492 MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
4493 pScsiTmReply->ResponseCode ==
4494 MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
4495 continue;
4496 if (mptsas_issue_tm(ioc,
4497 MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET,
4498 channel, id, (u64)lun, 0, 30, &issue_reset))
4499 goto out;
4500 termination_count +=
4501 le32_to_cpu(pScsiTmReply->TerminationCount);
4504 out:
4505 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4506 "%s - exit, query_count = %d termination_count = %d\n",
4507 ioc->name, __func__, query_count, termination_count));
4509 ioc->broadcast_aen_busy = 0;
4510 mpt_clear_taskmgmt_in_progress_flag(ioc);
4511 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4513 if (issue_reset) {
4514 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
4515 ioc->name, __func__);
4516 mpt_HardResetHandler(ioc, CAN_SLEEP);
4518 mptsas_free_fw_event(ioc, fw_event);
4522 * mptsas_send_ir2_event - handle exposing hidden disk when
4523 * an inactive raid volume is added
4525 * @ioc: Pointer to MPT_ADAPTER structure
4526 * @ir2_data
4529 static void
4530 mptsas_send_ir2_event(struct fw_event_work *fw_event)
4532 MPT_ADAPTER *ioc;
4533 struct mptsas_hotplug_event hot_plug_info;
4534 MPI_EVENT_DATA_IR2 *ir2_data;
4535 u8 reasonCode;
4536 RaidPhysDiskPage0_t phys_disk;
4538 ioc = fw_event->ioc;
4539 ir2_data = (MPI_EVENT_DATA_IR2 *)fw_event->event_data;
4540 reasonCode = ir2_data->ReasonCode;
4542 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4543 "ReasonCode=%02x\n", ioc->name, __func__, reasonCode));
4545 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4546 hot_plug_info.id = ir2_data->TargetID;
4547 hot_plug_info.channel = ir2_data->Bus;
4548 switch (reasonCode) {
4549 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
4550 hot_plug_info.event_type = MPTSAS_ADD_INACTIVE_VOLUME;
4551 break;
4552 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
4553 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4554 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4555 break;
4556 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
4557 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4558 mpt_raid_phys_disk_pg0(ioc,
4559 ir2_data->PhysDiskNum, &phys_disk);
4560 hot_plug_info.id = phys_disk.PhysDiskID;
4561 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4562 break;
4563 default:
4564 mptsas_free_fw_event(ioc, fw_event);
4565 return;
4567 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4570 static int
4571 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
4573 u32 event = le32_to_cpu(reply->Event);
4574 int sz, event_data_sz;
4575 struct fw_event_work *fw_event;
4576 unsigned long delay;
4578 /* events turned off due to host reset or driver unloading */
4579 if (ioc->fw_events_off)
4580 return 0;
4582 delay = msecs_to_jiffies(1);
4583 switch (event) {
4584 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
4586 EVENT_DATA_SAS_BROADCAST_PRIMITIVE *broadcast_event_data =
4587 (EVENT_DATA_SAS_BROADCAST_PRIMITIVE *)reply->Data;
4588 if (broadcast_event_data->Primitive !=
4589 MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
4590 return 0;
4591 if (ioc->broadcast_aen_busy)
4592 return 0;
4593 ioc->broadcast_aen_busy = 1;
4594 break;
4596 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
4598 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data =
4599 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data;
4601 if (sas_event_data->ReasonCode ==
4602 MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) {
4603 mptsas_target_reset_queue(ioc, sas_event_data);
4604 return 0;
4606 break;
4608 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
4610 MpiEventDataSasExpanderStatusChange_t *expander_data =
4611 (MpiEventDataSasExpanderStatusChange_t *)reply->Data;
4613 if (ioc->old_sas_discovery_protocal)
4614 return 0;
4616 if (expander_data->ReasonCode ==
4617 MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING &&
4618 ioc->device_missing_delay)
4619 delay = HZ * ioc->device_missing_delay;
4620 break;
4622 case MPI_EVENT_SAS_DISCOVERY:
4624 u32 discovery_status;
4625 EventDataSasDiscovery_t *discovery_data =
4626 (EventDataSasDiscovery_t *)reply->Data;
4628 discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus);
4629 ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0;
4630 if (ioc->old_sas_discovery_protocal && !discovery_status)
4631 mptsas_queue_rescan(ioc);
4632 return 0;
4634 case MPI_EVENT_INTEGRATED_RAID:
4635 case MPI_EVENT_PERSISTENT_TABLE_FULL:
4636 case MPI_EVENT_IR2:
4637 case MPI_EVENT_SAS_PHY_LINK_STATUS:
4638 case MPI_EVENT_QUEUE_FULL:
4639 break;
4640 default:
4641 return 0;
4644 event_data_sz = ((reply->MsgLength * 4) -
4645 offsetof(EventNotificationReply_t, Data));
4646 sz = offsetof(struct fw_event_work, event_data) + event_data_sz;
4647 fw_event = kzalloc(sz, GFP_ATOMIC);
4648 if (!fw_event) {
4649 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name,
4650 __func__, __LINE__);
4651 return 0;
4653 memcpy(fw_event->event_data, reply->Data, event_data_sz);
4654 fw_event->event = event;
4655 fw_event->ioc = ioc;
4656 mptsas_add_fw_event(ioc, fw_event, delay);
4657 return 0;
4660 /* Delete a volume when no longer listed in ioc pg2
4662 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id)
4664 struct scsi_device *sdev;
4665 int i;
4667 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, id, 0);
4668 if (!sdev)
4669 return;
4670 if (!ioc->raid_data.pIocPg2)
4671 goto out;
4672 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
4673 goto out;
4674 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
4675 if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id)
4676 goto release_sdev;
4677 out:
4678 printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4679 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL, id);
4680 scsi_remove_device(sdev);
4681 release_sdev:
4682 scsi_device_put(sdev);
4685 static int
4686 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
4688 struct Scsi_Host *sh;
4689 MPT_SCSI_HOST *hd;
4690 MPT_ADAPTER *ioc;
4691 unsigned long flags;
4692 int ii;
4693 int numSGE = 0;
4694 int scale;
4695 int ioc_cap;
4696 int error=0;
4697 int r;
4699 r = mpt_attach(pdev,id);
4700 if (r)
4701 return r;
4703 ioc = pci_get_drvdata(pdev);
4704 mptsas_fw_event_off(ioc);
4705 ioc->DoneCtx = mptsasDoneCtx;
4706 ioc->TaskCtx = mptsasTaskCtx;
4707 ioc->InternalCtx = mptsasInternalCtx;
4709 /* Added sanity check on readiness of the MPT adapter.
4711 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
4712 printk(MYIOC_s_WARN_FMT
4713 "Skipping because it's not operational!\n",
4714 ioc->name);
4715 error = -ENODEV;
4716 goto out_mptsas_probe;
4719 if (!ioc->active) {
4720 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
4721 ioc->name);
4722 error = -ENODEV;
4723 goto out_mptsas_probe;
4726 /* Sanity check - ensure at least 1 port is INITIATOR capable
4728 ioc_cap = 0;
4729 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
4730 if (ioc->pfacts[ii].ProtocolFlags &
4731 MPI_PORTFACTS_PROTOCOL_INITIATOR)
4732 ioc_cap++;
4735 if (!ioc_cap) {
4736 printk(MYIOC_s_WARN_FMT
4737 "Skipping ioc=%p because SCSI Initiator mode "
4738 "is NOT enabled!\n", ioc->name, ioc);
4739 return 0;
4742 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
4743 if (!sh) {
4744 printk(MYIOC_s_WARN_FMT
4745 "Unable to register controller with SCSI subsystem\n",
4746 ioc->name);
4747 error = -1;
4748 goto out_mptsas_probe;
4751 spin_lock_irqsave(&ioc->FreeQlock, flags);
4753 /* Attach the SCSI Host to the IOC structure
4755 ioc->sh = sh;
4757 sh->io_port = 0;
4758 sh->n_io_port = 0;
4759 sh->irq = 0;
4761 /* set 16 byte cdb's */
4762 sh->max_cmd_len = 16;
4764 sh->max_id = ioc->pfacts[0].PortSCSIID;
4765 sh->max_lun = max_lun;
4767 sh->transportt = mptsas_transport_template;
4769 /* Required entry.
4771 sh->unique_id = ioc->id;
4773 INIT_LIST_HEAD(&ioc->sas_topology);
4774 mutex_init(&ioc->sas_topology_mutex);
4775 mutex_init(&ioc->sas_discovery_mutex);
4776 mutex_init(&ioc->sas_mgmt.mutex);
4777 init_completion(&ioc->sas_mgmt.done);
4779 /* Verify that we won't exceed the maximum
4780 * number of chain buffers
4781 * We can optimize: ZZ = req_sz/sizeof(SGE)
4782 * For 32bit SGE's:
4783 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
4784 * + (req_sz - 64)/sizeof(SGE)
4785 * A slightly different algorithm is required for
4786 * 64bit SGEs.
4788 scale = ioc->req_sz/ioc->SGE_size;
4789 if (ioc->sg_addr_size == sizeof(u64)) {
4790 numSGE = (scale - 1) *
4791 (ioc->facts.MaxChainDepth-1) + scale +
4792 (ioc->req_sz - 60) / ioc->SGE_size;
4793 } else {
4794 numSGE = 1 + (scale - 1) *
4795 (ioc->facts.MaxChainDepth-1) + scale +
4796 (ioc->req_sz - 64) / ioc->SGE_size;
4799 if (numSGE < sh->sg_tablesize) {
4800 /* Reset this value */
4801 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4802 "Resetting sg_tablesize to %d from %d\n",
4803 ioc->name, numSGE, sh->sg_tablesize));
4804 sh->sg_tablesize = numSGE;
4807 hd = shost_priv(sh);
4808 hd->ioc = ioc;
4810 /* SCSI needs scsi_cmnd lookup table!
4811 * (with size equal to req_depth*PtrSz!)
4813 ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
4814 if (!ioc->ScsiLookup) {
4815 error = -ENOMEM;
4816 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4817 goto out_mptsas_probe;
4819 spin_lock_init(&ioc->scsi_lookup_lock);
4821 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
4822 ioc->name, ioc->ScsiLookup));
4824 /* Clear the TM flags
4826 hd->abortSCpnt = NULL;
4828 /* Clear the pointer used to store
4829 * single-threaded commands, i.e., those
4830 * issued during a bus scan, dv and
4831 * configuration pages.
4833 hd->cmdPtr = NULL;
4835 /* Initialize this SCSI Hosts' timers
4836 * To use, set the timer expires field
4837 * and add_timer
4839 init_timer(&hd->timer);
4840 hd->timer.data = (unsigned long) hd;
4841 hd->timer.function = mptscsih_timer_expired;
4843 ioc->sas_data.ptClear = mpt_pt_clear;
4845 hd->last_queue_full = 0;
4846 INIT_LIST_HEAD(&hd->target_reset_list);
4847 INIT_LIST_HEAD(&ioc->sas_device_info_list);
4848 mutex_init(&ioc->sas_device_info_mutex);
4850 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4852 if (ioc->sas_data.ptClear==1) {
4853 mptbase_sas_persist_operation(
4854 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
4857 error = scsi_add_host(sh, &ioc->pcidev->dev);
4858 if (error) {
4859 dprintk(ioc, printk(MYIOC_s_ERR_FMT
4860 "scsi_add_host failed\n", ioc->name));
4861 goto out_mptsas_probe;
4864 /* older firmware doesn't support expander events */
4865 if ((ioc->facts.HeaderVersion >> 8) < 0xE)
4866 ioc->old_sas_discovery_protocal = 1;
4867 mptsas_scan_sas_topology(ioc);
4868 mptsas_fw_event_on(ioc);
4869 return 0;
4871 out_mptsas_probe:
4873 mptscsih_remove(pdev);
4874 return error;
4877 void
4878 mptsas_shutdown(struct pci_dev *pdev)
4880 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
4882 mptsas_fw_event_off(ioc);
4883 mptsas_cleanup_fw_event_q(ioc);
4886 static void __devexit mptsas_remove(struct pci_dev *pdev)
4888 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
4889 struct mptsas_portinfo *p, *n;
4890 int i;
4892 mptsas_shutdown(pdev);
4894 mptsas_del_device_components(ioc);
4896 ioc->sas_discovery_ignore_events = 1;
4897 sas_remove_host(ioc->sh);
4899 mutex_lock(&ioc->sas_topology_mutex);
4900 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
4901 list_del(&p->list);
4902 for (i = 0 ; i < p->num_phys ; i++)
4903 mptsas_port_delete(ioc, p->phy_info[i].port_details);
4905 kfree(p->phy_info);
4906 kfree(p);
4908 mutex_unlock(&ioc->sas_topology_mutex);
4909 ioc->hba_port_info = NULL;
4910 mptscsih_remove(pdev);
4913 static struct pci_device_id mptsas_pci_table[] = {
4914 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
4915 PCI_ANY_ID, PCI_ANY_ID },
4916 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
4917 PCI_ANY_ID, PCI_ANY_ID },
4918 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
4919 PCI_ANY_ID, PCI_ANY_ID },
4920 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
4921 PCI_ANY_ID, PCI_ANY_ID },
4922 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
4923 PCI_ANY_ID, PCI_ANY_ID },
4924 {0} /* Terminating entry */
4926 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
4929 static struct pci_driver mptsas_driver = {
4930 .name = "mptsas",
4931 .id_table = mptsas_pci_table,
4932 .probe = mptsas_probe,
4933 .remove = __devexit_p(mptsas_remove),
4934 .shutdown = mptsas_shutdown,
4935 #ifdef CONFIG_PM
4936 .suspend = mptscsih_suspend,
4937 .resume = mptscsih_resume,
4938 #endif
4941 static int __init
4942 mptsas_init(void)
4944 int error;
4946 show_mptmod_ver(my_NAME, my_VERSION);
4948 mptsas_transport_template =
4949 sas_attach_transport(&mptsas_transport_functions);
4950 if (!mptsas_transport_template)
4951 return -ENODEV;
4953 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
4954 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
4955 mptsasInternalCtx =
4956 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
4957 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
4958 mptsasDeviceResetCtx =
4959 mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
4961 mpt_event_register(mptsasDoneCtx, mptsas_event_process);
4962 mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
4964 error = pci_register_driver(&mptsas_driver);
4965 if (error)
4966 sas_release_transport(mptsas_transport_template);
4968 return error;
4971 static void __exit
4972 mptsas_exit(void)
4974 pci_unregister_driver(&mptsas_driver);
4975 sas_release_transport(mptsas_transport_template);
4977 mpt_reset_deregister(mptsasDoneCtx);
4978 mpt_event_deregister(mptsasDoneCtx);
4980 mpt_deregister(mptsasMgmtCtx);
4981 mpt_deregister(mptsasInternalCtx);
4982 mpt_deregister(mptsasTaskCtx);
4983 mpt_deregister(mptsasDoneCtx);
4984 mpt_deregister(mptsasDeviceResetCtx);
4987 module_init(mptsas_init);
4988 module_exit(mptsas_exit);