[SCSI] mpt fusion: Firmware event implementation using seperate WorkQueue
[linux-2.6/kvm.git] / drivers / message / fusion / mptsas.c
blob22a027ec9e5d927f7267487850a6fc905015f07d
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);
117 static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
118 MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
120 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
121 "---- IO UNIT PAGE 0 ------------\n", ioc->name));
122 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
123 ioc->name, le16_to_cpu(phy_data->AttachedDeviceHandle)));
124 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Controller Handle=0x%X\n",
125 ioc->name, le16_to_cpu(phy_data->ControllerDevHandle)));
126 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port=0x%X\n",
127 ioc->name, phy_data->Port));
128 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port Flags=0x%X\n",
129 ioc->name, phy_data->PortFlags));
130 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Flags=0x%X\n",
131 ioc->name, phy_data->PhyFlags));
132 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
133 ioc->name, phy_data->NegotiatedLinkRate));
134 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
135 "Controller PHY Device Info=0x%X\n", ioc->name,
136 le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
137 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DiscoveryStatus=0x%X\n\n",
138 ioc->name, le32_to_cpu(phy_data->DiscoveryStatus)));
141 static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
143 __le64 sas_address;
145 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
147 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
148 "---- SAS PHY PAGE 0 ------------\n", ioc->name));
149 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
150 "Attached Device Handle=0x%X\n", ioc->name,
151 le16_to_cpu(pg0->AttachedDevHandle)));
152 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
153 ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
154 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
155 "Attached PHY Identifier=0x%X\n", ioc->name,
156 pg0->AttachedPhyIdentifier));
157 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Attached Device Info=0x%X\n",
158 ioc->name, le32_to_cpu(pg0->AttachedDeviceInfo)));
159 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
160 ioc->name, pg0->ProgrammedLinkRate));
161 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Change Count=0x%X\n",
162 ioc->name, pg0->ChangeCount));
163 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Info=0x%X\n\n",
164 ioc->name, le32_to_cpu(pg0->PhyInfo)));
167 static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
169 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
170 "---- SAS PHY PAGE 1 ------------\n", ioc->name));
171 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Invalid Dword Count=0x%x\n",
172 ioc->name, pg1->InvalidDwordCount));
173 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
174 "Running Disparity Error Count=0x%x\n", ioc->name,
175 pg1->RunningDisparityErrorCount));
176 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
177 "Loss Dword Synch Count=0x%x\n", ioc->name,
178 pg1->LossDwordSynchCount));
179 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
180 "PHY Reset Problem Count=0x%x\n\n", ioc->name,
181 pg1->PhyResetProblemCount));
184 static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
186 __le64 sas_address;
188 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
190 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
191 "---- SAS DEVICE PAGE 0 ---------\n", ioc->name));
192 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
193 ioc->name, le16_to_cpu(pg0->DevHandle)));
194 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Handle=0x%X\n",
195 ioc->name, le16_to_cpu(pg0->ParentDevHandle)));
196 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Enclosure Handle=0x%X\n",
197 ioc->name, le16_to_cpu(pg0->EnclosureHandle)));
198 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Slot=0x%X\n",
199 ioc->name, le16_to_cpu(pg0->Slot)));
200 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
201 ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
202 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Target ID=0x%X\n",
203 ioc->name, pg0->TargetID));
204 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Bus=0x%X\n",
205 ioc->name, pg0->Bus));
206 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Phy Num=0x%X\n",
207 ioc->name, pg0->PhyNum));
208 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Access Status=0x%X\n",
209 ioc->name, le16_to_cpu(pg0->AccessStatus)));
210 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Device Info=0x%X\n",
211 ioc->name, le32_to_cpu(pg0->DeviceInfo)));
212 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Flags=0x%X\n",
213 ioc->name, le16_to_cpu(pg0->Flags)));
214 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n\n",
215 ioc->name, pg0->PhysicalPort));
218 static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
220 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
221 "---- SAS EXPANDER PAGE 1 ------------\n", ioc->name));
222 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n",
223 ioc->name, pg1->PhysicalPort));
224 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Identifier=0x%X\n",
225 ioc->name, pg1->PhyIdentifier));
226 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
227 ioc->name, pg1->NegotiatedLinkRate));
228 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
229 ioc->name, pg1->ProgrammedLinkRate));
230 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hardware Link Rate=0x%X\n",
231 ioc->name, pg1->HwLinkRate));
232 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Owner Device Handle=0x%X\n",
233 ioc->name, le16_to_cpu(pg1->OwnerDevHandle)));
234 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
235 "Attached Device Handle=0x%X\n\n", ioc->name,
236 le16_to_cpu(pg1->AttachedDevHandle)));
239 /* inhibit sas firmware event handling */
240 static void
241 mptsas_fw_event_off(MPT_ADAPTER *ioc)
243 unsigned long flags;
245 spin_lock_irqsave(&ioc->fw_event_lock, flags);
246 ioc->fw_events_off = 1;
247 ioc->sas_discovery_quiesce_io = 0;
248 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
252 /* enable sas firmware event handling */
253 static void
254 mptsas_fw_event_on(MPT_ADAPTER *ioc)
256 unsigned long flags;
258 spin_lock_irqsave(&ioc->fw_event_lock, flags);
259 ioc->fw_events_off = 0;
260 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
263 /* queue a sas firmware event */
264 static void
265 mptsas_add_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
266 unsigned long delay)
268 unsigned long flags;
270 spin_lock_irqsave(&ioc->fw_event_lock, flags);
271 list_add_tail(&fw_event->list, &ioc->fw_event_list);
272 INIT_DELAYED_WORK(&fw_event->work, mptsas_firmware_event_work);
273 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: add (fw_event=0x%p)\n",
274 ioc->name, __func__, fw_event));
275 queue_delayed_work(ioc->fw_event_q, &fw_event->work,
276 delay);
277 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
280 /* free memory assoicated to a sas firmware event */
281 static void
282 mptsas_free_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event)
284 unsigned long flags;
286 spin_lock_irqsave(&ioc->fw_event_lock, flags);
287 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: kfree (fw_event=0x%p)\n",
288 ioc->name, __func__, fw_event));
289 list_del(&fw_event->list);
290 kfree(fw_event);
291 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
294 /* walk the firmware event queue, and either stop or wait for
295 * outstanding events to complete */
296 static void
297 mptsas_cleanup_fw_event_q(MPT_ADAPTER *ioc)
299 struct fw_event_work *fw_event, *next;
300 struct mptsas_target_reset_event *target_reset_list, *n;
301 u8 flush_q;
302 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
304 /* flush the target_reset_list */
305 if (!list_empty(&hd->target_reset_list)) {
306 list_for_each_entry_safe(target_reset_list, n,
307 &hd->target_reset_list, list) {
308 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
309 "%s: removing target reset for id=%d\n",
310 ioc->name, __func__,
311 target_reset_list->sas_event_data.TargetID));
312 list_del(&target_reset_list->list);
313 kfree(target_reset_list);
317 if (list_empty(&ioc->fw_event_list) ||
318 !ioc->fw_event_q || in_interrupt())
319 return;
321 flush_q = 0;
322 list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) {
323 if (cancel_delayed_work(&fw_event->work))
324 mptsas_free_fw_event(ioc, fw_event);
325 else
326 flush_q = 1;
328 if (flush_q)
329 flush_workqueue(ioc->fw_event_q);
333 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
335 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
336 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
339 static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
341 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
342 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
345 static struct mptsas_portinfo *
346 mptsas_get_hba_portinfo(MPT_ADAPTER *ioc)
348 struct list_head *head = &ioc->sas_topology;
349 struct mptsas_portinfo *pi = NULL;
351 /* always the first entry on sas_topology list */
353 if (!list_empty(head))
354 pi = list_entry(head->next, struct mptsas_portinfo, list);
356 return pi;
360 * mptsas_find_portinfo_by_handle
362 * This function should be called with the sas_topology_mutex already held
364 static struct mptsas_portinfo *
365 mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
367 struct mptsas_portinfo *port_info, *rc=NULL;
368 int i;
370 list_for_each_entry(port_info, &ioc->sas_topology, list)
371 for (i = 0; i < port_info->num_phys; i++)
372 if (port_info->phy_info[i].identify.handle == handle) {
373 rc = port_info;
374 goto out;
376 out:
377 return rc;
381 * Returns true if there is a scsi end device
383 static inline int
384 mptsas_is_end_device(struct mptsas_devinfo * attached)
386 if ((attached->sas_address) &&
387 (attached->device_info &
388 MPI_SAS_DEVICE_INFO_END_DEVICE) &&
389 ((attached->device_info &
390 MPI_SAS_DEVICE_INFO_SSP_TARGET) |
391 (attached->device_info &
392 MPI_SAS_DEVICE_INFO_STP_TARGET) |
393 (attached->device_info &
394 MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
395 return 1;
396 else
397 return 0;
400 /* no mutex */
401 static void
402 mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
404 struct mptsas_portinfo *port_info;
405 struct mptsas_phyinfo *phy_info;
406 u8 i;
408 if (!port_details)
409 return;
411 port_info = port_details->port_info;
412 phy_info = port_info->phy_info;
414 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d "
415 "bitmask=0x%016llX\n", ioc->name, __func__, port_details,
416 port_details->num_phys, (unsigned long long)
417 port_details->phy_bitmask));
419 for (i = 0; i < port_info->num_phys; i++, phy_info++) {
420 if(phy_info->port_details != port_details)
421 continue;
422 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
423 mptsas_set_rphy(ioc, phy_info, NULL);
424 phy_info->port_details = NULL;
426 kfree(port_details);
429 static inline struct sas_rphy *
430 mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
432 if (phy_info->port_details)
433 return phy_info->port_details->rphy;
434 else
435 return NULL;
438 static inline void
439 mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
441 if (phy_info->port_details) {
442 phy_info->port_details->rphy = rphy;
443 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
444 ioc->name, rphy));
447 if (rphy) {
448 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
449 &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
450 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
451 ioc->name, rphy, rphy->dev.release));
455 static inline struct sas_port *
456 mptsas_get_port(struct mptsas_phyinfo *phy_info)
458 if (phy_info->port_details)
459 return phy_info->port_details->port;
460 else
461 return NULL;
464 static inline void
465 mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_port *port)
467 if (phy_info->port_details)
468 phy_info->port_details->port = port;
470 if (port) {
471 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
472 &port->dev, MYIOC_s_FMT "add:", ioc->name));
473 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "port=%p release=%p\n",
474 ioc->name, port, port->dev.release));
478 static inline struct scsi_target *
479 mptsas_get_starget(struct mptsas_phyinfo *phy_info)
481 if (phy_info->port_details)
482 return phy_info->port_details->starget;
483 else
484 return NULL;
487 static inline void
488 mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
489 starget)
491 if (phy_info->port_details)
492 phy_info->port_details->starget = starget;
496 * mptsas_add_device_component -
497 * @ioc: Pointer to MPT_ADAPTER structure
498 * @channel: fw mapped id's
499 * @id:
500 * @sas_address:
501 * @device_info:
504 static void
505 mptsas_add_device_component(MPT_ADAPTER *ioc, u8 channel, u8 id,
506 u64 sas_address, u32 device_info, u16 slot, u64 enclosure_logical_id)
508 struct mptsas_device_info *sas_info, *next;
509 struct scsi_device *sdev;
510 struct scsi_target *starget;
511 struct sas_rphy *rphy;
514 * Delete all matching devices out of the list
516 mutex_lock(&ioc->sas_device_info_mutex);
517 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
518 list) {
519 if ((sas_info->sas_address == sas_address ||
520 (sas_info->fw.channel == channel &&
521 sas_info->fw.id == id))) {
522 list_del(&sas_info->list);
523 kfree(sas_info);
527 sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
528 if (!sas_info)
529 goto out;
532 * Set Firmware mapping
534 sas_info->fw.id = id;
535 sas_info->fw.channel = channel;
537 sas_info->sas_address = sas_address;
538 sas_info->device_info = device_info;
539 sas_info->slot = slot;
540 sas_info->enclosure_logical_id = enclosure_logical_id;
541 INIT_LIST_HEAD(&sas_info->list);
542 list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
545 * Set OS mapping
547 shost_for_each_device(sdev, ioc->sh) {
548 starget = scsi_target(sdev);
549 rphy = dev_to_rphy(starget->dev.parent);
550 if (rphy->identify.sas_address == sas_address) {
551 sas_info->os.id = starget->id;
552 sas_info->os.channel = starget->channel;
556 out:
557 mutex_unlock(&ioc->sas_device_info_mutex);
558 return;
562 * mptsas_add_device_component_by_fw -
563 * @ioc: Pointer to MPT_ADAPTER structure
564 * @channel: fw mapped id's
565 * @id:
568 static void
569 mptsas_add_device_component_by_fw(MPT_ADAPTER *ioc, u8 channel, u8 id)
571 struct mptsas_devinfo sas_device;
572 struct mptsas_enclosure enclosure_info;
573 int rc;
575 rc = mptsas_sas_device_pg0(ioc, &sas_device,
576 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
577 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
578 (channel << 8) + id);
579 if (rc)
580 return;
582 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
583 mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
584 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
585 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
586 sas_device.handle_enclosure);
588 mptsas_add_device_component(ioc, sas_device.channel,
589 sas_device.id, sas_device.sas_address, sas_device.device_info,
590 sas_device.slot, enclosure_info.enclosure_logical_id);
594 * mptsas_add_device_component_starget -
595 * @ioc: Pointer to MPT_ADAPTER structure
596 * @starget:
599 static void
600 mptsas_add_device_component_starget(MPT_ADAPTER *ioc,
601 struct scsi_target *starget)
603 VirtTarget *vtarget;
604 struct sas_rphy *rphy;
605 struct mptsas_phyinfo *phy_info = NULL;
606 struct mptsas_enclosure enclosure_info;
608 rphy = dev_to_rphy(starget->dev.parent);
609 vtarget = starget->hostdata;
610 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
611 rphy->identify.sas_address);
612 if (!phy_info)
613 return;
615 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
616 mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
617 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
618 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
619 phy_info->attached.handle_enclosure);
621 mptsas_add_device_component(ioc, phy_info->attached.channel,
622 phy_info->attached.id, phy_info->attached.sas_address,
623 phy_info->attached.device_info,
624 phy_info->attached.slot, enclosure_info.enclosure_logical_id);
628 * mptsas_del_device_components - Cleaning the list
629 * @ioc: Pointer to MPT_ADAPTER structure
632 static void
633 mptsas_del_device_components(MPT_ADAPTER *ioc)
635 struct mptsas_device_info *sas_info, *next;
637 mutex_lock(&ioc->sas_device_info_mutex);
638 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
639 list) {
640 list_del(&sas_info->list);
641 kfree(sas_info);
643 mutex_unlock(&ioc->sas_device_info_mutex);
648 * mptsas_setup_wide_ports
650 * Updates for new and existing narrow/wide port configuration
651 * in the sas_topology
653 static void
654 mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
656 struct mptsas_portinfo_details * port_details;
657 struct mptsas_phyinfo *phy_info, *phy_info_cmp;
658 u64 sas_address;
659 int i, j;
661 mutex_lock(&ioc->sas_topology_mutex);
663 phy_info = port_info->phy_info;
664 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
665 if (phy_info->attached.handle)
666 continue;
667 port_details = phy_info->port_details;
668 if (!port_details)
669 continue;
670 if (port_details->num_phys < 2)
671 continue;
673 * Removing a phy from a port, letting the last
674 * phy be removed by firmware events.
676 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
677 "%s: [%p]: deleting phy = %d\n",
678 ioc->name, __func__, port_details, i));
679 port_details->num_phys--;
680 port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
681 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
682 sas_port_delete_phy(port_details->port, phy_info->phy);
683 phy_info->port_details = NULL;
687 * Populate and refresh the tree
689 phy_info = port_info->phy_info;
690 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
691 sas_address = phy_info->attached.sas_address;
692 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "phy_id=%d sas_address=0x%018llX\n",
693 ioc->name, i, (unsigned long long)sas_address));
694 if (!sas_address)
695 continue;
696 port_details = phy_info->port_details;
698 * Forming a port
700 if (!port_details) {
701 port_details = kzalloc(sizeof(*port_details),
702 GFP_KERNEL);
703 if (!port_details)
704 goto out;
705 port_details->num_phys = 1;
706 port_details->port_info = port_info;
707 if (phy_info->phy_id < 64 )
708 port_details->phy_bitmask |=
709 (1 << phy_info->phy_id);
710 phy_info->sas_port_add_phy=1;
711 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tForming port\n\t\t"
712 "phy_id=%d sas_address=0x%018llX\n",
713 ioc->name, i, (unsigned long long)sas_address));
714 phy_info->port_details = port_details;
717 if (i == port_info->num_phys - 1)
718 continue;
719 phy_info_cmp = &port_info->phy_info[i + 1];
720 for (j = i + 1 ; j < port_info->num_phys ; j++,
721 phy_info_cmp++) {
722 if (!phy_info_cmp->attached.sas_address)
723 continue;
724 if (sas_address != phy_info_cmp->attached.sas_address)
725 continue;
726 if (phy_info_cmp->port_details == port_details )
727 continue;
728 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
729 "\t\tphy_id=%d sas_address=0x%018llX\n",
730 ioc->name, j, (unsigned long long)
731 phy_info_cmp->attached.sas_address));
732 if (phy_info_cmp->port_details) {
733 port_details->rphy =
734 mptsas_get_rphy(phy_info_cmp);
735 port_details->port =
736 mptsas_get_port(phy_info_cmp);
737 port_details->starget =
738 mptsas_get_starget(phy_info_cmp);
739 port_details->num_phys =
740 phy_info_cmp->port_details->num_phys;
741 if (!phy_info_cmp->port_details->num_phys)
742 kfree(phy_info_cmp->port_details);
743 } else
744 phy_info_cmp->sas_port_add_phy=1;
746 * Adding a phy to a port
748 phy_info_cmp->port_details = port_details;
749 if (phy_info_cmp->phy_id < 64 )
750 port_details->phy_bitmask |=
751 (1 << phy_info_cmp->phy_id);
752 port_details->num_phys++;
756 out:
758 for (i = 0; i < port_info->num_phys; i++) {
759 port_details = port_info->phy_info[i].port_details;
760 if (!port_details)
761 continue;
762 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
763 "%s: [%p]: phy_id=%02d num_phys=%02d "
764 "bitmask=0x%016llX\n", ioc->name, __func__,
765 port_details, i, port_details->num_phys,
766 (unsigned long long)port_details->phy_bitmask));
767 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n",
768 ioc->name, port_details->port, port_details->rphy));
770 dsaswideprintk(ioc, printk("\n"));
771 mutex_unlock(&ioc->sas_topology_mutex);
775 * csmisas_find_vtarget
777 * @ioc
778 * @volume_id
779 * @volume_bus
782 static VirtTarget *
783 mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
785 struct scsi_device *sdev;
786 VirtDevice *vdevice;
787 VirtTarget *vtarget = NULL;
789 shost_for_each_device(sdev, ioc->sh) {
790 vdevice = sdev->hostdata;
791 if ((vdevice == NULL) ||
792 (vdevice->vtarget == NULL))
793 continue;
794 if (vdevice->vtarget->id == id &&
795 vdevice->vtarget->channel == channel)
796 vtarget = vdevice->vtarget;
798 return vtarget;
801 static void
802 mptsas_queue_device_delete(MPT_ADAPTER *ioc,
803 MpiEventDataSasDeviceStatusChange_t *sas_event_data)
805 struct fw_event_work *fw_event;
806 int sz;
808 sz = offsetof(struct fw_event_work, event_data) +
809 sizeof(MpiEventDataSasDeviceStatusChange_t);
810 fw_event = kzalloc(sz, GFP_ATOMIC);
811 if (!fw_event) {
812 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
813 ioc->name, __func__, __LINE__);
814 return;
816 memcpy(fw_event->event_data, sas_event_data,
817 sizeof(MpiEventDataSasDeviceStatusChange_t));
818 fw_event->event = MPI_EVENT_SAS_DEVICE_STATUS_CHANGE;
819 fw_event->ioc = ioc;
820 mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
825 * mptsas_target_reset
827 * Issues TARGET_RESET to end device using handshaking method
829 * @ioc
830 * @channel
831 * @id
833 * Returns (1) success
834 * (0) failure
837 static int
838 mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
840 MPT_FRAME_HDR *mf;
841 SCSITaskMgmt_t *pScsiTm;
842 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0)
843 return 0;
846 mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
847 if (mf == NULL) {
848 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
849 "%s, no msg frames @%d!!\n", ioc->name,
850 __func__, __LINE__));
851 goto out_fail;
854 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
855 ioc->name, mf));
857 /* Format the Request
859 pScsiTm = (SCSITaskMgmt_t *) mf;
860 memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
861 pScsiTm->TargetID = id;
862 pScsiTm->Bus = channel;
863 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
864 pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
865 pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
867 DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
869 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
870 "TaskMgmt type=%d (sas device delete) fw_channel = %d fw_id = %d)\n",
871 ioc->name, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, channel, id));
873 mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
875 return 1;
877 out_fail:
879 mpt_clear_taskmgmt_in_progress_flag(ioc);
880 return 0;
884 * mptsas_target_reset_queue
886 * Receive request for TARGET_RESET after recieving an firmware
887 * event NOT_RESPONDING_EVENT, then put command in link list
888 * and queue if task_queue already in use.
890 * @ioc
891 * @sas_event_data
894 static void
895 mptsas_target_reset_queue(MPT_ADAPTER *ioc,
896 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
898 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
899 VirtTarget *vtarget = NULL;
900 struct mptsas_target_reset_event *target_reset_list;
901 u8 id, channel;
903 id = sas_event_data->TargetID;
904 channel = sas_event_data->Bus;
906 if (!(vtarget = mptsas_find_vtarget(ioc, channel, id)))
907 return;
909 vtarget->deleted = 1; /* block IO */
911 target_reset_list = kzalloc(sizeof(*target_reset_list),
912 GFP_ATOMIC);
913 if (!target_reset_list) {
914 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
915 "%s, failed to allocate mem @%d..!!\n",
916 ioc->name, __func__, __LINE__));
917 return;
920 memcpy(&target_reset_list->sas_event_data, sas_event_data,
921 sizeof(*sas_event_data));
922 list_add_tail(&target_reset_list->list, &hd->target_reset_list);
924 target_reset_list->time_count = jiffies;
926 if (mptsas_target_reset(ioc, channel, id)) {
927 target_reset_list->target_reset_issued = 1;
932 * mptsas_taskmgmt_complete - Completion for TARGET_RESET after
933 * NOT_RESPONDING_EVENT, enable work queue to finish off removing device
934 * from upper layers. then send next TARGET_RESET in the queue.
935 * @ioc: Pointer to MPT_ADAPTER structure
938 static int
939 mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
941 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
942 struct list_head *head = &hd->target_reset_list;
943 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
944 u8 id, channel;
945 struct mptsas_target_reset_event *target_reset_list;
946 SCSITaskMgmtReply_t *pScsiTmReply;
948 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt completed: "
949 "(mf = %p, mr = %p)\n", ioc->name, mf, mr));
951 pScsiTmReply = (SCSITaskMgmtReply_t *)mr;
952 if (pScsiTmReply) {
953 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
954 "\tTaskMgmt completed: fw_channel = %d, fw_id = %d,\n"
955 "\ttask_type = 0x%02X, iocstatus = 0x%04X "
956 "loginfo = 0x%08X,\n\tresponse_code = 0x%02X, "
957 "term_cmnds = %d\n", ioc->name,
958 pScsiTmReply->Bus, pScsiTmReply->TargetID,
959 pScsiTmReply->TaskType,
960 le16_to_cpu(pScsiTmReply->IOCStatus),
961 le32_to_cpu(pScsiTmReply->IOCLogInfo),
962 pScsiTmReply->ResponseCode,
963 le32_to_cpu(pScsiTmReply->TerminationCount)));
965 if (pScsiTmReply->ResponseCode)
966 mptscsih_taskmgmt_response_code(ioc,
967 pScsiTmReply->ResponseCode);
970 if (pScsiTmReply && (pScsiTmReply->TaskType ==
971 MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK || pScsiTmReply->TaskType ==
972 MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET)) {
973 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
974 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
975 memcpy(ioc->taskmgmt_cmds.reply, mr,
976 min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
977 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
978 ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
979 complete(&ioc->taskmgmt_cmds.done);
980 return 1;
982 return 0;
985 mpt_clear_taskmgmt_in_progress_flag(ioc);
987 if (list_empty(head))
988 return 1;
990 target_reset_list = list_entry(head->next,
991 struct mptsas_target_reset_event, list);
993 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
994 "TaskMgmt: completed (%d seconds)\n",
995 ioc->name, jiffies_to_msecs(jiffies -
996 target_reset_list->time_count)/1000));
998 sas_event_data = &target_reset_list->sas_event_data;
999 id = pScsiTmReply->TargetID;
1000 channel = pScsiTmReply->Bus;
1001 target_reset_list->time_count = jiffies;
1004 * retry target reset
1006 if (!target_reset_list->target_reset_issued) {
1007 if (mptsas_target_reset(ioc, channel, id))
1008 target_reset_list->target_reset_issued = 1;
1009 return 1;
1013 * enable work queue to remove device from upper layers
1015 list_del(&target_reset_list->list);
1016 if ((mptsas_find_vtarget(ioc, channel, id)) && !ioc->fw_events_off)
1017 mptsas_queue_device_delete(ioc,
1018 &target_reset_list->sas_event_data);
1022 * issue target reset to next device in the queue
1025 head = &hd->target_reset_list;
1026 if (list_empty(head))
1027 return 1;
1029 target_reset_list = list_entry(head->next, struct mptsas_target_reset_event,
1030 list);
1032 id = target_reset_list->sas_event_data.TargetID;
1033 channel = target_reset_list->sas_event_data.Bus;
1034 target_reset_list->time_count = jiffies;
1036 if (mptsas_target_reset(ioc, channel, id))
1037 target_reset_list->target_reset_issued = 1;
1039 return 1;
1043 * mptscsih_ioc_reset
1045 * @ioc
1046 * @reset_phase
1049 static int
1050 mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1052 MPT_SCSI_HOST *hd;
1053 int rc;
1055 rc = mptscsih_ioc_reset(ioc, reset_phase);
1056 if ((ioc->bus_type != SAS) || (!rc))
1057 return rc;
1059 hd = shost_priv(ioc->sh);
1060 if (!hd->ioc)
1061 goto out;
1063 switch (reset_phase) {
1064 case MPT_IOC_SETUP_RESET:
1065 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1066 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
1067 mptsas_fw_event_off(ioc);
1068 break;
1069 case MPT_IOC_PRE_RESET:
1070 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1071 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
1072 break;
1073 case MPT_IOC_POST_RESET:
1074 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1075 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
1076 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
1077 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_DID_IOCRESET;
1078 complete(&ioc->sas_mgmt.done);
1080 mptsas_cleanup_fw_event_q(ioc);
1081 mptsas_fw_event_on(ioc);
1082 break;
1083 default:
1084 break;
1087 out:
1088 return rc;
1093 * enum device_state -
1094 * @DEVICE_RETRY: need to retry the TUR
1095 * @DEVICE_ERROR: TUR return error, don't add device
1096 * @DEVICE_READY: device can be added
1099 enum device_state{
1100 DEVICE_RETRY,
1101 DEVICE_ERROR,
1102 DEVICE_READY,
1105 static int
1106 mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
1107 u32 form, u32 form_specific)
1109 ConfigExtendedPageHeader_t hdr;
1110 CONFIGPARMS cfg;
1111 SasEnclosurePage0_t *buffer;
1112 dma_addr_t dma_handle;
1113 int error;
1114 __le64 le_identifier;
1116 memset(&hdr, 0, sizeof(hdr));
1117 hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
1118 hdr.PageNumber = 0;
1119 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1120 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
1122 cfg.cfghdr.ehdr = &hdr;
1123 cfg.physAddr = -1;
1124 cfg.pageAddr = form + form_specific;
1125 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1126 cfg.dir = 0; /* read */
1127 cfg.timeout = 10;
1129 error = mpt_config(ioc, &cfg);
1130 if (error)
1131 goto out;
1132 if (!hdr.ExtPageLength) {
1133 error = -ENXIO;
1134 goto out;
1137 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1138 &dma_handle);
1139 if (!buffer) {
1140 error = -ENOMEM;
1141 goto out;
1144 cfg.physAddr = dma_handle;
1145 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1147 error = mpt_config(ioc, &cfg);
1148 if (error)
1149 goto out_free_consistent;
1151 /* save config data */
1152 memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
1153 enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
1154 enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
1155 enclosure->flags = le16_to_cpu(buffer->Flags);
1156 enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
1157 enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
1158 enclosure->start_id = buffer->StartTargetID;
1159 enclosure->start_channel = buffer->StartBus;
1160 enclosure->sep_id = buffer->SEPTargetID;
1161 enclosure->sep_channel = buffer->SEPBus;
1163 out_free_consistent:
1164 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1165 buffer, dma_handle);
1166 out:
1167 return error;
1171 * mptsas_add_end_device - report a new end device to sas transport layer
1172 * @ioc: Pointer to MPT_ADAPTER structure
1173 * @phy_info: decribes attached device
1175 * return (0) success (1) failure
1178 static int
1179 mptsas_add_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1181 struct sas_rphy *rphy;
1182 struct sas_port *port;
1183 struct sas_identify identify;
1184 char *ds = NULL;
1185 u8 fw_id;
1187 if (!phy_info) {
1188 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1189 "%s: exit at line=%d\n", ioc->name,
1190 __func__, __LINE__));
1191 return 1;
1194 fw_id = phy_info->attached.id;
1196 if (mptsas_get_rphy(phy_info)) {
1197 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1198 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1199 __func__, fw_id, __LINE__));
1200 return 2;
1203 port = mptsas_get_port(phy_info);
1204 if (!port) {
1205 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1206 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1207 __func__, fw_id, __LINE__));
1208 return 3;
1211 if (phy_info->attached.device_info &
1212 MPI_SAS_DEVICE_INFO_SSP_TARGET)
1213 ds = "ssp";
1214 if (phy_info->attached.device_info &
1215 MPI_SAS_DEVICE_INFO_STP_TARGET)
1216 ds = "stp";
1217 if (phy_info->attached.device_info &
1218 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1219 ds = "sata";
1221 printk(MYIOC_s_INFO_FMT "attaching %s device: fw_channel %d, fw_id %d,"
1222 " phy %d, sas_addr 0x%llx\n", ioc->name, ds,
1223 phy_info->attached.channel, phy_info->attached.id,
1224 phy_info->attached.phy_id, (unsigned long long)
1225 phy_info->attached.sas_address);
1227 mptsas_parse_device_info(&identify, &phy_info->attached);
1228 rphy = sas_end_device_alloc(port);
1229 if (!rphy) {
1230 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1231 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1232 __func__, fw_id, __LINE__));
1233 return 5; /* non-fatal: an rphy can be added later */
1236 rphy->identify = identify;
1237 if (sas_rphy_add(rphy)) {
1238 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1239 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1240 __func__, fw_id, __LINE__));
1241 sas_rphy_free(rphy);
1242 return 6;
1244 mptsas_set_rphy(ioc, phy_info, rphy);
1245 return 0;
1249 * mptsas_del_end_device - report a deleted end device to sas transport
1250 * layer
1251 * @ioc: Pointer to MPT_ADAPTER structure
1252 * @phy_info: decribes attached device
1255 static void
1256 mptsas_del_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1258 struct sas_rphy *rphy;
1259 struct sas_port *port;
1260 struct mptsas_portinfo *port_info;
1261 struct mptsas_phyinfo *phy_info_parent;
1262 int i;
1263 char *ds = NULL;
1264 u8 fw_id;
1265 u64 sas_address;
1267 if (!phy_info)
1268 return;
1270 fw_id = phy_info->attached.id;
1271 sas_address = phy_info->attached.sas_address;
1273 if (!phy_info->port_details) {
1274 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1275 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1276 __func__, fw_id, __LINE__));
1277 return;
1279 rphy = mptsas_get_rphy(phy_info);
1280 if (!rphy) {
1281 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1282 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1283 __func__, fw_id, __LINE__));
1284 return;
1287 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_INITIATOR
1288 || phy_info->attached.device_info
1289 & MPI_SAS_DEVICE_INFO_SMP_INITIATOR
1290 || phy_info->attached.device_info
1291 & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1292 ds = "initiator";
1293 if (phy_info->attached.device_info &
1294 MPI_SAS_DEVICE_INFO_SSP_TARGET)
1295 ds = "ssp";
1296 if (phy_info->attached.device_info &
1297 MPI_SAS_DEVICE_INFO_STP_TARGET)
1298 ds = "stp";
1299 if (phy_info->attached.device_info &
1300 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1301 ds = "sata";
1303 dev_printk(KERN_DEBUG, &rphy->dev, MYIOC_s_FMT
1304 "removing %s device: fw_channel %d, fw_id %d, phy %d,"
1305 "sas_addr 0x%llx\n", ioc->name, ds, phy_info->attached.channel,
1306 phy_info->attached.id, phy_info->attached.phy_id,
1307 (unsigned long long) sas_address);
1309 port = mptsas_get_port(phy_info);
1310 if (!port) {
1311 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1312 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1313 __func__, fw_id, __LINE__));
1314 return;
1316 port_info = phy_info->portinfo;
1317 phy_info_parent = port_info->phy_info;
1318 for (i = 0; i < port_info->num_phys; i++, phy_info_parent++) {
1319 if (!phy_info_parent->phy)
1320 continue;
1321 if (phy_info_parent->attached.sas_address !=
1322 sas_address)
1323 continue;
1324 dev_printk(KERN_DEBUG, &phy_info_parent->phy->dev,
1325 MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n",
1326 ioc->name, phy_info_parent->phy_id,
1327 phy_info_parent->phy);
1328 sas_port_delete_phy(port, phy_info_parent->phy);
1331 dev_printk(KERN_DEBUG, &port->dev, MYIOC_s_FMT
1332 "delete port %d, sas_addr (0x%llx)\n", ioc->name,
1333 port->port_identifier, (unsigned long long)sas_address);
1334 sas_port_delete(port);
1335 mptsas_set_port(ioc, phy_info, NULL);
1336 mptsas_port_delete(ioc, phy_info->port_details);
1339 struct mptsas_phyinfo *
1340 mptsas_refreshing_device_handles(MPT_ADAPTER *ioc,
1341 struct mptsas_devinfo *sas_device)
1343 struct mptsas_phyinfo *phy_info;
1344 struct mptsas_portinfo *port_info;
1345 int i;
1347 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
1348 sas_device->sas_address);
1349 if (!phy_info)
1350 goto out;
1351 port_info = phy_info->portinfo;
1352 if (!port_info)
1353 goto out;
1354 mutex_lock(&ioc->sas_topology_mutex);
1355 for (i = 0; i < port_info->num_phys; i++) {
1356 if (port_info->phy_info[i].attached.sas_address !=
1357 sas_device->sas_address)
1358 continue;
1359 port_info->phy_info[i].attached.channel = sas_device->channel;
1360 port_info->phy_info[i].attached.id = sas_device->id;
1361 port_info->phy_info[i].attached.sas_address =
1362 sas_device->sas_address;
1363 port_info->phy_info[i].attached.handle = sas_device->handle;
1364 port_info->phy_info[i].attached.handle_parent =
1365 sas_device->handle_parent;
1366 port_info->phy_info[i].attached.handle_enclosure =
1367 sas_device->handle_enclosure;
1369 mutex_unlock(&ioc->sas_topology_mutex);
1370 out:
1371 return phy_info;
1375 * mptsas_firmware_event_work - work thread for processing fw events
1376 * @work: work queue payload containing info describing the event
1377 * Context: user
1380 static void
1381 mptsas_firmware_event_work(struct work_struct *work)
1383 struct fw_event_work *fw_event =
1384 container_of(work, struct fw_event_work, work.work);
1385 MPT_ADAPTER *ioc = fw_event->ioc;
1388 /* events handling turned off during host reset */
1389 if (ioc->fw_events_off) {
1390 mptsas_free_fw_event(ioc, fw_event);
1391 return;
1394 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: fw_event=(0x%p), "
1395 "event = (0x%02x)\n", ioc->name, __func__, fw_event,
1396 (fw_event->event & 0xFF)));
1398 switch (fw_event->event) {
1399 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1400 mptsas_send_sas_event(fw_event);
1401 break;
1402 case MPI_EVENT_INTEGRATED_RAID:
1403 mptsas_send_raid_event(fw_event);
1404 break;
1405 case MPI_EVENT_IR2:
1406 mptsas_send_ir2_event(fw_event);
1407 break;
1408 case MPI_EVENT_PERSISTENT_TABLE_FULL:
1409 mptbase_sas_persist_operation(ioc,
1410 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1411 mptsas_free_fw_event(ioc, fw_event);
1412 break;
1418 static int
1419 mptsas_slave_configure(struct scsi_device *sdev)
1421 struct Scsi_Host *host = sdev->host;
1422 MPT_SCSI_HOST *hd = shost_priv(host);
1423 MPT_ADAPTER *ioc = hd->ioc;
1425 if (sdev->channel == MPTSAS_RAID_CHANNEL)
1426 goto out;
1428 sas_read_port_mode_page(sdev);
1430 mptsas_add_device_component_starget(ioc, scsi_target(sdev));
1432 out:
1433 return mptscsih_slave_configure(sdev);
1436 static int
1437 mptsas_target_alloc(struct scsi_target *starget)
1439 struct Scsi_Host *host = dev_to_shost(&starget->dev);
1440 MPT_SCSI_HOST *hd = shost_priv(host);
1441 VirtTarget *vtarget;
1442 u8 id, channel;
1443 struct sas_rphy *rphy;
1444 struct mptsas_portinfo *p;
1445 int i;
1446 MPT_ADAPTER *ioc = hd->ioc;
1448 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
1449 if (!vtarget)
1450 return -ENOMEM;
1452 vtarget->starget = starget;
1453 vtarget->ioc_id = ioc->id;
1454 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
1455 id = starget->id;
1456 channel = 0;
1459 * RAID volumes placed beyond the last expected port.
1461 if (starget->channel == MPTSAS_RAID_CHANNEL) {
1462 for (i=0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
1463 if (id == ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID)
1464 channel = ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus;
1465 goto out;
1468 rphy = dev_to_rphy(starget->dev.parent);
1469 mutex_lock(&ioc->sas_topology_mutex);
1470 list_for_each_entry(p, &ioc->sas_topology, list) {
1471 for (i = 0; i < p->num_phys; i++) {
1472 if (p->phy_info[i].attached.sas_address !=
1473 rphy->identify.sas_address)
1474 continue;
1475 id = p->phy_info[i].attached.id;
1476 channel = p->phy_info[i].attached.channel;
1477 mptsas_set_starget(&p->phy_info[i], starget);
1480 * Exposing hidden raid components
1482 if (mptscsih_is_phys_disk(ioc, channel, id)) {
1483 id = mptscsih_raid_id_to_num(ioc,
1484 channel, id);
1485 vtarget->tflags |=
1486 MPT_TARGET_FLAGS_RAID_COMPONENT;
1487 p->phy_info[i].attached.phys_disk_num = id;
1489 mutex_unlock(&ioc->sas_topology_mutex);
1490 goto out;
1493 mutex_unlock(&ioc->sas_topology_mutex);
1495 kfree(vtarget);
1496 return -ENXIO;
1498 out:
1499 vtarget->id = id;
1500 vtarget->channel = channel;
1501 starget->hostdata = vtarget;
1502 return 0;
1505 static void
1506 mptsas_target_destroy(struct scsi_target *starget)
1508 struct Scsi_Host *host = dev_to_shost(&starget->dev);
1509 MPT_SCSI_HOST *hd = shost_priv(host);
1510 struct sas_rphy *rphy;
1511 struct mptsas_portinfo *p;
1512 int i;
1513 MPT_ADAPTER *ioc = hd->ioc;
1514 VirtTarget *vtarget;
1516 if (!starget->hostdata)
1517 return;
1519 vtarget = starget->hostdata;
1522 if (starget->channel == MPTSAS_RAID_CHANNEL)
1523 goto out;
1525 rphy = dev_to_rphy(starget->dev.parent);
1526 list_for_each_entry(p, &ioc->sas_topology, list) {
1527 for (i = 0; i < p->num_phys; i++) {
1528 if (p->phy_info[i].attached.sas_address !=
1529 rphy->identify.sas_address)
1530 continue;
1532 starget_printk(KERN_INFO, starget, MYIOC_s_FMT
1533 "delete device: fw_channel %d, fw_id %d, phy %d, "
1534 "sas_addr 0x%llx\n", ioc->name,
1535 p->phy_info[i].attached.channel,
1536 p->phy_info[i].attached.id,
1537 p->phy_info[i].attached.phy_id, (unsigned long long)
1538 p->phy_info[i].attached.sas_address);
1540 mptsas_set_starget(&p->phy_info[i], NULL);
1544 out:
1545 vtarget->starget = NULL;
1546 kfree(starget->hostdata);
1547 starget->hostdata = NULL;
1551 static int
1552 mptsas_slave_alloc(struct scsi_device *sdev)
1554 struct Scsi_Host *host = sdev->host;
1555 MPT_SCSI_HOST *hd = shost_priv(host);
1556 struct sas_rphy *rphy;
1557 struct mptsas_portinfo *p;
1558 VirtDevice *vdevice;
1559 struct scsi_target *starget;
1560 int i;
1561 MPT_ADAPTER *ioc = hd->ioc;
1563 vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
1564 if (!vdevice) {
1565 printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
1566 ioc->name, sizeof(VirtDevice));
1567 return -ENOMEM;
1569 starget = scsi_target(sdev);
1570 vdevice->vtarget = starget->hostdata;
1572 if (sdev->channel == MPTSAS_RAID_CHANNEL)
1573 goto out;
1575 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
1576 mutex_lock(&ioc->sas_topology_mutex);
1577 list_for_each_entry(p, &ioc->sas_topology, list) {
1578 for (i = 0; i < p->num_phys; i++) {
1579 if (p->phy_info[i].attached.sas_address !=
1580 rphy->identify.sas_address)
1581 continue;
1582 vdevice->lun = sdev->lun;
1584 * Exposing hidden raid components
1586 if (mptscsih_is_phys_disk(ioc,
1587 p->phy_info[i].attached.channel,
1588 p->phy_info[i].attached.id))
1589 sdev->no_uld_attach = 1;
1590 mutex_unlock(&ioc->sas_topology_mutex);
1591 goto out;
1594 mutex_unlock(&ioc->sas_topology_mutex);
1596 kfree(vdevice);
1597 return -ENXIO;
1599 out:
1600 vdevice->vtarget->num_luns++;
1601 sdev->hostdata = vdevice;
1602 return 0;
1605 static int
1606 mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1608 MPT_SCSI_HOST *hd;
1609 MPT_ADAPTER *ioc;
1610 VirtDevice *vdevice = SCpnt->device->hostdata;
1612 if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
1613 SCpnt->result = DID_NO_CONNECT << 16;
1614 done(SCpnt);
1615 return 0;
1618 hd = shost_priv(SCpnt->device->host);
1619 ioc = hd->ioc;
1621 if (ioc->sas_discovery_quiesce_io)
1622 return SCSI_MLQUEUE_HOST_BUSY;
1624 // scsi_print_command(SCpnt);
1626 return mptscsih_qcmd(SCpnt,done);
1630 static struct scsi_host_template mptsas_driver_template = {
1631 .module = THIS_MODULE,
1632 .proc_name = "mptsas",
1633 .proc_info = mptscsih_proc_info,
1634 .name = "MPT SPI Host",
1635 .info = mptscsih_info,
1636 .queuecommand = mptsas_qcmd,
1637 .target_alloc = mptsas_target_alloc,
1638 .slave_alloc = mptsas_slave_alloc,
1639 .slave_configure = mptsas_slave_configure,
1640 .target_destroy = mptsas_target_destroy,
1641 .slave_destroy = mptscsih_slave_destroy,
1642 .change_queue_depth = mptscsih_change_queue_depth,
1643 .eh_abort_handler = mptscsih_abort,
1644 .eh_device_reset_handler = mptscsih_dev_reset,
1645 .eh_bus_reset_handler = mptscsih_bus_reset,
1646 .eh_host_reset_handler = mptscsih_host_reset,
1647 .bios_param = mptscsih_bios_param,
1648 .can_queue = MPT_FC_CAN_QUEUE,
1649 .this_id = -1,
1650 .sg_tablesize = MPT_SCSI_SG_DEPTH,
1651 .max_sectors = 8192,
1652 .cmd_per_lun = 7,
1653 .use_clustering = ENABLE_CLUSTERING,
1654 .shost_attrs = mptscsih_host_attrs,
1657 static int mptsas_get_linkerrors(struct sas_phy *phy)
1659 MPT_ADAPTER *ioc = phy_to_ioc(phy);
1660 ConfigExtendedPageHeader_t hdr;
1661 CONFIGPARMS cfg;
1662 SasPhyPage1_t *buffer;
1663 dma_addr_t dma_handle;
1664 int error;
1666 /* FIXME: only have link errors on local phys */
1667 if (!scsi_is_sas_phy_local(phy))
1668 return -EINVAL;
1670 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
1671 hdr.ExtPageLength = 0;
1672 hdr.PageNumber = 1 /* page number 1*/;
1673 hdr.Reserved1 = 0;
1674 hdr.Reserved2 = 0;
1675 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1676 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1678 cfg.cfghdr.ehdr = &hdr;
1679 cfg.physAddr = -1;
1680 cfg.pageAddr = phy->identify.phy_identifier;
1681 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1682 cfg.dir = 0; /* read */
1683 cfg.timeout = 10;
1685 error = mpt_config(ioc, &cfg);
1686 if (error)
1687 return error;
1688 if (!hdr.ExtPageLength)
1689 return -ENXIO;
1691 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1692 &dma_handle);
1693 if (!buffer)
1694 return -ENOMEM;
1696 cfg.physAddr = dma_handle;
1697 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1699 error = mpt_config(ioc, &cfg);
1700 if (error)
1701 goto out_free_consistent;
1703 mptsas_print_phy_pg1(ioc, buffer);
1705 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
1706 phy->running_disparity_error_count =
1707 le32_to_cpu(buffer->RunningDisparityErrorCount);
1708 phy->loss_of_dword_sync_count =
1709 le32_to_cpu(buffer->LossDwordSynchCount);
1710 phy->phy_reset_problem_count =
1711 le32_to_cpu(buffer->PhyResetProblemCount);
1713 out_free_consistent:
1714 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1715 buffer, dma_handle);
1716 return error;
1719 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
1720 MPT_FRAME_HDR *reply)
1722 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
1723 if (reply != NULL) {
1724 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_RF_VALID;
1725 memcpy(ioc->sas_mgmt.reply, reply,
1726 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
1728 complete(&ioc->sas_mgmt.done);
1729 return 1;
1732 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
1734 MPT_ADAPTER *ioc = phy_to_ioc(phy);
1735 SasIoUnitControlRequest_t *req;
1736 SasIoUnitControlReply_t *reply;
1737 MPT_FRAME_HDR *mf;
1738 MPIHeader_t *hdr;
1739 unsigned long timeleft;
1740 int error = -ERESTARTSYS;
1742 /* FIXME: fusion doesn't allow non-local phy reset */
1743 if (!scsi_is_sas_phy_local(phy))
1744 return -EINVAL;
1746 /* not implemented for expanders */
1747 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
1748 return -ENXIO;
1750 if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
1751 goto out;
1753 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
1754 if (!mf) {
1755 error = -ENOMEM;
1756 goto out_unlock;
1759 hdr = (MPIHeader_t *) mf;
1760 req = (SasIoUnitControlRequest_t *)mf;
1761 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
1762 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
1763 req->MsgContext = hdr->MsgContext;
1764 req->Operation = hard_reset ?
1765 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
1766 req->PhyNum = phy->identify.phy_identifier;
1768 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1770 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
1771 10 * HZ);
1772 if (!timeleft) {
1773 /* On timeout reset the board */
1774 mpt_free_msg_frame(ioc, mf);
1775 mpt_HardResetHandler(ioc, CAN_SLEEP);
1776 error = -ETIMEDOUT;
1777 goto out_unlock;
1780 /* a reply frame is expected */
1781 if ((ioc->sas_mgmt.status &
1782 MPT_MGMT_STATUS_RF_VALID) == 0) {
1783 error = -ENXIO;
1784 goto out_unlock;
1787 /* process the completed Reply Message Frame */
1788 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
1789 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
1790 printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
1791 ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo);
1792 error = -ENXIO;
1793 goto out_unlock;
1796 error = 0;
1798 out_unlock:
1799 mutex_unlock(&ioc->sas_mgmt.mutex);
1800 out:
1801 return error;
1804 static int
1805 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
1807 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1808 int i, error;
1809 struct mptsas_portinfo *p;
1810 struct mptsas_enclosure enclosure_info;
1811 u64 enclosure_handle;
1813 mutex_lock(&ioc->sas_topology_mutex);
1814 list_for_each_entry(p, &ioc->sas_topology, list) {
1815 for (i = 0; i < p->num_phys; i++) {
1816 if (p->phy_info[i].attached.sas_address ==
1817 rphy->identify.sas_address) {
1818 enclosure_handle = p->phy_info[i].
1819 attached.handle_enclosure;
1820 goto found_info;
1824 mutex_unlock(&ioc->sas_topology_mutex);
1825 return -ENXIO;
1827 found_info:
1828 mutex_unlock(&ioc->sas_topology_mutex);
1829 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
1830 error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
1831 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
1832 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
1833 if (!error)
1834 *identifier = enclosure_info.enclosure_logical_id;
1835 return error;
1838 static int
1839 mptsas_get_bay_identifier(struct sas_rphy *rphy)
1841 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1842 struct mptsas_portinfo *p;
1843 int i, rc;
1845 mutex_lock(&ioc->sas_topology_mutex);
1846 list_for_each_entry(p, &ioc->sas_topology, list) {
1847 for (i = 0; i < p->num_phys; i++) {
1848 if (p->phy_info[i].attached.sas_address ==
1849 rphy->identify.sas_address) {
1850 rc = p->phy_info[i].attached.slot;
1851 goto out;
1855 rc = -ENXIO;
1856 out:
1857 mutex_unlock(&ioc->sas_topology_mutex);
1858 return rc;
1861 static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1862 struct request *req)
1864 MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
1865 MPT_FRAME_HDR *mf;
1866 SmpPassthroughRequest_t *smpreq;
1867 struct request *rsp = req->next_rq;
1868 int ret;
1869 int flagsLength;
1870 unsigned long timeleft;
1871 char *psge;
1872 dma_addr_t dma_addr_in = 0;
1873 dma_addr_t dma_addr_out = 0;
1874 u64 sas_address = 0;
1876 if (!rsp) {
1877 printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n",
1878 ioc->name, __func__);
1879 return -EINVAL;
1882 /* do we need to support multiple segments? */
1883 if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
1884 printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
1885 ioc->name, __func__, req->bio->bi_vcnt, req->data_len,
1886 rsp->bio->bi_vcnt, rsp->data_len);
1887 return -EINVAL;
1890 ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
1891 if (ret)
1892 goto out;
1894 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
1895 if (!mf) {
1896 ret = -ENOMEM;
1897 goto out_unlock;
1900 smpreq = (SmpPassthroughRequest_t *)mf;
1901 memset(smpreq, 0, sizeof(*smpreq));
1903 smpreq->RequestDataLength = cpu_to_le16(req->data_len - 4);
1904 smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
1906 if (rphy)
1907 sas_address = rphy->identify.sas_address;
1908 else {
1909 struct mptsas_portinfo *port_info;
1911 mutex_lock(&ioc->sas_topology_mutex);
1912 port_info = mptsas_get_hba_portinfo(ioc);
1913 if (port_info && port_info->phy_info)
1914 sas_address =
1915 port_info->phy_info[0].phy->identify.sas_address;
1916 mutex_unlock(&ioc->sas_topology_mutex);
1919 *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
1921 psge = (char *)
1922 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
1924 /* request */
1925 flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1926 MPI_SGE_FLAGS_END_OF_BUFFER |
1927 MPI_SGE_FLAGS_DIRECTION)
1928 << MPI_SGE_FLAGS_SHIFT;
1929 flagsLength |= (req->data_len - 4);
1931 dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
1932 req->data_len, PCI_DMA_BIDIRECTIONAL);
1933 if (!dma_addr_out)
1934 goto put_mf;
1935 ioc->add_sge(psge, flagsLength, dma_addr_out);
1936 psge += (sizeof(u32) + sizeof(dma_addr_t));
1938 /* response */
1939 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
1940 flagsLength |= rsp->data_len + 4;
1941 dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio),
1942 rsp->data_len, PCI_DMA_BIDIRECTIONAL);
1943 if (!dma_addr_in)
1944 goto unmap;
1945 ioc->add_sge(psge, flagsLength, dma_addr_in);
1947 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1949 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
1950 if (!timeleft) {
1951 printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __func__);
1952 /* On timeout reset the board */
1953 mpt_HardResetHandler(ioc, CAN_SLEEP);
1954 ret = -ETIMEDOUT;
1955 goto unmap;
1957 mf = NULL;
1959 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
1960 SmpPassthroughReply_t *smprep;
1962 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
1963 memcpy(req->sense, smprep, sizeof(*smprep));
1964 req->sense_len = sizeof(*smprep);
1965 req->data_len = 0;
1966 rsp->data_len -= smprep->ResponseDataLength;
1967 } else {
1968 printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n",
1969 ioc->name, __func__);
1970 ret = -ENXIO;
1972 unmap:
1973 if (dma_addr_out)
1974 pci_unmap_single(ioc->pcidev, dma_addr_out, req->data_len,
1975 PCI_DMA_BIDIRECTIONAL);
1976 if (dma_addr_in)
1977 pci_unmap_single(ioc->pcidev, dma_addr_in, rsp->data_len,
1978 PCI_DMA_BIDIRECTIONAL);
1979 put_mf:
1980 if (mf)
1981 mpt_free_msg_frame(ioc, mf);
1982 out_unlock:
1983 mutex_unlock(&ioc->sas_mgmt.mutex);
1984 out:
1985 return ret;
1988 static struct sas_function_template mptsas_transport_functions = {
1989 .get_linkerrors = mptsas_get_linkerrors,
1990 .get_enclosure_identifier = mptsas_get_enclosure_identifier,
1991 .get_bay_identifier = mptsas_get_bay_identifier,
1992 .phy_reset = mptsas_phy_reset,
1993 .smp_handler = mptsas_smp_handler,
1996 static struct scsi_transport_template *mptsas_transport_template;
1998 static int
1999 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
2001 ConfigExtendedPageHeader_t hdr;
2002 CONFIGPARMS cfg;
2003 SasIOUnitPage0_t *buffer;
2004 dma_addr_t dma_handle;
2005 int error, i;
2007 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
2008 hdr.ExtPageLength = 0;
2009 hdr.PageNumber = 0;
2010 hdr.Reserved1 = 0;
2011 hdr.Reserved2 = 0;
2012 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2013 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2015 cfg.cfghdr.ehdr = &hdr;
2016 cfg.physAddr = -1;
2017 cfg.pageAddr = 0;
2018 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2019 cfg.dir = 0; /* read */
2020 cfg.timeout = 10;
2022 error = mpt_config(ioc, &cfg);
2023 if (error)
2024 goto out;
2025 if (!hdr.ExtPageLength) {
2026 error = -ENXIO;
2027 goto out;
2030 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2031 &dma_handle);
2032 if (!buffer) {
2033 error = -ENOMEM;
2034 goto out;
2037 cfg.physAddr = dma_handle;
2038 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2040 error = mpt_config(ioc, &cfg);
2041 if (error)
2042 goto out_free_consistent;
2044 port_info->num_phys = buffer->NumPhys;
2045 port_info->phy_info = kcalloc(port_info->num_phys,
2046 sizeof(*port_info->phy_info),GFP_KERNEL);
2047 if (!port_info->phy_info) {
2048 error = -ENOMEM;
2049 goto out_free_consistent;
2052 ioc->nvdata_version_persistent =
2053 le16_to_cpu(buffer->NvdataVersionPersistent);
2054 ioc->nvdata_version_default =
2055 le16_to_cpu(buffer->NvdataVersionDefault);
2057 for (i = 0; i < port_info->num_phys; i++) {
2058 mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
2059 port_info->phy_info[i].phy_id = i;
2060 port_info->phy_info[i].port_id =
2061 buffer->PhyData[i].Port;
2062 port_info->phy_info[i].negotiated_link_rate =
2063 buffer->PhyData[i].NegotiatedLinkRate;
2064 port_info->phy_info[i].portinfo = port_info;
2065 port_info->phy_info[i].handle =
2066 le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
2069 out_free_consistent:
2070 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2071 buffer, dma_handle);
2072 out:
2073 return error;
2076 static int
2077 mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
2079 ConfigExtendedPageHeader_t hdr;
2080 CONFIGPARMS cfg;
2081 SasIOUnitPage1_t *buffer;
2082 dma_addr_t dma_handle;
2083 int error;
2084 u16 device_missing_delay;
2086 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
2087 memset(&cfg, 0, sizeof(CONFIGPARMS));
2089 cfg.cfghdr.ehdr = &hdr;
2090 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2091 cfg.timeout = 10;
2092 cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2093 cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2094 cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
2095 cfg.cfghdr.ehdr->PageNumber = 1;
2097 error = mpt_config(ioc, &cfg);
2098 if (error)
2099 goto out;
2100 if (!hdr.ExtPageLength) {
2101 error = -ENXIO;
2102 goto out;
2105 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2106 &dma_handle);
2107 if (!buffer) {
2108 error = -ENOMEM;
2109 goto out;
2112 cfg.physAddr = dma_handle;
2113 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2115 error = mpt_config(ioc, &cfg);
2116 if (error)
2117 goto out_free_consistent;
2119 ioc->io_missing_delay =
2120 le16_to_cpu(buffer->IODeviceMissingDelay);
2121 device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay);
2122 ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
2123 (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
2124 device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
2126 out_free_consistent:
2127 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2128 buffer, dma_handle);
2129 out:
2130 return error;
2133 static int
2134 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2135 u32 form, u32 form_specific)
2137 ConfigExtendedPageHeader_t hdr;
2138 CONFIGPARMS cfg;
2139 SasPhyPage0_t *buffer;
2140 dma_addr_t dma_handle;
2141 int error;
2143 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
2144 hdr.ExtPageLength = 0;
2145 hdr.PageNumber = 0;
2146 hdr.Reserved1 = 0;
2147 hdr.Reserved2 = 0;
2148 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2149 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2151 cfg.cfghdr.ehdr = &hdr;
2152 cfg.dir = 0; /* read */
2153 cfg.timeout = 10;
2155 /* Get Phy Pg 0 for each Phy. */
2156 cfg.physAddr = -1;
2157 cfg.pageAddr = form + form_specific;
2158 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2160 error = mpt_config(ioc, &cfg);
2161 if (error)
2162 goto out;
2164 if (!hdr.ExtPageLength) {
2165 error = -ENXIO;
2166 goto out;
2169 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2170 &dma_handle);
2171 if (!buffer) {
2172 error = -ENOMEM;
2173 goto out;
2176 cfg.physAddr = dma_handle;
2177 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2179 error = mpt_config(ioc, &cfg);
2180 if (error)
2181 goto out_free_consistent;
2183 mptsas_print_phy_pg0(ioc, buffer);
2185 phy_info->hw_link_rate = buffer->HwLinkRate;
2186 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2187 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2188 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2190 out_free_consistent:
2191 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2192 buffer, dma_handle);
2193 out:
2194 return error;
2197 static int
2198 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
2199 u32 form, u32 form_specific)
2201 ConfigExtendedPageHeader_t hdr;
2202 CONFIGPARMS cfg;
2203 SasDevicePage0_t *buffer;
2204 dma_addr_t dma_handle;
2205 __le64 sas_address;
2206 int error=0;
2208 if (ioc->sas_discovery_runtime &&
2209 mptsas_is_end_device(device_info))
2210 goto out;
2212 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
2213 hdr.ExtPageLength = 0;
2214 hdr.PageNumber = 0;
2215 hdr.Reserved1 = 0;
2216 hdr.Reserved2 = 0;
2217 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2218 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
2220 cfg.cfghdr.ehdr = &hdr;
2221 cfg.pageAddr = form + form_specific;
2222 cfg.physAddr = -1;
2223 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2224 cfg.dir = 0; /* read */
2225 cfg.timeout = 10;
2227 memset(device_info, 0, sizeof(struct mptsas_devinfo));
2228 error = mpt_config(ioc, &cfg);
2229 if (error)
2230 goto out;
2231 if (!hdr.ExtPageLength) {
2232 error = -ENXIO;
2233 goto out;
2236 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2237 &dma_handle);
2238 if (!buffer) {
2239 error = -ENOMEM;
2240 goto out;
2243 cfg.physAddr = dma_handle;
2244 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2246 error = mpt_config(ioc, &cfg);
2247 if (error)
2248 goto out_free_consistent;
2250 mptsas_print_device_pg0(ioc, buffer);
2252 device_info->handle = le16_to_cpu(buffer->DevHandle);
2253 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
2254 device_info->handle_enclosure =
2255 le16_to_cpu(buffer->EnclosureHandle);
2256 device_info->slot = le16_to_cpu(buffer->Slot);
2257 device_info->phy_id = buffer->PhyNum;
2258 device_info->port_id = buffer->PhysicalPort;
2259 device_info->id = buffer->TargetID;
2260 device_info->phys_disk_num = ~0;
2261 device_info->channel = buffer->Bus;
2262 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2263 device_info->sas_address = le64_to_cpu(sas_address);
2264 device_info->device_info =
2265 le32_to_cpu(buffer->DeviceInfo);
2267 out_free_consistent:
2268 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2269 buffer, dma_handle);
2270 out:
2271 return error;
2274 static int
2275 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
2276 u32 form, u32 form_specific)
2278 ConfigExtendedPageHeader_t hdr;
2279 CONFIGPARMS cfg;
2280 SasExpanderPage0_t *buffer;
2281 dma_addr_t dma_handle;
2282 int i, error;
2284 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
2285 hdr.ExtPageLength = 0;
2286 hdr.PageNumber = 0;
2287 hdr.Reserved1 = 0;
2288 hdr.Reserved2 = 0;
2289 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2290 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2292 cfg.cfghdr.ehdr = &hdr;
2293 cfg.physAddr = -1;
2294 cfg.pageAddr = form + form_specific;
2295 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2296 cfg.dir = 0; /* read */
2297 cfg.timeout = 10;
2299 memset(port_info, 0, sizeof(struct mptsas_portinfo));
2300 error = mpt_config(ioc, &cfg);
2301 if (error)
2302 goto out;
2304 if (!hdr.ExtPageLength) {
2305 error = -ENXIO;
2306 goto out;
2309 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2310 &dma_handle);
2311 if (!buffer) {
2312 error = -ENOMEM;
2313 goto out;
2316 cfg.physAddr = dma_handle;
2317 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2319 error = mpt_config(ioc, &cfg);
2320 if (error)
2321 goto out_free_consistent;
2323 if (!buffer->NumPhys) {
2324 error = -ENODEV;
2325 goto out_free_consistent;
2328 /* save config data */
2329 port_info->num_phys = buffer->NumPhys;
2330 port_info->phy_info = kcalloc(port_info->num_phys,
2331 sizeof(*port_info->phy_info),GFP_KERNEL);
2332 if (!port_info->phy_info) {
2333 error = -ENOMEM;
2334 goto out_free_consistent;
2337 for (i = 0; i < port_info->num_phys; i++) {
2338 port_info->phy_info[i].portinfo = port_info;
2339 port_info->phy_info[i].handle =
2340 le16_to_cpu(buffer->DevHandle);
2343 out_free_consistent:
2344 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2345 buffer, dma_handle);
2346 out:
2347 return error;
2350 static int
2351 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2352 u32 form, u32 form_specific)
2354 ConfigExtendedPageHeader_t hdr;
2355 CONFIGPARMS cfg;
2356 SasExpanderPage1_t *buffer;
2357 dma_addr_t dma_handle;
2358 int error=0;
2360 if (ioc->sas_discovery_runtime &&
2361 mptsas_is_end_device(&phy_info->attached))
2362 goto out;
2364 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
2365 hdr.ExtPageLength = 0;
2366 hdr.PageNumber = 1;
2367 hdr.Reserved1 = 0;
2368 hdr.Reserved2 = 0;
2369 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2370 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2372 cfg.cfghdr.ehdr = &hdr;
2373 cfg.physAddr = -1;
2374 cfg.pageAddr = form + form_specific;
2375 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2376 cfg.dir = 0; /* read */
2377 cfg.timeout = 10;
2379 error = mpt_config(ioc, &cfg);
2380 if (error)
2381 goto out;
2383 if (!hdr.ExtPageLength) {
2384 error = -ENXIO;
2385 goto out;
2388 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2389 &dma_handle);
2390 if (!buffer) {
2391 error = -ENOMEM;
2392 goto out;
2395 cfg.physAddr = dma_handle;
2396 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2398 error = mpt_config(ioc, &cfg);
2399 if (error)
2400 goto out_free_consistent;
2403 mptsas_print_expander_pg1(ioc, buffer);
2405 /* save config data */
2406 phy_info->phy_id = buffer->PhyIdentifier;
2407 phy_info->port_id = buffer->PhysicalPort;
2408 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
2409 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2410 phy_info->hw_link_rate = buffer->HwLinkRate;
2411 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2412 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2414 out_free_consistent:
2415 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2416 buffer, dma_handle);
2417 out:
2418 return error;
2421 static void
2422 mptsas_parse_device_info(struct sas_identify *identify,
2423 struct mptsas_devinfo *device_info)
2425 u16 protocols;
2427 identify->sas_address = device_info->sas_address;
2428 identify->phy_identifier = device_info->phy_id;
2431 * Fill in Phy Initiator Port Protocol.
2432 * Bits 6:3, more than one bit can be set, fall through cases.
2434 protocols = device_info->device_info & 0x78;
2435 identify->initiator_port_protocols = 0;
2436 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
2437 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
2438 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
2439 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
2440 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
2441 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
2442 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
2443 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
2446 * Fill in Phy Target Port Protocol.
2447 * Bits 10:7, more than one bit can be set, fall through cases.
2449 protocols = device_info->device_info & 0x780;
2450 identify->target_port_protocols = 0;
2451 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
2452 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
2453 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
2454 identify->target_port_protocols |= SAS_PROTOCOL_STP;
2455 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
2456 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
2457 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2458 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
2461 * Fill in Attached device type.
2463 switch (device_info->device_info &
2464 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
2465 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
2466 identify->device_type = SAS_PHY_UNUSED;
2467 break;
2468 case MPI_SAS_DEVICE_INFO_END_DEVICE:
2469 identify->device_type = SAS_END_DEVICE;
2470 break;
2471 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
2472 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
2473 break;
2474 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
2475 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
2476 break;
2480 static int mptsas_probe_one_phy(struct device *dev,
2481 struct mptsas_phyinfo *phy_info, int index, int local)
2483 MPT_ADAPTER *ioc;
2484 struct sas_phy *phy;
2485 struct sas_port *port;
2486 int error = 0;
2488 if (!dev) {
2489 error = -ENODEV;
2490 goto out;
2493 if (!phy_info->phy) {
2494 phy = sas_phy_alloc(dev, index);
2495 if (!phy) {
2496 error = -ENOMEM;
2497 goto out;
2499 } else
2500 phy = phy_info->phy;
2502 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
2505 * Set Negotiated link rate.
2507 switch (phy_info->negotiated_link_rate) {
2508 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
2509 phy->negotiated_linkrate = SAS_PHY_DISABLED;
2510 break;
2511 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
2512 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
2513 break;
2514 case MPI_SAS_IOUNIT0_RATE_1_5:
2515 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
2516 break;
2517 case MPI_SAS_IOUNIT0_RATE_3_0:
2518 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
2519 break;
2520 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
2521 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
2522 default:
2523 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
2524 break;
2528 * Set Max hardware link rate.
2530 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
2531 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
2532 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
2533 break;
2534 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
2535 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
2536 break;
2537 default:
2538 break;
2542 * Set Max programmed link rate.
2544 switch (phy_info->programmed_link_rate &
2545 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
2546 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
2547 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
2548 break;
2549 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
2550 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
2551 break;
2552 default:
2553 break;
2557 * Set Min hardware link rate.
2559 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
2560 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
2561 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
2562 break;
2563 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
2564 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
2565 break;
2566 default:
2567 break;
2571 * Set Min programmed link rate.
2573 switch (phy_info->programmed_link_rate &
2574 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
2575 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
2576 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
2577 break;
2578 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
2579 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
2580 break;
2581 default:
2582 break;
2585 if (!phy_info->phy) {
2587 error = sas_phy_add(phy);
2588 if (error) {
2589 sas_phy_free(phy);
2590 goto out;
2592 phy_info->phy = phy;
2595 if (!phy_info->attached.handle ||
2596 !phy_info->port_details)
2597 goto out;
2599 port = mptsas_get_port(phy_info);
2600 ioc = phy_to_ioc(phy_info->phy);
2602 if (phy_info->sas_port_add_phy) {
2604 if (!port) {
2605 port = sas_port_alloc_num(dev);
2606 if (!port) {
2607 error = -ENOMEM;
2608 goto out;
2610 error = sas_port_add(port);
2611 if (error) {
2612 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2613 "%s: exit at line=%d\n", ioc->name,
2614 __func__, __LINE__));
2615 goto out;
2617 mptsas_set_port(ioc, phy_info, port);
2618 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2619 "sas_port_alloc: port=%p dev=%p port_id=%d\n",
2620 ioc->name, port, dev, port->port_identifier));
2622 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_port_add_phy: phy_id=%d\n",
2623 ioc->name, phy_info->phy_id));
2624 sas_port_add_phy(port, phy_info->phy);
2625 phy_info->sas_port_add_phy = 0;
2628 if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
2630 struct sas_rphy *rphy;
2631 struct device *parent;
2632 struct sas_identify identify;
2634 parent = dev->parent->parent;
2636 * Let the hotplug_work thread handle processing
2637 * the adding/removing of devices that occur
2638 * after start of day.
2640 if (ioc->sas_discovery_runtime &&
2641 mptsas_is_end_device(&phy_info->attached))
2642 goto out;
2644 mptsas_parse_device_info(&identify, &phy_info->attached);
2645 if (scsi_is_host_device(parent)) {
2646 struct mptsas_portinfo *port_info;
2647 int i;
2649 mutex_lock(&ioc->sas_topology_mutex);
2650 port_info = mptsas_get_hba_portinfo(ioc);
2651 mutex_unlock(&ioc->sas_topology_mutex);
2653 for (i = 0; i < port_info->num_phys; i++)
2654 if (port_info->phy_info[i].identify.sas_address ==
2655 identify.sas_address) {
2656 sas_port_mark_backlink(port);
2657 goto out;
2660 } else if (scsi_is_sas_rphy(parent)) {
2661 struct sas_rphy *parent_rphy = dev_to_rphy(parent);
2662 if (identify.sas_address ==
2663 parent_rphy->identify.sas_address) {
2664 sas_port_mark_backlink(port);
2665 goto out;
2669 switch (identify.device_type) {
2670 case SAS_END_DEVICE:
2671 rphy = sas_end_device_alloc(port);
2672 break;
2673 case SAS_EDGE_EXPANDER_DEVICE:
2674 case SAS_FANOUT_EXPANDER_DEVICE:
2675 rphy = sas_expander_alloc(port, identify.device_type);
2676 break;
2677 default:
2678 rphy = NULL;
2679 break;
2681 if (!rphy) {
2682 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2683 "%s: exit at line=%d\n", ioc->name,
2684 __func__, __LINE__));
2685 goto out;
2688 rphy->identify = identify;
2689 error = sas_rphy_add(rphy);
2690 if (error) {
2691 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2692 "%s: exit at line=%d\n", ioc->name,
2693 __func__, __LINE__));
2694 sas_rphy_free(rphy);
2695 goto out;
2697 mptsas_set_rphy(ioc, phy_info, rphy);
2700 out:
2701 return error;
2704 static int
2705 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
2707 struct mptsas_portinfo *port_info, *hba;
2708 int error = -ENOMEM, i;
2710 hba = kzalloc(sizeof(*port_info), GFP_KERNEL);
2711 if (! hba)
2712 goto out;
2714 error = mptsas_sas_io_unit_pg0(ioc, hba);
2715 if (error)
2716 goto out_free_port_info;
2718 mptsas_sas_io_unit_pg1(ioc);
2719 mutex_lock(&ioc->sas_topology_mutex);
2720 port_info = mptsas_get_hba_portinfo(ioc);
2721 if (!port_info) {
2722 port_info = hba;
2723 list_add_tail(&port_info->list, &ioc->sas_topology);
2724 } else {
2725 for (i = 0; i < hba->num_phys; i++) {
2726 port_info->phy_info[i].negotiated_link_rate =
2727 hba->phy_info[i].negotiated_link_rate;
2728 port_info->phy_info[i].handle =
2729 hba->phy_info[i].handle;
2730 port_info->phy_info[i].port_id =
2731 hba->phy_info[i].port_id;
2733 kfree(hba->phy_info);
2734 kfree(hba);
2735 hba = NULL;
2737 mutex_unlock(&ioc->sas_topology_mutex);
2738 for (i = 0; i < port_info->num_phys; i++) {
2739 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
2740 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
2741 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
2743 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
2744 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2745 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2746 port_info->phy_info[i].handle);
2747 port_info->phy_info[i].identify.phy_id =
2748 port_info->phy_info[i].phy_id = i;
2749 if (port_info->phy_info[i].attached.handle)
2750 mptsas_sas_device_pg0(ioc,
2751 &port_info->phy_info[i].attached,
2752 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2753 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2754 port_info->phy_info[i].attached.handle);
2757 mptsas_setup_wide_ports(ioc, port_info);
2759 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
2760 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
2761 &port_info->phy_info[i], ioc->sas_index, 1);
2763 return 0;
2765 out_free_port_info:
2766 kfree(hba);
2767 out:
2768 return error;
2771 static int
2772 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
2774 struct mptsas_portinfo *port_info, *p, *ex;
2775 struct device *parent;
2776 struct sas_rphy *rphy;
2777 int error = -ENOMEM, i, j;
2779 ex = kzalloc(sizeof(*port_info), GFP_KERNEL);
2780 if (!ex)
2781 goto out;
2783 error = mptsas_sas_expander_pg0(ioc, ex,
2784 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
2785 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
2786 if (error)
2787 goto out_free_port_info;
2789 *handle = ex->phy_info[0].handle;
2791 mutex_lock(&ioc->sas_topology_mutex);
2792 port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
2793 if (!port_info) {
2794 port_info = ex;
2795 list_add_tail(&port_info->list, &ioc->sas_topology);
2796 } else {
2797 for (i = 0; i < ex->num_phys; i++) {
2798 port_info->phy_info[i].handle =
2799 ex->phy_info[i].handle;
2800 port_info->phy_info[i].port_id =
2801 ex->phy_info[i].port_id;
2803 kfree(ex->phy_info);
2804 kfree(ex);
2805 ex = NULL;
2807 mutex_unlock(&ioc->sas_topology_mutex);
2809 for (i = 0; i < port_info->num_phys; i++) {
2810 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
2811 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
2812 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
2814 if (port_info->phy_info[i].identify.handle) {
2815 mptsas_sas_device_pg0(ioc,
2816 &port_info->phy_info[i].identify,
2817 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2818 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2819 port_info->phy_info[i].identify.handle);
2820 port_info->phy_info[i].identify.phy_id =
2821 port_info->phy_info[i].phy_id;
2824 if (port_info->phy_info[i].attached.handle) {
2825 mptsas_sas_device_pg0(ioc,
2826 &port_info->phy_info[i].attached,
2827 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2828 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2829 port_info->phy_info[i].attached.handle);
2830 port_info->phy_info[i].attached.phy_id =
2831 port_info->phy_info[i].phy_id;
2835 parent = &ioc->sh->shost_gendev;
2836 for (i = 0; i < port_info->num_phys; i++) {
2837 mutex_lock(&ioc->sas_topology_mutex);
2838 list_for_each_entry(p, &ioc->sas_topology, list) {
2839 for (j = 0; j < p->num_phys; j++) {
2840 if (port_info->phy_info[i].identify.handle !=
2841 p->phy_info[j].attached.handle)
2842 continue;
2843 rphy = mptsas_get_rphy(&p->phy_info[j]);
2844 parent = &rphy->dev;
2847 mutex_unlock(&ioc->sas_topology_mutex);
2850 mptsas_setup_wide_ports(ioc, port_info);
2852 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
2853 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
2854 ioc->sas_index, 0);
2856 return 0;
2858 out_free_port_info:
2859 if (ex) {
2860 kfree(ex->phy_info);
2861 kfree(ex);
2863 out:
2864 return error;
2868 * mptsas_delete_expander_phys
2871 * This will traverse topology, and remove expanders
2872 * that are no longer present
2874 static void
2875 mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
2877 struct mptsas_portinfo buffer;
2878 struct mptsas_portinfo *port_info, *n, *parent;
2879 struct mptsas_phyinfo *phy_info;
2880 struct sas_port * port;
2881 int i;
2882 u64 expander_sas_address;
2884 mutex_lock(&ioc->sas_topology_mutex);
2885 list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
2887 if (!(port_info->phy_info[0].identify.device_info &
2888 MPI_SAS_DEVICE_INFO_SMP_TARGET))
2889 continue;
2891 if (mptsas_sas_expander_pg0(ioc, &buffer,
2892 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
2893 MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
2894 port_info->phy_info[0].handle)) {
2897 * Obtain the port_info instance to the parent port
2899 parent = mptsas_find_portinfo_by_handle(ioc,
2900 port_info->phy_info[0].identify.handle_parent);
2902 if (!parent)
2903 goto next_port;
2905 expander_sas_address =
2906 port_info->phy_info[0].identify.sas_address;
2909 * Delete rphys in the parent that point
2910 * to this expander. The transport layer will
2911 * cleanup all the children.
2913 phy_info = parent->phy_info;
2914 for (i = 0; i < parent->num_phys; i++, phy_info++) {
2915 port = mptsas_get_port(phy_info);
2916 if (!port)
2917 continue;
2918 if (phy_info->attached.sas_address !=
2919 expander_sas_address)
2920 continue;
2921 dsaswideprintk(ioc,
2922 dev_printk(KERN_DEBUG, &port->dev,
2923 MYIOC_s_FMT "delete port (%d)\n", ioc->name,
2924 port->port_identifier));
2925 sas_port_delete(port);
2926 mptsas_port_delete(ioc, phy_info->port_details);
2928 next_port:
2930 phy_info = port_info->phy_info;
2931 for (i = 0; i < port_info->num_phys; i++, phy_info++)
2932 mptsas_port_delete(ioc, phy_info->port_details);
2934 list_del(&port_info->list);
2935 kfree(port_info->phy_info);
2936 kfree(port_info);
2939 * Free this memory allocated from inside
2940 * mptsas_sas_expander_pg0
2942 kfree(buffer.phy_info);
2944 mutex_unlock(&ioc->sas_topology_mutex);
2948 * Start of day discovery
2950 static void
2951 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
2953 u32 handle = 0xFFFF;
2954 int i;
2956 mutex_lock(&ioc->sas_discovery_mutex);
2957 mptsas_probe_hba_phys(ioc);
2958 while (!mptsas_probe_expander_phys(ioc, &handle))
2961 Reporting RAID volumes.
2963 if (!ioc->ir_firmware)
2964 goto out;
2965 if (!ioc->raid_data.pIocPg2)
2966 goto out;
2967 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
2968 goto out;
2969 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
2970 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
2971 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
2973 out:
2974 mutex_unlock(&ioc->sas_discovery_mutex);
2978 * Work queue thread to handle Runtime discovery
2979 * Mere purpose is the hot add/delete of expanders
2980 *(Mutex UNLOCKED)
2982 static void
2983 __mptsas_discovery_work(MPT_ADAPTER *ioc)
2985 u32 handle = 0xFFFF;
2987 ioc->sas_discovery_runtime=1;
2988 mptsas_delete_expander_phys(ioc);
2989 mptsas_probe_hba_phys(ioc);
2990 while (!mptsas_probe_expander_phys(ioc, &handle))
2992 ioc->sas_discovery_runtime=0;
2996 * Work queue thread to handle Runtime discovery
2997 * Mere purpose is the hot add/delete of expanders
2998 *(Mutex LOCKED)
3000 static void
3001 mptsas_discovery_work(struct work_struct *work)
3003 struct mptsas_discovery_event *ev =
3004 container_of(work, struct mptsas_discovery_event, work);
3005 MPT_ADAPTER *ioc = ev->ioc;
3007 mutex_lock(&ioc->sas_discovery_mutex);
3008 __mptsas_discovery_work(ioc);
3009 mutex_unlock(&ioc->sas_discovery_mutex);
3010 kfree(ev);
3014 static struct mptsas_phyinfo *
3015 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
3017 struct mptsas_portinfo *port_info;
3018 struct mptsas_phyinfo *phy_info = NULL;
3019 int i;
3021 mutex_lock(&ioc->sas_topology_mutex);
3022 list_for_each_entry(port_info, &ioc->sas_topology, list) {
3023 for (i = 0; i < port_info->num_phys; i++) {
3024 if (!mptsas_is_end_device(
3025 &port_info->phy_info[i].attached))
3026 continue;
3027 if (port_info->phy_info[i].attached.sas_address
3028 != sas_address)
3029 continue;
3030 phy_info = &port_info->phy_info[i];
3031 break;
3034 mutex_unlock(&ioc->sas_topology_mutex);
3035 return phy_info;
3039 static struct mptsas_phyinfo *
3040 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
3042 struct mptsas_portinfo *port_info;
3043 struct mptsas_phyinfo *phy_info = NULL;
3044 int i;
3046 mutex_lock(&ioc->sas_topology_mutex);
3047 list_for_each_entry(port_info, &ioc->sas_topology, list) {
3048 for (i = 0; i < port_info->num_phys; i++) {
3049 if (!mptsas_is_end_device(
3050 &port_info->phy_info[i].attached))
3051 continue;
3052 if (port_info->phy_info[i].attached.phys_disk_num == ~0)
3053 continue;
3054 if (port_info->phy_info[i].attached.phys_disk_num != id)
3055 continue;
3056 if (port_info->phy_info[i].attached.channel != channel)
3057 continue;
3058 phy_info = &port_info->phy_info[i];
3059 break;
3062 mutex_unlock(&ioc->sas_topology_mutex);
3063 return phy_info;
3066 static void
3067 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
3069 int rc;
3071 sdev->no_uld_attach = data ? 1 : 0;
3072 rc = scsi_device_reprobe(sdev);
3075 static void
3076 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
3078 starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
3079 mptsas_reprobe_lun);
3082 static void
3083 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
3085 CONFIGPARMS cfg;
3086 ConfigPageHeader_t hdr;
3087 dma_addr_t dma_handle;
3088 pRaidVolumePage0_t buffer = NULL;
3089 RaidPhysDiskPage0_t phys_disk;
3090 int i;
3091 struct mptsas_phyinfo *phy_info;
3092 struct mptsas_devinfo sas_device;
3094 memset(&cfg, 0 , sizeof(CONFIGPARMS));
3095 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
3096 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
3097 cfg.pageAddr = (channel << 8) + id;
3098 cfg.cfghdr.hdr = &hdr;
3099 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3101 if (mpt_config(ioc, &cfg) != 0)
3102 goto out;
3104 if (!hdr.PageLength)
3105 goto out;
3107 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
3108 &dma_handle);
3110 if (!buffer)
3111 goto out;
3113 cfg.physAddr = dma_handle;
3114 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3116 if (mpt_config(ioc, &cfg) != 0)
3117 goto out;
3119 if (!(buffer->VolumeStatus.Flags &
3120 MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
3121 goto out;
3123 if (!buffer->NumPhysDisks)
3124 goto out;
3126 for (i = 0; i < buffer->NumPhysDisks; i++) {
3128 if (mpt_raid_phys_disk_pg0(ioc,
3129 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
3130 continue;
3132 if (mptsas_sas_device_pg0(ioc, &sas_device,
3133 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
3134 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3135 (phys_disk.PhysDiskBus << 8) +
3136 phys_disk.PhysDiskID))
3137 continue;
3139 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3140 sas_device.sas_address);
3141 mptsas_add_end_device(ioc, phy_info);
3144 out:
3145 if (buffer)
3146 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
3147 dma_handle);
3150 * Work queue thread to handle SAS hotplug events
3152 static void
3153 mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
3154 struct mptsas_hotplug_event *hot_plug_info)
3156 struct mptsas_phyinfo *phy_info;
3157 struct scsi_target * starget;
3158 struct mptsas_devinfo sas_device;
3159 VirtTarget *vtarget;
3160 int i;
3162 switch (hot_plug_info->event_type) {
3164 case MPTSAS_ADD_PHYSDISK:
3166 if (!ioc->raid_data.pIocPg2)
3167 break;
3169 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
3170 if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID ==
3171 hot_plug_info->id) {
3172 printk(MYIOC_s_WARN_FMT "firmware bug: unable "
3173 "to add hidden disk - target_id matchs "
3174 "volume_id\n", ioc->name);
3175 mptsas_free_fw_event(ioc, fw_event);
3176 return;
3179 mpt_findImVolumes(ioc);
3181 case MPTSAS_ADD_DEVICE:
3182 memset(&sas_device, 0, sizeof(struct mptsas_devinfo));
3183 mptsas_sas_device_pg0(ioc, &sas_device,
3184 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
3185 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3186 (hot_plug_info->channel << 8) +
3187 hot_plug_info->id);
3189 if (!sas_device.handle)
3190 return;
3192 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3193 if (!phy_info)
3194 break;
3196 if (mptsas_get_rphy(phy_info))
3197 break;
3199 mptsas_add_end_device(ioc, phy_info);
3200 break;
3202 case MPTSAS_DEL_DEVICE:
3203 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3204 hot_plug_info->sas_address);
3205 mptsas_del_end_device(ioc, phy_info);
3206 break;
3208 case MPTSAS_DEL_PHYSDISK:
3210 mpt_findImVolumes(ioc);
3212 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
3213 ioc, hot_plug_info->channel,
3214 hot_plug_info->phys_disk_num);
3215 mptsas_del_end_device(ioc, phy_info);
3216 break;
3218 case MPTSAS_ADD_PHYSDISK_REPROBE:
3220 if (mptsas_sas_device_pg0(ioc, &sas_device,
3221 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
3222 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3223 (hot_plug_info->channel << 8) + hot_plug_info->id)) {
3224 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3225 "%s: fw_id=%d exit at line=%d\n", ioc->name,
3226 __func__, hot_plug_info->id, __LINE__));
3227 break;
3230 phy_info = mptsas_find_phyinfo_by_sas_address(
3231 ioc, sas_device.sas_address);
3233 if (!phy_info) {
3234 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3235 "%s: fw_id=%d exit at line=%d\n", ioc->name,
3236 __func__, hot_plug_info->id, __LINE__));
3237 break;
3240 starget = mptsas_get_starget(phy_info);
3241 if (!starget) {
3242 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3243 "%s: fw_id=%d exit at line=%d\n", ioc->name,
3244 __func__, hot_plug_info->id, __LINE__));
3245 break;
3248 vtarget = starget->hostdata;
3249 if (!vtarget) {
3250 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3251 "%s: fw_id=%d exit at line=%d\n", ioc->name,
3252 __func__, hot_plug_info->id, __LINE__));
3253 break;
3256 mpt_findImVolumes(ioc);
3258 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Hidding: "
3259 "fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
3260 ioc->name, hot_plug_info->channel, hot_plug_info->id,
3261 hot_plug_info->phys_disk_num, (unsigned long long)
3262 sas_device.sas_address);
3264 vtarget->id = hot_plug_info->phys_disk_num;
3265 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
3266 phy_info->attached.phys_disk_num = hot_plug_info->phys_disk_num;
3267 mptsas_reprobe_target(starget, 1);
3268 break;
3270 case MPTSAS_DEL_PHYSDISK_REPROBE:
3272 if (mptsas_sas_device_pg0(ioc, &sas_device,
3273 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
3274 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3275 (hot_plug_info->channel << 8) + hot_plug_info->id)) {
3276 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3277 "%s: fw_id=%d exit at line=%d\n",
3278 ioc->name, __func__,
3279 hot_plug_info->id, __LINE__));
3280 break;
3283 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3284 sas_device.sas_address);
3285 if (!phy_info) {
3286 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3287 "%s: fw_id=%d exit at line=%d\n", ioc->name,
3288 __func__, hot_plug_info->id, __LINE__));
3289 break;
3292 starget = mptsas_get_starget(phy_info);
3293 if (!starget) {
3294 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3295 "%s: fw_id=%d exit at line=%d\n", ioc->name,
3296 __func__, hot_plug_info->id, __LINE__));
3297 break;
3300 vtarget = starget->hostdata;
3301 if (!vtarget) {
3302 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3303 "%s: fw_id=%d exit at line=%d\n", ioc->name,
3304 __func__, hot_plug_info->id, __LINE__));
3305 break;
3308 if (!(vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)) {
3309 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3310 "%s: fw_id=%d exit at line=%d\n", ioc->name,
3311 __func__, hot_plug_info->id, __LINE__));
3312 break;
3315 mpt_findImVolumes(ioc);
3317 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Exposing:"
3318 " fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
3319 ioc->name, hot_plug_info->channel, hot_plug_info->id,
3320 hot_plug_info->phys_disk_num, (unsigned long long)
3321 sas_device.sas_address);
3323 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
3324 vtarget->id = hot_plug_info->id;
3325 phy_info->attached.phys_disk_num = ~0;
3326 mptsas_reprobe_target(starget, 0);
3327 mptsas_add_device_component_by_fw(ioc,
3328 hot_plug_info->channel, hot_plug_info->id);
3329 break;
3331 case MPTSAS_ADD_RAID:
3333 mpt_findImVolumes(ioc);
3334 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
3335 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
3336 hot_plug_info->id);
3337 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
3338 hot_plug_info->id, 0);
3339 break;
3341 case MPTSAS_DEL_RAID:
3343 mpt_findImVolumes(ioc);
3344 printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
3345 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
3346 hot_plug_info->id);
3347 scsi_remove_device(hot_plug_info->sdev);
3348 scsi_device_put(hot_plug_info->sdev);
3349 break;
3351 case MPTSAS_ADD_INACTIVE_VOLUME:
3353 mpt_findImVolumes(ioc);
3354 mptsas_adding_inactive_raid_components(ioc,
3355 hot_plug_info->channel, hot_plug_info->id);
3356 break;
3358 default:
3359 break;
3362 mptsas_free_fw_event(ioc, fw_event);
3365 static void
3366 mptsas_send_sas_event(struct fw_event_work *fw_event)
3368 MPT_ADAPTER *ioc;
3369 struct mptsas_hotplug_event hot_plug_info;
3370 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
3371 u32 device_info;
3372 u64 sas_address;
3374 ioc = fw_event->ioc;
3375 sas_event_data = (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
3376 fw_event->event_data;
3377 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
3379 if ((device_info &
3380 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
3381 MPI_SAS_DEVICE_INFO_STP_TARGET |
3382 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0) {
3383 mptsas_free_fw_event(ioc, fw_event);
3384 return;
3387 if (sas_event_data->ReasonCode ==
3388 MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED) {
3389 mptbase_sas_persist_operation(ioc,
3390 MPI_SAS_OP_CLEAR_NOT_PRESENT);
3391 mptsas_free_fw_event(ioc, fw_event);
3392 return;
3395 switch (sas_event_data->ReasonCode) {
3396 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
3397 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
3398 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
3399 hot_plug_info.handle = le16_to_cpu(sas_event_data->DevHandle);
3400 hot_plug_info.channel = sas_event_data->Bus;
3401 hot_plug_info.id = sas_event_data->TargetID;
3402 hot_plug_info.phy_id = sas_event_data->PhyNum;
3403 memcpy(&sas_address, &sas_event_data->SASAddress,
3404 sizeof(u64));
3405 hot_plug_info.sas_address = le64_to_cpu(sas_address);
3406 hot_plug_info.device_info = device_info;
3407 if (sas_event_data->ReasonCode &
3408 MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
3409 hot_plug_info.event_type = MPTSAS_ADD_DEVICE;
3410 else
3411 hot_plug_info.event_type = MPTSAS_DEL_DEVICE;
3412 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
3413 break;
3415 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
3416 mptbase_sas_persist_operation(ioc,
3417 MPI_SAS_OP_CLEAR_NOT_PRESENT);
3418 mptsas_free_fw_event(ioc, fw_event);
3419 break;
3421 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
3422 /* TODO */
3423 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
3424 /* TODO */
3425 default:
3426 mptsas_free_fw_event(ioc, fw_event);
3427 break;
3431 static void
3432 mptsas_send_raid_event(struct fw_event_work *fw_event)
3434 MPT_ADAPTER *ioc;
3435 EVENT_DATA_RAID *raid_event_data;
3436 struct mptsas_hotplug_event hot_plug_info;
3437 int status;
3438 int state;
3439 struct scsi_device *sdev = NULL;
3440 VirtDevice *vdevice = NULL;
3441 RaidPhysDiskPage0_t phys_disk;
3443 ioc = fw_event->ioc;
3444 raid_event_data = (EVENT_DATA_RAID *)fw_event->event_data;
3445 status = le32_to_cpu(raid_event_data->SettingsStatus);
3446 state = (status >> 8) & 0xff;
3448 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
3449 hot_plug_info.id = raid_event_data->VolumeID;
3450 hot_plug_info.channel = raid_event_data->VolumeBus;
3451 hot_plug_info.phys_disk_num = raid_event_data->PhysDiskNum;
3453 if (raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_DELETED ||
3454 raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_CREATED ||
3455 raid_event_data->ReasonCode ==
3456 MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED) {
3457 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
3458 hot_plug_info.id, 0);
3459 hot_plug_info.sdev = sdev;
3460 if (sdev)
3461 vdevice = sdev->hostdata;
3464 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
3465 "ReasonCode=%02x\n", ioc->name, __func__,
3466 raid_event_data->ReasonCode));
3468 switch (raid_event_data->ReasonCode) {
3469 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
3470 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK_REPROBE;
3471 break;
3472 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
3473 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK_REPROBE;
3474 break;
3475 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
3476 switch (state) {
3477 case MPI_PD_STATE_ONLINE:
3478 case MPI_PD_STATE_NOT_COMPATIBLE:
3479 mpt_raid_phys_disk_pg0(ioc,
3480 raid_event_data->PhysDiskNum, &phys_disk);
3481 hot_plug_info.id = phys_disk.PhysDiskID;
3482 hot_plug_info.channel = phys_disk.PhysDiskBus;
3483 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
3484 break;
3485 case MPI_PD_STATE_FAILED:
3486 case MPI_PD_STATE_MISSING:
3487 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
3488 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
3489 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
3490 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
3491 break;
3492 default:
3493 break;
3495 break;
3496 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
3497 if (!sdev)
3498 break;
3499 vdevice->vtarget->deleted = 1; /* block IO */
3500 hot_plug_info.event_type = MPTSAS_DEL_RAID;
3501 break;
3502 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
3503 if (sdev) {
3504 scsi_device_put(sdev);
3505 break;
3507 hot_plug_info.event_type = MPTSAS_ADD_RAID;
3508 break;
3509 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
3510 if (!(status & MPI_RAIDVOL0_STATUS_FLAG_ENABLED)) {
3511 if (!sdev)
3512 break;
3513 vdevice->vtarget->deleted = 1; /* block IO */
3514 hot_plug_info.event_type = MPTSAS_DEL_RAID;
3515 break;
3517 switch (state) {
3518 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
3519 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
3520 if (!sdev)
3521 break;
3522 vdevice->vtarget->deleted = 1; /* block IO */
3523 hot_plug_info.event_type = MPTSAS_DEL_RAID;
3524 break;
3525 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
3526 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
3527 if (sdev) {
3528 scsi_device_put(sdev);
3529 break;
3531 hot_plug_info.event_type = MPTSAS_ADD_RAID;
3532 break;
3533 default:
3534 break;
3536 break;
3537 default:
3538 break;
3541 if (hot_plug_info.event_type != MPTSAS_IGNORE_EVENT)
3542 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
3543 else
3544 mptsas_free_fw_event(ioc, fw_event);
3547 static void
3548 mptsas_send_discovery_event(MPT_ADAPTER *ioc,
3549 EVENT_DATA_SAS_DISCOVERY *discovery_data)
3551 struct mptsas_discovery_event *ev;
3552 u32 discovery_status;
3555 * DiscoveryStatus
3557 * This flag will be non-zero when firmware
3558 * kicks off discovery, and return to zero
3559 * once its completed.
3561 discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus);
3562 ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0;
3563 if (discovery_status)
3564 return;
3566 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
3567 if (!ev)
3568 return;
3569 INIT_WORK(&ev->work, mptsas_discovery_work);
3570 ev->ioc = ioc;
3571 schedule_work(&ev->work);
3575 * mptsas_send_ir2_event - handle exposing hidden disk when
3576 * an inactive raid volume is added
3578 * @ioc: Pointer to MPT_ADAPTER structure
3579 * @ir2_data
3582 static void
3583 mptsas_send_ir2_event(struct fw_event_work *fw_event)
3585 MPT_ADAPTER *ioc;
3586 struct mptsas_hotplug_event hot_plug_info;
3587 MPI_EVENT_DATA_IR2 *ir2_data;
3588 u8 reasonCode;
3590 ioc = fw_event->ioc;
3591 ir2_data = (MPI_EVENT_DATA_IR2 *)fw_event->event_data;
3592 reasonCode = ir2_data->ReasonCode;
3594 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
3595 "ReasonCode=%02x\n", ioc->name, __func__, reasonCode));
3597 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
3598 hot_plug_info.id = ir2_data->TargetID;
3599 hot_plug_info.channel = ir2_data->Bus;
3600 switch (reasonCode) {
3601 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
3602 hot_plug_info.event_type = MPTSAS_ADD_INACTIVE_VOLUME;
3603 break;
3604 default:
3605 mptsas_free_fw_event(ioc, fw_event);
3606 return;
3608 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
3611 static int
3612 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
3614 u32 event = le32_to_cpu(reply->Event);
3615 int sz, event_data_sz;
3616 struct fw_event_work *fw_event;
3617 unsigned long delay;
3619 /* events turned off due to host reset or driver unloading */
3620 if (ioc->fw_events_off)
3621 return 0;
3623 delay = msecs_to_jiffies(1);
3624 switch (event) {
3625 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
3627 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data =
3628 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data;
3630 if (sas_event_data->ReasonCode ==
3631 MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) {
3632 mptsas_target_reset_queue(ioc, sas_event_data);
3633 return 0;
3635 break;
3637 case MPI_EVENT_SAS_DISCOVERY:
3638 mptsas_send_discovery_event(ioc,
3639 (EVENT_DATA_SAS_DISCOVERY *)reply->Data);
3640 break;
3641 case MPI_EVENT_INTEGRATED_RAID:
3642 case MPI_EVENT_PERSISTENT_TABLE_FULL:
3643 case MPI_EVENT_IR2:
3644 case MPI_EVENT_SAS_PHY_LINK_STATUS:
3645 case MPI_EVENT_QUEUE_FULL:
3646 break;
3647 default:
3648 return 0;
3651 event_data_sz = ((reply->MsgLength * 4) -
3652 offsetof(EventNotificationReply_t, Data));
3653 sz = offsetof(struct fw_event_work, event_data) + event_data_sz;
3654 fw_event = kzalloc(sz, GFP_ATOMIC);
3655 if (!fw_event) {
3656 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name,
3657 __func__, __LINE__);
3658 return 0;
3660 memcpy(fw_event->event_data, reply->Data, event_data_sz);
3661 fw_event->event = event;
3662 fw_event->ioc = ioc;
3663 mptsas_add_fw_event(ioc, fw_event, delay);
3664 return 0;
3667 static int
3668 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3670 struct Scsi_Host *sh;
3671 MPT_SCSI_HOST *hd;
3672 MPT_ADAPTER *ioc;
3673 unsigned long flags;
3674 int ii;
3675 int numSGE = 0;
3676 int scale;
3677 int ioc_cap;
3678 int error=0;
3679 int r;
3681 r = mpt_attach(pdev,id);
3682 if (r)
3683 return r;
3685 ioc = pci_get_drvdata(pdev);
3686 mptsas_fw_event_off(ioc);
3687 ioc->DoneCtx = mptsasDoneCtx;
3688 ioc->TaskCtx = mptsasTaskCtx;
3689 ioc->InternalCtx = mptsasInternalCtx;
3691 /* Added sanity check on readiness of the MPT adapter.
3693 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
3694 printk(MYIOC_s_WARN_FMT
3695 "Skipping because it's not operational!\n",
3696 ioc->name);
3697 error = -ENODEV;
3698 goto out_mptsas_probe;
3701 if (!ioc->active) {
3702 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
3703 ioc->name);
3704 error = -ENODEV;
3705 goto out_mptsas_probe;
3708 /* Sanity check - ensure at least 1 port is INITIATOR capable
3710 ioc_cap = 0;
3711 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
3712 if (ioc->pfacts[ii].ProtocolFlags &
3713 MPI_PORTFACTS_PROTOCOL_INITIATOR)
3714 ioc_cap++;
3717 if (!ioc_cap) {
3718 printk(MYIOC_s_WARN_FMT
3719 "Skipping ioc=%p because SCSI Initiator mode "
3720 "is NOT enabled!\n", ioc->name, ioc);
3721 return 0;
3724 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
3725 if (!sh) {
3726 printk(MYIOC_s_WARN_FMT
3727 "Unable to register controller with SCSI subsystem\n",
3728 ioc->name);
3729 error = -1;
3730 goto out_mptsas_probe;
3733 spin_lock_irqsave(&ioc->FreeQlock, flags);
3735 /* Attach the SCSI Host to the IOC structure
3737 ioc->sh = sh;
3739 sh->io_port = 0;
3740 sh->n_io_port = 0;
3741 sh->irq = 0;
3743 /* set 16 byte cdb's */
3744 sh->max_cmd_len = 16;
3746 sh->max_id = ioc->pfacts[0].PortSCSIID;
3747 sh->max_lun = max_lun;
3749 sh->transportt = mptsas_transport_template;
3751 /* Required entry.
3753 sh->unique_id = ioc->id;
3755 INIT_LIST_HEAD(&ioc->sas_topology);
3756 mutex_init(&ioc->sas_topology_mutex);
3757 mutex_init(&ioc->sas_discovery_mutex);
3758 mutex_init(&ioc->sas_mgmt.mutex);
3759 init_completion(&ioc->sas_mgmt.done);
3761 /* Verify that we won't exceed the maximum
3762 * number of chain buffers
3763 * We can optimize: ZZ = req_sz/sizeof(SGE)
3764 * For 32bit SGE's:
3765 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
3766 * + (req_sz - 64)/sizeof(SGE)
3767 * A slightly different algorithm is required for
3768 * 64bit SGEs.
3770 scale = ioc->req_sz/ioc->SGE_size;
3771 if (ioc->sg_addr_size == sizeof(u64)) {
3772 numSGE = (scale - 1) *
3773 (ioc->facts.MaxChainDepth-1) + scale +
3774 (ioc->req_sz - 60) / ioc->SGE_size;
3775 } else {
3776 numSGE = 1 + (scale - 1) *
3777 (ioc->facts.MaxChainDepth-1) + scale +
3778 (ioc->req_sz - 64) / ioc->SGE_size;
3781 if (numSGE < sh->sg_tablesize) {
3782 /* Reset this value */
3783 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3784 "Resetting sg_tablesize to %d from %d\n",
3785 ioc->name, numSGE, sh->sg_tablesize));
3786 sh->sg_tablesize = numSGE;
3789 hd = shost_priv(sh);
3790 hd->ioc = ioc;
3792 /* SCSI needs scsi_cmnd lookup table!
3793 * (with size equal to req_depth*PtrSz!)
3795 ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
3796 if (!ioc->ScsiLookup) {
3797 error = -ENOMEM;
3798 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3799 goto out_mptsas_probe;
3801 spin_lock_init(&ioc->scsi_lookup_lock);
3803 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
3804 ioc->name, ioc->ScsiLookup));
3806 /* Clear the TM flags
3808 hd->abortSCpnt = NULL;
3810 /* Clear the pointer used to store
3811 * single-threaded commands, i.e., those
3812 * issued during a bus scan, dv and
3813 * configuration pages.
3815 hd->cmdPtr = NULL;
3817 /* Initialize this SCSI Hosts' timers
3818 * To use, set the timer expires field
3819 * and add_timer
3821 init_timer(&hd->timer);
3822 hd->timer.data = (unsigned long) hd;
3823 hd->timer.function = mptscsih_timer_expired;
3825 ioc->sas_data.ptClear = mpt_pt_clear;
3827 hd->last_queue_full = 0;
3828 INIT_LIST_HEAD(&hd->target_reset_list);
3829 INIT_LIST_HEAD(&ioc->sas_device_info_list);
3830 mutex_init(&ioc->sas_device_info_mutex);
3832 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3834 if (ioc->sas_data.ptClear==1) {
3835 mptbase_sas_persist_operation(
3836 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
3839 error = scsi_add_host(sh, &ioc->pcidev->dev);
3840 if (error) {
3841 dprintk(ioc, printk(MYIOC_s_ERR_FMT
3842 "scsi_add_host failed\n", ioc->name));
3843 goto out_mptsas_probe;
3846 mptsas_scan_sas_topology(ioc);
3847 mptsas_fw_event_on(ioc);
3848 return 0;
3850 out_mptsas_probe:
3852 mptscsih_remove(pdev);
3853 return error;
3856 void
3857 mptsas_shutdown(struct pci_dev *pdev)
3859 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
3861 mptsas_fw_event_off(ioc);
3862 mptsas_cleanup_fw_event_q(ioc);
3865 static void __devexit mptsas_remove(struct pci_dev *pdev)
3867 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
3868 struct mptsas_portinfo *p, *n;
3869 int i;
3871 mptsas_shutdown(pdev);
3873 mptsas_del_device_components(ioc);
3875 ioc->sas_discovery_ignore_events = 1;
3876 sas_remove_host(ioc->sh);
3878 mutex_lock(&ioc->sas_topology_mutex);
3879 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
3880 list_del(&p->list);
3881 for (i = 0 ; i < p->num_phys ; i++)
3882 mptsas_port_delete(ioc, p->phy_info[i].port_details);
3884 kfree(p->phy_info);
3885 kfree(p);
3887 mutex_unlock(&ioc->sas_topology_mutex);
3889 mptscsih_remove(pdev);
3892 static struct pci_device_id mptsas_pci_table[] = {
3893 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
3894 PCI_ANY_ID, PCI_ANY_ID },
3895 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
3896 PCI_ANY_ID, PCI_ANY_ID },
3897 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
3898 PCI_ANY_ID, PCI_ANY_ID },
3899 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
3900 PCI_ANY_ID, PCI_ANY_ID },
3901 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
3902 PCI_ANY_ID, PCI_ANY_ID },
3903 {0} /* Terminating entry */
3905 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
3908 static struct pci_driver mptsas_driver = {
3909 .name = "mptsas",
3910 .id_table = mptsas_pci_table,
3911 .probe = mptsas_probe,
3912 .remove = __devexit_p(mptsas_remove),
3913 .shutdown = mptsas_shutdown,
3914 #ifdef CONFIG_PM
3915 .suspend = mptscsih_suspend,
3916 .resume = mptscsih_resume,
3917 #endif
3920 static int __init
3921 mptsas_init(void)
3923 int error;
3925 show_mptmod_ver(my_NAME, my_VERSION);
3927 mptsas_transport_template =
3928 sas_attach_transport(&mptsas_transport_functions);
3929 if (!mptsas_transport_template)
3930 return -ENODEV;
3932 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
3933 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
3934 mptsasInternalCtx =
3935 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
3936 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
3937 mptsasDeviceResetCtx =
3938 mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
3940 mpt_event_register(mptsasDoneCtx, mptsas_event_process);
3941 mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
3943 error = pci_register_driver(&mptsas_driver);
3944 if (error)
3945 sas_release_transport(mptsas_transport_template);
3947 return error;
3950 static void __exit
3951 mptsas_exit(void)
3953 pci_unregister_driver(&mptsas_driver);
3954 sas_release_transport(mptsas_transport_template);
3956 mpt_reset_deregister(mptsasDoneCtx);
3957 mpt_event_deregister(mptsasDoneCtx);
3959 mpt_deregister(mptsasMgmtCtx);
3960 mpt_deregister(mptsasInternalCtx);
3961 mpt_deregister(mptsasTaskCtx);
3962 mpt_deregister(mptsasDoneCtx);
3963 mpt_deregister(mptsasDeviceResetCtx);
3966 module_init(mptsas_init);
3967 module_exit(mptsas_exit);