1 /*
2 * linux/drivers/message/fusion/mptsas.c
3 * For use with LSI PCI chip/adapter(s)
4 * running LSI Fusion MPT (Message Passing Technology) firmware.
5 *
6 * Copyright (c) 1999-2008 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 */
9 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
10 /*
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; version 2 of the License.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 NO WARRANTY
21 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
22 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
23 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
24 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
25 solely responsible for determining the appropriateness of using and
26 distributing the Program and assumes all risks associated with its
27 exercise of rights under this Agreement, including but not limited to
28 the risks and costs of program errors, damage to or loss of data,
29 programs or equipment, and unavailability or interruption of operations.
30
31 DISCLAIMER OF LIABILITY
32 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
33 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
35 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
38 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
39
40 You should have received a copy of the GNU General Public License
41 along with this program; if not, write to the Free Software
42 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
43 */
44 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
45
46 #include <linux/module.h>
47 #include <linux/kernel.h>
48 #include <linux/slab.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/jiffies.h>
52 #include <linux/workqueue.h>
53 #include <linux/delay.h> /* for mdelay */
54
55 #include <scsi/scsi.h>
56 #include <scsi/scsi_cmnd.h>
57 #include <scsi/scsi_device.h>
58 #include <scsi/scsi_host.h>
59 #include <scsi/scsi_transport_sas.h>
60 #include <scsi/scsi_transport.h>
61 #include <scsi/scsi_dbg.h>
62
63 #include "mptbase.h"
64 #include "mptscsih.h"
65 #include "mptsas.h"
66
67
68 #define my_NAME "Fusion MPT SAS Host driver"
69 #define my_VERSION MPT_LINUX_VERSION_COMMON
70 #define MYNAM "mptsas"
71
72 /*
73 * Reserved channel for integrated raid
74 */
75 #define MPTSAS_RAID_CHANNEL 1
76
77 #define SAS_CONFIG_PAGE_TIMEOUT 30
78 MODULE_AUTHOR(MODULEAUTHOR);
79 MODULE_DESCRIPTION(my_NAME);
80 MODULE_LICENSE("GPL");
81 MODULE_VERSION(my_VERSION);
82
83 static int mpt_pt_clear;
84 module_param(mpt_pt_clear, int, 0);
85 MODULE_PARM_DESC(mpt_pt_clear,
86 " Clear persistency table: enable=1 "
87 "(default=MPTSCSIH_PT_CLEAR=0)");
88
89 /* scsi-mid layer global parmeter is max_report_luns, which is 511 */
90 #define MPTSAS_MAX_LUN (16895)
91 static int max_lun = MPTSAS_MAX_LUN;
92 module_param(max_lun, int, 0);
93 MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
94
95 static int mpt_loadtime_max_sectors = 8192;
96 module_param(mpt_loadtime_max_sectors, int, 0);
97 MODULE_PARM_DESC(mpt_loadtime_max_sectors,
98 " Maximum sector define for Host Bus Adaptor.Range 64 to 8192 default=8192");
99
100 static u8 mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
101 static u8 mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
102 static u8 mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */
103 static u8 mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS;
104 static u8 mptsasDeviceResetCtx = MPT_MAX_PROTOCOL_DRIVERS;
105
106 static void mptsas_firmware_event_work(struct work_struct *work);
107 static void mptsas_send_sas_event(struct fw_event_work *fw_event);
108 static void mptsas_send_raid_event(struct fw_event_work *fw_event);
109 static void mptsas_send_ir2_event(struct fw_event_work *fw_event);
110 static void mptsas_parse_device_info(struct sas_identify *identify,
111 struct mptsas_devinfo *device_info);
112 static inline void mptsas_set_rphy(MPT_ADAPTER *ioc,
113 struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy);
114 static struct mptsas_phyinfo *mptsas_find_phyinfo_by_sas_address
115 (MPT_ADAPTER *ioc, u64 sas_address);
116 static int mptsas_sas_device_pg0(MPT_ADAPTER *ioc,
117 struct mptsas_devinfo *device_info, u32 form, u32 form_specific);
118 static int mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc,
119 struct mptsas_enclosure *enclosure, u32 form, u32 form_specific);
120 static int mptsas_add_end_device(MPT_ADAPTER *ioc,
121 struct mptsas_phyinfo *phy_info);
122 static void mptsas_del_end_device(MPT_ADAPTER *ioc,
123 struct mptsas_phyinfo *phy_info);
124 static void mptsas_send_link_status_event(struct fw_event_work *fw_event);
125 static struct mptsas_portinfo *mptsas_find_portinfo_by_sas_address
126 (MPT_ADAPTER *ioc, u64 sas_address);
127 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
128 struct mptsas_portinfo *port_info, u8 force);
129 static void mptsas_send_expander_event(struct fw_event_work *fw_event);
130 static void mptsas_not_responding_devices(MPT_ADAPTER *ioc);
131 static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
132 static void mptsas_broadcast_primitive_work(struct fw_event_work *fw_event);
133 static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
134 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
135 void mptsas_schedule_target_reset(void *ioc);
136
mptsas_print_phy_data(MPT_ADAPTER * ioc,MPI_SAS_IO_UNIT0_PHY_DATA * phy_data)137 static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
138 MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
139 {
140 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
141 "---- IO UNIT PAGE 0 ------------\n", ioc->name));
142 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
143 ioc->name, le16_to_cpu(phy_data->AttachedDeviceHandle)));
144 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Controller Handle=0x%X\n",
145 ioc->name, le16_to_cpu(phy_data->ControllerDevHandle)));
146 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port=0x%X\n",
147 ioc->name, phy_data->Port));
148 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port Flags=0x%X\n",
149 ioc->name, phy_data->PortFlags));
150 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Flags=0x%X\n",
151 ioc->name, phy_data->PhyFlags));
152 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
153 ioc->name, phy_data->NegotiatedLinkRate));
154 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
155 "Controller PHY Device Info=0x%X\n", ioc->name,
156 le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
157 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DiscoveryStatus=0x%X\n\n",
158 ioc->name, le32_to_cpu(phy_data->DiscoveryStatus)));
159 }
160
mptsas_print_phy_pg0(MPT_ADAPTER * ioc,SasPhyPage0_t * pg0)161 static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
162 {
163 __le64 sas_address;
164
165 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
166
167 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
168 "---- SAS PHY PAGE 0 ------------\n", ioc->name));
169 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
170 "Attached Device Handle=0x%X\n", ioc->name,
171 le16_to_cpu(pg0->AttachedDevHandle)));
172 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
173 ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
174 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
175 "Attached PHY Identifier=0x%X\n", ioc->name,
176 pg0->AttachedPhyIdentifier));
177 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Attached Device Info=0x%X\n",
178 ioc->name, le32_to_cpu(pg0->AttachedDeviceInfo)));
179 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
180 ioc->name, pg0->ProgrammedLinkRate));
181 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Change Count=0x%X\n",
182 ioc->name, pg0->ChangeCount));
183 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Info=0x%X\n\n",
184 ioc->name, le32_to_cpu(pg0->PhyInfo)));
185 }
186
mptsas_print_phy_pg1(MPT_ADAPTER * ioc,SasPhyPage1_t * pg1)187 static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
188 {
189 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
190 "---- SAS PHY PAGE 1 ------------\n", ioc->name));
191 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Invalid Dword Count=0x%x\n",
192 ioc->name, pg1->InvalidDwordCount));
193 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
194 "Running Disparity Error Count=0x%x\n", ioc->name,
195 pg1->RunningDisparityErrorCount));
196 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
197 "Loss Dword Synch Count=0x%x\n", ioc->name,
198 pg1->LossDwordSynchCount));
199 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
200 "PHY Reset Problem Count=0x%x\n\n", ioc->name,
201 pg1->PhyResetProblemCount));
202 }
203
mptsas_print_device_pg0(MPT_ADAPTER * ioc,SasDevicePage0_t * pg0)204 static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
205 {
206 __le64 sas_address;
207
208 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
209
210 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
211 "---- SAS DEVICE PAGE 0 ---------\n", ioc->name));
212 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
213 ioc->name, le16_to_cpu(pg0->DevHandle)));
214 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Handle=0x%X\n",
215 ioc->name, le16_to_cpu(pg0->ParentDevHandle)));
216 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Enclosure Handle=0x%X\n",
217 ioc->name, le16_to_cpu(pg0->EnclosureHandle)));
218 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Slot=0x%X\n",
219 ioc->name, le16_to_cpu(pg0->Slot)));
220 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
221 ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
222 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Target ID=0x%X\n",
223 ioc->name, pg0->TargetID));
224 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Bus=0x%X\n",
225 ioc->name, pg0->Bus));
226 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Phy Num=0x%X\n",
227 ioc->name, pg0->PhyNum));
228 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Access Status=0x%X\n",
229 ioc->name, le16_to_cpu(pg0->AccessStatus)));
230 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Device Info=0x%X\n",
231 ioc->name, le32_to_cpu(pg0->DeviceInfo)));
232 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Flags=0x%X\n",
233 ioc->name, le16_to_cpu(pg0->Flags)));
234 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n\n",
235 ioc->name, pg0->PhysicalPort));
236 }
237
mptsas_print_expander_pg1(MPT_ADAPTER * ioc,SasExpanderPage1_t * pg1)238 static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
239 {
240 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
241 "---- SAS EXPANDER PAGE 1 ------------\n", ioc->name));
242 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n",
243 ioc->name, pg1->PhysicalPort));
244 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Identifier=0x%X\n",
245 ioc->name, pg1->PhyIdentifier));
246 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
247 ioc->name, pg1->NegotiatedLinkRate));
248 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
249 ioc->name, pg1->ProgrammedLinkRate));
250 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hardware Link Rate=0x%X\n",
251 ioc->name, pg1->HwLinkRate));
252 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Owner Device Handle=0x%X\n",
253 ioc->name, le16_to_cpu(pg1->OwnerDevHandle)));
254 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
255 "Attached Device Handle=0x%X\n\n", ioc->name,
256 le16_to_cpu(pg1->AttachedDevHandle)));
257 }
258
259 /* inhibit sas firmware event handling */
260 static void
mptsas_fw_event_off(MPT_ADAPTER * ioc)261 mptsas_fw_event_off(MPT_ADAPTER *ioc)
262 {
263 unsigned long flags;
264
265 spin_lock_irqsave(&ioc->fw_event_lock, flags);
266 ioc->fw_events_off = 1;
267 ioc->sas_discovery_quiesce_io = 0;
268 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
269
270 }
271
272 /* enable sas firmware event handling */
273 static void
mptsas_fw_event_on(MPT_ADAPTER * ioc)274 mptsas_fw_event_on(MPT_ADAPTER *ioc)
275 {
276 unsigned long flags;
277
278 spin_lock_irqsave(&ioc->fw_event_lock, flags);
279 ioc->fw_events_off = 0;
280 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
281 }
282
283 /* queue a sas firmware event */
284 static void
mptsas_add_fw_event(MPT_ADAPTER * ioc,struct fw_event_work * fw_event,unsigned long delay)285 mptsas_add_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
286 unsigned long delay)
287 {
288 unsigned long flags;
289
290 spin_lock_irqsave(&ioc->fw_event_lock, flags);
291 list_add_tail(&fw_event->list, &ioc->fw_event_list);
292 fw_event->users = 1;
293 INIT_DELAYED_WORK(&fw_event->work, mptsas_firmware_event_work);
294 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: add (fw_event=0x%p)"
295 "on cpuid %d\n", ioc->name, __func__,
296 fw_event, smp_processor_id()));
297 queue_delayed_work_on(smp_processor_id(), ioc->fw_event_q,
298 &fw_event->work, delay);
299 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
300 }
301
302 /* requeue a sas firmware event */
303 static void
mptsas_requeue_fw_event(MPT_ADAPTER * ioc,struct fw_event_work * fw_event,unsigned long delay)304 mptsas_requeue_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
305 unsigned long delay)
306 {
307 unsigned long flags;
308 spin_lock_irqsave(&ioc->fw_event_lock, flags);
309 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: reschedule task "
310 "(fw_event=0x%p)on cpuid %d\n", ioc->name, __func__,
311 fw_event, smp_processor_id()));
312 fw_event->retries++;
313 queue_delayed_work_on(smp_processor_id(), ioc->fw_event_q,
314 &fw_event->work, msecs_to_jiffies(delay));
315 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
316 }
317
__mptsas_free_fw_event(MPT_ADAPTER * ioc,struct fw_event_work * fw_event)318 static void __mptsas_free_fw_event(MPT_ADAPTER *ioc,
319 struct fw_event_work *fw_event)
320 {
321 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: kfree (fw_event=0x%p)\n",
322 ioc->name, __func__, fw_event));
323 list_del(&fw_event->list);
324 kfree(fw_event);
325 }
326
327 /* free memory associated to a sas firmware event */
328 static void
mptsas_free_fw_event(MPT_ADAPTER * ioc,struct fw_event_work * fw_event)329 mptsas_free_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event)
330 {
331 unsigned long flags;
332
333 spin_lock_irqsave(&ioc->fw_event_lock, flags);
334 fw_event->users--;
335 if (!fw_event->users)
336 __mptsas_free_fw_event(ioc, fw_event);
337 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
338 }
339
340 /* walk the firmware event queue, and either stop or wait for
341 * outstanding events to complete */
342 static void
mptsas_cleanup_fw_event_q(MPT_ADAPTER * ioc)343 mptsas_cleanup_fw_event_q(MPT_ADAPTER *ioc)
344 {
345 struct fw_event_work *fw_event;
346 struct mptsas_target_reset_event *target_reset_list, *n;
347 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
348 unsigned long flags;
349
350 /* flush the target_reset_list */
351 if (!list_empty(&hd->target_reset_list)) {
352 list_for_each_entry_safe(target_reset_list, n,
353 &hd->target_reset_list, list) {
354 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
355 "%s: removing target reset for id=%d\n",
356 ioc->name, __func__,
357 target_reset_list->sas_event_data.TargetID));
358 list_del(&target_reset_list->list);
359 kfree(target_reset_list);
360 }
361 }
362
363 if (list_empty(&ioc->fw_event_list) || !ioc->fw_event_q)
364 return;
365
366 spin_lock_irqsave(&ioc->fw_event_lock, flags);
367
368 while (!list_empty(&ioc->fw_event_list)) {
369 bool canceled = false;
370
371 fw_event = list_first_entry(&ioc->fw_event_list,
372 struct fw_event_work, list);
373 fw_event->users++;
374 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
375 if (cancel_delayed_work_sync(&fw_event->work))
376 canceled = true;
377
378 spin_lock_irqsave(&ioc->fw_event_lock, flags);
379 if (canceled)
380 fw_event->users--;
381 fw_event->users--;
382 WARN_ON_ONCE(fw_event->users);
383 __mptsas_free_fw_event(ioc, fw_event);
384 }
385 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
386 }
387
388
phy_to_ioc(struct sas_phy * phy)389 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
390 {
391 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
392 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
393 }
394
rphy_to_ioc(struct sas_rphy * rphy)395 static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
396 {
397 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
398 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
399 }
400
401 /*
402 * mptsas_find_portinfo_by_handle
403 *
404 * This function should be called with the sas_topology_mutex already held
405 */
406 static struct mptsas_portinfo *
mptsas_find_portinfo_by_handle(MPT_ADAPTER * ioc,u16 handle)407 mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
408 {
409 struct mptsas_portinfo *port_info, *rc=NULL;
410 int i;
411
412 list_for_each_entry(port_info, &ioc->sas_topology, list)
413 for (i = 0; i < port_info->num_phys; i++)
414 if (port_info->phy_info[i].identify.handle == handle) {
415 rc = port_info;
416 goto out;
417 }
418 out:
419 return rc;
420 }
421
422 /**
423 * mptsas_find_portinfo_by_sas_address -
424 * @ioc: Pointer to MPT_ADAPTER structure
425 * @handle:
426 *
427 * This function should be called with the sas_topology_mutex already held
428 *
429 **/
430 static struct mptsas_portinfo *
mptsas_find_portinfo_by_sas_address(MPT_ADAPTER * ioc,u64 sas_address)431 mptsas_find_portinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
432 {
433 struct mptsas_portinfo *port_info, *rc = NULL;
434 int i;
435
436 if (sas_address >= ioc->hba_port_sas_addr &&
437 sas_address < (ioc->hba_port_sas_addr +
438 ioc->hba_port_num_phy))
439 return ioc->hba_port_info;
440
441 mutex_lock(&ioc->sas_topology_mutex);
442 list_for_each_entry(port_info, &ioc->sas_topology, list)
443 for (i = 0; i < port_info->num_phys; i++)
444 if (port_info->phy_info[i].identify.sas_address ==
445 sas_address) {
446 rc = port_info;
447 goto out;
448 }
449 out:
450 mutex_unlock(&ioc->sas_topology_mutex);
451 return rc;
452 }
453
454 /*
455 * Returns true if there is a scsi end device
456 */
457 static inline int
mptsas_is_end_device(struct mptsas_devinfo * attached)458 mptsas_is_end_device(struct mptsas_devinfo * attached)
459 {
460 if ((attached->sas_address) &&
461 (attached->device_info &
462 MPI_SAS_DEVICE_INFO_END_DEVICE) &&
463 ((attached->device_info &
464 MPI_SAS_DEVICE_INFO_SSP_TARGET) |
465 (attached->device_info &
466 MPI_SAS_DEVICE_INFO_STP_TARGET) |
467 (attached->device_info &
468 MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
469 return 1;
470 else
471 return 0;
472 }
473
474 /* no mutex */
475 static void
mptsas_port_delete(MPT_ADAPTER * ioc,struct mptsas_portinfo_details * port_details)476 mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
477 {
478 struct mptsas_portinfo *port_info;
479 struct mptsas_phyinfo *phy_info;
480 u8 i;
481
482 if (!port_details)
483 return;
484
485 port_info = port_details->port_info;
486 phy_info = port_info->phy_info;
487
488 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d "
489 "bitmask=0x%016llX\n", ioc->name, __func__, port_details,
490 port_details->num_phys, (unsigned long long)
491 port_details->phy_bitmask));
492
493 for (i = 0; i < port_info->num_phys; i++, phy_info++) {
494 if(phy_info->port_details != port_details)
495 continue;
496 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
497 mptsas_set_rphy(ioc, phy_info, NULL);
498 phy_info->port_details = NULL;
499 }
500 kfree(port_details);
501 }
502
503 static inline struct sas_rphy *
mptsas_get_rphy(struct mptsas_phyinfo * phy_info)504 mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
505 {
506 if (phy_info->port_details)
507 return phy_info->port_details->rphy;
508 else
509 return NULL;
510 }
511
512 static inline void
mptsas_set_rphy(MPT_ADAPTER * ioc,struct mptsas_phyinfo * phy_info,struct sas_rphy * rphy)513 mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
514 {
515 if (phy_info->port_details) {
516 phy_info->port_details->rphy = rphy;
517 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
518 ioc->name, rphy));
519 }
520
521 if (rphy) {
522 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
523 &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
524 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
525 ioc->name, rphy, rphy->dev.release));
526 }
527 }
528
529 static inline struct sas_port *
mptsas_get_port(struct mptsas_phyinfo * phy_info)530 mptsas_get_port(struct mptsas_phyinfo *phy_info)
531 {
532 if (phy_info->port_details)
533 return phy_info->port_details->port;
534 else
535 return NULL;
536 }
537
538 static inline void
mptsas_set_port(MPT_ADAPTER * ioc,struct mptsas_phyinfo * phy_info,struct sas_port * port)539 mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_port *port)
540 {
541 if (phy_info->port_details)
542 phy_info->port_details->port = port;
543
544 if (port) {
545 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
546 &port->dev, MYIOC_s_FMT "add:", ioc->name));
547 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "port=%p release=%p\n",
548 ioc->name, port, port->dev.release));
549 }
550 }
551
552 static inline struct scsi_target *
mptsas_get_starget(struct mptsas_phyinfo * phy_info)553 mptsas_get_starget(struct mptsas_phyinfo *phy_info)
554 {
555 if (phy_info->port_details)
556 return phy_info->port_details->starget;
557 else
558 return NULL;
559 }
560
561 static inline void
mptsas_set_starget(struct mptsas_phyinfo * phy_info,struct scsi_target * starget)562 mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
563 starget)
564 {
565 if (phy_info->port_details)
566 phy_info->port_details->starget = starget;
567 }
568
569 /**
570 * mptsas_add_device_component -
571 * @ioc: Pointer to MPT_ADAPTER structure
572 * @channel: fw mapped id's
573 * @id:
574 * @sas_address:
575 * @device_info:
576 *
577 **/
578 static void
mptsas_add_device_component(MPT_ADAPTER * ioc,u8 channel,u8 id,u64 sas_address,u32 device_info,u16 slot,u64 enclosure_logical_id)579 mptsas_add_device_component(MPT_ADAPTER *ioc, u8 channel, u8 id,
580 u64 sas_address, u32 device_info, u16 slot, u64 enclosure_logical_id)
581 {
582 struct mptsas_device_info *sas_info, *next;
583 struct scsi_device *sdev;
584 struct scsi_target *starget;
585 struct sas_rphy *rphy;
586
587 /*
588 * Delete all matching devices out of the list
589 */
590 mutex_lock(&ioc->sas_device_info_mutex);
591 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
592 list) {
593 if (!sas_info->is_logical_volume &&
594 (sas_info->sas_address == sas_address ||
595 (sas_info->fw.channel == channel &&
596 sas_info->fw.id == id))) {
597 list_del(&sas_info->list);
598 kfree(sas_info);
599 }
600 }
601
602 sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
603 if (!sas_info)
604 goto out;
605
606 /*
607 * Set Firmware mapping
608 */
609 sas_info->fw.id = id;
610 sas_info->fw.channel = channel;
611
612 sas_info->sas_address = sas_address;
613 sas_info->device_info = device_info;
614 sas_info->slot = slot;
615 sas_info->enclosure_logical_id = enclosure_logical_id;
616 INIT_LIST_HEAD(&sas_info->list);
617 list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
618
619 /*
620 * Set OS mapping
621 */
622 shost_for_each_device(sdev, ioc->sh) {
623 starget = scsi_target(sdev);
624 rphy = dev_to_rphy(starget->dev.parent);
625 if (rphy->identify.sas_address == sas_address) {
626 sas_info->os.id = starget->id;
627 sas_info->os.channel = starget->channel;
628 }
629 }
630
631 out:
632 mutex_unlock(&ioc->sas_device_info_mutex);
633 return;
634 }
635
636 /**
637 * mptsas_add_device_component_by_fw -
638 * @ioc: Pointer to MPT_ADAPTER structure
639 * @channel: fw mapped id's
640 * @id:
641 *
642 **/
643 static void
mptsas_add_device_component_by_fw(MPT_ADAPTER * ioc,u8 channel,u8 id)644 mptsas_add_device_component_by_fw(MPT_ADAPTER *ioc, u8 channel, u8 id)
645 {
646 struct mptsas_devinfo sas_device;
647 struct mptsas_enclosure enclosure_info;
648 int rc;
649
650 rc = mptsas_sas_device_pg0(ioc, &sas_device,
651 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
652 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
653 (channel << 8) + id);
654 if (rc)
655 return;
656
657 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
658 mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
659 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
660 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
661 sas_device.handle_enclosure);
662
663 mptsas_add_device_component(ioc, sas_device.channel,
664 sas_device.id, sas_device.sas_address, sas_device.device_info,
665 sas_device.slot, enclosure_info.enclosure_logical_id);
666 }
667
668 /**
669 * mptsas_add_device_component_starget_ir - Handle Integrated RAID, adding each individual device to list
670 * @ioc: Pointer to MPT_ADAPTER structure
671 * @channel: fw mapped id's
672 * @id:
673 *
674 **/
675 static void
mptsas_add_device_component_starget_ir(MPT_ADAPTER * ioc,struct scsi_target * starget)676 mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc,
677 struct scsi_target *starget)
678 {
679 CONFIGPARMS cfg;
680 ConfigPageHeader_t hdr;
681 dma_addr_t dma_handle;
682 pRaidVolumePage0_t buffer = NULL;
683 int i;
684 RaidPhysDiskPage0_t phys_disk;
685 struct mptsas_device_info *sas_info, *next;
686
687 memset(&cfg, 0 , sizeof(CONFIGPARMS));
688 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
689 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
690 /* assumption that all volumes on channel = 0 */
691 cfg.pageAddr = starget->id;
692 cfg.cfghdr.hdr = &hdr;
693 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
694 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
695
696 if (mpt_config(ioc, &cfg) != 0)
697 goto out;
698
699 if (!hdr.PageLength)
700 goto out;
701
702 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
703 &dma_handle);
704
705 if (!buffer)
706 goto out;
707
708 cfg.physAddr = dma_handle;
709 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
710
711 if (mpt_config(ioc, &cfg) != 0)
712 goto out;
713
714 if (!buffer->NumPhysDisks)
715 goto out;
716
717 /*
718 * Adding entry for hidden components
719 */
720 for (i = 0; i < buffer->NumPhysDisks; i++) {
721
722 if (mpt_raid_phys_disk_pg0(ioc,
723 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
724 continue;
725
726 mptsas_add_device_component_by_fw(ioc, phys_disk.PhysDiskBus,
727 phys_disk.PhysDiskID);
728
729 mutex_lock(&ioc->sas_device_info_mutex);
730 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
731 list) {
732 if (!sas_info->is_logical_volume &&
733 (sas_info->fw.channel == phys_disk.PhysDiskBus &&
734 sas_info->fw.id == phys_disk.PhysDiskID)) {
735 sas_info->is_hidden_raid_component = 1;
736 sas_info->volume_id = starget->id;
737 }
738 }
739 mutex_unlock(&ioc->sas_device_info_mutex);
740
741 }
742
743 /*
744 * Delete all matching devices out of the list
745 */
746 mutex_lock(&ioc->sas_device_info_mutex);
747 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
748 list) {
749 if (sas_info->is_logical_volume && sas_info->fw.id ==
750 starget->id) {
751 list_del(&sas_info->list);
752 kfree(sas_info);
753 }
754 }
755
756 sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
757 if (sas_info) {
758 sas_info->fw.id = starget->id;
759 sas_info->os.id = starget->id;
760 sas_info->os.channel = starget->channel;
761 sas_info->is_logical_volume = 1;
762 INIT_LIST_HEAD(&sas_info->list);
763 list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
764 }
765 mutex_unlock(&ioc->sas_device_info_mutex);
766
767 out:
768 if (buffer)
769 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
770 dma_handle);
771 }
772
773 /**
774 * mptsas_add_device_component_starget -
775 * @ioc: Pointer to MPT_ADAPTER structure
776 * @starget:
777 *
778 **/
779 static void
mptsas_add_device_component_starget(MPT_ADAPTER * ioc,struct scsi_target * starget)780 mptsas_add_device_component_starget(MPT_ADAPTER *ioc,
781 struct scsi_target *starget)
782 {
783 struct sas_rphy *rphy;
784 struct mptsas_phyinfo *phy_info = NULL;
785 struct mptsas_enclosure enclosure_info;
786
787 rphy = dev_to_rphy(starget->dev.parent);
788 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
789 rphy->identify.sas_address);
790 if (!phy_info)
791 return;
792
793 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
794 mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
795 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
796 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
797 phy_info->attached.handle_enclosure);
798
799 mptsas_add_device_component(ioc, phy_info->attached.channel,
800 phy_info->attached.id, phy_info->attached.sas_address,
801 phy_info->attached.device_info,
802 phy_info->attached.slot, enclosure_info.enclosure_logical_id);
803 }
804
805 /**
806 * mptsas_del_device_component_by_os - Once a device has been removed, we mark the entry in the list as being cached
807 * @ioc: Pointer to MPT_ADAPTER structure
808 * @channel: os mapped id's
809 * @id:
810 *
811 **/
812 static void
mptsas_del_device_component_by_os(MPT_ADAPTER * ioc,u8 channel,u8 id)813 mptsas_del_device_component_by_os(MPT_ADAPTER *ioc, u8 channel, u8 id)
814 {
815 struct mptsas_device_info *sas_info, *next;
816
817 /*
818 * Set is_cached flag
819 */
820 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
821 list) {
822 if (sas_info->os.channel == channel && sas_info->os.id == id)
823 sas_info->is_cached = 1;
824 }
825 }
826
827 /**
828 * mptsas_del_device_components - Cleaning the list
829 * @ioc: Pointer to MPT_ADAPTER structure
830 *
831 **/
832 static void
mptsas_del_device_components(MPT_ADAPTER * ioc)833 mptsas_del_device_components(MPT_ADAPTER *ioc)
834 {
835 struct mptsas_device_info *sas_info, *next;
836
837 mutex_lock(&ioc->sas_device_info_mutex);
838 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
839 list) {
840 list_del(&sas_info->list);
841 kfree(sas_info);
842 }
843 mutex_unlock(&ioc->sas_device_info_mutex);
844 }
845
846
847 /*
848 * mptsas_setup_wide_ports
849 *
850 * Updates for new and existing narrow/wide port configuration
851 * in the sas_topology
852 */
853 static void
mptsas_setup_wide_ports(MPT_ADAPTER * ioc,struct mptsas_portinfo * port_info)854 mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
855 {
856 struct mptsas_portinfo_details * port_details;
857 struct mptsas_phyinfo *phy_info, *phy_info_cmp;
858 u64 sas_address;
859 int i, j;
860
861 mutex_lock(&ioc->sas_topology_mutex);
862
863 phy_info = port_info->phy_info;
864 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
865 if (phy_info->attached.handle)
866 continue;
867 port_details = phy_info->port_details;
868 if (!port_details)
869 continue;
870 if (port_details->num_phys < 2)
871 continue;
872 /*
873 * Removing a phy from a port, letting the last
874 * phy be removed by firmware events.
875 */
876 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
877 "%s: [%p]: deleting phy = %d\n",
878 ioc->name, __func__, port_details, i));
879 port_details->num_phys--;
880 port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
881 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
882 if (phy_info->phy) {
883 devtprintk(ioc, dev_printk(KERN_DEBUG,
884 &phy_info->phy->dev, MYIOC_s_FMT
885 "delete phy %d, phy-obj (0x%p)\n", ioc->name,
886 phy_info->phy_id, phy_info->phy));
887 sas_port_delete_phy(port_details->port, phy_info->phy);
888 }
889 phy_info->port_details = NULL;
890 }
891
892 /*
893 * Populate and refresh the tree
894 */
895 phy_info = port_info->phy_info;
896 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
897 sas_address = phy_info->attached.sas_address;
898 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "phy_id=%d sas_address=0x%018llX\n",
899 ioc->name, i, (unsigned long long)sas_address));
900 if (!sas_address)
901 continue;
902 port_details = phy_info->port_details;
903 /*
904 * Forming a port
905 */
906 if (!port_details) {
907 port_details = kzalloc(sizeof(struct
908 mptsas_portinfo_details), GFP_KERNEL);
909 if (!port_details)
910 goto out;
911 port_details->num_phys = 1;
912 port_details->port_info = port_info;
913 if (phy_info->phy_id < 64 )
914 port_details->phy_bitmask |=
915 (1 << phy_info->phy_id);
916 phy_info->sas_port_add_phy=1;
917 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tForming port\n\t\t"
918 "phy_id=%d sas_address=0x%018llX\n",
919 ioc->name, i, (unsigned long long)sas_address));
920 phy_info->port_details = port_details;
921 }
922
923 if (i == port_info->num_phys - 1)
924 continue;
925 phy_info_cmp = &port_info->phy_info[i + 1];
926 for (j = i + 1 ; j < port_info->num_phys ; j++,
927 phy_info_cmp++) {
928 if (!phy_info_cmp->attached.sas_address)
929 continue;
930 if (sas_address != phy_info_cmp->attached.sas_address)
931 continue;
932 if (phy_info_cmp->port_details == port_details )
933 continue;
934 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
935 "\t\tphy_id=%d sas_address=0x%018llX\n",
936 ioc->name, j, (unsigned long long)
937 phy_info_cmp->attached.sas_address));
938 if (phy_info_cmp->port_details) {
939 port_details->rphy =
940 mptsas_get_rphy(phy_info_cmp);
941 port_details->port =
942 mptsas_get_port(phy_info_cmp);
943 port_details->starget =
944 mptsas_get_starget(phy_info_cmp);
945 port_details->num_phys =
946 phy_info_cmp->port_details->num_phys;
947 if (!phy_info_cmp->port_details->num_phys)
948 kfree(phy_info_cmp->port_details);
949 } else
950 phy_info_cmp->sas_port_add_phy=1;
951 /*
952 * Adding a phy to a port
953 */
954 phy_info_cmp->port_details = port_details;
955 if (phy_info_cmp->phy_id < 64 )
956 port_details->phy_bitmask |=
957 (1 << phy_info_cmp->phy_id);
958 port_details->num_phys++;
959 }
960 }
961
962 out:
963
964 for (i = 0; i < port_info->num_phys; i++) {
965 port_details = port_info->phy_info[i].port_details;
966 if (!port_details)
967 continue;
968 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
969 "%s: [%p]: phy_id=%02d num_phys=%02d "
970 "bitmask=0x%016llX\n", ioc->name, __func__,
971 port_details, i, port_details->num_phys,
972 (unsigned long long)port_details->phy_bitmask));
973 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n",
974 ioc->name, port_details->port, port_details->rphy));
975 }
976 dsaswideprintk(ioc, printk("\n"));
977 mutex_unlock(&ioc->sas_topology_mutex);
978 }
979
980 /**
981 * csmisas_find_vtarget
982 *
983 * @ioc
984 * @volume_id
985 * @volume_bus
986 *
987 **/
988 static VirtTarget *
mptsas_find_vtarget(MPT_ADAPTER * ioc,u8 channel,u8 id)989 mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
990 {
991 struct scsi_device *sdev;
992 VirtDevice *vdevice;
993 VirtTarget *vtarget = NULL;
994
995 shost_for_each_device(sdev, ioc->sh) {
996 vdevice = sdev->hostdata;
997 if ((vdevice == NULL) ||
998 (vdevice->vtarget == NULL))
999 continue;
1000 if ((vdevice->vtarget->tflags &
1001 MPT_TARGET_FLAGS_RAID_COMPONENT ||
1002 vdevice->vtarget->raidVolume))
1003 continue;
1004 if (vdevice->vtarget->id == id &&
1005 vdevice->vtarget->channel == channel)
1006 vtarget = vdevice->vtarget;
1007 }
1008 return vtarget;
1009 }
1010
1011 static void
mptsas_queue_device_delete(MPT_ADAPTER * ioc,MpiEventDataSasDeviceStatusChange_t * sas_event_data)1012 mptsas_queue_device_delete(MPT_ADAPTER *ioc,
1013 MpiEventDataSasDeviceStatusChange_t *sas_event_data)
1014 {
1015 struct fw_event_work *fw_event;
1016
1017 fw_event = kzalloc(sizeof(*fw_event) +
1018 sizeof(MpiEventDataSasDeviceStatusChange_t),
1019 GFP_ATOMIC);
1020 if (!fw_event) {
1021 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
1022 ioc->name, __func__, __LINE__);
1023 return;
1024 }
1025 memcpy(fw_event->event_data, sas_event_data,
1026 sizeof(MpiEventDataSasDeviceStatusChange_t));
1027 fw_event->event = MPI_EVENT_SAS_DEVICE_STATUS_CHANGE;
1028 fw_event->ioc = ioc;
1029 mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
1030 }
1031
1032 static void
mptsas_queue_rescan(MPT_ADAPTER * ioc)1033 mptsas_queue_rescan(MPT_ADAPTER *ioc)
1034 {
1035 struct fw_event_work *fw_event;
1036
1037 fw_event = kzalloc(sizeof(*fw_event), GFP_ATOMIC);
1038 if (!fw_event) {
1039 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
1040 ioc->name, __func__, __LINE__);
1041 return;
1042 }
1043 fw_event->event = -1;
1044 fw_event->ioc = ioc;
1045 mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
1046 }
1047
1048
1049 /**
1050 * mptsas_target_reset
1051 *
1052 * Issues TARGET_RESET to end device using handshaking method
1053 *
1054 * @ioc
1055 * @channel
1056 * @id
1057 *
1058 * Returns (1) success
1059 * (0) failure
1060 *
1061 **/
1062 static int
mptsas_target_reset(MPT_ADAPTER * ioc,u8 channel,u8 id)1063 mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
1064 {
1065 MPT_FRAME_HDR *mf;
1066 SCSITaskMgmt_t *pScsiTm;
1067 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0)
1068 return 0;
1069
1070
1071 mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
1072 if (mf == NULL) {
1073 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1074 "%s, no msg frames @%d!!\n", ioc->name,
1075 __func__, __LINE__));
1076 goto out_fail;
1077 }
1078
1079 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1080 ioc->name, mf));
1081
1082 /* Format the Request
1083 */
1084 pScsiTm = (SCSITaskMgmt_t *) mf;
1085 memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
1086 pScsiTm->TargetID = id;
1087 pScsiTm->Bus = channel;
1088 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1089 pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
1090 pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
1091
1092 DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
1093
1094 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1095 "TaskMgmt type=%d (sas device delete) fw_channel = %d fw_id = %d)\n",
1096 ioc->name, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, channel, id));
1097
1098 mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
1099
1100 return 1;
1101
1102 out_fail:
1103
1104 mpt_clear_taskmgmt_in_progress_flag(ioc);
1105 return 0;
1106 }
1107
1108 static void
mptsas_block_io_sdev(struct scsi_device * sdev,void * data)1109 mptsas_block_io_sdev(struct scsi_device *sdev, void *data)
1110 {
1111 scsi_device_set_state(sdev, SDEV_BLOCK);
1112 }
1113
1114 static void
mptsas_block_io_starget(struct scsi_target * starget)1115 mptsas_block_io_starget(struct scsi_target *starget)
1116 {
1117 if (starget)
1118 starget_for_each_device(starget, NULL, mptsas_block_io_sdev);
1119 }
1120
1121 /**
1122 * mptsas_target_reset_queue
1123 *
1124 * Receive request for TARGET_RESET after receiving an firmware
1125 * event NOT_RESPONDING_EVENT, then put command in link list
1126 * and queue if task_queue already in use.
1127 *
1128 * @ioc
1129 * @sas_event_data
1130 *
1131 **/
1132 static void
mptsas_target_reset_queue(MPT_ADAPTER * ioc,EVENT_DATA_SAS_DEVICE_STATUS_CHANGE * sas_event_data)1133 mptsas_target_reset_queue(MPT_ADAPTER *ioc,
1134 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1135 {
1136 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
1137 VirtTarget *vtarget = NULL;
1138 struct mptsas_target_reset_event *target_reset_list;
1139 u8 id, channel;
1140
1141 id = sas_event_data->TargetID;
1142 channel = sas_event_data->Bus;
1143
1144 vtarget = mptsas_find_vtarget(ioc, channel, id);
1145 if (vtarget) {
1146 mptsas_block_io_starget(vtarget->starget);
1147 vtarget->deleted = 1; /* block IO */
1148 }
1149
1150 target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event),
1151 GFP_ATOMIC);
1152 if (!target_reset_list) {
1153 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1154 "%s, failed to allocate mem @%d..!!\n",
1155 ioc->name, __func__, __LINE__));
1156 return;
1157 }
1158
1159 memcpy(&target_reset_list->sas_event_data, sas_event_data,
1160 sizeof(*sas_event_data));
1161 list_add_tail(&target_reset_list->list, &hd->target_reset_list);
1162
1163 target_reset_list->time_count = jiffies;
1164
1165 if (mptsas_target_reset(ioc, channel, id)) {
1166 target_reset_list->target_reset_issued = 1;
1167 }
1168 }
1169
1170 /**
1171 * mptsas_schedule_target_reset- send pending target reset
1172 * @iocp: per adapter object
1173 *
1174 * This function will delete scheduled target reset from the list and
1175 * try to send next target reset. This will be called from completion
1176 * context of any Task management command.
1177 */
1178
1179 void
mptsas_schedule_target_reset(void * iocp)1180 mptsas_schedule_target_reset(void *iocp)
1181 {
1182 MPT_ADAPTER *ioc = (MPT_ADAPTER *)(iocp);
1183 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
1184 struct list_head *head = &hd->target_reset_list;
1185 struct mptsas_target_reset_event *target_reset_list;
1186 u8 id, channel;
1187 /*
1188 * issue target reset to next device in the queue
1189 */
1190
1191 if (list_empty(head))
1192 return;
1193
1194 target_reset_list = list_entry(head->next,
1195 struct mptsas_target_reset_event, list);
1196
1197 id = target_reset_list->sas_event_data.TargetID;
1198 channel = target_reset_list->sas_event_data.Bus;
1199 target_reset_list->time_count = jiffies;
1200
1201 if (mptsas_target_reset(ioc, channel, id))
1202 target_reset_list->target_reset_issued = 1;
1203 return;
1204 }
1205
1206
1207 /**
1208 * mptsas_taskmgmt_complete - complete SAS task management function
1209 * @ioc: Pointer to MPT_ADAPTER structure
1210 *
1211 * Completion for TARGET_RESET after NOT_RESPONDING_EVENT, enable work
1212 * queue to finish off removing device from upper layers. then send next
1213 * TARGET_RESET in the queue.
1214 **/
1215 static int
mptsas_taskmgmt_complete(MPT_ADAPTER * ioc,MPT_FRAME_HDR * mf,MPT_FRAME_HDR * mr)1216 mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
1217 {
1218 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
1219 struct list_head *head = &hd->target_reset_list;
1220 u8 id, channel;
1221 struct mptsas_target_reset_event *target_reset_list;
1222 SCSITaskMgmtReply_t *pScsiTmReply;
1223
1224 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt completed: "
1225 "(mf = %p, mr = %p)\n", ioc->name, mf, mr));
1226
1227 pScsiTmReply = (SCSITaskMgmtReply_t *)mr;
1228 if (!pScsiTmReply)
1229 return 0;
1230
1231 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1232 "\tTaskMgmt completed: fw_channel = %d, fw_id = %d,\n"
1233 "\ttask_type = 0x%02X, iocstatus = 0x%04X "
1234 "loginfo = 0x%08X,\n\tresponse_code = 0x%02X, "
1235 "term_cmnds = %d\n", ioc->name,
1236 pScsiTmReply->Bus, pScsiTmReply->TargetID,
1237 pScsiTmReply->TaskType,
1238 le16_to_cpu(pScsiTmReply->IOCStatus),
1239 le32_to_cpu(pScsiTmReply->IOCLogInfo),
1240 pScsiTmReply->ResponseCode,
1241 le32_to_cpu(pScsiTmReply->TerminationCount)));
1242
1243 if (pScsiTmReply->ResponseCode)
1244 mptscsih_taskmgmt_response_code(ioc,
1245 pScsiTmReply->ResponseCode);
1246
1247 if (pScsiTmReply->TaskType ==
1248 MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK || pScsiTmReply->TaskType ==
1249 MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET) {
1250 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
1251 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
1252 memcpy(ioc->taskmgmt_cmds.reply, mr,
1253 min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
1254 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
1255 ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
1256 complete(&ioc->taskmgmt_cmds.done);
1257 return 1;
1258 }
1259 return 0;
1260 }
1261
1262 mpt_clear_taskmgmt_in_progress_flag(ioc);
1263
1264 if (list_empty(head))
1265 return 1;
1266
1267 target_reset_list = list_entry(head->next,
1268 struct mptsas_target_reset_event, list);
1269
1270 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1271 "TaskMgmt: completed (%d seconds)\n",
1272 ioc->name, jiffies_to_msecs(jiffies -
1273 target_reset_list->time_count)/1000));
1274
1275 id = pScsiTmReply->TargetID;
1276 channel = pScsiTmReply->Bus;
1277 target_reset_list->time_count = jiffies;
1278
1279 /*
1280 * retry target reset
1281 */
1282 if (!target_reset_list->target_reset_issued) {
1283 if (mptsas_target_reset(ioc, channel, id))
1284 target_reset_list->target_reset_issued = 1;
1285 return 1;
1286 }
1287
1288 /*
1289 * enable work queue to remove device from upper layers
1290 */
1291 list_del(&target_reset_list->list);
1292 if (!ioc->fw_events_off)
1293 mptsas_queue_device_delete(ioc,
1294 &target_reset_list->sas_event_data);
1295
1296
1297 ioc->schedule_target_reset(ioc);
1298
1299 return 1;
1300 }
1301
1302 /**
1303 * mptscsih_ioc_reset
1304 *
1305 * @ioc
1306 * @reset_phase
1307 *
1308 **/
1309 static int
mptsas_ioc_reset(MPT_ADAPTER * ioc,int reset_phase)1310 mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1311 {
1312 MPT_SCSI_HOST *hd;
1313 int rc;
1314
1315 rc = mptscsih_ioc_reset(ioc, reset_phase);
1316 if ((ioc->bus_type != SAS) || (!rc))
1317 return rc;
1318
1319 hd = shost_priv(ioc->sh);
1320 if (!hd->ioc)
1321 goto out;
1322
1323 switch (reset_phase) {
1324 case MPT_IOC_SETUP_RESET:
1325 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1326 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
1327 mptsas_fw_event_off(ioc);
1328 break;
1329 case MPT_IOC_PRE_RESET:
1330 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1331 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
1332 break;
1333 case MPT_IOC_POST_RESET:
1334 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1335 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
1336 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
1337 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_DID_IOCRESET;
1338 complete(&ioc->sas_mgmt.done);
1339 }
1340 mptsas_cleanup_fw_event_q(ioc);
1341 mptsas_queue_rescan(ioc);
1342 break;
1343 default:
1344 break;
1345 }
1346
1347 out:
1348 return rc;
1349 }
1350
1351
1352 /**
1353 * enum device_state -
1354 * @DEVICE_RETRY: need to retry the TUR
1355 * @DEVICE_ERROR: TUR return error, don't add device
1356 * @DEVICE_READY: device can be added
1357 *
1358 */
1359 enum device_state{
1360 DEVICE_RETRY,
1361 DEVICE_ERROR,
1362 DEVICE_READY,
1363 };
1364
1365 static int
mptsas_sas_enclosure_pg0(MPT_ADAPTER * ioc,struct mptsas_enclosure * enclosure,u32 form,u32 form_specific)1366 mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
1367 u32 form, u32 form_specific)
1368 {
1369 ConfigExtendedPageHeader_t hdr;
1370 CONFIGPARMS cfg;
1371 SasEnclosurePage0_t *buffer;
1372 dma_addr_t dma_handle;
1373 int error;
1374 __le64 le_identifier;
1375
1376 memset(&hdr, 0, sizeof(hdr));
1377 hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
1378 hdr.PageNumber = 0;
1379 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1380 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
1381
1382 cfg.cfghdr.ehdr = &hdr;
1383 cfg.physAddr = -1;
1384 cfg.pageAddr = form + form_specific;
1385 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1386 cfg.dir = 0; /* read */
1387 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
1388
1389 error = mpt_config(ioc, &cfg);
1390 if (error)
1391 goto out;
1392 if (!hdr.ExtPageLength) {
1393 error = -ENXIO;
1394 goto out;
1395 }
1396
1397 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1398 &dma_handle);
1399 if (!buffer) {
1400 error = -ENOMEM;
1401 goto out;
1402 }
1403
1404 cfg.physAddr = dma_handle;
1405 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1406
1407 error = mpt_config(ioc, &cfg);
1408 if (error)
1409 goto out_free_consistent;
1410
1411 /* save config data */
1412 memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
1413 enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
1414 enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
1415 enclosure->flags = le16_to_cpu(buffer->Flags);
1416 enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
1417 enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
1418 enclosure->start_id = buffer->StartTargetID;
1419 enclosure->start_channel = buffer->StartBus;
1420 enclosure->sep_id = buffer->SEPTargetID;
1421 enclosure->sep_channel = buffer->SEPBus;
1422
1423 out_free_consistent:
1424 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1425 buffer, dma_handle);
1426 out:
1427 return error;
1428 }
1429
1430 /**
1431 * mptsas_add_end_device - report a new end device to sas transport layer
1432 * @ioc: Pointer to MPT_ADAPTER structure
1433 * @phy_info: describes attached device
1434 *
1435 * return (0) success (1) failure
1436 *
1437 **/
1438 static int
mptsas_add_end_device(MPT_ADAPTER * ioc,struct mptsas_phyinfo * phy_info)1439 mptsas_add_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1440 {
1441 struct sas_rphy *rphy;
1442 struct sas_port *port;
1443 struct sas_identify identify;
1444 char *ds = NULL;
1445 u8 fw_id;
1446
1447 if (!phy_info) {
1448 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1449 "%s: exit at line=%d\n", ioc->name,
1450 __func__, __LINE__));
1451 return 1;
1452 }
1453
1454 fw_id = phy_info->attached.id;
1455
1456 if (mptsas_get_rphy(phy_info)) {
1457 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1458 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1459 __func__, fw_id, __LINE__));
1460 return 2;
1461 }
1462
1463 port = mptsas_get_port(phy_info);
1464 if (!port) {
1465 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1466 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1467 __func__, fw_id, __LINE__));
1468 return 3;
1469 }
1470
1471 if (phy_info->attached.device_info &
1472 MPI_SAS_DEVICE_INFO_SSP_TARGET)
1473 ds = "ssp";
1474 if (phy_info->attached.device_info &
1475 MPI_SAS_DEVICE_INFO_STP_TARGET)
1476 ds = "stp";
1477 if (phy_info->attached.device_info &
1478 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1479 ds = "sata";
1480
1481 printk(MYIOC_s_INFO_FMT "attaching %s device: fw_channel %d, fw_id %d,"
1482 " phy %d, sas_addr 0x%llx\n", ioc->name, ds,
1483 phy_info->attached.channel, phy_info->attached.id,
1484 phy_info->attached.phy_id, (unsigned long long)
1485 phy_info->attached.sas_address);
1486
1487 mptsas_parse_device_info(&identify, &phy_info->attached);
1488 rphy = sas_end_device_alloc(port);
1489 if (!rphy) {
1490 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1491 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1492 __func__, fw_id, __LINE__));
1493 return 5; /* non-fatal: an rphy can be added later */
1494 }
1495
1496 rphy->identify = identify;
1497 if (sas_rphy_add(rphy)) {
1498 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1499 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1500 __func__, fw_id, __LINE__));
1501 sas_rphy_free(rphy);
1502 return 6;
1503 }
1504 mptsas_set_rphy(ioc, phy_info, rphy);
1505 return 0;
1506 }
1507
1508 /**
1509 * mptsas_del_end_device - report a deleted end device to sas transport layer
1510 * @ioc: Pointer to MPT_ADAPTER structure
1511 * @phy_info: describes attached device
1512 *
1513 **/
1514 static void
mptsas_del_end_device(MPT_ADAPTER * ioc,struct mptsas_phyinfo * phy_info)1515 mptsas_del_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1516 {
1517 struct sas_rphy *rphy;
1518 struct sas_port *port;
1519 struct mptsas_portinfo *port_info;
1520 struct mptsas_phyinfo *phy_info_parent;
1521 int i;
1522 char *ds = NULL;
1523 u8 fw_id;
1524 u64 sas_address;
1525
1526 if (!phy_info)
1527 return;
1528
1529 fw_id = phy_info->attached.id;
1530 sas_address = phy_info->attached.sas_address;
1531
1532 if (!phy_info->port_details) {
1533 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1534 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1535 __func__, fw_id, __LINE__));
1536 return;
1537 }
1538 rphy = mptsas_get_rphy(phy_info);
1539 if (!rphy) {
1540 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1541 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1542 __func__, fw_id, __LINE__));
1543 return;
1544 }
1545
1546 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_INITIATOR
1547 || phy_info->attached.device_info
1548 & MPI_SAS_DEVICE_INFO_SMP_INITIATOR
1549 || phy_info->attached.device_info
1550 & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1551 ds = "initiator";
1552 if (phy_info->attached.device_info &
1553 MPI_SAS_DEVICE_INFO_SSP_TARGET)
1554 ds = "ssp";
1555 if (phy_info->attached.device_info &
1556 MPI_SAS_DEVICE_INFO_STP_TARGET)
1557 ds = "stp";
1558 if (phy_info->attached.device_info &
1559 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1560 ds = "sata";
1561
1562 dev_printk(KERN_DEBUG, &rphy->dev, MYIOC_s_FMT
1563 "removing %s device: fw_channel %d, fw_id %d, phy %d,"
1564 "sas_addr 0x%llx\n", ioc->name, ds, phy_info->attached.channel,
1565 phy_info->attached.id, phy_info->attached.phy_id,
1566 (unsigned long long) sas_address);
1567
1568 port = mptsas_get_port(phy_info);
1569 if (!port) {
1570 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1571 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1572 __func__, fw_id, __LINE__));
1573 return;
1574 }
1575 port_info = phy_info->portinfo;
1576 phy_info_parent = port_info->phy_info;
1577 for (i = 0; i < port_info->num_phys; i++, phy_info_parent++) {
1578 if (!phy_info_parent->phy)
1579 continue;
1580 if (phy_info_parent->attached.sas_address !=
1581 sas_address)
1582 continue;
1583 dev_printk(KERN_DEBUG, &phy_info_parent->phy->dev,
1584 MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n",
1585 ioc->name, phy_info_parent->phy_id,
1586 phy_info_parent->phy);
1587 sas_port_delete_phy(port, phy_info_parent->phy);
1588 }
1589
1590 dev_printk(KERN_DEBUG, &port->dev, MYIOC_s_FMT
1591 "delete port %d, sas_addr (0x%llx)\n", ioc->name,
1592 port->port_identifier, (unsigned long long)sas_address);
1593 sas_port_delete(port);
1594 mptsas_set_port(ioc, phy_info, NULL);
1595 mptsas_port_delete(ioc, phy_info->port_details);
1596 }
1597
1598 static struct mptsas_phyinfo *
mptsas_refreshing_device_handles(MPT_ADAPTER * ioc,struct mptsas_devinfo * sas_device)1599 mptsas_refreshing_device_handles(MPT_ADAPTER *ioc,
1600 struct mptsas_devinfo *sas_device)
1601 {
1602 struct mptsas_phyinfo *phy_info;
1603 struct mptsas_portinfo *port_info;
1604 int i;
1605
1606 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
1607 sas_device->sas_address);
1608 if (!phy_info)
1609 goto out;
1610 port_info = phy_info->portinfo;
1611 if (!port_info)
1612 goto out;
1613 mutex_lock(&ioc->sas_topology_mutex);
1614 for (i = 0; i < port_info->num_phys; i++) {
1615 if (port_info->phy_info[i].attached.sas_address !=
1616 sas_device->sas_address)
1617 continue;
1618 port_info->phy_info[i].attached.channel = sas_device->channel;
1619 port_info->phy_info[i].attached.id = sas_device->id;
1620 port_info->phy_info[i].attached.sas_address =
1621 sas_device->sas_address;
1622 port_info->phy_info[i].attached.handle = sas_device->handle;
1623 port_info->phy_info[i].attached.handle_parent =
1624 sas_device->handle_parent;
1625 port_info->phy_info[i].attached.handle_enclosure =
1626 sas_device->handle_enclosure;
1627 }
1628 mutex_unlock(&ioc->sas_topology_mutex);
1629 out:
1630 return phy_info;
1631 }
1632
1633 /**
1634 * mptsas_firmware_event_work - work thread for processing fw events
1635 * @work: work queue payload containing info describing the event
1636 * Context: user
1637 *
1638 */
1639 static void
mptsas_firmware_event_work(struct work_struct * work)1640 mptsas_firmware_event_work(struct work_struct *work)
1641 {
1642 struct fw_event_work *fw_event =
1643 container_of(work, struct fw_event_work, work.work);
1644 MPT_ADAPTER *ioc = fw_event->ioc;
1645
1646 /* special rescan topology handling */
1647 if (fw_event->event == -1) {
1648 if (ioc->in_rescan) {
1649 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1650 "%s: rescan ignored as it is in progress\n",
1651 ioc->name, __func__));
1652 return;
1653 }
1654 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: rescan after "
1655 "reset\n", ioc->name, __func__));
1656 ioc->in_rescan = 1;
1657 mptsas_not_responding_devices(ioc);
1658 mptsas_scan_sas_topology(ioc);
1659 ioc->in_rescan = 0;
1660 mptsas_free_fw_event(ioc, fw_event);
1661 mptsas_fw_event_on(ioc);
1662 return;
1663 }
1664
1665 /* events handling turned off during host reset */
1666 if (ioc->fw_events_off) {
1667 mptsas_free_fw_event(ioc, fw_event);
1668 return;
1669 }
1670
1671 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: fw_event=(0x%p), "
1672 "event = (0x%02x)\n", ioc->name, __func__, fw_event,
1673 (fw_event->event & 0xFF)));
1674
1675 switch (fw_event->event) {
1676 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1677 mptsas_send_sas_event(fw_event);
1678 break;
1679 case MPI_EVENT_INTEGRATED_RAID:
1680 mptsas_send_raid_event(fw_event);
1681 break;
1682 case MPI_EVENT_IR2:
1683 mptsas_send_ir2_event(fw_event);
1684 break;
1685 case MPI_EVENT_PERSISTENT_TABLE_FULL:
1686 mptbase_sas_persist_operation(ioc,
1687 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1688 mptsas_free_fw_event(ioc, fw_event);
1689 break;
1690 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
1691 mptsas_broadcast_primitive_work(fw_event);
1692 break;
1693 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
1694 mptsas_send_expander_event(fw_event);
1695 break;
1696 case MPI_EVENT_SAS_PHY_LINK_STATUS:
1697 mptsas_send_link_status_event(fw_event);
1698 break;
1699 case MPI_EVENT_QUEUE_FULL:
1700 mptsas_handle_queue_full_event(fw_event);
1701 break;
1702 }
1703 }
1704
1705
1706
1707 static int
mptsas_slave_configure(struct scsi_device * sdev)1708 mptsas_slave_configure(struct scsi_device *sdev)
1709 {
1710 struct Scsi_Host *host = sdev->host;
1711 MPT_SCSI_HOST *hd = shost_priv(host);
1712 MPT_ADAPTER *ioc = hd->ioc;
1713 VirtDevice *vdevice = sdev->hostdata;
1714
1715 if (vdevice->vtarget->deleted) {
1716 sdev_printk(KERN_INFO, sdev, "clearing deleted flag\n");
1717 vdevice->vtarget->deleted = 0;
1718 }
1719
1720 /*
1721 * RAID volumes placed beyond the last expected port.
1722 * Ignore sending sas mode pages in that case..
1723 */
1724 if (sdev->channel == MPTSAS_RAID_CHANNEL) {
1725 mptsas_add_device_component_starget_ir(ioc, scsi_target(sdev));
1726 goto out;
1727 }
1728
1729 sas_read_port_mode_page(sdev);
1730
1731 mptsas_add_device_component_starget(ioc, scsi_target(sdev));
1732
1733 out:
1734 return mptscsih_slave_configure(sdev);
1735 }
1736
1737 static int
mptsas_target_alloc(struct scsi_target * starget)1738 mptsas_target_alloc(struct scsi_target *starget)
1739 {
1740 struct Scsi_Host *host = dev_to_shost(&starget->dev);
1741 MPT_SCSI_HOST *hd = shost_priv(host);
1742 VirtTarget *vtarget;
1743 u8 id, channel;
1744 struct sas_rphy *rphy;
1745 struct mptsas_portinfo *p;
1746 int i;
1747 MPT_ADAPTER *ioc = hd->ioc;
1748
1749 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
1750 if (!vtarget)
1751 return -ENOMEM;
1752
1753 vtarget->starget = starget;
1754 vtarget->ioc_id = ioc->id;
1755 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
1756 id = starget->id;
1757 channel = 0;
1758
1759 /*
1760 * RAID volumes placed beyond the last expected port.
1761 */
1762 if (starget->channel == MPTSAS_RAID_CHANNEL) {
1763 if (!ioc->raid_data.pIocPg2) {
1764 kfree(vtarget);
1765 return -ENXIO;
1766 }
1767 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
1768 if (id == ioc->raid_data.pIocPg2->
1769 RaidVolume[i].VolumeID) {
1770 channel = ioc->raid_data.pIocPg2->
1771 RaidVolume[i].VolumeBus;
1772 }
1773 }
1774 vtarget->raidVolume = 1;
1775 goto out;
1776 }
1777
1778 rphy = dev_to_rphy(starget->dev.parent);
1779 mutex_lock(&ioc->sas_topology_mutex);
1780 list_for_each_entry(p, &ioc->sas_topology, list) {
1781 for (i = 0; i < p->num_phys; i++) {
1782 if (p->phy_info[i].attached.sas_address !=
1783 rphy->identify.sas_address)
1784 continue;
1785 id = p->phy_info[i].attached.id;
1786 channel = p->phy_info[i].attached.channel;
1787 mptsas_set_starget(&p->phy_info[i], starget);
1788
1789 /*
1790 * Exposing hidden raid components
1791 */
1792 if (mptscsih_is_phys_disk(ioc, channel, id)) {
1793 id = mptscsih_raid_id_to_num(ioc,
1794 channel, id);
1795 vtarget->tflags |=
1796 MPT_TARGET_FLAGS_RAID_COMPONENT;
1797 p->phy_info[i].attached.phys_disk_num = id;
1798 }
1799 mutex_unlock(&ioc->sas_topology_mutex);
1800 goto out;
1801 }
1802 }
1803 mutex_unlock(&ioc->sas_topology_mutex);
1804
1805 kfree(vtarget);
1806 return -ENXIO;
1807
1808 out:
1809 vtarget->id = id;
1810 vtarget->channel = channel;
1811 starget->hostdata = vtarget;
1812 return 0;
1813 }
1814
1815 static void
mptsas_target_destroy(struct scsi_target * starget)1816 mptsas_target_destroy(struct scsi_target *starget)
1817 {
1818 struct Scsi_Host *host = dev_to_shost(&starget->dev);
1819 MPT_SCSI_HOST *hd = shost_priv(host);
1820 struct sas_rphy *rphy;
1821 struct mptsas_portinfo *p;
1822 int i;
1823 MPT_ADAPTER *ioc = hd->ioc;
1824 VirtTarget *vtarget;
1825
1826 if (!starget->hostdata)
1827 return;
1828
1829 vtarget = starget->hostdata;
1830
1831 mptsas_del_device_component_by_os(ioc, starget->channel,
1832 starget->id);
1833
1834
1835 if (starget->channel == MPTSAS_RAID_CHANNEL)
1836 goto out;
1837
1838 rphy = dev_to_rphy(starget->dev.parent);
1839 list_for_each_entry(p, &ioc->sas_topology, list) {
1840 for (i = 0; i < p->num_phys; i++) {
1841 if (p->phy_info[i].attached.sas_address !=
1842 rphy->identify.sas_address)
1843 continue;
1844
1845 starget_printk(KERN_INFO, starget, MYIOC_s_FMT
1846 "delete device: fw_channel %d, fw_id %d, phy %d, "
1847 "sas_addr 0x%llx\n", ioc->name,
1848 p->phy_info[i].attached.channel,
1849 p->phy_info[i].attached.id,
1850 p->phy_info[i].attached.phy_id, (unsigned long long)
1851 p->phy_info[i].attached.sas_address);
1852
1853 mptsas_set_starget(&p->phy_info[i], NULL);
1854 }
1855 }
1856
1857 out:
1858 vtarget->starget = NULL;
1859 kfree(starget->hostdata);
1860 starget->hostdata = NULL;
1861 }
1862
1863
1864 static int
mptsas_slave_alloc(struct scsi_device * sdev)1865 mptsas_slave_alloc(struct scsi_device *sdev)
1866 {
1867 struct Scsi_Host *host = sdev->host;
1868 MPT_SCSI_HOST *hd = shost_priv(host);
1869 struct sas_rphy *rphy;
1870 struct mptsas_portinfo *p;
1871 VirtDevice *vdevice;
1872 struct scsi_target *starget;
1873 int i;
1874 MPT_ADAPTER *ioc = hd->ioc;
1875
1876 vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
1877 if (!vdevice) {
1878 printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
1879 ioc->name, sizeof(VirtDevice));
1880 return -ENOMEM;
1881 }
1882 starget = scsi_target(sdev);
1883 vdevice->vtarget = starget->hostdata;
1884
1885 if (sdev->channel == MPTSAS_RAID_CHANNEL)
1886 goto out;
1887
1888 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
1889 mutex_lock(&ioc->sas_topology_mutex);
1890 list_for_each_entry(p, &ioc->sas_topology, list) {
1891 for (i = 0; i < p->num_phys; i++) {
1892 if (p->phy_info[i].attached.sas_address !=
1893 rphy->identify.sas_address)
1894 continue;
1895 vdevice->lun = sdev->lun;
1896 /*
1897 * Exposing hidden raid components
1898 */
1899 if (mptscsih_is_phys_disk(ioc,
1900 p->phy_info[i].attached.channel,
1901 p->phy_info[i].attached.id))
1902 sdev->no_uld_attach = 1;
1903 mutex_unlock(&ioc->sas_topology_mutex);
1904 goto out;
1905 }
1906 }
1907 mutex_unlock(&ioc->sas_topology_mutex);
1908
1909 kfree(vdevice);
1910 return -ENXIO;
1911
1912 out:
1913 vdevice->vtarget->num_luns++;
1914 sdev->hostdata = vdevice;
1915 return 0;
1916 }
1917
1918 static int
mptsas_qcmd(struct Scsi_Host * shost,struct scsi_cmnd * SCpnt)1919 mptsas_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt)
1920 {
1921 MPT_SCSI_HOST *hd;
1922 MPT_ADAPTER *ioc;
1923 VirtDevice *vdevice = SCpnt->device->hostdata;
1924
1925 if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
1926 SCpnt->result = DID_NO_CONNECT << 16;
1927 SCpnt->scsi_done(SCpnt);
1928 return 0;
1929 }
1930
1931 hd = shost_priv(shost);
1932 ioc = hd->ioc;
1933
1934 if (ioc->sas_discovery_quiesce_io)
1935 return SCSI_MLQUEUE_HOST_BUSY;
1936
1937 if (ioc->debug_level & MPT_DEBUG_SCSI)
1938 scsi_print_command(SCpnt);
1939
1940 return mptscsih_qcmd(SCpnt);
1941 }
1942
1943 /**
1944 * mptsas_mptsas_eh_timed_out - resets the scsi_cmnd timeout
1945 * if the device under question is currently in the
1946 * device removal delay.
1947 * @sc: scsi command that the midlayer is about to time out
1948 *
1949 **/
mptsas_eh_timed_out(struct scsi_cmnd * sc)1950 static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc)
1951 {
1952 MPT_SCSI_HOST *hd;
1953 MPT_ADAPTER *ioc;
1954 VirtDevice *vdevice;
1955 enum blk_eh_timer_return rc = BLK_EH_DONE;
1956
1957 hd = shost_priv(sc->device->host);
1958 if (hd == NULL) {
1959 printk(KERN_ERR MYNAM ": %s: Can't locate host! (sc=%p)\n",
1960 __func__, sc);
1961 goto done;
1962 }
1963
1964 ioc = hd->ioc;
1965 if (ioc->bus_type != SAS) {
1966 printk(KERN_ERR MYNAM ": %s: Wrong bus type (sc=%p)\n",
1967 __func__, sc);
1968 goto done;
1969 }
1970
1971 /* In case if IOC is in reset from internal context.
1972 * Do not execute EEH for the same IOC. SML should to reset timer.
1973 */
1974 if (ioc->ioc_reset_in_progress) {
1975 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: ioc is in reset,"
1976 "SML need to reset the timer (sc=%p)\n",
1977 ioc->name, __func__, sc));
1978 rc = BLK_EH_RESET_TIMER;
1979 }
1980 vdevice = sc->device->hostdata;
1981 if (vdevice && vdevice->vtarget && (vdevice->vtarget->inDMD
1982 || vdevice->vtarget->deleted)) {
1983 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: target removed "
1984 "or in device removal delay (sc=%p)\n",
1985 ioc->name, __func__, sc));
1986 rc = BLK_EH_RESET_TIMER;
1987 goto done;
1988 }
1989
1990 done:
1991 return rc;
1992 }
1993
1994
1995 static struct scsi_host_template mptsas_driver_template = {
1996 .module = THIS_MODULE,
1997 .proc_name = "mptsas",
1998 .show_info = mptscsih_show_info,
1999 .name = "MPT SAS Host",
2000 .info = mptscsih_info,
2001 .queuecommand = mptsas_qcmd,
2002 .target_alloc = mptsas_target_alloc,
2003 .slave_alloc = mptsas_slave_alloc,
2004 .slave_configure = mptsas_slave_configure,
2005 .target_destroy = mptsas_target_destroy,
2006 .slave_destroy = mptscsih_slave_destroy,
2007 .change_queue_depth = mptscsih_change_queue_depth,
2008 .eh_timed_out = mptsas_eh_timed_out,
2009 .eh_abort_handler = mptscsih_abort,
2010 .eh_device_reset_handler = mptscsih_dev_reset,
2011 .eh_host_reset_handler = mptscsih_host_reset,
2012 .bios_param = mptscsih_bios_param,
2013 .can_queue = MPT_SAS_CAN_QUEUE,
2014 .this_id = -1,
2015 .sg_tablesize = MPT_SCSI_SG_DEPTH,
2016 .max_sectors = 8192,
2017 .cmd_per_lun = 7,
2018 .shost_attrs = mptscsih_host_attrs,
2019 .no_write_same = 1,
2020 };
2021
mptsas_get_linkerrors(struct sas_phy * phy)2022 static int mptsas_get_linkerrors(struct sas_phy *phy)
2023 {
2024 MPT_ADAPTER *ioc = phy_to_ioc(phy);
2025 ConfigExtendedPageHeader_t hdr;
2026 CONFIGPARMS cfg;
2027 SasPhyPage1_t *buffer;
2028 dma_addr_t dma_handle;
2029 int error;
2030
2031 /* FIXME: only have link errors on local phys */
2032 if (!scsi_is_sas_phy_local(phy))
2033 return -EINVAL;
2034
2035 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
2036 hdr.ExtPageLength = 0;
2037 hdr.PageNumber = 1 /* page number 1*/;
2038 hdr.Reserved1 = 0;
2039 hdr.Reserved2 = 0;
2040 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2041 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2042
2043 cfg.cfghdr.ehdr = &hdr;
2044 cfg.physAddr = -1;
2045 cfg.pageAddr = phy->identify.phy_identifier;
2046 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2047 cfg.dir = 0; /* read */
2048 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2049
2050 error = mpt_config(ioc, &cfg);
2051 if (error)
2052 return error;
2053 if (!hdr.ExtPageLength)
2054 return -ENXIO;
2055
2056 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2057 &dma_handle);
2058 if (!buffer)
2059 return -ENOMEM;
2060
2061 cfg.physAddr = dma_handle;
2062 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2063
2064 error = mpt_config(ioc, &cfg);
2065 if (error)
2066 goto out_free_consistent;
2067
2068 mptsas_print_phy_pg1(ioc, buffer);
2069
2070 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
2071 phy->running_disparity_error_count =
2072 le32_to_cpu(buffer->RunningDisparityErrorCount);
2073 phy->loss_of_dword_sync_count =
2074 le32_to_cpu(buffer->LossDwordSynchCount);
2075 phy->phy_reset_problem_count =
2076 le32_to_cpu(buffer->PhyResetProblemCount);
2077
2078 out_free_consistent:
2079 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2080 buffer, dma_handle);
2081 return error;
2082 }
2083
mptsas_mgmt_done(MPT_ADAPTER * ioc,MPT_FRAME_HDR * req,MPT_FRAME_HDR * reply)2084 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2085 MPT_FRAME_HDR *reply)
2086 {
2087 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2088 if (reply != NULL) {
2089 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_RF_VALID;
2090 memcpy(ioc->sas_mgmt.reply, reply,
2091 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
2092 }
2093
2094 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
2095 ioc->sas_mgmt.status &= ~MPT_MGMT_STATUS_PENDING;
2096 complete(&ioc->sas_mgmt.done);
2097 return 1;
2098 }
2099 return 0;
2100 }
2101
mptsas_phy_reset(struct sas_phy * phy,int hard_reset)2102 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
2103 {
2104 MPT_ADAPTER *ioc = phy_to_ioc(phy);
2105 SasIoUnitControlRequest_t *req;
2106 SasIoUnitControlReply_t *reply;
2107 MPT_FRAME_HDR *mf;
2108 MPIHeader_t *hdr;
2109 unsigned long timeleft;
2110 int error = -ERESTARTSYS;
2111
2112 /* FIXME: fusion doesn't allow non-local phy reset */
2113 if (!scsi_is_sas_phy_local(phy))
2114 return -EINVAL;
2115
2116 /* not implemented for expanders */
2117 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
2118 return -ENXIO;
2119
2120 if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
2121 goto out;
2122
2123 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2124 if (!mf) {
2125 error = -ENOMEM;
2126 goto out_unlock;
2127 }
2128
2129 hdr = (MPIHeader_t *) mf;
2130 req = (SasIoUnitControlRequest_t *)mf;
2131 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
2132 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
2133 req->MsgContext = hdr->MsgContext;
2134 req->Operation = hard_reset ?
2135 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
2136 req->PhyNum = phy->identify.phy_identifier;
2137
2138 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2139 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2140
2141 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
2142 10 * HZ);
2143 if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2144 error = -ETIME;
2145 mpt_free_msg_frame(ioc, mf);
2146 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2147 goto out_unlock;
2148 if (!timeleft)
2149 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2150 goto out_unlock;
2151 }
2152
2153 /* a reply frame is expected */
2154 if ((ioc->sas_mgmt.status &
2155 MPT_MGMT_STATUS_RF_VALID) == 0) {
2156 error = -ENXIO;
2157 goto out_unlock;
2158 }
2159
2160 /* process the completed Reply Message Frame */
2161 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
2162 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
2163 printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
2164 ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo);
2165 error = -ENXIO;
2166 goto out_unlock;
2167 }
2168
2169 error = 0;
2170
2171 out_unlock:
2172 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2173 mutex_unlock(&ioc->sas_mgmt.mutex);
2174 out:
2175 return error;
2176 }
2177
2178 static int
mptsas_get_enclosure_identifier(struct sas_rphy * rphy,u64 * identifier)2179 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
2180 {
2181 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2182 int i, error;
2183 struct mptsas_portinfo *p;
2184 struct mptsas_enclosure enclosure_info;
2185 u64 enclosure_handle;
2186
2187 mutex_lock(&ioc->sas_topology_mutex);
2188 list_for_each_entry(p, &ioc->sas_topology, list) {
2189 for (i = 0; i < p->num_phys; i++) {
2190 if (p->phy_info[i].attached.sas_address ==
2191 rphy->identify.sas_address) {
2192 enclosure_handle = p->phy_info[i].
2193 attached.handle_enclosure;
2194 goto found_info;
2195 }
2196 }
2197 }
2198 mutex_unlock(&ioc->sas_topology_mutex);
2199 return -ENXIO;
2200
2201 found_info:
2202 mutex_unlock(&ioc->sas_topology_mutex);
2203 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
2204 error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
2205 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
2206 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
2207 if (!error)
2208 *identifier = enclosure_info.enclosure_logical_id;
2209 return error;
2210 }
2211
2212 static int
mptsas_get_bay_identifier(struct sas_rphy * rphy)2213 mptsas_get_bay_identifier(struct sas_rphy *rphy)
2214 {
2215 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2216 struct mptsas_portinfo *p;
2217 int i, rc;
2218
2219 mutex_lock(&ioc->sas_topology_mutex);
2220 list_for_each_entry(p, &ioc->sas_topology, list) {
2221 for (i = 0; i < p->num_phys; i++) {
2222 if (p->phy_info[i].attached.sas_address ==
2223 rphy->identify.sas_address) {
2224 rc = p->phy_info[i].attached.slot;
2225 goto out;
2226 }
2227 }
2228 }
2229 rc = -ENXIO;
2230 out:
2231 mutex_unlock(&ioc->sas_topology_mutex);
2232 return rc;
2233 }
2234
mptsas_smp_handler(struct bsg_job * job,struct Scsi_Host * shost,struct sas_rphy * rphy)2235 static void mptsas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
2236 struct sas_rphy *rphy)
2237 {
2238 MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
2239 MPT_FRAME_HDR *mf;
2240 SmpPassthroughRequest_t *smpreq;
2241 int flagsLength;
2242 unsigned long timeleft;
2243 char *psge;
2244 u64 sas_address = 0;
2245 unsigned int reslen = 0;
2246 int ret = -EINVAL;
2247
2248 /* do we need to support multiple segments? */
2249 if (job->request_payload.sg_cnt > 1 ||
2250 job->reply_payload.sg_cnt > 1) {
2251 printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u, rsp %u\n",
2252 ioc->name, __func__, job->request_payload.payload_len,
2253 job->reply_payload.payload_len);
2254 goto out;
2255 }
2256
2257 ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2258 if (ret)
2259 goto out;
2260
2261 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2262 if (!mf) {
2263 ret = -ENOMEM;
2264 goto out_unlock;
2265 }
2266
2267 smpreq = (SmpPassthroughRequest_t *)mf;
2268 memset(smpreq, 0, sizeof(*smpreq));
2269
2270 smpreq->RequestDataLength =
2271 cpu_to_le16(job->request_payload.payload_len - 4);
2272 smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2273
2274 if (rphy)
2275 sas_address = rphy->identify.sas_address;
2276 else {
2277 struct mptsas_portinfo *port_info;
2278
2279 mutex_lock(&ioc->sas_topology_mutex);
2280 port_info = ioc->hba_port_info;
2281 if (port_info && port_info->phy_info)
2282 sas_address =
2283 port_info->phy_info[0].phy->identify.sas_address;
2284 mutex_unlock(&ioc->sas_topology_mutex);
2285 }
2286
2287 *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2288
2289 psge = (char *)
2290 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2291
2292 /* request */
2293 flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2294 MPI_SGE_FLAGS_END_OF_BUFFER |
2295 MPI_SGE_FLAGS_DIRECTION)
2296 << MPI_SGE_FLAGS_SHIFT;
2297
2298 if (!dma_map_sg(&ioc->pcidev->dev, job->request_payload.sg_list,
2299 1, PCI_DMA_BIDIRECTIONAL))
2300 goto put_mf;
2301
2302 flagsLength |= (sg_dma_len(job->request_payload.sg_list) - 4);
2303 ioc->add_sge(psge, flagsLength,
2304 sg_dma_address(job->request_payload.sg_list));
2305 psge += ioc->SGE_size;
2306
2307 /* response */
2308 flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2309 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2310 MPI_SGE_FLAGS_IOC_TO_HOST |
2311 MPI_SGE_FLAGS_END_OF_BUFFER;
2312
2313 flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2314
2315 if (!dma_map_sg(&ioc->pcidev->dev, job->reply_payload.sg_list,
2316 1, PCI_DMA_BIDIRECTIONAL))
2317 goto unmap_out;
2318 flagsLength |= sg_dma_len(job->reply_payload.sg_list) + 4;
2319 ioc->add_sge(psge, flagsLength,
2320 sg_dma_address(job->reply_payload.sg_list));
2321
2322 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2323 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2324
2325 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2326 if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2327 ret = -ETIME;
2328 mpt_free_msg_frame(ioc, mf);
2329 mf = NULL;
2330 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2331 goto unmap_in;
2332 if (!timeleft)
2333 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2334 goto unmap_in;
2335 }
2336 mf = NULL;
2337
2338 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2339 SmpPassthroughReply_t *smprep;
2340
2341 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2342 memcpy(job->reply, smprep, sizeof(*smprep));
2343 job->reply_len = sizeof(*smprep);
2344 reslen = smprep->ResponseDataLength;
2345 } else {
2346 printk(MYIOC_s_ERR_FMT
2347 "%s: smp passthru reply failed to be returned\n",
2348 ioc->name, __func__);
2349 ret = -ENXIO;
2350 }
2351
2352 unmap_in:
2353 dma_unmap_sg(&ioc->pcidev->dev, job->reply_payload.sg_list, 1,
2354 PCI_DMA_BIDIRECTIONAL);
2355 unmap_out:
2356 dma_unmap_sg(&ioc->pcidev->dev, job->request_payload.sg_list, 1,
2357 PCI_DMA_BIDIRECTIONAL);
2358 put_mf:
2359 if (mf)
2360 mpt_free_msg_frame(ioc, mf);
2361 out_unlock:
2362 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2363 mutex_unlock(&ioc->sas_mgmt.mutex);
2364 out:
2365 bsg_job_done(job, ret, reslen);
2366 }
2367
2368 static struct sas_function_template mptsas_transport_functions = {
2369 .get_linkerrors = mptsas_get_linkerrors,
2370 .get_enclosure_identifier = mptsas_get_enclosure_identifier,
2371 .get_bay_identifier = mptsas_get_bay_identifier,
2372 .phy_reset = mptsas_phy_reset,
2373 .smp_handler = mptsas_smp_handler,
2374 };
2375
2376 static struct scsi_transport_template *mptsas_transport_template;
2377
2378 static int
mptsas_sas_io_unit_pg0(MPT_ADAPTER * ioc,struct mptsas_portinfo * port_info)2379 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
2380 {
2381 ConfigExtendedPageHeader_t hdr;
2382 CONFIGPARMS cfg;
2383 SasIOUnitPage0_t *buffer;
2384 dma_addr_t dma_handle;
2385 int error, i;
2386
2387 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
2388 hdr.ExtPageLength = 0;
2389 hdr.PageNumber = 0;
2390 hdr.Reserved1 = 0;
2391 hdr.Reserved2 = 0;
2392 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2393 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2394
2395 cfg.cfghdr.ehdr = &hdr;
2396 cfg.physAddr = -1;
2397 cfg.pageAddr = 0;
2398 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2399 cfg.dir = 0; /* read */
2400 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2401
2402 error = mpt_config(ioc, &cfg);
2403 if (error)
2404 goto out;
2405 if (!hdr.ExtPageLength) {
2406 error = -ENXIO;
2407 goto out;
2408 }
2409
2410 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2411 &dma_handle);
2412 if (!buffer) {
2413 error = -ENOMEM;
2414 goto out;
2415 }
2416
2417 cfg.physAddr = dma_handle;
2418 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2419
2420 error = mpt_config(ioc, &cfg);
2421 if (error)
2422 goto out_free_consistent;
2423
2424 port_info->num_phys = buffer->NumPhys;
2425 port_info->phy_info = kcalloc(port_info->num_phys,
2426 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2427 if (!port_info->phy_info) {
2428 error = -ENOMEM;
2429 goto out_free_consistent;
2430 }
2431
2432 ioc->nvdata_version_persistent =
2433 le16_to_cpu(buffer->NvdataVersionPersistent);
2434 ioc->nvdata_version_default =
2435 le16_to_cpu(buffer->NvdataVersionDefault);
2436
2437 for (i = 0; i < port_info->num_phys; i++) {
2438 mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
2439 port_info->phy_info[i].phy_id = i;
2440 port_info->phy_info[i].port_id =
2441 buffer->PhyData[i].Port;
2442 port_info->phy_info[i].negotiated_link_rate =
2443 buffer->PhyData[i].NegotiatedLinkRate;
2444 port_info->phy_info[i].portinfo = port_info;
2445 port_info->phy_info[i].handle =
2446 le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
2447 }
2448
2449 out_free_consistent:
2450 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2451 buffer, dma_handle);
2452 out:
2453 return error;
2454 }
2455
2456 static int
mptsas_sas_io_unit_pg1(MPT_ADAPTER * ioc)2457 mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
2458 {
2459 ConfigExtendedPageHeader_t hdr;
2460 CONFIGPARMS cfg;
2461 SasIOUnitPage1_t *buffer;
2462 dma_addr_t dma_handle;
2463 int error;
2464 u8 device_missing_delay;
2465
2466 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
2467 memset(&cfg, 0, sizeof(CONFIGPARMS));
2468
2469 cfg.cfghdr.ehdr = &hdr;
2470 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2471 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2472 cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2473 cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2474 cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
2475 cfg.cfghdr.ehdr->PageNumber = 1;
2476
2477 error = mpt_config(ioc, &cfg);
2478 if (error)
2479 goto out;
2480 if (!hdr.ExtPageLength) {
2481 error = -ENXIO;
2482 goto out;
2483 }
2484
2485 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2486 &dma_handle);
2487 if (!buffer) {
2488 error = -ENOMEM;
2489 goto out;
2490 }
2491
2492 cfg.physAddr = dma_handle;
2493 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2494
2495 error = mpt_config(ioc, &cfg);
2496 if (error)
2497 goto out_free_consistent;
2498
2499 ioc->io_missing_delay =
2500 le16_to_cpu(buffer->IODeviceMissingDelay);
2501 device_missing_delay = buffer->ReportDeviceMissingDelay;
2502 ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
2503 (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
2504 device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
2505
2506 out_free_consistent:
2507 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2508 buffer, dma_handle);
2509 out:
2510 return error;
2511 }
2512
2513 static int
mptsas_sas_phy_pg0(MPT_ADAPTER * ioc,struct mptsas_phyinfo * phy_info,u32 form,u32 form_specific)2514 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2515 u32 form, u32 form_specific)
2516 {
2517 ConfigExtendedPageHeader_t hdr;
2518 CONFIGPARMS cfg;
2519 SasPhyPage0_t *buffer;
2520 dma_addr_t dma_handle;
2521 int error;
2522
2523 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
2524 hdr.ExtPageLength = 0;
2525 hdr.PageNumber = 0;
2526 hdr.Reserved1 = 0;
2527 hdr.Reserved2 = 0;
2528 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2529 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2530
2531 cfg.cfghdr.ehdr = &hdr;
2532 cfg.dir = 0; /* read */
2533 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2534
2535 /* Get Phy Pg 0 for each Phy. */
2536 cfg.physAddr = -1;
2537 cfg.pageAddr = form + form_specific;
2538 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2539
2540 error = mpt_config(ioc, &cfg);
2541 if (error)
2542 goto out;
2543
2544 if (!hdr.ExtPageLength) {
2545 error = -ENXIO;
2546 goto out;
2547 }
2548
2549 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2550 &dma_handle);
2551 if (!buffer) {
2552 error = -ENOMEM;
2553 goto out;
2554 }
2555
2556 cfg.physAddr = dma_handle;
2557 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2558
2559 error = mpt_config(ioc, &cfg);
2560 if (error)
2561 goto out_free_consistent;
2562
2563 mptsas_print_phy_pg0(ioc, buffer);
2564
2565 phy_info->hw_link_rate = buffer->HwLinkRate;
2566 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2567 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2568 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2569
2570 out_free_consistent:
2571 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2572 buffer, dma_handle);
2573 out:
2574 return error;
2575 }
2576
2577 static int
mptsas_sas_device_pg0(MPT_ADAPTER * ioc,struct mptsas_devinfo * device_info,u32 form,u32 form_specific)2578 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
2579 u32 form, u32 form_specific)
2580 {
2581 ConfigExtendedPageHeader_t hdr;
2582 CONFIGPARMS cfg;
2583 SasDevicePage0_t *buffer;
2584 dma_addr_t dma_handle;
2585 __le64 sas_address;
2586 int error=0;
2587
2588 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
2589 hdr.ExtPageLength = 0;
2590 hdr.PageNumber = 0;
2591 hdr.Reserved1 = 0;
2592 hdr.Reserved2 = 0;
2593 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2594 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
2595
2596 cfg.cfghdr.ehdr = &hdr;
2597 cfg.pageAddr = form + form_specific;
2598 cfg.physAddr = -1;
2599 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2600 cfg.dir = 0; /* read */
2601 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2602
2603 memset(device_info, 0, sizeof(struct mptsas_devinfo));
2604 error = mpt_config(ioc, &cfg);
2605 if (error)
2606 goto out;
2607 if (!hdr.ExtPageLength) {
2608 error = -ENXIO;
2609 goto out;
2610 }
2611
2612 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2613 &dma_handle);
2614 if (!buffer) {
2615 error = -ENOMEM;
2616 goto out;
2617 }
2618
2619 cfg.physAddr = dma_handle;
2620 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2621
2622 error = mpt_config(ioc, &cfg);
2623
2624 if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2625 error = -ENODEV;
2626 goto out_free_consistent;
2627 }
2628
2629 if (error)
2630 goto out_free_consistent;
2631
2632 mptsas_print_device_pg0(ioc, buffer);
2633
2634 memset(device_info, 0, sizeof(struct mptsas_devinfo));
2635 device_info->handle = le16_to_cpu(buffer->DevHandle);
2636 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
2637 device_info->handle_enclosure =
2638 le16_to_cpu(buffer->EnclosureHandle);
2639 device_info->slot = le16_to_cpu(buffer->Slot);
2640 device_info->phy_id = buffer->PhyNum;
2641 device_info->port_id = buffer->PhysicalPort;
2642 device_info->id = buffer->TargetID;
2643 device_info->phys_disk_num = ~0;
2644 device_info->channel = buffer->Bus;
2645 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2646 device_info->sas_address = le64_to_cpu(sas_address);
2647 device_info->device_info =
2648 le32_to_cpu(buffer->DeviceInfo);
2649 device_info->flags = le16_to_cpu(buffer->Flags);
2650
2651 out_free_consistent:
2652 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2653 buffer, dma_handle);
2654 out:
2655 return error;
2656 }
2657
2658 static int
mptsas_sas_expander_pg0(MPT_ADAPTER * ioc,struct mptsas_portinfo * port_info,u32 form,u32 form_specific)2659 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
2660 u32 form, u32 form_specific)
2661 {
2662 ConfigExtendedPageHeader_t hdr;
2663 CONFIGPARMS cfg;
2664 SasExpanderPage0_t *buffer;
2665 dma_addr_t dma_handle;
2666 int i, error;
2667 __le64 sas_address;
2668
2669 memset(port_info, 0, sizeof(struct mptsas_portinfo));
2670 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
2671 hdr.ExtPageLength = 0;
2672 hdr.PageNumber = 0;
2673 hdr.Reserved1 = 0;
2674 hdr.Reserved2 = 0;
2675 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2676 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2677
2678 cfg.cfghdr.ehdr = &hdr;
2679 cfg.physAddr = -1;
2680 cfg.pageAddr = form + form_specific;
2681 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2682 cfg.dir = 0; /* read */
2683 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2684
2685 memset(port_info, 0, sizeof(struct mptsas_portinfo));
2686 error = mpt_config(ioc, &cfg);
2687 if (error)
2688 goto out;
2689
2690 if (!hdr.ExtPageLength) {
2691 error = -ENXIO;
2692 goto out;
2693 }
2694
2695 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2696 &dma_handle);
2697 if (!buffer) {
2698 error = -ENOMEM;
2699 goto out;
2700 }
2701
2702 cfg.physAddr = dma_handle;
2703 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2704
2705 error = mpt_config(ioc, &cfg);
2706 if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2707 error = -ENODEV;
2708 goto out_free_consistent;
2709 }
2710
2711 if (error)
2712 goto out_free_consistent;
2713
2714 /* save config data */
2715 port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1;
2716 port_info->phy_info = kcalloc(port_info->num_phys,
2717 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2718 if (!port_info->phy_info) {
2719 error = -ENOMEM;
2720 goto out_free_consistent;
2721 }
2722
2723 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2724 for (i = 0; i < port_info->num_phys; i++) {
2725 port_info->phy_info[i].portinfo = port_info;
2726 port_info->phy_info[i].handle =
2727 le16_to_cpu(buffer->DevHandle);
2728 port_info->phy_info[i].identify.sas_address =
2729 le64_to_cpu(sas_address);
2730 port_info->phy_info[i].identify.handle_parent =
2731 le16_to_cpu(buffer->ParentDevHandle);
2732 }
2733
2734 out_free_consistent:
2735 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2736 buffer, dma_handle);
2737 out:
2738 return error;
2739 }
2740
2741 static int
mptsas_sas_expander_pg1(MPT_ADAPTER * ioc,struct mptsas_phyinfo * phy_info,u32 form,u32 form_specific)2742 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2743 u32 form, u32 form_specific)
2744 {
2745 ConfigExtendedPageHeader_t hdr;
2746 CONFIGPARMS cfg;
2747 SasExpanderPage1_t *buffer;
2748 dma_addr_t dma_handle;
2749 int error=0;
2750
2751 hdr.PageVersion = MPI_SASEXPANDER1_PAGEVERSION;
2752 hdr.ExtPageLength = 0;
2753 hdr.PageNumber = 1;
2754 hdr.Reserved1 = 0;
2755 hdr.Reserved2 = 0;
2756 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2757 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2758
2759 cfg.cfghdr.ehdr = &hdr;
2760 cfg.physAddr = -1;
2761 cfg.pageAddr = form + form_specific;
2762 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2763 cfg.dir = 0; /* read */
2764 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2765
2766 error = mpt_config(ioc, &cfg);
2767 if (error)
2768 goto out;
2769
2770 if (!hdr.ExtPageLength) {
2771 error = -ENXIO;
2772 goto out;
2773 }
2774
2775 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2776 &dma_handle);
2777 if (!buffer) {
2778 error = -ENOMEM;
2779 goto out;
2780 }
2781
2782 cfg.physAddr = dma_handle;
2783 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2784
2785 error = mpt_config(ioc, &cfg);
2786
2787 if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2788 error = -ENODEV;
2789 goto out_free_consistent;
2790 }
2791
2792 if (error)
2793 goto out_free_consistent;
2794
2795
2796 mptsas_print_expander_pg1(ioc, buffer);
2797
2798 /* save config data */
2799 phy_info->phy_id = buffer->PhyIdentifier;
2800 phy_info->port_id = buffer->PhysicalPort;
2801 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
2802 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2803 phy_info->hw_link_rate = buffer->HwLinkRate;
2804 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2805 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2806
2807 out_free_consistent:
2808 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2809 buffer, dma_handle);
2810 out:
2811 return error;
2812 }
2813
2814 struct rep_manu_request{
2815 u8 smp_frame_type;
2816 u8 function;
2817 u8 reserved;
2818 u8 request_length;
2819 };
2820
2821 struct rep_manu_reply{
2822 u8 smp_frame_type; /* 0x41 */
2823 u8 function; /* 0x01 */
2824 u8 function_result;
2825 u8 response_length;
2826 u16 expander_change_count;
2827 u8 reserved0[2];
2828 u8 sas_format:1;
2829 u8 reserved1:7;
2830 u8 reserved2[3];
2831 u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
2832 u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
2833 u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
2834 u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
2835 u16 component_id;
2836 u8 component_revision_id;
2837 u8 reserved3;
2838 u8 vendor_specific[8];
2839 };
2840
2841 /**
2842 * mptsas_exp_repmanufacture_info -
2843 * @ioc: per adapter object
2844 * @sas_address: expander sas address
2845 * @edev: the sas_expander_device object
2846 *
2847 * Fills in the sas_expander_device object when SMP port is created.
2848 *
2849 * Returns 0 for success, non-zero for failure.
2850 */
2851 static int
mptsas_exp_repmanufacture_info(MPT_ADAPTER * ioc,u64 sas_address,struct sas_expander_device * edev)2852 mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
2853 u64 sas_address, struct sas_expander_device *edev)
2854 {
2855 MPT_FRAME_HDR *mf;
2856 SmpPassthroughRequest_t *smpreq;
2857 SmpPassthroughReply_t *smprep;
2858 struct rep_manu_reply *manufacture_reply;
2859 struct rep_manu_request *manufacture_request;
2860 int ret;
2861 int flagsLength;
2862 unsigned long timeleft;
2863 char *psge;
2864 unsigned long flags;
2865 void *data_out = NULL;
2866 dma_addr_t data_out_dma = 0;
2867 u32 sz;
2868
2869 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2870 if (ioc->ioc_reset_in_progress) {
2871 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2872 printk(MYIOC_s_INFO_FMT "%s: host reset in progress!\n",
2873 __func__, ioc->name);
2874 return -EFAULT;
2875 }
2876 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2877
2878 ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2879 if (ret)
2880 goto out;
2881
2882 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2883 if (!mf) {
2884 ret = -ENOMEM;
2885 goto out_unlock;
2886 }
2887
2888 smpreq = (SmpPassthroughRequest_t *)mf;
2889 memset(smpreq, 0, sizeof(*smpreq));
2890
2891 sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
2892
2893 data_out = pci_alloc_consistent(ioc->pcidev, sz, &data_out_dma);
2894 if (!data_out) {
2895 printk(KERN_ERR "Memory allocation failure at %s:%d/%s()!\n",
2896 __FILE__, __LINE__, __func__);
2897 ret = -ENOMEM;
2898 goto put_mf;
2899 }
2900
2901 manufacture_request = data_out;
2902 manufacture_request->smp_frame_type = 0x40;
2903 manufacture_request->function = 1;
2904 manufacture_request->reserved = 0;
2905 manufacture_request->request_length = 0;
2906
2907 smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2908 smpreq->PhysicalPort = 0xFF;
2909 *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2910 smpreq->RequestDataLength = sizeof(struct rep_manu_request);
2911
2912 psge = (char *)
2913 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2914
2915 flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2916 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2917 MPI_SGE_FLAGS_HOST_TO_IOC |
2918 MPI_SGE_FLAGS_END_OF_BUFFER;
2919 flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2920 flagsLength |= sizeof(struct rep_manu_request);
2921
2922 ioc->add_sge(psge, flagsLength, data_out_dma);
2923 psge += ioc->SGE_size;
2924
2925 flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2926 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2927 MPI_SGE_FLAGS_IOC_TO_HOST |
2928 MPI_SGE_FLAGS_END_OF_BUFFER;
2929 flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2930 flagsLength |= sizeof(struct rep_manu_reply);
2931 ioc->add_sge(psge, flagsLength, data_out_dma +
2932 sizeof(struct rep_manu_request));
2933
2934 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2935 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2936
2937 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2938 if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2939 ret = -ETIME;
2940 mpt_free_msg_frame(ioc, mf);
2941 mf = NULL;
2942 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2943 goto out_free;
2944 if (!timeleft)
2945 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2946 goto out_free;
2947 }
2948
2949 mf = NULL;
2950
2951 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2952 u8 *tmp;
2953
2954 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2955 if (le16_to_cpu(smprep->ResponseDataLength) !=
2956 sizeof(struct rep_manu_reply))
2957 goto out_free;
2958
2959 manufacture_reply = data_out + sizeof(struct rep_manu_request);
2960 strncpy(edev->vendor_id, manufacture_reply->vendor_id,
2961 SAS_EXPANDER_VENDOR_ID_LEN);
2962 strncpy(edev->product_id, manufacture_reply->product_id,
2963 SAS_EXPANDER_PRODUCT_ID_LEN);
2964 strncpy(edev->product_rev, manufacture_reply->product_rev,
2965 SAS_EXPANDER_PRODUCT_REV_LEN);
2966 edev->level = manufacture_reply->sas_format;
2967 if (manufacture_reply->sas_format) {
2968 strncpy(edev->component_vendor_id,
2969 manufacture_reply->component_vendor_id,
2970 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
2971 tmp = (u8 *)&manufacture_reply->component_id;
2972 edev->component_id = tmp[0] << 8 | tmp[1];
2973 edev->component_revision_id =
2974 manufacture_reply->component_revision_id;
2975 }
2976 } else {
2977 printk(MYIOC_s_ERR_FMT
2978 "%s: smp passthru reply failed to be returned\n",
2979 ioc->name, __func__);
2980 ret = -ENXIO;
2981 }
2982 out_free:
2983 if (data_out_dma)
2984 pci_free_consistent(ioc->pcidev, sz, data_out, data_out_dma);
2985 put_mf:
2986 if (mf)
2987 mpt_free_msg_frame(ioc, mf);
2988 out_unlock:
2989 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2990 mutex_unlock(&ioc->sas_mgmt.mutex);
2991 out:
2992 return ret;
2993 }
2994
2995 static void
mptsas_parse_device_info(struct sas_identify * identify,struct mptsas_devinfo * device_info)2996 mptsas_parse_device_info(struct sas_identify *identify,
2997 struct mptsas_devinfo *device_info)
2998 {
2999 u16 protocols;
3000
3001 identify->sas_address = device_info->sas_address;
3002 identify->phy_identifier = device_info->phy_id;
3003
3004 /*
3005 * Fill in Phy Initiator Port Protocol.
3006 * Bits 6:3, more than one bit can be set, fall through cases.
3007 */
3008 protocols = device_info->device_info & 0x78;
3009 identify->initiator_port_protocols = 0;
3010 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
3011 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
3012 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
3013 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
3014 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
3015 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
3016 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
3017 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
3018
3019 /*
3020 * Fill in Phy Target Port Protocol.
3021 * Bits 10:7, more than one bit can be set, fall through cases.
3022 */
3023 protocols = device_info->device_info & 0x780;
3024 identify->target_port_protocols = 0;
3025 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
3026 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
3027 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
3028 identify->target_port_protocols |= SAS_PROTOCOL_STP;
3029 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
3030 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
3031 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
3032 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
3033
3034 /*
3035 * Fill in Attached device type.
3036 */
3037 switch (device_info->device_info &
3038 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
3039 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
3040 identify->device_type = SAS_PHY_UNUSED;
3041 break;
3042 case MPI_SAS_DEVICE_INFO_END_DEVICE:
3043 identify->device_type = SAS_END_DEVICE;
3044 break;
3045 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
3046 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
3047 break;
3048 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
3049 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
3050 break;
3051 }
3052 }
3053
mptsas_probe_one_phy(struct device * dev,struct mptsas_phyinfo * phy_info,int index,int local)3054 static int mptsas_probe_one_phy(struct device *dev,
3055 struct mptsas_phyinfo *phy_info, int index, int local)
3056 {
3057 MPT_ADAPTER *ioc;
3058 struct sas_phy *phy;
3059 struct sas_port *port;
3060 int error = 0;
3061 VirtTarget *vtarget;
3062
3063 if (!dev) {
3064 error = -ENODEV;
3065 goto out;
3066 }
3067
3068 if (!phy_info->phy) {
3069 phy = sas_phy_alloc(dev, index);
3070 if (!phy) {
3071 error = -ENOMEM;
3072 goto out;
3073 }
3074 } else
3075 phy = phy_info->phy;
3076
3077 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
3078
3079 /*
3080 * Set Negotiated link rate.
3081 */
3082 switch (phy_info->negotiated_link_rate) {
3083 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
3084 phy->negotiated_linkrate = SAS_PHY_DISABLED;
3085 break;
3086 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
3087 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
3088 break;
3089 case MPI_SAS_IOUNIT0_RATE_1_5:
3090 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
3091 break;
3092 case MPI_SAS_IOUNIT0_RATE_3_0:
3093 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
3094 break;
3095 case MPI_SAS_IOUNIT0_RATE_6_0:
3096 phy->negotiated_linkrate = SAS_LINK_RATE_6_0_GBPS;
3097 break;
3098 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
3099 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
3100 default:
3101 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
3102 break;
3103 }
3104
3105 /*
3106 * Set Max hardware link rate.
3107 */
3108 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
3109 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
3110 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
3111 break;
3112 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
3113 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
3114 break;
3115 default:
3116 break;
3117 }
3118
3119 /*
3120 * Set Max programmed link rate.
3121 */
3122 switch (phy_info->programmed_link_rate &
3123 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
3124 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
3125 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
3126 break;
3127 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
3128 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
3129 break;
3130 default:
3131 break;
3132 }
3133
3134 /*
3135 * Set Min hardware link rate.
3136 */
3137 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
3138 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
3139 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
3140 break;
3141 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
3142 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
3143 break;
3144 default:
3145 break;
3146 }
3147
3148 /*
3149 * Set Min programmed link rate.
3150 */
3151 switch (phy_info->programmed_link_rate &
3152 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
3153 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
3154 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
3155 break;
3156 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
3157 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
3158 break;
3159 default:
3160 break;
3161 }
3162
3163 if (!phy_info->phy) {
3164
3165 error = sas_phy_add(phy);
3166 if (error) {
3167 sas_phy_free(phy);
3168 goto out;
3169 }
3170 phy_info->phy = phy;
3171 }
3172
3173 if (!phy_info->attached.handle ||
3174 !phy_info->port_details)
3175 goto out;
3176
3177 port = mptsas_get_port(phy_info);
3178 ioc = phy_to_ioc(phy_info->phy);
3179
3180 if (phy_info->sas_port_add_phy) {
3181
3182 if (!port) {
3183 port = sas_port_alloc_num(dev);
3184 if (!port) {
3185 error = -ENOMEM;
3186 goto out;
3187 }
3188 error = sas_port_add(port);
3189 if (error) {
3190 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3191 "%s: exit at line=%d\n", ioc->name,
3192 __func__, __LINE__));
3193 goto out;
3194 }
3195 mptsas_set_port(ioc, phy_info, port);
3196 devtprintk(ioc, dev_printk(KERN_DEBUG, &port->dev,
3197 MYIOC_s_FMT "add port %d, sas_addr (0x%llx)\n",
3198 ioc->name, port->port_identifier,
3199 (unsigned long long)phy_info->
3200 attached.sas_address));
3201 }
3202 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3203 "sas_port_add_phy: phy_id=%d\n",
3204 ioc->name, phy_info->phy_id));
3205 sas_port_add_phy(port, phy_info->phy);
3206 phy_info->sas_port_add_phy = 0;
3207 devtprintk(ioc, dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3208 MYIOC_s_FMT "add phy %d, phy-obj (0x%p)\n", ioc->name,
3209 phy_info->phy_id, phy_info->phy));
3210 }
3211 if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
3212
3213 struct sas_rphy *rphy;
3214 struct device *parent;
3215 struct sas_identify identify;
3216
3217 parent = dev->parent->parent;
3218 /*
3219 * Let the hotplug_work thread handle processing
3220 * the adding/removing of devices that occur
3221 * after start of day.
3222 */
3223 if (mptsas_is_end_device(&phy_info->attached) &&
3224 phy_info->attached.handle_parent) {
3225 goto out;
3226 }
3227
3228 mptsas_parse_device_info(&identify, &phy_info->attached);
3229 if (scsi_is_host_device(parent)) {
3230 struct mptsas_portinfo *port_info;
3231 int i;
3232
3233 port_info = ioc->hba_port_info;
3234
3235 for (i = 0; i < port_info->num_phys; i++)
3236 if (port_info->phy_info[i].identify.sas_address ==
3237 identify.sas_address) {
3238 sas_port_mark_backlink(port);
3239 goto out;
3240 }
3241
3242 } else if (scsi_is_sas_rphy(parent)) {
3243 struct sas_rphy *parent_rphy = dev_to_rphy(parent);
3244 if (identify.sas_address ==
3245 parent_rphy->identify.sas_address) {
3246 sas_port_mark_backlink(port);
3247 goto out;
3248 }
3249 }
3250
3251 switch (identify.device_type) {
3252 case SAS_END_DEVICE:
3253 rphy = sas_end_device_alloc(port);
3254 break;
3255 case SAS_EDGE_EXPANDER_DEVICE:
3256 case SAS_FANOUT_EXPANDER_DEVICE:
3257 rphy = sas_expander_alloc(port, identify.device_type);
3258 break;
3259 default:
3260 rphy = NULL;
3261 break;
3262 }
3263 if (!rphy) {
3264 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3265 "%s: exit at line=%d\n", ioc->name,
3266 __func__, __LINE__));
3267 goto out;
3268 }
3269
3270 rphy->identify = identify;
3271 error = sas_rphy_add(rphy);
3272 if (error) {
3273 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3274 "%s: exit at line=%d\n", ioc->name,
3275 __func__, __LINE__));
3276 sas_rphy_free(rphy);
3277 goto out;
3278 }
3279 mptsas_set_rphy(ioc, phy_info, rphy);
3280 if (identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
3281 identify.device_type == SAS_FANOUT_EXPANDER_DEVICE)
3282 mptsas_exp_repmanufacture_info(ioc,
3283 identify.sas_address,
3284 rphy_to_expander_device(rphy));
3285 }
3286
3287 /* If the device exists,verify it wasn't previously flagged
3288 as a missing device. If so, clear it */
3289 vtarget = mptsas_find_vtarget(ioc,
3290 phy_info->attached.channel,
3291 phy_info->attached.id);
3292 if (vtarget && vtarget->inDMD) {
3293 printk(KERN_INFO "Device returned, unsetting inDMD\n");
3294 vtarget->inDMD = 0;
3295 }
3296
3297 out:
3298 return error;
3299 }
3300
3301 static int
mptsas_probe_hba_phys(MPT_ADAPTER * ioc)3302 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
3303 {
3304 struct mptsas_portinfo *port_info, *hba;
3305 int error = -ENOMEM, i;
3306
3307 hba = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3308 if (! hba)
3309 goto out;
3310
3311 error = mptsas_sas_io_unit_pg0(ioc, hba);
3312 if (error)
3313 goto out_free_port_info;
3314
3315 mptsas_sas_io_unit_pg1(ioc);
3316 mutex_lock(&ioc->sas_topology_mutex);
3317 port_info = ioc->hba_port_info;
3318 if (!port_info) {
3319 ioc->hba_port_info = port_info = hba;
3320 ioc->hba_port_num_phy = port_info->num_phys;
3321 list_add_tail(&port_info->list, &ioc->sas_topology);
3322 } else {
3323 for (i = 0; i < hba->num_phys; i++) {
3324 port_info->phy_info[i].negotiated_link_rate =
3325 hba->phy_info[i].negotiated_link_rate;
3326 port_info->phy_info[i].handle =
3327 hba->phy_info[i].handle;
3328 port_info->phy_info[i].port_id =
3329 hba->phy_info[i].port_id;
3330 }
3331 kfree(hba->phy_info);
3332 kfree(hba);
3333 hba = NULL;
3334 }
3335 mutex_unlock(&ioc->sas_topology_mutex);
3336 #if defined(CPQ_CIM)
3337 ioc->num_ports = port_info->num_phys;
3338 #endif
3339 for (i = 0; i < port_info->num_phys; i++) {
3340 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
3341 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
3342 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
3343 port_info->phy_info[i].identify.handle =
3344 port_info->phy_info[i].handle;
3345 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
3346 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3347 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3348 port_info->phy_info[i].identify.handle);
3349 if (!ioc->hba_port_sas_addr)
3350 ioc->hba_port_sas_addr =
3351 port_info->phy_info[i].identify.sas_address;
3352 port_info->phy_info[i].identify.phy_id =
3353 port_info->phy_info[i].phy_id = i;
3354 if (port_info->phy_info[i].attached.handle)
3355 mptsas_sas_device_pg0(ioc,
3356 &port_info->phy_info[i].attached,
3357 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3358 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3359 port_info->phy_info[i].attached.handle);
3360 }
3361
3362 mptsas_setup_wide_ports(ioc, port_info);
3363
3364 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3365 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
3366 &port_info->phy_info[i], ioc->sas_index, 1);
3367
3368 return 0;
3369
3370 out_free_port_info:
3371 kfree(hba);
3372 out:
3373 return error;
3374 }
3375
3376 static void
mptsas_expander_refresh(MPT_ADAPTER * ioc,struct mptsas_portinfo * port_info)3377 mptsas_expander_refresh(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
3378 {
3379 struct mptsas_portinfo *parent;
3380 struct device *parent_dev;
3381 struct sas_rphy *rphy;
3382 int i;
3383 u64 sas_address; /* expander sas address */
3384 u32 handle;
3385
3386 handle = port_info->phy_info[0].handle;
3387 sas_address = port_info->phy_info[0].identify.sas_address;
3388 for (i = 0; i < port_info->num_phys; i++) {
3389 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
3390 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
3391 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + handle);
3392
3393 mptsas_sas_device_pg0(ioc,
3394 &port_info->phy_info[i].identify,
3395 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3396 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3397 port_info->phy_info[i].identify.handle);
3398 port_info->phy_info[i].identify.phy_id =
3399 port_info->phy_info[i].phy_id;
3400
3401 if (port_info->phy_info[i].attached.handle) {
3402 mptsas_sas_device_pg0(ioc,
3403 &port_info->phy_info[i].attached,
3404 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3405 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3406 port_info->phy_info[i].attached.handle);
3407 port_info->phy_info[i].attached.phy_id =
3408 port_info->phy_info[i].phy_id;
3409 }
3410 }
3411
3412 mutex_lock(&ioc->sas_topology_mutex);
3413 parent = mptsas_find_portinfo_by_handle(ioc,
3414 port_info->phy_info[0].identify.handle_parent);
3415 if (!parent) {
3416 mutex_unlock(&ioc->sas_topology_mutex);
3417 return;
3418 }
3419 for (i = 0, parent_dev = NULL; i < parent->num_phys && !parent_dev;
3420 i++) {
3421 if (parent->phy_info[i].attached.sas_address == sas_address) {
3422 rphy = mptsas_get_rphy(&parent->phy_info[i]);
3423 parent_dev = &rphy->dev;
3424 }
3425 }
3426 mutex_unlock(&ioc->sas_topology_mutex);
3427
3428 mptsas_setup_wide_ports(ioc, port_info);
3429 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3430 mptsas_probe_one_phy(parent_dev, &port_info->phy_info[i],
3431 ioc->sas_index, 0);
3432 }
3433
3434 static void
mptsas_expander_event_add(MPT_ADAPTER * ioc,MpiEventDataSasExpanderStatusChange_t * expander_data)3435 mptsas_expander_event_add(MPT_ADAPTER *ioc,
3436 MpiEventDataSasExpanderStatusChange_t *expander_data)
3437 {
3438 struct mptsas_portinfo *port_info;
3439 int i;
3440 __le64 sas_address;
3441
3442 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3443 BUG_ON(!port_info);
3444 port_info->num_phys = (expander_data->NumPhys) ?
3445 expander_data->NumPhys : 1;
3446 port_info->phy_info = kcalloc(port_info->num_phys,
3447 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
3448 BUG_ON(!port_info->phy_info);
3449 memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3450 for (i = 0; i < port_info->num_phys; i++) {
3451 port_info->phy_info[i].portinfo = port_info;
3452 port_info->phy_info[i].handle =
3453 le16_to_cpu(expander_data->DevHandle);
3454 port_info->phy_info[i].identify.sas_address =
3455 le64_to_cpu(sas_address);
3456 port_info->phy_info[i].identify.handle_parent =
3457 le16_to_cpu(expander_data->ParentDevHandle);
3458 }
3459
3460 mutex_lock(&ioc->sas_topology_mutex);
3461 list_add_tail(&port_info->list, &ioc->sas_topology);
3462 mutex_unlock(&ioc->sas_topology_mutex);
3463
3464 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3465 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3466 (unsigned long long)sas_address);
3467
3468 mptsas_expander_refresh(ioc, port_info);
3469 }
3470
3471 /**
3472 * mptsas_delete_expander_siblings - remove siblings attached to expander
3473 * @ioc: Pointer to MPT_ADAPTER structure
3474 * @parent: the parent port_info object
3475 * @expander: the expander port_info object
3476 **/
3477 static void
mptsas_delete_expander_siblings(MPT_ADAPTER * ioc,struct mptsas_portinfo * parent,struct mptsas_portinfo * expander)3478 mptsas_delete_expander_siblings(MPT_ADAPTER *ioc, struct mptsas_portinfo
3479 *parent, struct mptsas_portinfo *expander)
3480 {
3481 struct mptsas_phyinfo *phy_info;
3482 struct mptsas_portinfo *port_info;
3483 struct sas_rphy *rphy;
3484 int i;
3485
3486 phy_info = expander->phy_info;
3487 for (i = 0; i < expander->num_phys; i++, phy_info++) {
3488 rphy = mptsas_get_rphy(phy_info);
3489 if (!rphy)
3490 continue;
3491 if (rphy->identify.device_type == SAS_END_DEVICE)
3492 mptsas_del_end_device(ioc, phy_info);
3493 }
3494
3495 phy_info = expander->phy_info;
3496 for (i = 0; i < expander->num_phys; i++, phy_info++) {
3497 rphy = mptsas_get_rphy(phy_info);
3498 if (!rphy)
3499 continue;
3500 if (rphy->identify.device_type ==
3501 MPI_SAS_DEVICE_INFO_EDGE_EXPANDER ||
3502 rphy->identify.device_type ==
3503 MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
3504 port_info = mptsas_find_portinfo_by_sas_address(ioc,
3505 rphy->identify.sas_address);
3506 if (!port_info)
3507 continue;
3508 if (port_info == parent) /* backlink rphy */
3509 continue;
3510 /*
3511 Delete this expander even if the expdevpage is exists
3512 because the parent expander is already deleted
3513 */
3514 mptsas_expander_delete(ioc, port_info, 1);
3515 }
3516 }
3517 }
3518
3519
3520 /**
3521 * mptsas_expander_delete - remove this expander
3522 * @ioc: Pointer to MPT_ADAPTER structure
3523 * @port_info: expander port_info struct
3524 * @force: Flag to forcefully delete the expander
3525 *
3526 **/
3527
mptsas_expander_delete(MPT_ADAPTER * ioc,struct mptsas_portinfo * port_info,u8 force)3528 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
3529 struct mptsas_portinfo *port_info, u8 force)
3530 {
3531
3532 struct mptsas_portinfo *parent;
3533 int i;
3534 u64 expander_sas_address;
3535 struct mptsas_phyinfo *phy_info;
3536 struct mptsas_portinfo buffer;
3537 struct mptsas_portinfo_details *port_details;
3538 struct sas_port *port;
3539
3540 if (!port_info)
3541 return;
3542
3543 /* see if expander is still there before deleting */
3544 mptsas_sas_expander_pg0(ioc, &buffer,
3545 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3546 MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
3547 port_info->phy_info[0].identify.handle);
3548
3549 if (buffer.num_phys) {
3550 kfree(buffer.phy_info);
3551 if (!force)
3552 return;
3553 }
3554
3555
3556 /*
3557 * Obtain the port_info instance to the parent port
3558 */
3559 port_details = NULL;
3560 expander_sas_address =
3561 port_info->phy_info[0].identify.sas_address;
3562 parent = mptsas_find_portinfo_by_handle(ioc,
3563 port_info->phy_info[0].identify.handle_parent);
3564 mptsas_delete_expander_siblings(ioc, parent, port_info);
3565 if (!parent)
3566 goto out;
3567
3568 /*
3569 * Delete rphys in the parent that point
3570 * to this expander.
3571 */
3572 phy_info = parent->phy_info;
3573 port = NULL;
3574 for (i = 0; i < parent->num_phys; i++, phy_info++) {
3575 if (!phy_info->phy)
3576 continue;
3577 if (phy_info->attached.sas_address !=
3578 expander_sas_address)
3579 continue;
3580 if (!port) {
3581 port = mptsas_get_port(phy_info);
3582 port_details = phy_info->port_details;
3583 }
3584 dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3585 MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n", ioc->name,
3586 phy_info->phy_id, phy_info->phy);
3587 sas_port_delete_phy(port, phy_info->phy);
3588 }
3589 if (port) {
3590 dev_printk(KERN_DEBUG, &port->dev,
3591 MYIOC_s_FMT "delete port %d, sas_addr (0x%llx)\n",
3592 ioc->name, port->port_identifier,
3593 (unsigned long long)expander_sas_address);
3594 sas_port_delete(port);
3595 mptsas_port_delete(ioc, port_details);
3596 }
3597 out:
3598
3599 printk(MYIOC_s_INFO_FMT "delete expander: num_phys %d, "
3600 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3601 (unsigned long long)expander_sas_address);
3602
3603 /*
3604 * free link
3605 */
3606 list_del(&port_info->list);
3607 kfree(port_info->phy_info);
3608 kfree(port_info);
3609 }
3610
3611
3612 /**
3613 * mptsas_send_expander_event - expanders events
3614 * @ioc: Pointer to MPT_ADAPTER structure
3615 * @expander_data: event data
3616 *
3617 *
3618 * This function handles adding, removing, and refreshing
3619 * device handles within the expander objects.
3620 */
3621 static void
mptsas_send_expander_event(struct fw_event_work * fw_event)3622 mptsas_send_expander_event(struct fw_event_work *fw_event)
3623 {
3624 MPT_ADAPTER *ioc;
3625 MpiEventDataSasExpanderStatusChange_t *expander_data;
3626 struct mptsas_portinfo *port_info;
3627 __le64 sas_address;
3628 int i;
3629
3630 ioc = fw_event->ioc;
3631 expander_data = (MpiEventDataSasExpanderStatusChange_t *)
3632 fw_event->event_data;
3633 memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3634 sas_address = le64_to_cpu(sas_address);
3635 port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3636
3637 if (expander_data->ReasonCode == MPI_EVENT_SAS_EXP_RC_ADDED) {
3638 if (port_info) {
3639 for (i = 0; i < port_info->num_phys; i++) {
3640 port_info->phy_info[i].portinfo = port_info;
3641 port_info->phy_info[i].handle =
3642 le16_to_cpu(expander_data->DevHandle);
3643 port_info->phy_info[i].identify.sas_address =
3644 le64_to_cpu(sas_address);
3645 port_info->phy_info[i].identify.handle_parent =
3646 le16_to_cpu(expander_data->ParentDevHandle);
3647 }
3648 mptsas_expander_refresh(ioc, port_info);
3649 } else if (!port_info && expander_data->NumPhys)
3650 mptsas_expander_event_add(ioc, expander_data);
3651 } else if (expander_data->ReasonCode ==
3652 MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING)
3653 mptsas_expander_delete(ioc, port_info, 0);
3654
3655 mptsas_free_fw_event(ioc, fw_event);
3656 }
3657
3658
3659 /**
3660 * mptsas_expander_add -
3661 * @ioc: Pointer to MPT_ADAPTER structure
3662 * @handle:
3663 *
3664 */
3665 static struct mptsas_portinfo *
mptsas_expander_add(MPT_ADAPTER * ioc,u16 handle)3666 mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
3667 {
3668 struct mptsas_portinfo buffer, *port_info;
3669 int i;
3670
3671 if ((mptsas_sas_expander_pg0(ioc, &buffer,
3672 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3673 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)))
3674 return NULL;
3675
3676 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_ATOMIC);
3677 if (!port_info) {
3678 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3679 "%s: exit at line=%d\n", ioc->name,
3680 __func__, __LINE__));
3681 return NULL;
3682 }
3683 port_info->num_phys = buffer.num_phys;
3684 port_info->phy_info = buffer.phy_info;
3685 for (i = 0; i < port_info->num_phys; i++)
3686 port_info->phy_info[i].portinfo = port_info;
3687 mutex_lock(&ioc->sas_topology_mutex);
3688 list_add_tail(&port_info->list, &ioc->sas_topology);
3689 mutex_unlock(&ioc->sas_topology_mutex);
3690 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3691 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3692 (unsigned long long)buffer.phy_info[0].identify.sas_address);
3693 mptsas_expander_refresh(ioc, port_info);
3694 return port_info;
3695 }
3696
3697 static void
mptsas_send_link_status_event(struct fw_event_work * fw_event)3698 mptsas_send_link_status_event(struct fw_event_work *fw_event)
3699 {
3700 MPT_ADAPTER *ioc;
3701 MpiEventDataSasPhyLinkStatus_t *link_data;
3702 struct mptsas_portinfo *port_info;
3703 struct mptsas_phyinfo *phy_info = NULL;
3704 __le64 sas_address;
3705 u8 phy_num;
3706 u8 link_rate;
3707
3708 ioc = fw_event->ioc;
3709 link_data = (MpiEventDataSasPhyLinkStatus_t *)fw_event->event_data;
3710
3711 memcpy(&sas_address, &link_data->SASAddress, sizeof(__le64));
3712 sas_address = le64_to_cpu(sas_address);
3713 link_rate = link_data->LinkRates >> 4;
3714 phy_num = link_data->PhyNum;
3715
3716 port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3717 if (port_info) {
3718 phy_info = &port_info->phy_info[phy_num];
3719 if (phy_info)
3720 phy_info->negotiated_link_rate = link_rate;
3721 }
3722
3723 if (link_rate == MPI_SAS_IOUNIT0_RATE_1_5 ||
3724 link_rate == MPI_SAS_IOUNIT0_RATE_3_0 ||
3725 link_rate == MPI_SAS_IOUNIT0_RATE_6_0) {
3726
3727 if (!port_info) {
3728 if (ioc->old_sas_discovery_protocal) {
3729 port_info = mptsas_expander_add(ioc,
3730 le16_to_cpu(link_data->DevHandle));
3731 if (port_info)
3732 goto out;
3733 }
3734 goto out;
3735 }
3736
3737 if (port_info == ioc->hba_port_info)
3738 mptsas_probe_hba_phys(ioc);
3739 else
3740 mptsas_expander_refresh(ioc, port_info);
3741 } else if (phy_info && phy_info->phy) {
3742 if (link_rate == MPI_SAS_IOUNIT0_RATE_PHY_DISABLED)
3743 phy_info->phy->negotiated_linkrate =
3744 SAS_PHY_DISABLED;
3745 else if (link_rate ==
3746 MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION)
3747 phy_info->phy->negotiated_linkrate =
3748 SAS_LINK_RATE_FAILED;
3749 else {
3750 phy_info->phy->negotiated_linkrate =
3751 SAS_LINK_RATE_UNKNOWN;
3752 if (ioc->device_missing_delay &&
3753 mptsas_is_end_device(&phy_info->attached)) {
3754 struct scsi_device *sdev;
3755 VirtDevice *vdevice;
3756 u8 channel, id;
3757 id = phy_info->attached.id;
3758 channel = phy_info->attached.channel;
3759 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3760 "Link down for fw_id %d:fw_channel %d\n",
3761 ioc->name, phy_info->attached.id,
3762 phy_info->attached.channel));
3763
3764 shost_for_each_device(sdev, ioc->sh) {
3765 vdevice = sdev->hostdata;
3766 if ((vdevice == NULL) ||
3767 (vdevice->vtarget == NULL))
3768 continue;
3769 if ((vdevice->vtarget->tflags &
3770 MPT_TARGET_FLAGS_RAID_COMPONENT ||
3771 vdevice->vtarget->raidVolume))
3772 continue;
3773 if (vdevice->vtarget->id == id &&
3774 vdevice->vtarget->channel ==
3775 channel)
3776 devtprintk(ioc,
3777 printk(MYIOC_s_DEBUG_FMT
3778 "SDEV OUTSTANDING CMDS"
3779 "%d\n", ioc->name,
3780 scsi_device_busy(sdev)));
3781 }
3782
3783 }
3784 }
3785 }
3786 out:
3787 mptsas_free_fw_event(ioc, fw_event);
3788 }
3789
3790 static void
mptsas_not_responding_devices(MPT_ADAPTER * ioc)3791 mptsas_not_responding_devices(MPT_ADAPTER *ioc)
3792 {
3793 struct mptsas_portinfo buffer, *port_info;
3794 struct mptsas_device_info *sas_info;
3795 struct mptsas_devinfo sas_device;
3796 u32 handle;
3797 VirtTarget *vtarget = NULL;
3798 struct mptsas_phyinfo *phy_info;
3799 u8 found_expander;
3800 int retval, retry_count;
3801 unsigned long flags;
3802
3803 mpt_findImVolumes(ioc);
3804
3805 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3806 if (ioc->ioc_reset_in_progress) {
3807 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3808 "%s: exiting due to a parallel reset \n", ioc->name,
3809 __func__));
3810 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3811 return;
3812 }
3813 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3814
3815 /* devices, logical volumes */
3816 mutex_lock(&ioc->sas_device_info_mutex);
3817 redo_device_scan:
3818 list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) {
3819 if (sas_info->is_cached)
3820 continue;
3821 if (!sas_info->is_logical_volume) {
3822 sas_device.handle = 0;
3823 retry_count = 0;
3824 retry_page:
3825 retval = mptsas_sas_device_pg0(ioc, &sas_device,
3826 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID
3827 << MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3828 (sas_info->fw.channel << 8) +
3829 sas_info->fw.id);
3830
3831 if (sas_device.handle)
3832 continue;
3833 if (retval == -EBUSY) {
3834 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3835 if (ioc->ioc_reset_in_progress) {
3836 dfailprintk(ioc,
3837 printk(MYIOC_s_DEBUG_FMT
3838 "%s: exiting due to reset\n",
3839 ioc->name, __func__));
3840 spin_unlock_irqrestore
3841 (&ioc->taskmgmt_lock, flags);
3842 mutex_unlock(&ioc->
3843 sas_device_info_mutex);
3844 return;
3845 }
3846 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
3847 flags);
3848 }
3849
3850 if (retval && (retval != -ENODEV)) {
3851 if (retry_count < 10) {
3852 retry_count++;
3853 goto retry_page;
3854 } else {
3855 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3856 "%s: Config page retry exceeded retry "
3857 "count deleting device 0x%llx\n",
3858 ioc->name, __func__,
3859 sas_info->sas_address));
3860 }
3861 }
3862
3863 /* delete device */
3864 vtarget = mptsas_find_vtarget(ioc,
3865 sas_info->fw.channel, sas_info->fw.id);
3866
3867 if (vtarget)
3868 vtarget->deleted = 1;
3869
3870 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3871 sas_info->sas_address);
3872
3873 mptsas_del_end_device(ioc, phy_info);
3874 goto redo_device_scan;
3875 } else
3876 mptsas_volume_delete(ioc, sas_info->fw.id);
3877 }
3878 mutex_unlock(&ioc->sas_device_info_mutex);
3879
3880 /* expanders */
3881 mutex_lock(&ioc->sas_topology_mutex);
3882 redo_expander_scan:
3883 list_for_each_entry(port_info, &ioc->sas_topology, list) {
3884
3885 if (!(port_info->phy_info[0].identify.device_info &
3886 MPI_SAS_DEVICE_INFO_SMP_TARGET))
3887 continue;
3888 found_expander = 0;
3889 handle = 0xFFFF;
3890 while (!mptsas_sas_expander_pg0(ioc, &buffer,
3891 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3892 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle) &&
3893 !found_expander) {
3894
3895 handle = buffer.phy_info[0].handle;
3896 if (buffer.phy_info[0].identify.sas_address ==
3897 port_info->phy_info[0].identify.sas_address) {
3898 found_expander = 1;
3899 }
3900 kfree(buffer.phy_info);
3901 }
3902
3903 if (!found_expander) {
3904 mptsas_expander_delete(ioc, port_info, 0);
3905 goto redo_expander_scan;
3906 }
3907 }
3908 mutex_unlock(&ioc->sas_topology_mutex);
3909 }
3910
3911 /**
3912 * mptsas_probe_expanders - adding expanders
3913 * @ioc: Pointer to MPT_ADAPTER structure
3914 *
3915 **/
3916 static void
mptsas_probe_expanders(MPT_ADAPTER * ioc)3917 mptsas_probe_expanders(MPT_ADAPTER *ioc)
3918 {
3919 struct mptsas_portinfo buffer, *port_info;
3920 u32 handle;
3921 int i;
3922
3923 handle = 0xFFFF;
3924 while (!mptsas_sas_expander_pg0(ioc, &buffer,
3925 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3926 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)) {
3927
3928 handle = buffer.phy_info[0].handle;
3929 port_info = mptsas_find_portinfo_by_sas_address(ioc,
3930 buffer.phy_info[0].identify.sas_address);
3931
3932 if (port_info) {
3933 /* refreshing handles */
3934 for (i = 0; i < buffer.num_phys; i++) {
3935 port_info->phy_info[i].handle = handle;
3936 port_info->phy_info[i].identify.handle_parent =
3937 buffer.phy_info[0].identify.handle_parent;
3938 }
3939 mptsas_expander_refresh(ioc, port_info);
3940 kfree(buffer.phy_info);
3941 continue;
3942 }
3943
3944 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3945 if (!port_info) {
3946 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3947 "%s: exit at line=%d\n", ioc->name,
3948 __func__, __LINE__));
3949 return;
3950 }
3951 port_info->num_phys = buffer.num_phys;
3952 port_info->phy_info = buffer.phy_info;
3953 for (i = 0; i < port_info->num_phys; i++)
3954 port_info->phy_info[i].portinfo = port_info;
3955 mutex_lock(&ioc->sas_topology_mutex);
3956 list_add_tail(&port_info->list, &ioc->sas_topology);
3957 mutex_unlock(&ioc->sas_topology_mutex);
3958 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3959 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3960 (unsigned long long)buffer.phy_info[0].identify.sas_address);
3961 mptsas_expander_refresh(ioc, port_info);
3962 }
3963 }
3964
3965 static void
mptsas_probe_devices(MPT_ADAPTER * ioc)3966 mptsas_probe_devices(MPT_ADAPTER *ioc)
3967 {
3968 u16 handle;
3969 struct mptsas_devinfo sas_device;
3970 struct mptsas_phyinfo *phy_info;
3971
3972 handle = 0xFFFF;
3973 while (!(mptsas_sas_device_pg0(ioc, &sas_device,
3974 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
3975
3976 handle = sas_device.handle;
3977
3978 if ((sas_device.device_info &
3979 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
3980 MPI_SAS_DEVICE_INFO_STP_TARGET |
3981 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0)
3982 continue;
3983
3984 /* If there is no FW B_T mapping for this device then continue
3985 * */
3986 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
3987 || !(sas_device.flags &
3988 MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
3989 continue;
3990
3991 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3992 if (!phy_info)
3993 continue;
3994
3995 if (mptsas_get_rphy(phy_info))
3996 continue;
3997
3998 mptsas_add_end_device(ioc, phy_info);
3999 }
4000 }
4001
4002 /**
4003 * mptsas_scan_sas_topology -
4004 * @ioc: Pointer to MPT_ADAPTER structure
4005 * @sas_address:
4006 *
4007 **/
4008 static void
mptsas_scan_sas_topology(MPT_ADAPTER * ioc)4009 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
4010 {
4011 struct scsi_device *sdev;
4012 int i;
4013
4014 mptsas_probe_hba_phys(ioc);
4015 mptsas_probe_expanders(ioc);
4016 mptsas_probe_devices(ioc);
4017
4018 /*
4019 Reporting RAID volumes.
4020 */
4021 if (!ioc->ir_firmware || !ioc->raid_data.pIocPg2 ||
4022 !ioc->raid_data.pIocPg2->NumActiveVolumes)
4023 return;
4024 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
4025 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
4026 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
4027 if (sdev) {
4028 scsi_device_put(sdev);
4029 continue;
4030 }
4031 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4032 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4033 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID);
4034 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4035 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
4036 }
4037 }
4038
4039
4040 static void
mptsas_handle_queue_full_event(struct fw_event_work * fw_event)4041 mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
4042 {
4043 MPT_ADAPTER *ioc;
4044 EventDataQueueFull_t *qfull_data;
4045 struct mptsas_device_info *sas_info;
4046 struct scsi_device *sdev;
4047 int depth;
4048 int id = -1;
4049 int channel = -1;
4050 int fw_id, fw_channel;
4051 u16 current_depth;
4052
4053
4054 ioc = fw_event->ioc;
4055 qfull_data = (EventDataQueueFull_t *)fw_event->event_data;
4056 fw_id = qfull_data->TargetID;
4057 fw_channel = qfull_data->Bus;
4058 current_depth = le16_to_cpu(qfull_data->CurrentDepth);
4059
4060 /* if hidden raid component, look for the volume id */
4061 mutex_lock(&ioc->sas_device_info_mutex);
4062 if (mptscsih_is_phys_disk(ioc, fw_channel, fw_id)) {
4063 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
4064 list) {
4065 if (sas_info->is_cached ||
4066 sas_info->is_logical_volume)
4067 continue;
4068 if (sas_info->is_hidden_raid_component &&
4069 (sas_info->fw.channel == fw_channel &&
4070 sas_info->fw.id == fw_id)) {
4071 id = sas_info->volume_id;
4072 channel = MPTSAS_RAID_CHANNEL;
4073 goto out;
4074 }
4075 }
4076 } else {
4077 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
4078 list) {
4079 if (sas_info->is_cached ||
4080 sas_info->is_hidden_raid_component ||
4081 sas_info->is_logical_volume)
4082 continue;
4083 if (sas_info->fw.channel == fw_channel &&
4084 sas_info->fw.id == fw_id) {
4085 id = sas_info->os.id;
4086 channel = sas_info->os.channel;
4087 goto out;
4088 }
4089 }
4090
4091 }
4092
4093 out:
4094 mutex_unlock(&ioc->sas_device_info_mutex);
4095
4096 if (id != -1) {
4097 shost_for_each_device(sdev, ioc->sh) {
4098 if (sdev->id == id && sdev->channel == channel) {
4099 if (current_depth > sdev->queue_depth) {
4100 sdev_printk(KERN_INFO, sdev,
4101 "strange observation, the queue "
4102 "depth is (%d) meanwhile fw queue "
4103 "depth (%d)\n", sdev->queue_depth,
4104 current_depth);
4105 continue;
4106 }
4107 depth = scsi_track_queue_full(sdev,
4108 sdev->queue_depth - 1);
4109 if (depth > 0)
4110 sdev_printk(KERN_INFO, sdev,
4111 "Queue depth reduced to (%d)\n",
4112 depth);
4113 else if (depth < 0)
4114 sdev_printk(KERN_INFO, sdev,
4115 "Tagged Command Queueing is being "
4116 "disabled\n");
4117 else if (depth == 0)
4118 sdev_printk(KERN_DEBUG, sdev,
4119 "Queue depth not changed yet\n");
4120 }
4121 }
4122 }
4123
4124 mptsas_free_fw_event(ioc, fw_event);
4125 }
4126
4127
4128 static struct mptsas_phyinfo *
mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER * ioc,u64 sas_address)4129 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
4130 {
4131 struct mptsas_portinfo *port_info;
4132 struct mptsas_phyinfo *phy_info = NULL;
4133 int i;
4134
4135 mutex_lock(&ioc->sas_topology_mutex);
4136 list_for_each_entry(port_info, &ioc->sas_topology, list) {
4137 for (i = 0; i < port_info->num_phys; i++) {
4138 if (!mptsas_is_end_device(
4139 &port_info->phy_info[i].attached))
4140 continue;
4141 if (port_info->phy_info[i].attached.sas_address
4142 != sas_address)
4143 continue;
4144 phy_info = &port_info->phy_info[i];
4145 break;
4146 }
4147 }
4148 mutex_unlock(&ioc->sas_topology_mutex);
4149 return phy_info;
4150 }
4151
4152 /**
4153 * mptsas_find_phyinfo_by_phys_disk_num -
4154 * @ioc: Pointer to MPT_ADAPTER structure
4155 * @phys_disk_num:
4156 * @channel:
4157 * @id:
4158 *
4159 **/
4160 static struct mptsas_phyinfo *
mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER * ioc,u8 phys_disk_num,u8 channel,u8 id)4161 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
4162 u8 channel, u8 id)
4163 {
4164 struct mptsas_phyinfo *phy_info = NULL;
4165 struct mptsas_portinfo *port_info;
4166 RaidPhysDiskPage1_t *phys_disk = NULL;
4167 int num_paths;
4168 u64 sas_address = 0;
4169 int i;
4170
4171 phy_info = NULL;
4172 if (!ioc->raid_data.pIocPg3)
4173 return NULL;
4174 /* dual port support */
4175 num_paths = mpt_raid_phys_disk_get_num_paths(ioc, phys_disk_num);
4176 if (!num_paths)
4177 goto out;
4178 phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
4179 (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
4180 if (!phys_disk)
4181 goto out;
4182 mpt_raid_phys_disk_pg1(ioc, phys_disk_num, phys_disk);
4183 for (i = 0; i < num_paths; i++) {
4184 if ((phys_disk->Path[i].Flags & 1) != 0)
4185 /* entry no longer valid */
4186 continue;
4187 if ((id == phys_disk->Path[i].PhysDiskID) &&
4188 (channel == phys_disk->Path[i].PhysDiskBus)) {
4189 memcpy(&sas_address, &phys_disk->Path[i].WWID,
4190 sizeof(u64));
4191 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4192 sas_address);
4193 goto out;
4194 }
4195 }
4196
4197 out:
4198 kfree(phys_disk);
4199 if (phy_info)
4200 return phy_info;
4201
4202 /*
4203 * Extra code to handle RAID0 case, where the sas_address is not updated
4204 * in phys_disk_page_1 when hotswapped
4205 */
4206 mutex_lock(&ioc->sas_topology_mutex);
4207 list_for_each_entry(port_info, &ioc->sas_topology, list) {
4208 for (i = 0; i < port_info->num_phys && !phy_info; i++) {
4209 if (!mptsas_is_end_device(
4210 &port_info->phy_info[i].attached))
4211 continue;
4212 if (port_info->phy_info[i].attached.phys_disk_num == ~0)
4213 continue;
4214 if ((port_info->phy_info[i].attached.phys_disk_num ==
4215 phys_disk_num) &&
4216 (port_info->phy_info[i].attached.id == id) &&
4217 (port_info->phy_info[i].attached.channel ==
4218 channel))
4219 phy_info = &port_info->phy_info[i];
4220 }
4221 }
4222 mutex_unlock(&ioc->sas_topology_mutex);
4223 return phy_info;
4224 }
4225
4226 static void
mptsas_reprobe_lun(struct scsi_device * sdev,void * data)4227 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
4228 {
4229 int rc;
4230
4231 sdev->no_uld_attach = data ? 1 : 0;
4232 rc = scsi_device_reprobe(sdev);
4233 }
4234
4235 static void
mptsas_reprobe_target(struct scsi_target * starget,int uld_attach)4236 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
4237 {
4238 starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
4239 mptsas_reprobe_lun);
4240 }
4241
4242 static void
mptsas_adding_inactive_raid_components(MPT_ADAPTER * ioc,u8 channel,u8 id)4243 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
4244 {
4245 CONFIGPARMS cfg;
4246 ConfigPageHeader_t hdr;
4247 dma_addr_t dma_handle;
4248 pRaidVolumePage0_t buffer = NULL;
4249 RaidPhysDiskPage0_t phys_disk;
4250 int i;
4251 struct mptsas_phyinfo *phy_info;
4252 struct mptsas_devinfo sas_device;
4253
4254 memset(&cfg, 0 , sizeof(CONFIGPARMS));
4255 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4256 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
4257 cfg.pageAddr = (channel << 8) + id;
4258 cfg.cfghdr.hdr = &hdr;
4259 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4260 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
4261
4262 if (mpt_config(ioc, &cfg) != 0)
4263 goto out;
4264
4265 if (!hdr.PageLength)
4266 goto out;
4267
4268 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4269 &dma_handle);
4270
4271 if (!buffer)
4272 goto out;
4273
4274 cfg.physAddr = dma_handle;
4275 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4276
4277 if (mpt_config(ioc, &cfg) != 0)
4278 goto out;
4279
4280 if (!(buffer->VolumeStatus.Flags &
4281 MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
4282 goto out;
4283
4284 if (!buffer->NumPhysDisks)
4285 goto out;
4286
4287 for (i = 0; i < buffer->NumPhysDisks; i++) {
4288
4289 if (mpt_raid_phys_disk_pg0(ioc,
4290 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
4291 continue;
4292
4293 if (mptsas_sas_device_pg0(ioc, &sas_device,
4294 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4295 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4296 (phys_disk.PhysDiskBus << 8) +
4297 phys_disk.PhysDiskID))
4298 continue;
4299
4300 /* If there is no FW B_T mapping for this device then continue
4301 * */
4302 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4303 || !(sas_device.flags &
4304 MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4305 continue;
4306
4307
4308 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4309 sas_device.sas_address);
4310 mptsas_add_end_device(ioc, phy_info);
4311 }
4312
4313 out:
4314 if (buffer)
4315 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4316 dma_handle);
4317 }
4318 /*
4319 * Work queue thread to handle SAS hotplug events
4320 */
4321 static void
mptsas_hotplug_work(MPT_ADAPTER * ioc,struct fw_event_work * fw_event,struct mptsas_hotplug_event * hot_plug_info)4322 mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
4323 struct mptsas_hotplug_event *hot_plug_info)
4324 {
4325 struct mptsas_phyinfo *phy_info;
4326 struct scsi_target * starget;
4327 struct mptsas_devinfo sas_device;
4328 VirtTarget *vtarget;
4329 int i;
4330 struct mptsas_portinfo *port_info;
4331
4332 switch (hot_plug_info->event_type) {
4333
4334 case MPTSAS_ADD_PHYSDISK:
4335
4336 if (!ioc->raid_data.pIocPg2)
4337 break;
4338
4339 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
4340 if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID ==
4341 hot_plug_info->id) {
4342 printk(MYIOC_s_WARN_FMT "firmware bug: unable "
4343 "to add hidden disk - target_id matches "
4344 "volume_id\n", ioc->name);
4345 mptsas_free_fw_event(ioc, fw_event);
4346 return;
4347 }
4348 }
4349 mpt_findImVolumes(ioc);
4350 fallthrough;
4351
4352 case MPTSAS_ADD_DEVICE:
4353 memset(&sas_device, 0, sizeof(struct mptsas_devinfo));
4354 mptsas_sas_device_pg0(ioc, &sas_device,
4355 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4356 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4357 (hot_plug_info->channel << 8) +
4358 hot_plug_info->id);
4359
4360 /* If there is no FW B_T mapping for this device then break
4361 * */
4362 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4363 || !(sas_device.flags &
4364 MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4365 break;
4366
4367 if (!sas_device.handle)
4368 return;
4369
4370 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
4371 /* Device hot plug */
4372 if (!phy_info) {
4373 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4374 "%s %d HOT PLUG: "
4375 "parent handle of device %x\n", ioc->name,
4376 __func__, __LINE__, sas_device.handle_parent));
4377 port_info = mptsas_find_portinfo_by_handle(ioc,
4378 sas_device.handle_parent);
4379
4380 if (port_info == ioc->hba_port_info)
4381 mptsas_probe_hba_phys(ioc);
4382 else if (port_info)
4383 mptsas_expander_refresh(ioc, port_info);
4384 else {
4385 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4386 "%s %d port info is NULL\n",
4387 ioc->name, __func__, __LINE__));
4388 break;
4389 }
4390 phy_info = mptsas_refreshing_device_handles
4391 (ioc, &sas_device);
4392 }
4393
4394 if (!phy_info) {
4395 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4396 "%s %d phy info is NULL\n",
4397 ioc->name, __func__, __LINE__));
4398 break;
4399 }
4400
4401 if (mptsas_get_rphy(phy_info))
4402 break;
4403
4404 mptsas_add_end_device(ioc, phy_info);
4405 break;
4406
4407 case MPTSAS_DEL_DEVICE:
4408 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4409 hot_plug_info->sas_address);
4410 mptsas_del_end_device(ioc, phy_info);
4411 break;
4412
4413 case MPTSAS_DEL_PHYSDISK:
4414
4415 mpt_findImVolumes(ioc);
4416
4417 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
4418 ioc, hot_plug_info->phys_disk_num,
4419 hot_plug_info->channel,
4420 hot_plug_info->id);
4421 mptsas_del_end_device(ioc, phy_info);
4422 break;
4423
4424 case MPTSAS_ADD_PHYSDISK_REPROBE:
4425
4426 if (mptsas_sas_device_pg0(ioc, &sas_device,
4427 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4428 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4429 (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4430 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4431 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4432 __func__, hot_plug_info->id, __LINE__));
4433 break;
4434 }
4435
4436 /* If there is no FW B_T mapping for this device then break
4437 * */
4438 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4439 || !(sas_device.flags &
4440 MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4441 break;
4442
4443 phy_info = mptsas_find_phyinfo_by_sas_address(
4444 ioc, sas_device.sas_address);
4445
4446 if (!phy_info) {
4447 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4448 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4449 __func__, hot_plug_info->id, __LINE__));
4450 break;
4451 }
4452
4453 starget = mptsas_get_starget(phy_info);
4454 if (!starget) {
4455 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4456 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4457 __func__, hot_plug_info->id, __LINE__));
4458 break;
4459 }
4460
4461 vtarget = starget->hostdata;
4462 if (!vtarget) {
4463 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4464 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4465 __func__, hot_plug_info->id, __LINE__));
4466 break;
4467 }
4468
4469 mpt_findImVolumes(ioc);
4470
4471 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Hidding: "
4472 "fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4473 ioc->name, hot_plug_info->channel, hot_plug_info->id,
4474 hot_plug_info->phys_disk_num, (unsigned long long)
4475 sas_device.sas_address);
4476
4477 vtarget->id = hot_plug_info->phys_disk_num;
4478 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
4479 phy_info->attached.phys_disk_num = hot_plug_info->phys_disk_num;
4480 mptsas_reprobe_target(starget, 1);
4481 break;
4482
4483 case MPTSAS_DEL_PHYSDISK_REPROBE:
4484
4485 if (mptsas_sas_device_pg0(ioc, &sas_device,
4486 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4487 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4488 (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4489 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4490 "%s: fw_id=%d exit at line=%d\n",
4491 ioc->name, __func__,
4492 hot_plug_info->id, __LINE__));
4493 break;
4494 }
4495
4496 /* If there is no FW B_T mapping for this device then break
4497 * */
4498 if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4499 || !(sas_device.flags &
4500 MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4501 break;
4502
4503 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4504 sas_device.sas_address);
4505 if (!phy_info) {
4506 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4507 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4508 __func__, hot_plug_info->id, __LINE__));
4509 break;
4510 }
4511
4512 starget = mptsas_get_starget(phy_info);
4513 if (!starget) {
4514 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4515 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4516 __func__, hot_plug_info->id, __LINE__));
4517 break;
4518 }
4519
4520 vtarget = starget->hostdata;
4521 if (!vtarget) {
4522 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4523 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4524 __func__, hot_plug_info->id, __LINE__));
4525 break;
4526 }
4527
4528 if (!(vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)) {
4529 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4530 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4531 __func__, hot_plug_info->id, __LINE__));
4532 break;
4533 }
4534
4535 mpt_findImVolumes(ioc);
4536
4537 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Exposing:"
4538 " fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4539 ioc->name, hot_plug_info->channel, hot_plug_info->id,
4540 hot_plug_info->phys_disk_num, (unsigned long long)
4541 sas_device.sas_address);
4542
4543 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
4544 vtarget->id = hot_plug_info->id;
4545 phy_info->attached.phys_disk_num = ~0;
4546 mptsas_reprobe_target(starget, 0);
4547 mptsas_add_device_component_by_fw(ioc,
4548 hot_plug_info->channel, hot_plug_info->id);
4549 break;
4550
4551 case MPTSAS_ADD_RAID:
4552
4553 mpt_findImVolumes(ioc);
4554 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4555 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4556 hot_plug_info->id);
4557 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4558 hot_plug_info->id, 0);
4559 break;
4560
4561 case MPTSAS_DEL_RAID:
4562
4563 mpt_findImVolumes(ioc);
4564 printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4565 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4566 hot_plug_info->id);
4567 scsi_remove_device(hot_plug_info->sdev);
4568 scsi_device_put(hot_plug_info->sdev);
4569 break;
4570
4571 case MPTSAS_ADD_INACTIVE_VOLUME:
4572
4573 mpt_findImVolumes(ioc);
4574 mptsas_adding_inactive_raid_components(ioc,
4575 hot_plug_info->channel, hot_plug_info->id);
4576 break;
4577
4578 default:
4579 break;
4580 }
4581
4582 mptsas_free_fw_event(ioc, fw_event);
4583 }
4584
4585 static void
mptsas_send_sas_event(struct fw_event_work * fw_event)4586 mptsas_send_sas_event(struct fw_event_work *fw_event)
4587 {
4588 MPT_ADAPTER *ioc;
4589 struct mptsas_hotplug_event hot_plug_info;
4590 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
4591 u32 device_info;
4592 u64 sas_address;
4593
4594 ioc = fw_event->ioc;
4595 sas_event_data = (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
4596 fw_event->event_data;
4597 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
4598
4599 if ((device_info &
4600 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
4601 MPI_SAS_DEVICE_INFO_STP_TARGET |
4602 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0) {
4603 mptsas_free_fw_event(ioc, fw_event);
4604 return;
4605 }
4606
4607 if (sas_event_data->ReasonCode ==
4608 MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED) {
4609 mptbase_sas_persist_operation(ioc,
4610 MPI_SAS_OP_CLEAR_NOT_PRESENT);
4611 mptsas_free_fw_event(ioc, fw_event);
4612 return;
4613 }
4614
4615 switch (sas_event_data->ReasonCode) {
4616 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
4617 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
4618 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4619 hot_plug_info.handle = le16_to_cpu(sas_event_data->DevHandle);
4620 hot_plug_info.channel = sas_event_data->Bus;
4621 hot_plug_info.id = sas_event_data->TargetID;
4622 hot_plug_info.phy_id = sas_event_data->PhyNum;
4623 memcpy(&sas_address, &sas_event_data->SASAddress,
4624 sizeof(u64));
4625 hot_plug_info.sas_address = le64_to_cpu(sas_address);
4626 hot_plug_info.device_info = device_info;
4627 if (sas_event_data->ReasonCode &
4628 MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
4629 hot_plug_info.event_type = MPTSAS_ADD_DEVICE;
4630 else
4631 hot_plug_info.event_type = MPTSAS_DEL_DEVICE;
4632 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4633 break;
4634
4635 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
4636 mptbase_sas_persist_operation(ioc,
4637 MPI_SAS_OP_CLEAR_NOT_PRESENT);
4638 mptsas_free_fw_event(ioc, fw_event);
4639 break;
4640
4641 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
4642 /* TODO */
4643 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
4644 /* TODO */
4645 default:
4646 mptsas_free_fw_event(ioc, fw_event);
4647 break;
4648 }
4649 }
4650
4651 static void
mptsas_send_raid_event(struct fw_event_work * fw_event)4652 mptsas_send_raid_event(struct fw_event_work *fw_event)
4653 {
4654 MPT_ADAPTER *ioc;
4655 EVENT_DATA_RAID *raid_event_data;
4656 struct mptsas_hotplug_event hot_plug_info;
4657 int status;
4658 int state;
4659 struct scsi_device *sdev = NULL;
4660 VirtDevice *vdevice = NULL;
4661 RaidPhysDiskPage0_t phys_disk;
4662
4663 ioc = fw_event->ioc;
4664 raid_event_data = (EVENT_DATA_RAID *)fw_event->event_data;
4665 status = le32_to_cpu(raid_event_data->SettingsStatus);
4666 state = (status >> 8) & 0xff;
4667
4668 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4669 hot_plug_info.id = raid_event_data->VolumeID;
4670 hot_plug_info.channel = raid_event_data->VolumeBus;
4671 hot_plug_info.phys_disk_num = raid_event_data->PhysDiskNum;
4672
4673 if (raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_DELETED ||
4674 raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_CREATED ||
4675 raid_event_data->ReasonCode ==
4676 MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED) {
4677 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
4678 hot_plug_info.id, 0);
4679 hot_plug_info.sdev = sdev;
4680 if (sdev)
4681 vdevice = sdev->hostdata;
4682 }
4683
4684 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4685 "ReasonCode=%02x\n", ioc->name, __func__,
4686 raid_event_data->ReasonCode));
4687
4688 switch (raid_event_data->ReasonCode) {
4689 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4690 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK_REPROBE;
4691 break;
4692 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4693 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK_REPROBE;
4694 break;
4695 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4696 switch (state) {
4697 case MPI_PD_STATE_ONLINE:
4698 case MPI_PD_STATE_NOT_COMPATIBLE:
4699 mpt_raid_phys_disk_pg0(ioc,
4700 raid_event_data->PhysDiskNum, &phys_disk);
4701 hot_plug_info.id = phys_disk.PhysDiskID;
4702 hot_plug_info.channel = phys_disk.PhysDiskBus;
4703 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4704 break;
4705 case MPI_PD_STATE_FAILED:
4706 case MPI_PD_STATE_MISSING:
4707 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
4708 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
4709 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
4710 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4711 break;
4712 default:
4713 break;
4714 }
4715 break;
4716 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4717 if (!sdev)
4718 break;
4719 vdevice->vtarget->deleted = 1; /* block IO */
4720 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4721 break;
4722 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4723 if (sdev) {
4724 scsi_device_put(sdev);
4725 break;
4726 }
4727 hot_plug_info.event_type = MPTSAS_ADD_RAID;
4728 break;
4729 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4730 if (!(status & MPI_RAIDVOL0_STATUS_FLAG_ENABLED)) {
4731 if (!sdev)
4732 break;
4733 vdevice->vtarget->deleted = 1; /* block IO */
4734 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4735 break;
4736 }
4737 switch (state) {
4738 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
4739 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
4740 if (!sdev)
4741 break;
4742 vdevice->vtarget->deleted = 1; /* block IO */
4743 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4744 break;
4745 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
4746 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
4747 if (sdev) {
4748 scsi_device_put(sdev);
4749 break;
4750 }
4751 hot_plug_info.event_type = MPTSAS_ADD_RAID;
4752 break;
4753 default:
4754 break;
4755 }
4756 break;
4757 default:
4758 break;
4759 }
4760
4761 if (hot_plug_info.event_type != MPTSAS_IGNORE_EVENT)
4762 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4763 else
4764 mptsas_free_fw_event(ioc, fw_event);
4765 }
4766
4767 /**
4768 * mptsas_issue_tm - send mptsas internal tm request
4769 * @ioc: Pointer to MPT_ADAPTER structure
4770 * @type: Task Management type
4771 * @channel: channel number for task management
4772 * @id: Logical Target ID for reset (if appropriate)
4773 * @lun: Logical unit for reset (if appropriate)
4774 * @task_context: Context for the task to be aborted
4775 * @timeout: timeout for task management control
4776 *
4777 * return 0 on success and -1 on failure:
4778 *
4779 */
4780 static int
mptsas_issue_tm(MPT_ADAPTER * ioc,u8 type,u8 channel,u8 id,u64 lun,int task_context,ulong timeout,u8 * issue_reset)4781 mptsas_issue_tm(MPT_ADAPTER *ioc, u8 type, u8 channel, u8 id, u64 lun,
4782 int task_context, ulong timeout, u8 *issue_reset)
4783 {
4784 MPT_FRAME_HDR *mf;
4785 SCSITaskMgmt_t *pScsiTm;
4786 int retval;
4787 unsigned long timeleft;
4788
4789 *issue_reset = 0;
4790 mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
4791 if (mf == NULL) {
4792 retval = -1; /* return failure */
4793 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "TaskMgmt request: no "
4794 "msg frames!!\n", ioc->name));
4795 goto out;
4796 }
4797
4798 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request: mr = %p, "
4799 "task_type = 0x%02X,\n\t timeout = %ld, fw_channel = %d, "
4800 "fw_id = %d, lun = %lld,\n\t task_context = 0x%x\n", ioc->name, mf,
4801 type, timeout, channel, id, (unsigned long long)lun,
4802 task_context));
4803
4804 pScsiTm = (SCSITaskMgmt_t *) mf;
4805 memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
4806 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
4807 pScsiTm->TaskType = type;
4808 pScsiTm->MsgFlags = 0;
4809 pScsiTm->TargetID = id;
4810 pScsiTm->Bus = channel;
4811 pScsiTm->ChainOffset = 0;
4812 pScsiTm->Reserved = 0;
4813 pScsiTm->Reserved1 = 0;
4814 pScsiTm->TaskMsgContext = task_context;
4815 int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
4816
4817 INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4818 CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
4819 retval = 0;
4820 mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
4821
4822 /* Now wait for the command to complete */
4823 timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
4824 timeout*HZ);
4825 if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
4826 retval = -1; /* return failure */
4827 dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
4828 "TaskMgmt request: TIMED OUT!(mr=%p)\n", ioc->name, mf));
4829 mpt_free_msg_frame(ioc, mf);
4830 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
4831 goto out;
4832 *issue_reset = 1;
4833 goto out;
4834 }
4835
4836 if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
4837 retval = -1; /* return failure */
4838 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4839 "TaskMgmt request: failed with no reply\n", ioc->name));
4840 goto out;
4841 }
4842
4843 out:
4844 CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4845 return retval;
4846 }
4847
4848 /**
4849 * mptsas_broadcast_primitive_work - Handle broadcast primitives
4850 * @work: work queue payload containing info describing the event
4851 *
4852 * this will be handled in workqueue context.
4853 */
4854 static void
mptsas_broadcast_primitive_work(struct fw_event_work * fw_event)4855 mptsas_broadcast_primitive_work(struct fw_event_work *fw_event)
4856 {
4857 MPT_ADAPTER *ioc = fw_event->ioc;
4858 MPT_FRAME_HDR *mf;
4859 VirtDevice *vdevice;
4860 int ii;
4861 struct scsi_cmnd *sc;
4862 SCSITaskMgmtReply_t *pScsiTmReply;
4863 u8 issue_reset;
4864 int task_context;
4865 u8 channel, id;
4866 int lun;
4867 u32 termination_count;
4868 u32 query_count;
4869
4870 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4871 "%s - enter\n", ioc->name, __func__));
4872
4873 mutex_lock(&ioc->taskmgmt_cmds.mutex);
4874 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
4875 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4876 mptsas_requeue_fw_event(ioc, fw_event, 1000);
4877 return;
4878 }
4879
4880 issue_reset = 0;
4881 termination_count = 0;
4882 query_count = 0;
4883 mpt_findImVolumes(ioc);
4884 pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
4885
4886 for (ii = 0; ii < ioc->req_depth; ii++) {
4887 if (ioc->fw_events_off)
4888 goto out;
4889 sc = mptscsih_get_scsi_lookup(ioc, ii);
4890 if (!sc)
4891 continue;
4892 mf = MPT_INDEX_2_MFPTR(ioc, ii);
4893 if (!mf)
4894 continue;
4895 task_context = mf->u.frame.hwhdr.msgctxu.MsgContext;
4896 vdevice = sc->device->hostdata;
4897 if (!vdevice || !vdevice->vtarget)
4898 continue;
4899 if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
4900 continue; /* skip hidden raid components */
4901 if (vdevice->vtarget->raidVolume)
4902 continue; /* skip hidden raid components */
4903 channel = vdevice->vtarget->channel;
4904 id = vdevice->vtarget->id;
4905 lun = vdevice->lun;
4906 if (mptsas_issue_tm(ioc, MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK,
4907 channel, id, (u64)lun, task_context, 30, &issue_reset))
4908 goto out;
4909 query_count++;
4910 termination_count +=
4911 le32_to_cpu(pScsiTmReply->TerminationCount);
4912 if ((pScsiTmReply->IOCStatus == MPI_IOCSTATUS_SUCCESS) &&
4913 (pScsiTmReply->ResponseCode ==
4914 MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
4915 pScsiTmReply->ResponseCode ==
4916 MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
4917 continue;
4918 if (mptsas_issue_tm(ioc,
4919 MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET,
4920 channel, id, (u64)lun, 0, 30, &issue_reset))
4921 goto out;
4922 termination_count +=
4923 le32_to_cpu(pScsiTmReply->TerminationCount);
4924 }
4925
4926 out:
4927 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4928 "%s - exit, query_count = %d termination_count = %d\n",
4929 ioc->name, __func__, query_count, termination_count));
4930
4931 ioc->broadcast_aen_busy = 0;
4932 mpt_clear_taskmgmt_in_progress_flag(ioc);
4933 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4934
4935 if (issue_reset) {
4936 printk(MYIOC_s_WARN_FMT
4937 "Issuing Reset from %s!! doorbell=0x%08x\n",
4938 ioc->name, __func__, mpt_GetIocState(ioc, 0));
4939 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
4940 }
4941 mptsas_free_fw_event(ioc, fw_event);
4942 }
4943
4944 /*
4945 * mptsas_send_ir2_event - handle exposing hidden disk when
4946 * an inactive raid volume is added
4947 *
4948 * @ioc: Pointer to MPT_ADAPTER structure
4949 * @ir2_data
4950 *
4951 */
4952 static void
mptsas_send_ir2_event(struct fw_event_work * fw_event)4953 mptsas_send_ir2_event(struct fw_event_work *fw_event)
4954 {
4955 MPT_ADAPTER *ioc;
4956 struct mptsas_hotplug_event hot_plug_info;
4957 MPI_EVENT_DATA_IR2 *ir2_data;
4958 u8 reasonCode;
4959 RaidPhysDiskPage0_t phys_disk;
4960
4961 ioc = fw_event->ioc;
4962 ir2_data = (MPI_EVENT_DATA_IR2 *)fw_event->event_data;
4963 reasonCode = ir2_data->ReasonCode;
4964
4965 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4966 "ReasonCode=%02x\n", ioc->name, __func__, reasonCode));
4967
4968 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4969 hot_plug_info.id = ir2_data->TargetID;
4970 hot_plug_info.channel = ir2_data->Bus;
4971 switch (reasonCode) {
4972 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
4973 hot_plug_info.event_type = MPTSAS_ADD_INACTIVE_VOLUME;
4974 break;
4975 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
4976 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4977 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4978 break;
4979 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
4980 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4981 mpt_raid_phys_disk_pg0(ioc,
4982 ir2_data->PhysDiskNum, &phys_disk);
4983 hot_plug_info.id = phys_disk.PhysDiskID;
4984 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4985 break;
4986 default:
4987 mptsas_free_fw_event(ioc, fw_event);
4988 return;
4989 }
4990 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4991 }
4992
4993 static int
mptsas_event_process(MPT_ADAPTER * ioc,EventNotificationReply_t * reply)4994 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
4995 {
4996 u32 event = le32_to_cpu(reply->Event);
4997 int event_data_sz;
4998 struct fw_event_work *fw_event;
4999 unsigned long delay;
5000
5001 if (ioc->bus_type != SAS)
5002 return 0;
5003
5004 /* events turned off due to host reset or driver unloading */
5005 if (ioc->fw_events_off)
5006 return 0;
5007
5008 delay = msecs_to_jiffies(1);
5009 switch (event) {
5010 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
5011 {
5012 EVENT_DATA_SAS_BROADCAST_PRIMITIVE *broadcast_event_data =
5013 (EVENT_DATA_SAS_BROADCAST_PRIMITIVE *)reply->Data;
5014 if (broadcast_event_data->Primitive !=
5015 MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
5016 return 0;
5017 if (ioc->broadcast_aen_busy)
5018 return 0;
5019 ioc->broadcast_aen_busy = 1;
5020 break;
5021 }
5022 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5023 {
5024 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data =
5025 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data;
5026 u16 ioc_stat;
5027 ioc_stat = le16_to_cpu(reply->IOCStatus);
5028
5029 if (sas_event_data->ReasonCode ==
5030 MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) {
5031 mptsas_target_reset_queue(ioc, sas_event_data);
5032 return 0;
5033 }
5034 if (sas_event_data->ReasonCode ==
5035 MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
5036 ioc->device_missing_delay &&
5037 (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)) {
5038 VirtTarget *vtarget = NULL;
5039 u8 id, channel;
5040
5041 id = sas_event_data->TargetID;
5042 channel = sas_event_data->Bus;
5043
5044 vtarget = mptsas_find_vtarget(ioc, channel, id);
5045 if (vtarget) {
5046 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5047 "LogInfo (0x%x) available for "
5048 "INTERNAL_DEVICE_RESET"
5049 "fw_id %d fw_channel %d\n", ioc->name,
5050 le32_to_cpu(reply->IOCLogInfo),
5051 id, channel));
5052 if (vtarget->raidVolume) {
5053 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5054 "Skipping Raid Volume for inDMD\n",
5055 ioc->name));
5056 } else {
5057 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5058 "Setting device flag inDMD\n",
5059 ioc->name));
5060 vtarget->inDMD = 1;
5061 }
5062
5063 }
5064
5065 }
5066
5067 break;
5068 }
5069 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
5070 {
5071 MpiEventDataSasExpanderStatusChange_t *expander_data =
5072 (MpiEventDataSasExpanderStatusChange_t *)reply->Data;
5073
5074 if (ioc->old_sas_discovery_protocal)
5075 return 0;
5076
5077 if (expander_data->ReasonCode ==
5078 MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING &&
5079 ioc->device_missing_delay)
5080 delay = HZ * ioc->device_missing_delay;
5081 break;
5082 }
5083 case MPI_EVENT_SAS_DISCOVERY:
5084 {
5085 u32 discovery_status;
5086 EventDataSasDiscovery_t *discovery_data =
5087 (EventDataSasDiscovery_t *)reply->Data;
5088
5089 discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus);
5090 ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0;
5091 if (ioc->old_sas_discovery_protocal && !discovery_status)
5092 mptsas_queue_rescan(ioc);
5093 return 0;
5094 }
5095 case MPI_EVENT_INTEGRATED_RAID:
5096 case MPI_EVENT_PERSISTENT_TABLE_FULL:
5097 case MPI_EVENT_IR2:
5098 case MPI_EVENT_SAS_PHY_LINK_STATUS:
5099 case MPI_EVENT_QUEUE_FULL:
5100 break;
5101 default:
5102 return 0;
5103 }
5104
5105 event_data_sz = ((reply->MsgLength * 4) -
5106 offsetof(EventNotificationReply_t, Data));
5107 fw_event = kzalloc(sizeof(*fw_event) + event_data_sz, GFP_ATOMIC);
5108 if (!fw_event) {
5109 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name,
5110 __func__, __LINE__);
5111 return 0;
5112 }
5113 memcpy(fw_event->event_data, reply->Data, event_data_sz);
5114 fw_event->event = event;
5115 fw_event->ioc = ioc;
5116 mptsas_add_fw_event(ioc, fw_event, delay);
5117 return 0;
5118 }
5119
5120 /* Delete a volume when no longer listed in ioc pg2
5121 */
mptsas_volume_delete(MPT_ADAPTER * ioc,u8 id)5122 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id)
5123 {
5124 struct scsi_device *sdev;
5125 int i;
5126
5127 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, id, 0);
5128 if (!sdev)
5129 return;
5130 if (!ioc->raid_data.pIocPg2)
5131 goto out;
5132 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
5133 goto out;
5134 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
5135 if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id)
5136 goto release_sdev;
5137 out:
5138 printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
5139 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL, id);
5140 scsi_remove_device(sdev);
5141 release_sdev:
5142 scsi_device_put(sdev);
5143 }
5144
5145 static int
mptsas_probe(struct pci_dev * pdev,const struct pci_device_id * id)5146 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5147 {
5148 struct Scsi_Host *sh;
5149 MPT_SCSI_HOST *hd;
5150 MPT_ADAPTER *ioc;
5151 unsigned long flags;
5152 int ii;
5153 int numSGE = 0;
5154 int scale;
5155 int ioc_cap;
5156 int error=0;
5157 int r;
5158
5159 r = mpt_attach(pdev,id);
5160 if (r)
5161 return r;
5162
5163 ioc = pci_get_drvdata(pdev);
5164 mptsas_fw_event_off(ioc);
5165 ioc->DoneCtx = mptsasDoneCtx;
5166 ioc->TaskCtx = mptsasTaskCtx;
5167 ioc->InternalCtx = mptsasInternalCtx;
5168 ioc->schedule_target_reset = &mptsas_schedule_target_reset;
5169 ioc->schedule_dead_ioc_flush_running_cmds =
5170 &mptscsih_flush_running_cmds;
5171 /* Added sanity check on readiness of the MPT adapter.
5172 */
5173 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
5174 printk(MYIOC_s_WARN_FMT
5175 "Skipping because it's not operational!\n",
5176 ioc->name);
5177 error = -ENODEV;
5178 goto out_mptsas_probe;
5179 }
5180
5181 if (!ioc->active) {
5182 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
5183 ioc->name);
5184 error = -ENODEV;
5185 goto out_mptsas_probe;
5186 }
5187
5188 /* Sanity check - ensure at least 1 port is INITIATOR capable
5189 */
5190 ioc_cap = 0;
5191 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
5192 if (ioc->pfacts[ii].ProtocolFlags &
5193 MPI_PORTFACTS_PROTOCOL_INITIATOR)
5194 ioc_cap++;
5195 }
5196
5197 if (!ioc_cap) {
5198 printk(MYIOC_s_WARN_FMT
5199 "Skipping ioc=%p because SCSI Initiator mode "
5200 "is NOT enabled!\n", ioc->name, ioc);
5201 return 0;
5202 }
5203
5204 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
5205 if (!sh) {
5206 printk(MYIOC_s_WARN_FMT
5207 "Unable to register controller with SCSI subsystem\n",
5208 ioc->name);
5209 error = -1;
5210 goto out_mptsas_probe;
5211 }
5212
5213 spin_lock_irqsave(&ioc->FreeQlock, flags);
5214
5215 /* Attach the SCSI Host to the IOC structure
5216 */
5217 ioc->sh = sh;
5218
5219 sh->io_port = 0;
5220 sh->n_io_port = 0;
5221 sh->irq = 0;
5222
5223 /* set 16 byte cdb's */
5224 sh->max_cmd_len = 16;
5225 sh->can_queue = min_t(int, ioc->req_depth - 10, sh->can_queue);
5226 sh->max_id = -1;
5227 sh->max_lun = max_lun;
5228 sh->transportt = mptsas_transport_template;
5229
5230 /* Required entry.
5231 */
5232 sh->unique_id = ioc->id;
5233
5234 INIT_LIST_HEAD(&ioc->sas_topology);
5235 mutex_init(&ioc->sas_topology_mutex);
5236 mutex_init(&ioc->sas_discovery_mutex);
5237 mutex_init(&ioc->sas_mgmt.mutex);
5238 init_completion(&ioc->sas_mgmt.done);
5239
5240 /* Verify that we won't exceed the maximum
5241 * number of chain buffers
5242 * We can optimize: ZZ = req_sz/sizeof(SGE)
5243 * For 32bit SGE's:
5244 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
5245 * + (req_sz - 64)/sizeof(SGE)
5246 * A slightly different algorithm is required for
5247 * 64bit SGEs.
5248 */
5249 scale = ioc->req_sz/ioc->SGE_size;
5250 if (ioc->sg_addr_size == sizeof(u64)) {
5251 numSGE = (scale - 1) *
5252 (ioc->facts.MaxChainDepth-1) + scale +
5253 (ioc->req_sz - 60) / ioc->SGE_size;
5254 } else {
5255 numSGE = 1 + (scale - 1) *
5256 (ioc->facts.MaxChainDepth-1) + scale +
5257 (ioc->req_sz - 64) / ioc->SGE_size;
5258 }
5259
5260 if (numSGE < sh->sg_tablesize) {
5261 /* Reset this value */
5262 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5263 "Resetting sg_tablesize to %d from %d\n",
5264 ioc->name, numSGE, sh->sg_tablesize));
5265 sh->sg_tablesize = numSGE;
5266 }
5267
5268 if (mpt_loadtime_max_sectors) {
5269 if (mpt_loadtime_max_sectors < 64 ||
5270 mpt_loadtime_max_sectors > 8192) {
5271 printk(MYIOC_s_INFO_FMT "Invalid value passed for"
5272 "mpt_loadtime_max_sectors %d."
5273 "Range from 64 to 8192\n", ioc->name,
5274 mpt_loadtime_max_sectors);
5275 }
5276 mpt_loadtime_max_sectors &= 0xFFFFFFFE;
5277 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5278 "Resetting max sector to %d from %d\n",
5279 ioc->name, mpt_loadtime_max_sectors, sh->max_sectors));
5280 sh->max_sectors = mpt_loadtime_max_sectors;
5281 }
5282
5283 hd = shost_priv(sh);
5284 hd->ioc = ioc;
5285
5286 /* SCSI needs scsi_cmnd lookup table!
5287 * (with size equal to req_depth*PtrSz!)
5288 */
5289 ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
5290 if (!ioc->ScsiLookup) {
5291 error = -ENOMEM;
5292 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5293 goto out_mptsas_probe;
5294 }
5295 spin_lock_init(&ioc->scsi_lookup_lock);
5296
5297 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
5298 ioc->name, ioc->ScsiLookup));
5299
5300 ioc->sas_data.ptClear = mpt_pt_clear;
5301
5302 hd->last_queue_full = 0;
5303 INIT_LIST_HEAD(&hd->target_reset_list);
5304 INIT_LIST_HEAD(&ioc->sas_device_info_list);
5305 mutex_init(&ioc->sas_device_info_mutex);
5306
5307 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5308
5309 if (ioc->sas_data.ptClear==1) {
5310 mptbase_sas_persist_operation(
5311 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
5312 }
5313
5314 error = scsi_add_host(sh, &ioc->pcidev->dev);
5315 if (error) {
5316 dprintk(ioc, printk(MYIOC_s_ERR_FMT
5317 "scsi_add_host failed\n", ioc->name));
5318 goto out_mptsas_probe;
5319 }
5320
5321 /* older firmware doesn't support expander events */
5322 if ((ioc->facts.HeaderVersion >> 8) < 0xE)
5323 ioc->old_sas_discovery_protocal = 1;
5324 mptsas_scan_sas_topology(ioc);
5325 mptsas_fw_event_on(ioc);
5326 return 0;
5327
5328 out_mptsas_probe:
5329
5330 mptscsih_remove(pdev);
5331 return error;
5332 }
5333
5334 static void
mptsas_shutdown(struct pci_dev * pdev)5335 mptsas_shutdown(struct pci_dev *pdev)
5336 {
5337 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
5338
5339 mptsas_fw_event_off(ioc);
5340 mptsas_cleanup_fw_event_q(ioc);
5341 }
5342
mptsas_remove(struct pci_dev * pdev)5343 static void mptsas_remove(struct pci_dev *pdev)
5344 {
5345 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
5346 struct mptsas_portinfo *p, *n;
5347 int i;
5348
5349 if (!ioc->sh) {
5350 printk(MYIOC_s_INFO_FMT "IOC is in Target mode\n", ioc->name);
5351 mpt_detach(pdev);
5352 return;
5353 }
5354
5355 mptsas_shutdown(pdev);
5356
5357 mptsas_del_device_components(ioc);
5358
5359 ioc->sas_discovery_ignore_events = 1;
5360 sas_remove_host(ioc->sh);
5361
5362 mutex_lock(&ioc->sas_topology_mutex);
5363 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
5364 list_del(&p->list);
5365 for (i = 0 ; i < p->num_phys ; i++)
5366 mptsas_port_delete(ioc, p->phy_info[i].port_details);
5367
5368 kfree(p->phy_info);
5369 kfree(p);
5370 }
5371 mutex_unlock(&ioc->sas_topology_mutex);
5372 ioc->hba_port_info = NULL;
5373 mptscsih_remove(pdev);
5374 }
5375
5376 static struct pci_device_id mptsas_pci_table[] = {
5377 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
5378 PCI_ANY_ID, PCI_ANY_ID },
5379 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
5380 PCI_ANY_ID, PCI_ANY_ID },
5381 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
5382 PCI_ANY_ID, PCI_ANY_ID },
5383 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
5384 PCI_ANY_ID, PCI_ANY_ID },
5385 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
5386 PCI_ANY_ID, PCI_ANY_ID },
5387 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068_820XELP,
5388 PCI_ANY_ID, PCI_ANY_ID },
5389 {0} /* Terminating entry */
5390 };
5391 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
5392
5393
5394 static struct pci_driver mptsas_driver = {
5395 .name = "mptsas",
5396 .id_table = mptsas_pci_table,
5397 .probe = mptsas_probe,
5398 .remove = mptsas_remove,
5399 .shutdown = mptsas_shutdown,
5400 #ifdef CONFIG_PM
5401 .suspend = mptscsih_suspend,
5402 .resume = mptscsih_resume,
5403 #endif
5404 };
5405
5406 static int __init
mptsas_init(void)5407 mptsas_init(void)
5408 {
5409 int error;
5410
5411 show_mptmod_ver(my_NAME, my_VERSION);
5412
5413 mptsas_transport_template =
5414 sas_attach_transport(&mptsas_transport_functions);
5415 if (!mptsas_transport_template)
5416 return -ENODEV;
5417
5418 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER,
5419 "mptscsih_io_done");
5420 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER,
5421 "mptscsih_taskmgmt_complete");
5422 mptsasInternalCtx =
5423 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER,
5424 "mptscsih_scandv_complete");
5425 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER,
5426 "mptsas_mgmt_done");
5427 mptsasDeviceResetCtx =
5428 mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER,
5429 "mptsas_taskmgmt_complete");
5430
5431 mpt_event_register(mptsasDoneCtx, mptsas_event_process);
5432 mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
5433
5434 error = pci_register_driver(&mptsas_driver);
5435 if (error)
5436 sas_release_transport(mptsas_transport_template);
5437
5438 return error;
5439 }
5440
5441 static void __exit
mptsas_exit(void)5442 mptsas_exit(void)
5443 {
5444 pci_unregister_driver(&mptsas_driver);
5445 sas_release_transport(mptsas_transport_template);
5446
5447 mpt_reset_deregister(mptsasDoneCtx);
5448 mpt_event_deregister(mptsasDoneCtx);
5449
5450 mpt_deregister(mptsasMgmtCtx);
5451 mpt_deregister(mptsasInternalCtx);
5452 mpt_deregister(mptsasTaskCtx);
5453 mpt_deregister(mptsasDoneCtx);
5454 mpt_deregister(mptsasDeviceResetCtx);
5455 }
5456
5457 module_init(mptsas_init);
5458 module_exit(mptsas_exit);
5459