blob: ec48c010a3bab595cf54f74fb3082a80b94e693c [file] [log] [blame]
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301/*
2 * Scsi Host Layer for MPT (Message Passing Technology) based controllers
3 *
4 * This code is based on drivers/scsi/mpt3sas/mpt3sas_scsih.c
Sreekanth Reddya4ffce02014-09-12 15:35:29 +05305 * Copyright (C) 2012-2014 LSI Corporation
Sreekanth Reddya03bd152015-01-12 11:39:02 +05306 * Copyright (C) 2013-2014 Avago Technologies
7 * (mailto: MPT-FusionLinux.pdl@avagotech.com)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * NO WARRANTY
20 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
21 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
22 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
23 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
24 * solely responsible for determining the appropriateness of using and
25 * distributing the Program and assumes all risks associated with its
26 * exercise of rights under this Agreement, including but not limited to
27 * the risks and costs of program errors, damage to or loss of data,
28 * programs or equipment, and unavailability or interruption of operations.
29
30 * DISCLAIMER OF LIABILITY
31 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
32 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
34 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
35 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
36 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
37 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
38
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
42 * USA.
43 */
44
Sreekanth Reddyf92363d2012-11-30 07:44:21 +053045#include <linux/module.h>
46#include <linux/kernel.h>
47#include <linux/init.h>
48#include <linux/errno.h>
49#include <linux/blkdev.h>
50#include <linux/sched.h>
51#include <linux/workqueue.h>
52#include <linux/delay.h>
53#include <linux/pci.h>
ojabb5d5f282016-12-28 11:05:24 +000054#include <linux/pci-aspm.h>
Sreekanth Reddyf92363d2012-11-30 07:44:21 +053055#include <linux/interrupt.h>
56#include <linux/aer.h>
57#include <linux/raid_class.h>
Sreekanth Reddy7786ab62015-11-11 17:30:28 +053058#include <asm/unaligned.h>
Sreekanth Reddyf92363d2012-11-30 07:44:21 +053059
60#include "mpt3sas_base.h"
61
Sreekanth Reddyf92363d2012-11-30 07:44:21 +053062#define RAID_CHANNEL 1
63/* forward proto's */
64static void _scsih_expander_node_remove(struct MPT3SAS_ADAPTER *ioc,
65 struct _sas_node *sas_expander);
66static void _firmware_event_work(struct work_struct *work);
67
68static void _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc,
69 struct _sas_device *sas_device);
70static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle,
71 u8 retry_count, u8 is_pd);
72
73static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid);
74
Sreekanth Reddyf92363d2012-11-30 07:44:21 +053075/* global parameters */
76LIST_HEAD(mpt3sas_ioc_list);
Sreekanth Reddy08c4d552015-11-11 17:30:33 +053077/* global ioc lock for list operations */
78DEFINE_SPINLOCK(gioc_lock);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +053079
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +053080MODULE_AUTHOR(MPT3SAS_AUTHOR);
81MODULE_DESCRIPTION(MPT3SAS_DESCRIPTION);
82MODULE_LICENSE("GPL");
83MODULE_VERSION(MPT3SAS_DRIVER_VERSION);
84MODULE_ALIAS("mpt2sas");
85
Sreekanth Reddyf92363d2012-11-30 07:44:21 +053086/* local parameters */
87static u8 scsi_io_cb_idx = -1;
88static u8 tm_cb_idx = -1;
89static u8 ctl_cb_idx = -1;
90static u8 base_cb_idx = -1;
91static u8 port_enable_cb_idx = -1;
92static u8 transport_cb_idx = -1;
93static u8 scsih_cb_idx = -1;
94static u8 config_cb_idx = -1;
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +053095static int mpt2_ids;
96static int mpt3_ids;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +053097
98static u8 tm_tr_cb_idx = -1 ;
99static u8 tm_tr_volume_cb_idx = -1 ;
100static u8 tm_sas_control_cb_idx = -1;
101
102/* command line options */
103static u32 logging_level;
104MODULE_PARM_DESC(logging_level,
105 " bits for enabling additional logging info (default=0)");
106
107
108static ushort max_sectors = 0xFFFF;
109module_param(max_sectors, ushort, 0);
110MODULE_PARM_DESC(max_sectors, "max sectors, range 64 to 32767 default=32767");
111
112
113static int missing_delay[2] = {-1, -1};
114module_param_array(missing_delay, int, NULL, 0);
115MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay");
116
117/* scsi-mid layer global parmeter is max_report_luns, which is 511 */
118#define MPT3SAS_MAX_LUN (16895)
Hannes Reinecke1abf6352014-06-25 15:27:38 +0200119static u64 max_lun = MPT3SAS_MAX_LUN;
120module_param(max_lun, ullong, 0);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530121MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
122
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +0530123static ushort hbas_to_enumerate;
124module_param(hbas_to_enumerate, ushort, 0);
125MODULE_PARM_DESC(hbas_to_enumerate,
126 " 0 - enumerates both SAS 2.0 & SAS 3.0 generation HBAs\n \
127 1 - enumerates only SAS 2.0 generation HBAs\n \
128 2 - enumerates only SAS 3.0 generation HBAs (default=0)");
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530129
130/* diag_buffer_enable is bitwise
131 * bit 0 set = TRACE
132 * bit 1 set = SNAPSHOT
133 * bit 2 set = EXTENDED
134 *
135 * Either bit can be set, or both
136 */
137static int diag_buffer_enable = -1;
138module_param(diag_buffer_enable, int, 0);
139MODULE_PARM_DESC(diag_buffer_enable,
140 " post diag buffers (TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)");
141static int disable_discovery = -1;
142module_param(disable_discovery, int, 0);
143MODULE_PARM_DESC(disable_discovery, " disable discovery ");
144
145
146/* permit overriding the host protection capabilities mask (EEDP/T10 PI) */
147static int prot_mask = -1;
148module_param(prot_mask, int, 0);
149MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=7 ");
150
151
152/* raid transport support */
Sreekanth Reddy7497392a2015-11-11 17:30:19 +0530153struct raid_template *mpt3sas_raid_template;
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +0530154struct raid_template *mpt2sas_raid_template;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530155
156
157/**
158 * struct sense_info - common structure for obtaining sense keys
159 * @skey: sense key
160 * @asc: additional sense code
161 * @ascq: additional sense code qualifier
162 */
163struct sense_info {
164 u8 skey;
165 u8 asc;
166 u8 ascq;
167};
168
169#define MPT3SAS_PROCESS_TRIGGER_DIAG (0xFFFB)
Sreekanth Reddy0f624c32014-09-12 15:35:26 +0530170#define MPT3SAS_TURN_ON_PFA_LED (0xFFFC)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530171#define MPT3SAS_PORT_ENABLE_COMPLETE (0xFFFD)
172#define MPT3SAS_ABRT_TASK_SET (0xFFFE)
173#define MPT3SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF)
174/**
175 * struct fw_event_work - firmware event struct
176 * @list: link list framework
177 * @work: work object (ioc->fault_reset_work_q)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530178 * @ioc: per adapter object
179 * @device_handle: device handle
180 * @VF_ID: virtual function id
181 * @VP_ID: virtual port id
182 * @ignore: flag meaning this event has been marked to ignore
Joe Lawrenceb8ac0cc2016-04-18 10:50:12 -0400183 * @event: firmware event MPI2_EVENT_XXX defined in mpi2_ioc.h
184 * @refcount: kref for this event
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530185 * @event_data: reply event data payload follows
186 *
187 * This object stored on ioc->fw_event_list.
188 */
189struct fw_event_work {
190 struct list_head list;
191 struct work_struct work;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530192
193 struct MPT3SAS_ADAPTER *ioc;
194 u16 device_handle;
195 u8 VF_ID;
196 u8 VP_ID;
197 u8 ignore;
198 u16 event;
Sreekanth Reddy146b16c2015-11-11 17:30:31 +0530199 struct kref refcount;
Joe Lawrence35b62362014-06-25 17:05:34 -0400200 char event_data[0] __aligned(4);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530201};
202
Sreekanth Reddy146b16c2015-11-11 17:30:31 +0530203static void fw_event_work_free(struct kref *r)
204{
205 kfree(container_of(r, struct fw_event_work, refcount));
206}
207
208static void fw_event_work_get(struct fw_event_work *fw_work)
209{
210 kref_get(&fw_work->refcount);
211}
212
213static void fw_event_work_put(struct fw_event_work *fw_work)
214{
215 kref_put(&fw_work->refcount, fw_event_work_free);
216}
217
218static struct fw_event_work *alloc_fw_event_work(int len)
219{
220 struct fw_event_work *fw_event;
221
222 fw_event = kzalloc(sizeof(*fw_event) + len, GFP_ATOMIC);
223 if (!fw_event)
224 return NULL;
225
226 kref_init(&fw_event->refcount);
227 return fw_event;
228}
229
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530230/**
231 * struct _scsi_io_transfer - scsi io transfer
232 * @handle: sas device handle (assigned by firmware)
233 * @is_raid: flag set for hidden raid components
234 * @dir: DMA_TO_DEVICE, DMA_FROM_DEVICE,
235 * @data_length: data transfer length
236 * @data_dma: dma pointer to data
237 * @sense: sense data
238 * @lun: lun number
239 * @cdb_length: cdb length
240 * @cdb: cdb contents
241 * @timeout: timeout for this command
242 * @VF_ID: virtual function id
243 * @VP_ID: virtual port id
244 * @valid_reply: flag set for reply message
245 * @sense_length: sense length
246 * @ioc_status: ioc status
247 * @scsi_state: scsi state
248 * @scsi_status: scsi staus
249 * @log_info: log information
250 * @transfer_length: data length transfer when there is a reply message
251 *
252 * Used for sending internal scsi commands to devices within this module.
253 * Refer to _scsi_send_scsi_io().
254 */
255struct _scsi_io_transfer {
256 u16 handle;
257 u8 is_raid;
258 enum dma_data_direction dir;
259 u32 data_length;
260 dma_addr_t data_dma;
261 u8 sense[SCSI_SENSE_BUFFERSIZE];
262 u32 lun;
263 u8 cdb_length;
264 u8 cdb[32];
265 u8 timeout;
266 u8 VF_ID;
267 u8 VP_ID;
268 u8 valid_reply;
269 /* the following bits are only valid when 'valid_reply = 1' */
270 u32 sense_length;
271 u16 ioc_status;
272 u8 scsi_state;
273 u8 scsi_status;
274 u32 log_info;
275 u32 transfer_length;
276};
277
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530278/**
279 * _scsih_set_debug_level - global setting of ioc->logging_level.
280 *
281 * Note: The logging levels are defined in mpt3sas_debug.h.
282 */
283static int
284_scsih_set_debug_level(const char *val, struct kernel_param *kp)
285{
286 int ret = param_set_int(val, kp);
287 struct MPT3SAS_ADAPTER *ioc;
288
289 if (ret)
290 return ret;
291
292 pr_info("setting logging_level(0x%08x)\n", logging_level);
Sreekanth Reddy08c4d552015-11-11 17:30:33 +0530293 spin_lock(&gioc_lock);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530294 list_for_each_entry(ioc, &mpt3sas_ioc_list, list)
295 ioc->logging_level = logging_level;
Sreekanth Reddy08c4d552015-11-11 17:30:33 +0530296 spin_unlock(&gioc_lock);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530297 return 0;
298}
299module_param_call(logging_level, _scsih_set_debug_level, param_get_int,
300 &logging_level, 0644);
301
302/**
303 * _scsih_srch_boot_sas_address - search based on sas_address
304 * @sas_address: sas address
305 * @boot_device: boot device object from bios page 2
306 *
307 * Returns 1 when there's a match, 0 means no match.
308 */
309static inline int
310_scsih_srch_boot_sas_address(u64 sas_address,
311 Mpi2BootDeviceSasWwid_t *boot_device)
312{
313 return (sas_address == le64_to_cpu(boot_device->SASAddress)) ? 1 : 0;
314}
315
316/**
317 * _scsih_srch_boot_device_name - search based on device name
318 * @device_name: device name specified in INDENTIFY fram
319 * @boot_device: boot device object from bios page 2
320 *
321 * Returns 1 when there's a match, 0 means no match.
322 */
323static inline int
324_scsih_srch_boot_device_name(u64 device_name,
325 Mpi2BootDeviceDeviceName_t *boot_device)
326{
327 return (device_name == le64_to_cpu(boot_device->DeviceName)) ? 1 : 0;
328}
329
330/**
331 * _scsih_srch_boot_encl_slot - search based on enclosure_logical_id/slot
332 * @enclosure_logical_id: enclosure logical id
333 * @slot_number: slot number
334 * @boot_device: boot device object from bios page 2
335 *
336 * Returns 1 when there's a match, 0 means no match.
337 */
338static inline int
339_scsih_srch_boot_encl_slot(u64 enclosure_logical_id, u16 slot_number,
340 Mpi2BootDeviceEnclosureSlot_t *boot_device)
341{
342 return (enclosure_logical_id == le64_to_cpu(boot_device->
343 EnclosureLogicalID) && slot_number == le16_to_cpu(boot_device->
344 SlotNumber)) ? 1 : 0;
345}
346
347/**
348 * _scsih_is_boot_device - search for matching boot device.
349 * @sas_address: sas address
350 * @device_name: device name specified in INDENTIFY fram
351 * @enclosure_logical_id: enclosure logical id
352 * @slot_number: slot number
353 * @form: specifies boot device form
354 * @boot_device: boot device object from bios page 2
355 *
356 * Returns 1 when there's a match, 0 means no match.
357 */
358static int
359_scsih_is_boot_device(u64 sas_address, u64 device_name,
360 u64 enclosure_logical_id, u16 slot, u8 form,
361 Mpi2BiosPage2BootDevice_t *boot_device)
362{
363 int rc = 0;
364
365 switch (form) {
366 case MPI2_BIOSPAGE2_FORM_SAS_WWID:
367 if (!sas_address)
368 break;
369 rc = _scsih_srch_boot_sas_address(
370 sas_address, &boot_device->SasWwid);
371 break;
372 case MPI2_BIOSPAGE2_FORM_ENCLOSURE_SLOT:
373 if (!enclosure_logical_id)
374 break;
375 rc = _scsih_srch_boot_encl_slot(
376 enclosure_logical_id,
377 slot, &boot_device->EnclosureSlot);
378 break;
379 case MPI2_BIOSPAGE2_FORM_DEVICE_NAME:
380 if (!device_name)
381 break;
382 rc = _scsih_srch_boot_device_name(
383 device_name, &boot_device->DeviceName);
384 break;
385 case MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED:
386 break;
387 }
388
389 return rc;
390}
391
392/**
393 * _scsih_get_sas_address - set the sas_address for given device handle
394 * @handle: device handle
395 * @sas_address: sas address
396 *
397 * Returns 0 success, non-zero when failure
398 */
399static int
400_scsih_get_sas_address(struct MPT3SAS_ADAPTER *ioc, u16 handle,
401 u64 *sas_address)
402{
403 Mpi2SasDevicePage0_t sas_device_pg0;
404 Mpi2ConfigReply_t mpi_reply;
405 u32 ioc_status;
406
407 *sas_address = 0;
408
409 if (handle <= ioc->sas_hba.num_phys) {
410 *sas_address = ioc->sas_hba.sas_address;
411 return 0;
412 }
413
414 if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
415 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
416 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name,
417 __FILE__, __LINE__, __func__);
418 return -ENXIO;
419 }
420
421 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
422 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
423 *sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
424 return 0;
425 }
426
427 /* we hit this becuase the given parent handle doesn't exist */
428 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
429 return -ENXIO;
430
431 /* else error case */
432 pr_err(MPT3SAS_FMT
433 "handle(0x%04x), ioc_status(0x%04x), failure at %s:%d/%s()!\n",
434 ioc->name, handle, ioc_status,
435 __FILE__, __LINE__, __func__);
436 return -EIO;
437}
438
439/**
440 * _scsih_determine_boot_device - determine boot device.
441 * @ioc: per adapter object
442 * @device: either sas_device or raid_device object
443 * @is_raid: [flag] 1 = raid object, 0 = sas object
444 *
445 * Determines whether this device should be first reported device to
446 * to scsi-ml or sas transport, this purpose is for persistent boot device.
447 * There are primary, alternate, and current entries in bios page 2. The order
448 * priority is primary, alternate, then current. This routine saves
449 * the corresponding device object and is_raid flag in the ioc object.
450 * The saved data to be used later in _scsih_probe_boot_devices().
451 */
452static void
453_scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc,
454 void *device, u8 is_raid)
455{
456 struct _sas_device *sas_device;
457 struct _raid_device *raid_device;
458 u64 sas_address;
459 u64 device_name;
460 u64 enclosure_logical_id;
461 u16 slot;
462
463 /* only process this function when driver loads */
464 if (!ioc->is_driver_loading)
465 return;
466
467 /* no Bios, return immediately */
468 if (!ioc->bios_pg3.BiosVersion)
469 return;
470
471 if (!is_raid) {
472 sas_device = device;
473 sas_address = sas_device->sas_address;
474 device_name = sas_device->device_name;
475 enclosure_logical_id = sas_device->enclosure_logical_id;
476 slot = sas_device->slot;
477 } else {
478 raid_device = device;
479 sas_address = raid_device->wwid;
480 device_name = 0;
481 enclosure_logical_id = 0;
482 slot = 0;
483 }
484
485 if (!ioc->req_boot_device.device) {
486 if (_scsih_is_boot_device(sas_address, device_name,
487 enclosure_logical_id, slot,
488 (ioc->bios_pg2.ReqBootDeviceForm &
489 MPI2_BIOSPAGE2_FORM_MASK),
490 &ioc->bios_pg2.RequestedBootDevice)) {
491 dinitprintk(ioc, pr_info(MPT3SAS_FMT
492 "%s: req_boot_device(0x%016llx)\n",
493 ioc->name, __func__,
494 (unsigned long long)sas_address));
495 ioc->req_boot_device.device = device;
496 ioc->req_boot_device.is_raid = is_raid;
497 }
498 }
499
500 if (!ioc->req_alt_boot_device.device) {
501 if (_scsih_is_boot_device(sas_address, device_name,
502 enclosure_logical_id, slot,
503 (ioc->bios_pg2.ReqAltBootDeviceForm &
504 MPI2_BIOSPAGE2_FORM_MASK),
505 &ioc->bios_pg2.RequestedAltBootDevice)) {
506 dinitprintk(ioc, pr_info(MPT3SAS_FMT
507 "%s: req_alt_boot_device(0x%016llx)\n",
508 ioc->name, __func__,
509 (unsigned long long)sas_address));
510 ioc->req_alt_boot_device.device = device;
511 ioc->req_alt_boot_device.is_raid = is_raid;
512 }
513 }
514
515 if (!ioc->current_boot_device.device) {
516 if (_scsih_is_boot_device(sas_address, device_name,
517 enclosure_logical_id, slot,
518 (ioc->bios_pg2.CurrentBootDeviceForm &
519 MPI2_BIOSPAGE2_FORM_MASK),
520 &ioc->bios_pg2.CurrentBootDevice)) {
521 dinitprintk(ioc, pr_info(MPT3SAS_FMT
522 "%s: current_boot_device(0x%016llx)\n",
523 ioc->name, __func__,
524 (unsigned long long)sas_address));
525 ioc->current_boot_device.device = device;
526 ioc->current_boot_device.is_raid = is_raid;
527 }
528 }
529}
530
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530531static struct _sas_device *
532__mpt3sas_get_sdev_from_target(struct MPT3SAS_ADAPTER *ioc,
533 struct MPT3SAS_TARGET *tgt_priv)
534{
535 struct _sas_device *ret;
536
537 assert_spin_locked(&ioc->sas_device_lock);
538
539 ret = tgt_priv->sdev;
540 if (ret)
541 sas_device_get(ret);
542
543 return ret;
544}
545
546static struct _sas_device *
547mpt3sas_get_sdev_from_target(struct MPT3SAS_ADAPTER *ioc,
548 struct MPT3SAS_TARGET *tgt_priv)
549{
550 struct _sas_device *ret;
551 unsigned long flags;
552
553 spin_lock_irqsave(&ioc->sas_device_lock, flags);
554 ret = __mpt3sas_get_sdev_from_target(ioc, tgt_priv);
555 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
556
557 return ret;
558}
559
560
561struct _sas_device *
562__mpt3sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc,
563 u64 sas_address)
564{
565 struct _sas_device *sas_device;
566
567 assert_spin_locked(&ioc->sas_device_lock);
568
569 list_for_each_entry(sas_device, &ioc->sas_device_list, list)
570 if (sas_device->sas_address == sas_address)
571 goto found_device;
572
573 list_for_each_entry(sas_device, &ioc->sas_device_init_list, list)
574 if (sas_device->sas_address == sas_address)
575 goto found_device;
576
577 return NULL;
578
579found_device:
580 sas_device_get(sas_device);
581 return sas_device;
582}
583
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530584/**
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530585 * mpt3sas_get_sdev_by_addr - sas device search
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530586 * @ioc: per adapter object
587 * @sas_address: sas address
588 * Context: Calling function should acquire ioc->sas_device_lock
589 *
590 * This searches for sas_device based on sas_address, then return sas_device
591 * object.
592 */
593struct _sas_device *
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530594mpt3sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc,
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530595 u64 sas_address)
596{
597 struct _sas_device *sas_device;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530598 unsigned long flags;
599
600 spin_lock_irqsave(&ioc->sas_device_lock, flags);
601 sas_device = __mpt3sas_get_sdev_by_addr(ioc,
602 sas_address);
603 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
604
605 return sas_device;
606}
607
608static struct _sas_device *
609__mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
610{
611 struct _sas_device *sas_device;
612
613 assert_spin_locked(&ioc->sas_device_lock);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530614
615 list_for_each_entry(sas_device, &ioc->sas_device_list, list)
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530616 if (sas_device->handle == handle)
617 goto found_device;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530618
619 list_for_each_entry(sas_device, &ioc->sas_device_init_list, list)
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530620 if (sas_device->handle == handle)
621 goto found_device;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530622
623 return NULL;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530624
625found_device:
626 sas_device_get(sas_device);
627 return sas_device;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530628}
629
630/**
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530631 * mpt3sas_get_sdev_by_handle - sas device search
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530632 * @ioc: per adapter object
633 * @handle: sas device handle (assigned by firmware)
634 * Context: Calling function should acquire ioc->sas_device_lock
635 *
636 * This searches for sas_device based on sas_address, then return sas_device
637 * object.
638 */
639static struct _sas_device *
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530640mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530641{
642 struct _sas_device *sas_device;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530643 unsigned long flags;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530644
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530645 spin_lock_irqsave(&ioc->sas_device_lock, flags);
646 sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
647 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530648
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530649 return sas_device;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530650}
651
652/**
653 * _scsih_sas_device_remove - remove sas_device from list.
654 * @ioc: per adapter object
655 * @sas_device: the sas_device object
656 * Context: This function will acquire ioc->sas_device_lock.
657 *
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530658 * If sas_device is on the list, remove it and decrement its reference count.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530659 */
660static void
661_scsih_sas_device_remove(struct MPT3SAS_ADAPTER *ioc,
662 struct _sas_device *sas_device)
663{
664 unsigned long flags;
665
666 if (!sas_device)
667 return;
Sreekanth Reddye6d45e32015-06-30 12:24:52 +0530668 pr_info(MPT3SAS_FMT
669 "removing handle(0x%04x), sas_addr(0x%016llx)\n",
670 ioc->name, sas_device->handle,
671 (unsigned long long) sas_device->sas_address);
672
673 if (sas_device->enclosure_handle != 0)
674 pr_info(MPT3SAS_FMT
675 "removing enclosure logical id(0x%016llx), slot(%d)\n",
676 ioc->name, (unsigned long long)
677 sas_device->enclosure_logical_id, sas_device->slot);
678
679 if (sas_device->connector_name[0] != '\0')
680 pr_info(MPT3SAS_FMT
681 "removing enclosure level(0x%04x), connector name( %s)\n",
682 ioc->name, sas_device->enclosure_level,
683 sas_device->connector_name);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530684
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530685 /*
686 * The lock serializes access to the list, but we still need to verify
687 * that nobody removed the entry while we were waiting on the lock.
688 */
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530689 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530690 if (!list_empty(&sas_device->list)) {
691 list_del_init(&sas_device->list);
692 sas_device_put(sas_device);
693 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530694 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
695}
696
697/**
698 * _scsih_device_remove_by_handle - removing device object by handle
699 * @ioc: per adapter object
700 * @handle: device handle
701 *
702 * Return nothing.
703 */
704static void
705_scsih_device_remove_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
706{
707 struct _sas_device *sas_device;
708 unsigned long flags;
709
710 if (ioc->shost_recovery)
711 return;
712
713 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530714 sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
715 if (sas_device) {
716 list_del_init(&sas_device->list);
717 sas_device_put(sas_device);
718 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530719 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530720 if (sas_device) {
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530721 _scsih_remove_device(ioc, sas_device);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530722 sas_device_put(sas_device);
723 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530724}
725
726/**
727 * mpt3sas_device_remove_by_sas_address - removing device object by sas address
728 * @ioc: per adapter object
729 * @sas_address: device sas_address
730 *
731 * Return nothing.
732 */
733void
734mpt3sas_device_remove_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
735 u64 sas_address)
736{
737 struct _sas_device *sas_device;
738 unsigned long flags;
739
740 if (ioc->shost_recovery)
741 return;
742
743 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530744 sas_device = __mpt3sas_get_sdev_by_addr(ioc, sas_address);
745 if (sas_device) {
746 list_del_init(&sas_device->list);
747 sas_device_put(sas_device);
748 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530749 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530750 if (sas_device) {
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530751 _scsih_remove_device(ioc, sas_device);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530752 sas_device_put(sas_device);
753 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530754}
755
756/**
757 * _scsih_sas_device_add - insert sas_device to the list.
758 * @ioc: per adapter object
759 * @sas_device: the sas_device object
760 * Context: This function will acquire ioc->sas_device_lock.
761 *
762 * Adding new object to the ioc->sas_device_list.
763 */
764static void
765_scsih_sas_device_add(struct MPT3SAS_ADAPTER *ioc,
766 struct _sas_device *sas_device)
767{
768 unsigned long flags;
769
770 dewtprintk(ioc, pr_info(MPT3SAS_FMT
771 "%s: handle(0x%04x), sas_addr(0x%016llx)\n",
772 ioc->name, __func__, sas_device->handle,
773 (unsigned long long)sas_device->sas_address));
774
Sreekanth Reddye6d45e32015-06-30 12:24:52 +0530775 if (sas_device->enclosure_handle != 0)
776 dewtprintk(ioc, pr_info(MPT3SAS_FMT
777 "%s: enclosure logical id(0x%016llx), slot( %d)\n",
778 ioc->name, __func__, (unsigned long long)
779 sas_device->enclosure_logical_id, sas_device->slot));
780
781 if (sas_device->connector_name[0] != '\0')
782 dewtprintk(ioc, pr_info(MPT3SAS_FMT
783 "%s: enclosure level(0x%04x), connector name( %s)\n",
784 ioc->name, __func__,
785 sas_device->enclosure_level, sas_device->connector_name));
786
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530787 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530788 sas_device_get(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530789 list_add_tail(&sas_device->list, &ioc->sas_device_list);
790 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
791
792 if (!mpt3sas_transport_port_add(ioc, sas_device->handle,
793 sas_device->sas_address_parent)) {
794 _scsih_sas_device_remove(ioc, sas_device);
795 } else if (!sas_device->starget) {
796 /*
797 * When asyn scanning is enabled, its not possible to remove
798 * devices while scanning is turned on due to an oops in
799 * scsi_sysfs_add_sdev()->add_device()->sysfs_addrm_start()
800 */
Sreekanth Reddyf5edbe72013-06-29 03:54:51 +0530801 if (!ioc->is_driver_loading) {
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530802 mpt3sas_transport_port_remove(ioc,
803 sas_device->sas_address,
804 sas_device->sas_address_parent);
Sreekanth Reddyf5edbe72013-06-29 03:54:51 +0530805 _scsih_sas_device_remove(ioc, sas_device);
806 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530807 }
808}
809
810/**
811 * _scsih_sas_device_init_add - insert sas_device to the list.
812 * @ioc: per adapter object
813 * @sas_device: the sas_device object
814 * Context: This function will acquire ioc->sas_device_lock.
815 *
816 * Adding new object at driver load time to the ioc->sas_device_init_list.
817 */
818static void
819_scsih_sas_device_init_add(struct MPT3SAS_ADAPTER *ioc,
820 struct _sas_device *sas_device)
821{
822 unsigned long flags;
823
824 dewtprintk(ioc, pr_info(MPT3SAS_FMT
825 "%s: handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name,
826 __func__, sas_device->handle,
827 (unsigned long long)sas_device->sas_address));
828
Sreekanth Reddye6d45e32015-06-30 12:24:52 +0530829 if (sas_device->enclosure_handle != 0)
830 dewtprintk(ioc, pr_info(MPT3SAS_FMT
831 "%s: enclosure logical id(0x%016llx), slot( %d)\n",
832 ioc->name, __func__, (unsigned long long)
833 sas_device->enclosure_logical_id, sas_device->slot));
834
835 if (sas_device->connector_name[0] != '\0')
836 dewtprintk(ioc, pr_info(MPT3SAS_FMT
837 "%s: enclosure level(0x%04x), connector name( %s)\n",
838 ioc->name, __func__, sas_device->enclosure_level,
839 sas_device->connector_name));
840
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530841 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +0530842 sas_device_get(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530843 list_add_tail(&sas_device->list, &ioc->sas_device_init_list);
844 _scsih_determine_boot_device(ioc, sas_device, 0);
845 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
846}
847
848/**
849 * _scsih_raid_device_find_by_id - raid device search
850 * @ioc: per adapter object
851 * @id: sas device target id
852 * @channel: sas device channel
853 * Context: Calling function should acquire ioc->raid_device_lock
854 *
855 * This searches for raid_device based on target id, then return raid_device
856 * object.
857 */
858static struct _raid_device *
859_scsih_raid_device_find_by_id(struct MPT3SAS_ADAPTER *ioc, int id, int channel)
860{
861 struct _raid_device *raid_device, *r;
862
863 r = NULL;
864 list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
865 if (raid_device->id == id && raid_device->channel == channel) {
866 r = raid_device;
867 goto out;
868 }
869 }
870
871 out:
872 return r;
873}
874
875/**
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +0530876 * mpt3sas_raid_device_find_by_handle - raid device search
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530877 * @ioc: per adapter object
878 * @handle: sas device handle (assigned by firmware)
879 * Context: Calling function should acquire ioc->raid_device_lock
880 *
881 * This searches for raid_device based on handle, then return raid_device
882 * object.
883 */
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +0530884struct _raid_device *
885mpt3sas_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530886{
887 struct _raid_device *raid_device, *r;
888
889 r = NULL;
890 list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
891 if (raid_device->handle != handle)
892 continue;
893 r = raid_device;
894 goto out;
895 }
896
897 out:
898 return r;
899}
900
901/**
902 * _scsih_raid_device_find_by_wwid - raid device search
903 * @ioc: per adapter object
904 * @handle: sas device handle (assigned by firmware)
905 * Context: Calling function should acquire ioc->raid_device_lock
906 *
907 * This searches for raid_device based on wwid, then return raid_device
908 * object.
909 */
910static struct _raid_device *
911_scsih_raid_device_find_by_wwid(struct MPT3SAS_ADAPTER *ioc, u64 wwid)
912{
913 struct _raid_device *raid_device, *r;
914
915 r = NULL;
916 list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
917 if (raid_device->wwid != wwid)
918 continue;
919 r = raid_device;
920 goto out;
921 }
922
923 out:
924 return r;
925}
926
927/**
928 * _scsih_raid_device_add - add raid_device object
929 * @ioc: per adapter object
930 * @raid_device: raid_device object
931 *
932 * This is added to the raid_device_list link list.
933 */
934static void
935_scsih_raid_device_add(struct MPT3SAS_ADAPTER *ioc,
936 struct _raid_device *raid_device)
937{
938 unsigned long flags;
939
940 dewtprintk(ioc, pr_info(MPT3SAS_FMT
941 "%s: handle(0x%04x), wwid(0x%016llx)\n", ioc->name, __func__,
942 raid_device->handle, (unsigned long long)raid_device->wwid));
943
944 spin_lock_irqsave(&ioc->raid_device_lock, flags);
945 list_add_tail(&raid_device->list, &ioc->raid_device_list);
946 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
947}
948
949/**
950 * _scsih_raid_device_remove - delete raid_device object
951 * @ioc: per adapter object
952 * @raid_device: raid_device object
953 *
954 */
955static void
956_scsih_raid_device_remove(struct MPT3SAS_ADAPTER *ioc,
957 struct _raid_device *raid_device)
958{
959 unsigned long flags;
960
961 spin_lock_irqsave(&ioc->raid_device_lock, flags);
962 list_del(&raid_device->list);
963 kfree(raid_device);
964 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
965}
966
967/**
968 * mpt3sas_scsih_expander_find_by_handle - expander device search
969 * @ioc: per adapter object
970 * @handle: expander handle (assigned by firmware)
971 * Context: Calling function should acquire ioc->sas_device_lock
972 *
973 * This searches for expander device based on handle, then returns the
974 * sas_node object.
975 */
976struct _sas_node *
977mpt3sas_scsih_expander_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
978{
979 struct _sas_node *sas_expander, *r;
980
981 r = NULL;
982 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
983 if (sas_expander->handle != handle)
984 continue;
985 r = sas_expander;
986 goto out;
987 }
988 out:
989 return r;
990}
991
992/**
993 * mpt3sas_scsih_expander_find_by_sas_address - expander device search
994 * @ioc: per adapter object
995 * @sas_address: sas address
996 * Context: Calling function should acquire ioc->sas_node_lock.
997 *
998 * This searches for expander device based on sas_address, then returns the
999 * sas_node object.
1000 */
1001struct _sas_node *
1002mpt3sas_scsih_expander_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
1003 u64 sas_address)
1004{
1005 struct _sas_node *sas_expander, *r;
1006
1007 r = NULL;
1008 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
1009 if (sas_expander->sas_address != sas_address)
1010 continue;
1011 r = sas_expander;
1012 goto out;
1013 }
1014 out:
1015 return r;
1016}
1017
1018/**
1019 * _scsih_expander_node_add - insert expander device to the list.
1020 * @ioc: per adapter object
1021 * @sas_expander: the sas_device object
1022 * Context: This function will acquire ioc->sas_node_lock.
1023 *
1024 * Adding new object to the ioc->sas_expander_list.
1025 *
1026 * Return nothing.
1027 */
1028static void
1029_scsih_expander_node_add(struct MPT3SAS_ADAPTER *ioc,
1030 struct _sas_node *sas_expander)
1031{
1032 unsigned long flags;
1033
1034 spin_lock_irqsave(&ioc->sas_node_lock, flags);
1035 list_add_tail(&sas_expander->list, &ioc->sas_expander_list);
1036 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1037}
1038
1039/**
1040 * _scsih_is_end_device - determines if device is an end device
1041 * @device_info: bitfield providing information about the device.
1042 * Context: none
1043 *
1044 * Returns 1 if end device.
1045 */
1046static int
1047_scsih_is_end_device(u32 device_info)
1048{
1049 if (device_info & MPI2_SAS_DEVICE_INFO_END_DEVICE &&
1050 ((device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) |
1051 (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET) |
1052 (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)))
1053 return 1;
1054 else
1055 return 0;
1056}
1057
1058/**
1059 * _scsih_scsi_lookup_get - returns scmd entry
1060 * @ioc: per adapter object
1061 * @smid: system request message index
1062 *
1063 * Returns the smid stored scmd pointer.
1064 */
1065static struct scsi_cmnd *
1066_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, u16 smid)
1067{
1068 return ioc->scsi_lookup[smid - 1].scmd;
1069}
1070
1071/**
1072 * _scsih_scsi_lookup_get_clear - returns scmd entry
1073 * @ioc: per adapter object
1074 * @smid: system request message index
1075 *
1076 * Returns the smid stored scmd pointer.
1077 * Then will derefrence the stored scmd pointer.
1078 */
1079static inline struct scsi_cmnd *
1080_scsih_scsi_lookup_get_clear(struct MPT3SAS_ADAPTER *ioc, u16 smid)
1081{
1082 unsigned long flags;
1083 struct scsi_cmnd *scmd;
1084
1085 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1086 scmd = ioc->scsi_lookup[smid - 1].scmd;
1087 ioc->scsi_lookup[smid - 1].scmd = NULL;
1088 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1089
1090 return scmd;
1091}
1092
1093/**
1094 * _scsih_scsi_lookup_find_by_scmd - scmd lookup
1095 * @ioc: per adapter object
1096 * @smid: system request message index
1097 * @scmd: pointer to scsi command object
1098 * Context: This function will acquire ioc->scsi_lookup_lock.
1099 *
1100 * This will search for a scmd pointer in the scsi_lookup array,
1101 * returning the revelent smid. A returned value of zero means invalid.
1102 */
1103static u16
1104_scsih_scsi_lookup_find_by_scmd(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd
1105 *scmd)
1106{
1107 u16 smid;
1108 unsigned long flags;
1109 int i;
1110
1111 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1112 smid = 0;
1113 for (i = 0; i < ioc->scsiio_depth; i++) {
1114 if (ioc->scsi_lookup[i].scmd == scmd) {
1115 smid = ioc->scsi_lookup[i].smid;
1116 goto out;
1117 }
1118 }
1119 out:
1120 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1121 return smid;
1122}
1123
1124/**
1125 * _scsih_scsi_lookup_find_by_target - search for matching channel:id
1126 * @ioc: per adapter object
1127 * @id: target id
1128 * @channel: channel
1129 * Context: This function will acquire ioc->scsi_lookup_lock.
1130 *
1131 * This will search for a matching channel:id in the scsi_lookup array,
1132 * returning 1 if found.
1133 */
1134static u8
1135_scsih_scsi_lookup_find_by_target(struct MPT3SAS_ADAPTER *ioc, int id,
1136 int channel)
1137{
1138 u8 found;
1139 unsigned long flags;
1140 int i;
1141
1142 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1143 found = 0;
1144 for (i = 0 ; i < ioc->scsiio_depth; i++) {
1145 if (ioc->scsi_lookup[i].scmd &&
1146 (ioc->scsi_lookup[i].scmd->device->id == id &&
1147 ioc->scsi_lookup[i].scmd->device->channel == channel)) {
1148 found = 1;
1149 goto out;
1150 }
1151 }
1152 out:
1153 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1154 return found;
1155}
1156
1157/**
1158 * _scsih_scsi_lookup_find_by_lun - search for matching channel:id:lun
1159 * @ioc: per adapter object
1160 * @id: target id
1161 * @lun: lun number
1162 * @channel: channel
1163 * Context: This function will acquire ioc->scsi_lookup_lock.
1164 *
1165 * This will search for a matching channel:id:lun in the scsi_lookup array,
1166 * returning 1 if found.
1167 */
1168static u8
1169_scsih_scsi_lookup_find_by_lun(struct MPT3SAS_ADAPTER *ioc, int id,
1170 unsigned int lun, int channel)
1171{
1172 u8 found;
1173 unsigned long flags;
1174 int i;
1175
1176 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1177 found = 0;
1178 for (i = 0 ; i < ioc->scsiio_depth; i++) {
1179 if (ioc->scsi_lookup[i].scmd &&
1180 (ioc->scsi_lookup[i].scmd->device->id == id &&
1181 ioc->scsi_lookup[i].scmd->device->channel == channel &&
1182 ioc->scsi_lookup[i].scmd->device->lun == lun)) {
1183 found = 1;
1184 goto out;
1185 }
1186 }
1187 out:
1188 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1189 return found;
1190}
1191
Christoph Hellwigcf75d5d2014-11-13 15:13:20 +01001192/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301193 * scsih_change_queue_depth - setting device queue depth
Christoph Hellwigcf75d5d2014-11-13 15:13:20 +01001194 * @sdev: scsi device struct
1195 * @qdepth: requested queue depth
1196 *
1197 * Returns queue depth.
1198 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07001199static int
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301200scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301201{
1202 struct Scsi_Host *shost = sdev->host;
1203 int max_depth;
1204 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
1205 struct MPT3SAS_DEVICE *sas_device_priv_data;
1206 struct MPT3SAS_TARGET *sas_target_priv_data;
1207 struct _sas_device *sas_device;
1208 unsigned long flags;
1209
1210 max_depth = shost->can_queue;
1211
1212 /* limit max device queue for SATA to 32 */
1213 sas_device_priv_data = sdev->hostdata;
1214 if (!sas_device_priv_data)
1215 goto not_sata;
1216 sas_target_priv_data = sas_device_priv_data->sas_target;
1217 if (!sas_target_priv_data)
1218 goto not_sata;
1219 if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))
1220 goto not_sata;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05301221
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301222 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05301223 sas_device = __mpt3sas_get_sdev_from_target(ioc, sas_target_priv_data);
1224 if (sas_device) {
1225 if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
1226 max_depth = MPT3SAS_SATA_QUEUE_DEPTH;
1227
1228 sas_device_put(sas_device);
1229 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301230 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1231
1232 not_sata:
1233
1234 if (!sdev->tagged_supported)
1235 max_depth = 1;
1236 if (qdepth > max_depth)
1237 qdepth = max_depth;
Christoph Hellwigcf75d5d2014-11-13 15:13:20 +01001238 return scsi_change_queue_depth(sdev, qdepth);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301239}
1240
1241/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301242 * scsih_target_alloc - target add routine
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301243 * @starget: scsi target struct
1244 *
1245 * Returns 0 if ok. Any other return is assumed to be an error and
1246 * the device is ignored.
1247 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07001248static int
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301249scsih_target_alloc(struct scsi_target *starget)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301250{
1251 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
1252 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
1253 struct MPT3SAS_TARGET *sas_target_priv_data;
1254 struct _sas_device *sas_device;
1255 struct _raid_device *raid_device;
1256 unsigned long flags;
1257 struct sas_rphy *rphy;
1258
Joe Lawrence62c4da42014-06-25 17:04:22 -04001259 sas_target_priv_data = kzalloc(sizeof(*sas_target_priv_data),
1260 GFP_KERNEL);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301261 if (!sas_target_priv_data)
1262 return -ENOMEM;
1263
1264 starget->hostdata = sas_target_priv_data;
1265 sas_target_priv_data->starget = starget;
1266 sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE;
1267
1268 /* RAID volumes */
1269 if (starget->channel == RAID_CHANNEL) {
1270 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1271 raid_device = _scsih_raid_device_find_by_id(ioc, starget->id,
1272 starget->channel);
1273 if (raid_device) {
1274 sas_target_priv_data->handle = raid_device->handle;
1275 sas_target_priv_data->sas_address = raid_device->wwid;
1276 sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME;
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05301277 if (ioc->is_warpdrive)
Sreekanth Reddy6d3a56e2016-10-28 10:09:12 +05301278 sas_target_priv_data->raid_device = raid_device;
1279 raid_device->starget = starget;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301280 }
1281 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1282 return 0;
1283 }
1284
1285 /* sas/sata devices */
1286 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1287 rphy = dev_to_rphy(starget->dev.parent);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05301288 sas_device = __mpt3sas_get_sdev_by_addr(ioc,
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301289 rphy->identify.sas_address);
1290
1291 if (sas_device) {
1292 sas_target_priv_data->handle = sas_device->handle;
1293 sas_target_priv_data->sas_address = sas_device->sas_address;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05301294 sas_target_priv_data->sdev = sas_device;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301295 sas_device->starget = starget;
1296 sas_device->id = starget->id;
1297 sas_device->channel = starget->channel;
1298 if (test_bit(sas_device->handle, ioc->pd_handles))
1299 sas_target_priv_data->flags |=
1300 MPT_TARGET_FLAGS_RAID_COMPONENT;
1301 if (sas_device->fast_path)
1302 sas_target_priv_data->flags |= MPT_TARGET_FASTPATH_IO;
1303 }
1304 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1305
1306 return 0;
1307}
1308
1309/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301310 * scsih_target_destroy - target destroy routine
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301311 * @starget: scsi target struct
1312 *
1313 * Returns nothing.
1314 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07001315static void
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301316scsih_target_destroy(struct scsi_target *starget)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301317{
1318 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
1319 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
1320 struct MPT3SAS_TARGET *sas_target_priv_data;
1321 struct _sas_device *sas_device;
1322 struct _raid_device *raid_device;
1323 unsigned long flags;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301324
1325 sas_target_priv_data = starget->hostdata;
1326 if (!sas_target_priv_data)
1327 return;
1328
1329 if (starget->channel == RAID_CHANNEL) {
1330 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1331 raid_device = _scsih_raid_device_find_by_id(ioc, starget->id,
1332 starget->channel);
1333 if (raid_device) {
1334 raid_device->starget = NULL;
1335 raid_device->sdev = NULL;
1336 }
1337 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1338 goto out;
1339 }
1340
1341 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05301342 sas_device = __mpt3sas_get_sdev_from_target(ioc, sas_target_priv_data);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301343 if (sas_device && (sas_device->starget == starget) &&
1344 (sas_device->id == starget->id) &&
1345 (sas_device->channel == starget->channel))
1346 sas_device->starget = NULL;
1347
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05301348 if (sas_device) {
1349 /*
1350 * Corresponding get() is in _scsih_target_alloc()
1351 */
1352 sas_target_priv_data->sdev = NULL;
1353 sas_device_put(sas_device);
1354
1355 sas_device_put(sas_device);
1356 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301357 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1358
1359 out:
1360 kfree(sas_target_priv_data);
1361 starget->hostdata = NULL;
1362}
1363
1364/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301365 * scsih_slave_alloc - device add routine
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301366 * @sdev: scsi device struct
1367 *
1368 * Returns 0 if ok. Any other return is assumed to be an error and
1369 * the device is ignored.
1370 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07001371static int
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301372scsih_slave_alloc(struct scsi_device *sdev)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301373{
1374 struct Scsi_Host *shost;
1375 struct MPT3SAS_ADAPTER *ioc;
1376 struct MPT3SAS_TARGET *sas_target_priv_data;
1377 struct MPT3SAS_DEVICE *sas_device_priv_data;
1378 struct scsi_target *starget;
1379 struct _raid_device *raid_device;
Sreekanth Reddyb65cfed2013-06-29 03:52:03 +05301380 struct _sas_device *sas_device;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301381 unsigned long flags;
1382
Joe Lawrence62c4da42014-06-25 17:04:22 -04001383 sas_device_priv_data = kzalloc(sizeof(*sas_device_priv_data),
1384 GFP_KERNEL);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301385 if (!sas_device_priv_data)
1386 return -ENOMEM;
1387
1388 sas_device_priv_data->lun = sdev->lun;
1389 sas_device_priv_data->flags = MPT_DEVICE_FLAGS_INIT;
1390
1391 starget = scsi_target(sdev);
1392 sas_target_priv_data = starget->hostdata;
1393 sas_target_priv_data->num_luns++;
1394 sas_device_priv_data->sas_target = sas_target_priv_data;
1395 sdev->hostdata = sas_device_priv_data;
1396 if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT))
1397 sdev->no_uld_attach = 1;
1398
1399 shost = dev_to_shost(&starget->dev);
1400 ioc = shost_priv(shost);
1401 if (starget->channel == RAID_CHANNEL) {
1402 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1403 raid_device = _scsih_raid_device_find_by_id(ioc,
1404 starget->id, starget->channel);
1405 if (raid_device)
1406 raid_device->sdev = sdev; /* raid is single lun */
1407 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1408 }
1409
Sreekanth Reddyb65cfed2013-06-29 03:52:03 +05301410 if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
1411 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05301412 sas_device = __mpt3sas_get_sdev_by_addr(ioc,
Sreekanth Reddyb65cfed2013-06-29 03:52:03 +05301413 sas_target_priv_data->sas_address);
1414 if (sas_device && (sas_device->starget == NULL)) {
1415 sdev_printk(KERN_INFO, sdev,
1416 "%s : sas_device->starget set to starget @ %d\n",
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05301417 __func__, __LINE__);
Sreekanth Reddyb65cfed2013-06-29 03:52:03 +05301418 sas_device->starget = starget;
1419 }
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05301420
1421 if (sas_device)
1422 sas_device_put(sas_device);
1423
Sreekanth Reddyb65cfed2013-06-29 03:52:03 +05301424 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1425 }
1426
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301427 return 0;
1428}
1429
1430/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301431 * scsih_slave_destroy - device destroy routine
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301432 * @sdev: scsi device struct
1433 *
1434 * Returns nothing.
1435 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07001436static void
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301437scsih_slave_destroy(struct scsi_device *sdev)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301438{
1439 struct MPT3SAS_TARGET *sas_target_priv_data;
1440 struct scsi_target *starget;
1441 struct Scsi_Host *shost;
1442 struct MPT3SAS_ADAPTER *ioc;
1443 struct _sas_device *sas_device;
1444 unsigned long flags;
1445
1446 if (!sdev->hostdata)
1447 return;
1448
1449 starget = scsi_target(sdev);
1450 sas_target_priv_data = starget->hostdata;
1451 sas_target_priv_data->num_luns--;
1452
1453 shost = dev_to_shost(&starget->dev);
1454 ioc = shost_priv(shost);
1455
1456 if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
1457 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05301458 sas_device = __mpt3sas_get_sdev_from_target(ioc,
1459 sas_target_priv_data);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301460 if (sas_device && !sas_target_priv_data->num_luns)
1461 sas_device->starget = NULL;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05301462
1463 if (sas_device)
1464 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301465 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1466 }
1467
1468 kfree(sdev->hostdata);
1469 sdev->hostdata = NULL;
1470}
1471
1472/**
1473 * _scsih_display_sata_capabilities - sata capabilities
1474 * @ioc: per adapter object
1475 * @handle: device handle
1476 * @sdev: scsi device struct
1477 */
1478static void
1479_scsih_display_sata_capabilities(struct MPT3SAS_ADAPTER *ioc,
1480 u16 handle, struct scsi_device *sdev)
1481{
1482 Mpi2ConfigReply_t mpi_reply;
1483 Mpi2SasDevicePage0_t sas_device_pg0;
1484 u32 ioc_status;
1485 u16 flags;
1486 u32 device_info;
1487
1488 if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
1489 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
1490 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1491 ioc->name, __FILE__, __LINE__, __func__);
1492 return;
1493 }
1494
1495 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1496 MPI2_IOCSTATUS_MASK;
1497 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1498 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1499 ioc->name, __FILE__, __LINE__, __func__);
1500 return;
1501 }
1502
1503 flags = le16_to_cpu(sas_device_pg0.Flags);
1504 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
1505
1506 sdev_printk(KERN_INFO, sdev,
1507 "atapi(%s), ncq(%s), asyn_notify(%s), smart(%s), fua(%s), "
1508 "sw_preserve(%s)\n",
1509 (device_info & MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE) ? "y" : "n",
1510 (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED) ? "y" : "n",
1511 (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY) ? "y" :
1512 "n",
1513 (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED) ? "y" : "n",
1514 (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED) ? "y" : "n",
1515 (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE) ? "y" : "n");
1516}
1517
1518/*
1519 * raid transport support -
1520 * Enabled for SLES11 and newer, in older kernels the driver will panic when
1521 * unloading the driver followed by a load - I beleive that the subroutine
1522 * raid_class_release() is not cleaning up properly.
1523 */
1524
1525/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301526 * scsih_is_raid - return boolean indicating device is raid volume
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301527 * @dev the device struct object
1528 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07001529static int
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301530scsih_is_raid(struct device *dev)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301531{
1532 struct scsi_device *sdev = to_scsi_device(dev);
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05301533 struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301534
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05301535 if (ioc->is_warpdrive)
1536 return 0;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301537 return (sdev->channel == RAID_CHANNEL) ? 1 : 0;
1538}
1539
1540/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301541 * scsih_get_resync - get raid volume resync percent complete
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301542 * @dev the device struct object
1543 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07001544static void
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301545scsih_get_resync(struct device *dev)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301546{
1547 struct scsi_device *sdev = to_scsi_device(dev);
1548 struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host);
1549 static struct _raid_device *raid_device;
1550 unsigned long flags;
1551 Mpi2RaidVolPage0_t vol_pg0;
1552 Mpi2ConfigReply_t mpi_reply;
1553 u32 volume_status_flags;
1554 u8 percent_complete;
1555 u16 handle;
1556
1557 percent_complete = 0;
1558 handle = 0;
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05301559 if (ioc->is_warpdrive)
1560 goto out;
1561
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301562 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1563 raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
1564 sdev->channel);
1565 if (raid_device) {
1566 handle = raid_device->handle;
1567 percent_complete = raid_device->percent_complete;
1568 }
1569 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1570
1571 if (!handle)
1572 goto out;
1573
1574 if (mpt3sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
1575 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
1576 sizeof(Mpi2RaidVolPage0_t))) {
1577 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1578 ioc->name, __FILE__, __LINE__, __func__);
1579 percent_complete = 0;
1580 goto out;
1581 }
1582
1583 volume_status_flags = le32_to_cpu(vol_pg0.VolumeStatusFlags);
1584 if (!(volume_status_flags &
1585 MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS))
1586 percent_complete = 0;
1587
1588 out:
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05301589
1590 switch (ioc->hba_mpi_version_belonged) {
1591 case MPI2_VERSION:
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05301592 raid_set_resync(mpt2sas_raid_template, dev, percent_complete);
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05301593 break;
1594 case MPI25_VERSION:
1595 case MPI26_VERSION:
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05301596 raid_set_resync(mpt3sas_raid_template, dev, percent_complete);
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05301597 break;
1598 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301599}
1600
1601/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301602 * scsih_get_state - get raid volume level
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301603 * @dev the device struct object
1604 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07001605static void
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301606scsih_get_state(struct device *dev)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301607{
1608 struct scsi_device *sdev = to_scsi_device(dev);
1609 struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host);
1610 static struct _raid_device *raid_device;
1611 unsigned long flags;
1612 Mpi2RaidVolPage0_t vol_pg0;
1613 Mpi2ConfigReply_t mpi_reply;
1614 u32 volstate;
1615 enum raid_state state = RAID_STATE_UNKNOWN;
1616 u16 handle = 0;
1617
1618 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1619 raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
1620 sdev->channel);
1621 if (raid_device)
1622 handle = raid_device->handle;
1623 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1624
1625 if (!raid_device)
1626 goto out;
1627
1628 if (mpt3sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
1629 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
1630 sizeof(Mpi2RaidVolPage0_t))) {
1631 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1632 ioc->name, __FILE__, __LINE__, __func__);
1633 goto out;
1634 }
1635
1636 volstate = le32_to_cpu(vol_pg0.VolumeStatusFlags);
1637 if (volstate & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) {
1638 state = RAID_STATE_RESYNCING;
1639 goto out;
1640 }
1641
1642 switch (vol_pg0.VolumeState) {
1643 case MPI2_RAID_VOL_STATE_OPTIMAL:
1644 case MPI2_RAID_VOL_STATE_ONLINE:
1645 state = RAID_STATE_ACTIVE;
1646 break;
1647 case MPI2_RAID_VOL_STATE_DEGRADED:
1648 state = RAID_STATE_DEGRADED;
1649 break;
1650 case MPI2_RAID_VOL_STATE_FAILED:
1651 case MPI2_RAID_VOL_STATE_MISSING:
1652 state = RAID_STATE_OFFLINE;
1653 break;
1654 }
1655 out:
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05301656 switch (ioc->hba_mpi_version_belonged) {
1657 case MPI2_VERSION:
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05301658 raid_set_state(mpt2sas_raid_template, dev, state);
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05301659 break;
1660 case MPI25_VERSION:
1661 case MPI26_VERSION:
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05301662 raid_set_state(mpt3sas_raid_template, dev, state);
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05301663 break;
1664 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301665}
1666
1667/**
1668 * _scsih_set_level - set raid level
1669 * @sdev: scsi device struct
1670 * @volume_type: volume type
1671 */
1672static void
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05301673_scsih_set_level(struct MPT3SAS_ADAPTER *ioc,
1674 struct scsi_device *sdev, u8 volume_type)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301675{
1676 enum raid_level level = RAID_LEVEL_UNKNOWN;
1677
1678 switch (volume_type) {
1679 case MPI2_RAID_VOL_TYPE_RAID0:
1680 level = RAID_LEVEL_0;
1681 break;
1682 case MPI2_RAID_VOL_TYPE_RAID10:
1683 level = RAID_LEVEL_10;
1684 break;
1685 case MPI2_RAID_VOL_TYPE_RAID1E:
1686 level = RAID_LEVEL_1E;
1687 break;
1688 case MPI2_RAID_VOL_TYPE_RAID1:
1689 level = RAID_LEVEL_1;
1690 break;
1691 }
1692
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05301693 switch (ioc->hba_mpi_version_belonged) {
1694 case MPI2_VERSION:
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05301695 raid_set_level(mpt2sas_raid_template,
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05301696 &sdev->sdev_gendev, level);
1697 break;
1698 case MPI25_VERSION:
1699 case MPI26_VERSION:
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05301700 raid_set_level(mpt3sas_raid_template,
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05301701 &sdev->sdev_gendev, level);
1702 break;
1703 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301704}
1705
1706
1707/**
1708 * _scsih_get_volume_capabilities - volume capabilities
1709 * @ioc: per adapter object
1710 * @sas_device: the raid_device object
1711 *
1712 * Returns 0 for success, else 1
1713 */
1714static int
1715_scsih_get_volume_capabilities(struct MPT3SAS_ADAPTER *ioc,
1716 struct _raid_device *raid_device)
1717{
1718 Mpi2RaidVolPage0_t *vol_pg0;
1719 Mpi2RaidPhysDiskPage0_t pd_pg0;
1720 Mpi2SasDevicePage0_t sas_device_pg0;
1721 Mpi2ConfigReply_t mpi_reply;
1722 u16 sz;
1723 u8 num_pds;
1724
1725 if ((mpt3sas_config_get_number_pds(ioc, raid_device->handle,
1726 &num_pds)) || !num_pds) {
1727 dfailprintk(ioc, pr_warn(MPT3SAS_FMT
1728 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
1729 __func__));
1730 return 1;
1731 }
1732
1733 raid_device->num_pds = num_pds;
1734 sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds *
1735 sizeof(Mpi2RaidVol0PhysDisk_t));
1736 vol_pg0 = kzalloc(sz, GFP_KERNEL);
1737 if (!vol_pg0) {
1738 dfailprintk(ioc, pr_warn(MPT3SAS_FMT
1739 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
1740 __func__));
1741 return 1;
1742 }
1743
1744 if ((mpt3sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0,
1745 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) {
1746 dfailprintk(ioc, pr_warn(MPT3SAS_FMT
1747 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
1748 __func__));
1749 kfree(vol_pg0);
1750 return 1;
1751 }
1752
1753 raid_device->volume_type = vol_pg0->VolumeType;
1754
1755 /* figure out what the underlying devices are by
1756 * obtaining the device_info bits for the 1st device
1757 */
1758 if (!(mpt3sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
1759 &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM,
1760 vol_pg0->PhysDisk[0].PhysDiskNum))) {
1761 if (!(mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply,
1762 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
1763 le16_to_cpu(pd_pg0.DevHandle)))) {
1764 raid_device->device_info =
1765 le32_to_cpu(sas_device_pg0.DeviceInfo);
1766 }
1767 }
1768
1769 kfree(vol_pg0);
1770 return 0;
1771}
1772
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301773/**
1774 * _scsih_enable_tlr - setting TLR flags
1775 * @ioc: per adapter object
1776 * @sdev: scsi device struct
1777 *
1778 * Enabling Transaction Layer Retries for tape devices when
1779 * vpd page 0x90 is present
1780 *
1781 */
1782static void
1783_scsih_enable_tlr(struct MPT3SAS_ADAPTER *ioc, struct scsi_device *sdev)
1784{
1785
1786 /* only for TAPE */
1787 if (sdev->type != TYPE_TAPE)
1788 return;
1789
1790 if (!(ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR))
1791 return;
1792
1793 sas_enable_tlr(sdev);
1794 sdev_printk(KERN_INFO, sdev, "TLR %s\n",
1795 sas_is_tlr_enabled(sdev) ? "Enabled" : "Disabled");
1796 return;
1797
1798}
1799
1800/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301801 * scsih_slave_configure - device configure routine.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301802 * @sdev: scsi device struct
1803 *
1804 * Returns 0 if ok. Any other return is assumed to be an error and
1805 * the device is ignored.
1806 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07001807static int
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301808scsih_slave_configure(struct scsi_device *sdev)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301809{
1810 struct Scsi_Host *shost = sdev->host;
1811 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
1812 struct MPT3SAS_DEVICE *sas_device_priv_data;
1813 struct MPT3SAS_TARGET *sas_target_priv_data;
1814 struct _sas_device *sas_device;
1815 struct _raid_device *raid_device;
1816 unsigned long flags;
1817 int qdepth;
1818 u8 ssp_target = 0;
1819 char *ds = "";
1820 char *r_level = "";
1821 u16 handle, volume_handle = 0;
1822 u64 volume_wwid = 0;
1823
1824 qdepth = 1;
1825 sas_device_priv_data = sdev->hostdata;
1826 sas_device_priv_data->configured_lun = 1;
1827 sas_device_priv_data->flags &= ~MPT_DEVICE_FLAGS_INIT;
1828 sas_target_priv_data = sas_device_priv_data->sas_target;
1829 handle = sas_target_priv_data->handle;
1830
1831 /* raid volume handling */
1832 if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME) {
1833
1834 spin_lock_irqsave(&ioc->raid_device_lock, flags);
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05301835 raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301836 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1837 if (!raid_device) {
1838 dfailprintk(ioc, pr_warn(MPT3SAS_FMT
1839 "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
1840 __LINE__, __func__));
1841 return 1;
1842 }
1843
1844 if (_scsih_get_volume_capabilities(ioc, raid_device)) {
1845 dfailprintk(ioc, pr_warn(MPT3SAS_FMT
1846 "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
1847 __LINE__, __func__));
1848 return 1;
1849 }
1850
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05301851 /*
1852 * WARPDRIVE: Initialize the required data for Direct IO
1853 */
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05301854 mpt3sas_init_warpdrive_properties(ioc, raid_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301855
1856 /* RAID Queue Depth Support
1857 * IS volume = underlying qdepth of drive type, either
1858 * MPT3SAS_SAS_QUEUE_DEPTH or MPT3SAS_SATA_QUEUE_DEPTH
1859 * IM/IME/R10 = 128 (MPT3SAS_RAID_QUEUE_DEPTH)
1860 */
1861 if (raid_device->device_info &
1862 MPI2_SAS_DEVICE_INFO_SSP_TARGET) {
1863 qdepth = MPT3SAS_SAS_QUEUE_DEPTH;
1864 ds = "SSP";
1865 } else {
1866 qdepth = MPT3SAS_SATA_QUEUE_DEPTH;
1867 if (raid_device->device_info &
1868 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
1869 ds = "SATA";
1870 else
1871 ds = "STP";
1872 }
1873
1874 switch (raid_device->volume_type) {
1875 case MPI2_RAID_VOL_TYPE_RAID0:
1876 r_level = "RAID0";
1877 break;
1878 case MPI2_RAID_VOL_TYPE_RAID1E:
1879 qdepth = MPT3SAS_RAID_QUEUE_DEPTH;
1880 if (ioc->manu_pg10.OEMIdentifier &&
1881 (le32_to_cpu(ioc->manu_pg10.GenericFlags0) &
1882 MFG10_GF0_R10_DISPLAY) &&
1883 !(raid_device->num_pds % 2))
1884 r_level = "RAID10";
1885 else
1886 r_level = "RAID1E";
1887 break;
1888 case MPI2_RAID_VOL_TYPE_RAID1:
1889 qdepth = MPT3SAS_RAID_QUEUE_DEPTH;
1890 r_level = "RAID1";
1891 break;
1892 case MPI2_RAID_VOL_TYPE_RAID10:
1893 qdepth = MPT3SAS_RAID_QUEUE_DEPTH;
1894 r_level = "RAID10";
1895 break;
1896 case MPI2_RAID_VOL_TYPE_UNKNOWN:
1897 default:
1898 qdepth = MPT3SAS_RAID_QUEUE_DEPTH;
1899 r_level = "RAIDX";
1900 break;
1901 }
1902
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05301903 if (!ioc->hide_ir_msg)
1904 sdev_printk(KERN_INFO, sdev,
1905 "%s: handle(0x%04x), wwid(0x%016llx),"
1906 " pd_count(%d), type(%s)\n",
1907 r_level, raid_device->handle,
1908 (unsigned long long)raid_device->wwid,
1909 raid_device->num_pds, ds);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301910
Chaitra P B6c197092016-05-06 14:29:30 +05301911 if (shost->max_sectors > MPT3SAS_RAID_MAX_SECTORS) {
1912 blk_queue_max_hw_sectors(sdev->request_queue,
1913 MPT3SAS_RAID_MAX_SECTORS);
1914 sdev_printk(KERN_INFO, sdev,
1915 "Set queue's max_sector to: %u\n",
1916 MPT3SAS_RAID_MAX_SECTORS);
1917 }
1918
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05301919 scsih_change_queue_depth(sdev, qdepth);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301920
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05301921 /* raid transport support */
1922 if (!ioc->is_warpdrive)
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05301923 _scsih_set_level(ioc, sdev, raid_device->volume_type);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301924 return 0;
1925 }
1926
1927 /* non-raid handling */
1928 if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1929 if (mpt3sas_config_get_volume_handle(ioc, handle,
1930 &volume_handle)) {
1931 dfailprintk(ioc, pr_warn(MPT3SAS_FMT
1932 "failure at %s:%d/%s()!\n", ioc->name,
1933 __FILE__, __LINE__, __func__));
1934 return 1;
1935 }
1936 if (volume_handle && mpt3sas_config_get_volume_wwid(ioc,
1937 volume_handle, &volume_wwid)) {
1938 dfailprintk(ioc, pr_warn(MPT3SAS_FMT
1939 "failure at %s:%d/%s()!\n", ioc->name,
1940 __FILE__, __LINE__, __func__));
1941 return 1;
1942 }
1943 }
1944
1945 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05301946 sas_device = __mpt3sas_get_sdev_by_addr(ioc,
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301947 sas_device_priv_data->sas_target->sas_address);
1948 if (!sas_device) {
1949 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1950 dfailprintk(ioc, pr_warn(MPT3SAS_FMT
1951 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
1952 __func__));
1953 return 1;
1954 }
1955
1956 sas_device->volume_handle = volume_handle;
1957 sas_device->volume_wwid = volume_wwid;
1958 if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) {
1959 qdepth = MPT3SAS_SAS_QUEUE_DEPTH;
1960 ssp_target = 1;
Suganath prabu Subramani30158dc2016-01-28 12:07:01 +05301961 if (sas_device->device_info &
1962 MPI2_SAS_DEVICE_INFO_SEP) {
1963 sdev_printk(KERN_WARNING, sdev,
1964 "set ignore_delay_remove for handle(0x%04x)\n",
1965 sas_device_priv_data->sas_target->handle);
1966 sas_device_priv_data->ignore_delay_remove = 1;
1967 ds = "SES";
1968 } else
1969 ds = "SSP";
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301970 } else {
1971 qdepth = MPT3SAS_SATA_QUEUE_DEPTH;
1972 if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET)
1973 ds = "STP";
1974 else if (sas_device->device_info &
1975 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
1976 ds = "SATA";
1977 }
1978
1979 sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), " \
1980 "sas_addr(0x%016llx), phy(%d), device_name(0x%016llx)\n",
1981 ds, handle, (unsigned long long)sas_device->sas_address,
1982 sas_device->phy, (unsigned long long)sas_device->device_name);
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05301983 if (sas_device->enclosure_handle != 0)
1984 sdev_printk(KERN_INFO, sdev,
1985 "%s: enclosure_logical_id(0x%016llx), slot(%d)\n",
1986 ds, (unsigned long long)
1987 sas_device->enclosure_logical_id, sas_device->slot);
1988 if (sas_device->connector_name[0] != '\0')
1989 sdev_printk(KERN_INFO, sdev,
1990 "%s: enclosure level(0x%04x), connector name( %s)\n",
1991 ds, sas_device->enclosure_level,
1992 sas_device->connector_name);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301993
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05301994 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301995 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1996
1997 if (!ssp_target)
1998 _scsih_display_sata_capabilities(ioc, handle, sdev);
1999
2000
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05302001 scsih_change_queue_depth(sdev, qdepth);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302002
2003 if (ssp_target) {
2004 sas_read_port_mode_page(sdev);
2005 _scsih_enable_tlr(ioc, sdev);
2006 }
2007
2008 return 0;
2009}
2010
2011/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05302012 * scsih_bios_param - fetch head, sector, cylinder info for a disk
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302013 * @sdev: scsi device struct
2014 * @bdev: pointer to block device context
2015 * @capacity: device size (in 512 byte sectors)
2016 * @params: three element array to place output:
2017 * params[0] number of heads (max 255)
2018 * params[1] number of sectors (max 63)
2019 * params[2] number of cylinders
2020 *
2021 * Return nothing.
2022 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07002023static int
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05302024scsih_bios_param(struct scsi_device *sdev, struct block_device *bdev,
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302025 sector_t capacity, int params[])
2026{
2027 int heads;
2028 int sectors;
2029 sector_t cylinders;
2030 ulong dummy;
2031
2032 heads = 64;
2033 sectors = 32;
2034
2035 dummy = heads * sectors;
2036 cylinders = capacity;
2037 sector_div(cylinders, dummy);
2038
2039 /*
2040 * Handle extended translation size for logical drives
2041 * > 1Gb
2042 */
2043 if ((ulong)capacity >= 0x200000) {
2044 heads = 255;
2045 sectors = 63;
2046 dummy = heads * sectors;
2047 cylinders = capacity;
2048 sector_div(cylinders, dummy);
2049 }
2050
2051 /* return result */
2052 params[0] = heads;
2053 params[1] = sectors;
2054 params[2] = cylinders;
2055
2056 return 0;
2057}
2058
2059/**
2060 * _scsih_response_code - translation of device response code
2061 * @ioc: per adapter object
2062 * @response_code: response code returned by the device
2063 *
2064 * Return nothing.
2065 */
2066static void
2067_scsih_response_code(struct MPT3SAS_ADAPTER *ioc, u8 response_code)
2068{
2069 char *desc;
2070
2071 switch (response_code) {
2072 case MPI2_SCSITASKMGMT_RSP_TM_COMPLETE:
2073 desc = "task management request completed";
2074 break;
2075 case MPI2_SCSITASKMGMT_RSP_INVALID_FRAME:
2076 desc = "invalid frame";
2077 break;
2078 case MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2079 desc = "task management request not supported";
2080 break;
2081 case MPI2_SCSITASKMGMT_RSP_TM_FAILED:
2082 desc = "task management request failed";
2083 break;
2084 case MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2085 desc = "task management request succeeded";
2086 break;
2087 case MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2088 desc = "invalid lun";
2089 break;
2090 case 0xA:
2091 desc = "overlapped tag attempted";
2092 break;
2093 case MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2094 desc = "task queued, however not sent to target";
2095 break;
2096 default:
2097 desc = "unknown";
2098 break;
2099 }
2100 pr_warn(MPT3SAS_FMT "response_code(0x%01x): %s\n",
2101 ioc->name, response_code, desc);
2102}
2103
2104/**
2105 * _scsih_tm_done - tm completion routine
2106 * @ioc: per adapter object
2107 * @smid: system request message index
2108 * @msix_index: MSIX table index supplied by the OS
2109 * @reply: reply message frame(lower 32bit addr)
2110 * Context: none.
2111 *
2112 * The callback handler when using scsih_issue_tm.
2113 *
2114 * Return 1 meaning mf should be freed from _base_interrupt
2115 * 0 means the mf is freed from this function.
2116 */
2117static u8
2118_scsih_tm_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
2119{
2120 MPI2DefaultReply_t *mpi_reply;
2121
2122 if (ioc->tm_cmds.status == MPT3_CMD_NOT_USED)
2123 return 1;
2124 if (ioc->tm_cmds.smid != smid)
2125 return 1;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302126 ioc->tm_cmds.status |= MPT3_CMD_COMPLETE;
2127 mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
2128 if (mpi_reply) {
2129 memcpy(ioc->tm_cmds.reply, mpi_reply, mpi_reply->MsgLength*4);
2130 ioc->tm_cmds.status |= MPT3_CMD_REPLY_VALID;
2131 }
2132 ioc->tm_cmds.status &= ~MPT3_CMD_PENDING;
2133 complete(&ioc->tm_cmds.done);
2134 return 1;
2135}
2136
2137/**
2138 * mpt3sas_scsih_set_tm_flag - set per target tm_busy
2139 * @ioc: per adapter object
2140 * @handle: device handle
2141 *
2142 * During taskmangement request, we need to freeze the device queue.
2143 */
2144void
2145mpt3sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle)
2146{
2147 struct MPT3SAS_DEVICE *sas_device_priv_data;
2148 struct scsi_device *sdev;
2149 u8 skip = 0;
2150
2151 shost_for_each_device(sdev, ioc->shost) {
2152 if (skip)
2153 continue;
2154 sas_device_priv_data = sdev->hostdata;
2155 if (!sas_device_priv_data)
2156 continue;
2157 if (sas_device_priv_data->sas_target->handle == handle) {
2158 sas_device_priv_data->sas_target->tm_busy = 1;
2159 skip = 1;
2160 ioc->ignore_loginfos = 1;
2161 }
2162 }
2163}
2164
2165/**
2166 * mpt3sas_scsih_clear_tm_flag - clear per target tm_busy
2167 * @ioc: per adapter object
2168 * @handle: device handle
2169 *
2170 * During taskmangement request, we need to freeze the device queue.
2171 */
2172void
2173mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle)
2174{
2175 struct MPT3SAS_DEVICE *sas_device_priv_data;
2176 struct scsi_device *sdev;
2177 u8 skip = 0;
2178
2179 shost_for_each_device(sdev, ioc->shost) {
2180 if (skip)
2181 continue;
2182 sas_device_priv_data = sdev->hostdata;
2183 if (!sas_device_priv_data)
2184 continue;
2185 if (sas_device_priv_data->sas_target->handle == handle) {
2186 sas_device_priv_data->sas_target->tm_busy = 0;
2187 skip = 1;
2188 ioc->ignore_loginfos = 0;
2189 }
2190 }
2191}
2192
2193/**
2194 * mpt3sas_scsih_issue_tm - main routine for sending tm requests
2195 * @ioc: per adapter struct
2196 * @device_handle: device handle
2197 * @channel: the channel assigned by the OS
2198 * @id: the id assigned by the OS
2199 * @lun: lun number
2200 * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
2201 * @smid_task: smid assigned to the task
2202 * @timeout: timeout in seconds
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302203 * Context: user
2204 *
2205 * A generic API for sending task management requests to firmware.
2206 *
2207 * The callback index is set inside `ioc->tm_cb_idx`.
2208 *
2209 * Return SUCCESS or FAILED.
2210 */
2211int
2212mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
Calvin Owens96902832016-07-28 21:38:20 -07002213 uint id, uint lun, u8 type, u16 smid_task, ulong timeout)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302214{
2215 Mpi2SCSITaskManagementRequest_t *mpi_request;
2216 Mpi2SCSITaskManagementReply_t *mpi_reply;
2217 u16 smid = 0;
2218 u32 ioc_state;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302219 struct scsiio_tracker *scsi_lookup = NULL;
2220 int rc;
Suganath prabu Subramani03d1fb32016-01-28 12:07:06 +05302221 u16 msix_task = 0;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302222
Calvin Owens96902832016-07-28 21:38:20 -07002223 lockdep_assert_held(&ioc->tm_cmds.mutex);
2224
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302225 if (ioc->tm_cmds.status != MPT3_CMD_NOT_USED) {
2226 pr_info(MPT3SAS_FMT "%s: tm_cmd busy!!!\n",
2227 __func__, ioc->name);
Calvin Owens96902832016-07-28 21:38:20 -07002228 return FAILED;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302229 }
2230
2231 if (ioc->shost_recovery || ioc->remove_host ||
2232 ioc->pci_error_recovery) {
2233 pr_info(MPT3SAS_FMT "%s: host reset in progress!\n",
2234 __func__, ioc->name);
Calvin Owens96902832016-07-28 21:38:20 -07002235 return FAILED;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302236 }
2237
2238 ioc_state = mpt3sas_base_get_iocstate(ioc, 0);
2239 if (ioc_state & MPI2_DOORBELL_USED) {
2240 dhsprintk(ioc, pr_info(MPT3SAS_FMT
2241 "unexpected doorbell active!\n", ioc->name));
Calvin Owens98c56ad2016-07-28 21:38:21 -07002242 rc = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
Calvin Owens96902832016-07-28 21:38:20 -07002243 return (!rc) ? SUCCESS : FAILED;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302244 }
2245
2246 if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
2247 mpt3sas_base_fault_info(ioc, ioc_state &
2248 MPI2_DOORBELL_DATA_MASK);
Calvin Owens98c56ad2016-07-28 21:38:21 -07002249 rc = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
Calvin Owens96902832016-07-28 21:38:20 -07002250 return (!rc) ? SUCCESS : FAILED;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302251 }
2252
2253 smid = mpt3sas_base_get_smid_hpr(ioc, ioc->tm_cb_idx);
2254 if (!smid) {
2255 pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
2256 ioc->name, __func__);
Calvin Owens96902832016-07-28 21:38:20 -07002257 return FAILED;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302258 }
2259
2260 if (type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2261 scsi_lookup = &ioc->scsi_lookup[smid_task - 1];
2262
2263 dtmprintk(ioc, pr_info(MPT3SAS_FMT
2264 "sending tm: handle(0x%04x), task_type(0x%02x), smid(%d)\n",
2265 ioc->name, handle, type, smid_task));
2266 ioc->tm_cmds.status = MPT3_CMD_PENDING;
2267 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
2268 ioc->tm_cmds.smid = smid;
2269 memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
2270 memset(ioc->tm_cmds.reply, 0, sizeof(Mpi2SCSITaskManagementReply_t));
2271 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
2272 mpi_request->DevHandle = cpu_to_le16(handle);
2273 mpi_request->TaskType = type;
2274 mpi_request->TaskMID = cpu_to_le16(smid_task);
2275 int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
2276 mpt3sas_scsih_set_tm_flag(ioc, handle);
2277 init_completion(&ioc->tm_cmds.done);
Suganath prabu Subramani03d1fb32016-01-28 12:07:06 +05302278 if ((type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK) &&
2279 (scsi_lookup->msix_io < ioc->reply_queue_count))
2280 msix_task = scsi_lookup->msix_io;
2281 else
2282 msix_task = 0;
2283 mpt3sas_base_put_smid_hi_priority(ioc, smid, msix_task);
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07002284 wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302285 if (!(ioc->tm_cmds.status & MPT3_CMD_COMPLETE)) {
2286 pr_err(MPT3SAS_FMT "%s: timeout\n",
2287 ioc->name, __func__);
2288 _debug_dump_mf(mpi_request,
2289 sizeof(Mpi2SCSITaskManagementRequest_t)/4);
2290 if (!(ioc->tm_cmds.status & MPT3_CMD_RESET)) {
Calvin Owens98c56ad2016-07-28 21:38:21 -07002291 rc = mpt3sas_base_hard_reset_handler(ioc,
2292 FORCE_BIG_HAMMER);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302293 rc = (!rc) ? SUCCESS : FAILED;
Calvin Owens96902832016-07-28 21:38:20 -07002294 goto out;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302295 }
2296 }
2297
Chaitra P B5f0dfb72016-05-06 14:29:31 +05302298 /* sync IRQs in case those were busy during flush. */
2299 mpt3sas_base_sync_reply_irqs(ioc);
2300
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302301 if (ioc->tm_cmds.status & MPT3_CMD_REPLY_VALID) {
2302 mpt3sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT);
2303 mpi_reply = ioc->tm_cmds.reply;
2304 dtmprintk(ioc, pr_info(MPT3SAS_FMT "complete tm: " \
2305 "ioc_status(0x%04x), loginfo(0x%08x), term_count(0x%08x)\n",
2306 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
2307 le32_to_cpu(mpi_reply->IOCLogInfo),
2308 le32_to_cpu(mpi_reply->TerminationCount)));
2309 if (ioc->logging_level & MPT_DEBUG_TM) {
2310 _scsih_response_code(ioc, mpi_reply->ResponseCode);
2311 if (mpi_reply->IOCStatus)
2312 _debug_dump_mf(mpi_request,
2313 sizeof(Mpi2SCSITaskManagementRequest_t)/4);
2314 }
2315 }
2316
2317 switch (type) {
2318 case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
2319 rc = SUCCESS;
2320 if (scsi_lookup->scmd == NULL)
2321 break;
2322 rc = FAILED;
2323 break;
2324
2325 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
2326 if (_scsih_scsi_lookup_find_by_target(ioc, id, channel))
2327 rc = FAILED;
2328 else
2329 rc = SUCCESS;
2330 break;
2331 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
2332 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
2333 if (_scsih_scsi_lookup_find_by_lun(ioc, id, lun, channel))
2334 rc = FAILED;
2335 else
2336 rc = SUCCESS;
2337 break;
2338 case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK:
2339 rc = SUCCESS;
2340 break;
2341 default:
2342 rc = FAILED;
2343 break;
2344 }
2345
Calvin Owens96902832016-07-28 21:38:20 -07002346out:
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302347 mpt3sas_scsih_clear_tm_flag(ioc, handle);
2348 ioc->tm_cmds.status = MPT3_CMD_NOT_USED;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302349 return rc;
Calvin Owens96902832016-07-28 21:38:20 -07002350}
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302351
Calvin Owens96902832016-07-28 21:38:20 -07002352int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
2353 uint channel, uint id, uint lun, u8 type, u16 smid_task, ulong timeout)
2354{
2355 int ret;
2356
2357 mutex_lock(&ioc->tm_cmds.mutex);
2358 ret = mpt3sas_scsih_issue_tm(ioc, handle, channel, id, lun, type,
2359 smid_task, timeout);
2360 mutex_unlock(&ioc->tm_cmds.mutex);
2361
2362 return ret;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302363}
2364
2365/**
2366 * _scsih_tm_display_info - displays info about the device
2367 * @ioc: per adapter struct
2368 * @scmd: pointer to scsi command object
2369 *
2370 * Called by task management callback handlers.
2371 */
2372static void
2373_scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd)
2374{
2375 struct scsi_target *starget = scmd->device->sdev_target;
2376 struct MPT3SAS_TARGET *priv_target = starget->hostdata;
2377 struct _sas_device *sas_device = NULL;
2378 unsigned long flags;
2379 char *device_str = NULL;
2380
2381 if (!priv_target)
2382 return;
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05302383 if (ioc->hide_ir_msg)
2384 device_str = "WarpDrive";
2385 else
2386 device_str = "volume";
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302387
2388 scsi_print_command(scmd);
2389 if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
2390 starget_printk(KERN_INFO, starget,
2391 "%s handle(0x%04x), %s wwid(0x%016llx)\n",
2392 device_str, priv_target->handle,
2393 device_str, (unsigned long long)priv_target->sas_address);
2394 } else {
2395 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05302396 sas_device = __mpt3sas_get_sdev_from_target(ioc, priv_target);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302397 if (sas_device) {
2398 if (priv_target->flags &
2399 MPT_TARGET_FLAGS_RAID_COMPONENT) {
2400 starget_printk(KERN_INFO, starget,
2401 "volume handle(0x%04x), "
2402 "volume wwid(0x%016llx)\n",
2403 sas_device->volume_handle,
2404 (unsigned long long)sas_device->volume_wwid);
2405 }
2406 starget_printk(KERN_INFO, starget,
2407 "handle(0x%04x), sas_address(0x%016llx), phy(%d)\n",
2408 sas_device->handle,
2409 (unsigned long long)sas_device->sas_address,
2410 sas_device->phy);
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05302411 if (sas_device->enclosure_handle != 0)
2412 starget_printk(KERN_INFO, starget,
2413 "enclosure_logical_id(0x%016llx), slot(%d)\n",
2414 (unsigned long long)
2415 sas_device->enclosure_logical_id,
2416 sas_device->slot);
Suganath prabu Subramani869817f2016-01-28 12:07:00 +05302417 if (sas_device->connector_name[0] != '\0')
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05302418 starget_printk(KERN_INFO, starget,
2419 "enclosure level(0x%04x),connector name(%s)\n",
2420 sas_device->enclosure_level,
2421 sas_device->connector_name);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05302422
2423 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302424 }
2425 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2426 }
2427}
2428
2429/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05302430 * scsih_abort - eh threads main abort routine
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302431 * @scmd: pointer to scsi command object
2432 *
2433 * Returns SUCCESS if command aborted else FAILED
2434 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07002435static int
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05302436scsih_abort(struct scsi_cmnd *scmd)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302437{
2438 struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
2439 struct MPT3SAS_DEVICE *sas_device_priv_data;
2440 u16 smid;
2441 u16 handle;
2442 int r;
2443
2444 sdev_printk(KERN_INFO, scmd->device,
2445 "attempting task abort! scmd(%p)\n", scmd);
2446 _scsih_tm_display_info(ioc, scmd);
2447
2448 sas_device_priv_data = scmd->device->hostdata;
2449 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
2450 sdev_printk(KERN_INFO, scmd->device,
2451 "device been deleted! scmd(%p)\n", scmd);
2452 scmd->result = DID_NO_CONNECT << 16;
2453 scmd->scsi_done(scmd);
2454 r = SUCCESS;
2455 goto out;
2456 }
2457
2458 /* search for the command */
2459 smid = _scsih_scsi_lookup_find_by_scmd(ioc, scmd);
2460 if (!smid) {
2461 scmd->result = DID_RESET << 16;
2462 r = SUCCESS;
2463 goto out;
2464 }
2465
2466 /* for hidden raid components and volumes this is not supported */
2467 if (sas_device_priv_data->sas_target->flags &
2468 MPT_TARGET_FLAGS_RAID_COMPONENT ||
2469 sas_device_priv_data->sas_target->flags & MPT_TARGET_FLAGS_VOLUME) {
2470 scmd->result = DID_RESET << 16;
2471 r = FAILED;
2472 goto out;
2473 }
2474
2475 mpt3sas_halt_firmware(ioc);
2476
2477 handle = sas_device_priv_data->sas_target->handle;
Calvin Owens96902832016-07-28 21:38:20 -07002478 r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel,
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302479 scmd->device->id, scmd->device->lun,
Calvin Owens96902832016-07-28 21:38:20 -07002480 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302481
2482 out:
2483 sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n",
2484 ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
2485 return r;
2486}
2487
2488/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05302489 * scsih_dev_reset - eh threads main device reset routine
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302490 * @scmd: pointer to scsi command object
2491 *
2492 * Returns SUCCESS if command aborted else FAILED
2493 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07002494static int
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05302495scsih_dev_reset(struct scsi_cmnd *scmd)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302496{
2497 struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
2498 struct MPT3SAS_DEVICE *sas_device_priv_data;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05302499 struct _sas_device *sas_device = NULL;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302500 u16 handle;
2501 int r;
2502
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05302503 struct scsi_target *starget = scmd->device->sdev_target;
2504 struct MPT3SAS_TARGET *target_priv_data = starget->hostdata;
2505
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302506 sdev_printk(KERN_INFO, scmd->device,
2507 "attempting device reset! scmd(%p)\n", scmd);
2508 _scsih_tm_display_info(ioc, scmd);
2509
2510 sas_device_priv_data = scmd->device->hostdata;
2511 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
2512 sdev_printk(KERN_INFO, scmd->device,
2513 "device been deleted! scmd(%p)\n", scmd);
2514 scmd->result = DID_NO_CONNECT << 16;
2515 scmd->scsi_done(scmd);
2516 r = SUCCESS;
2517 goto out;
2518 }
2519
2520 /* for hidden raid components obtain the volume_handle */
2521 handle = 0;
2522 if (sas_device_priv_data->sas_target->flags &
2523 MPT_TARGET_FLAGS_RAID_COMPONENT) {
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05302524 sas_device = mpt3sas_get_sdev_from_target(ioc,
2525 target_priv_data);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302526 if (sas_device)
2527 handle = sas_device->volume_handle;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302528 } else
2529 handle = sas_device_priv_data->sas_target->handle;
2530
2531 if (!handle) {
2532 scmd->result = DID_RESET << 16;
2533 r = FAILED;
2534 goto out;
2535 }
2536
Calvin Owens96902832016-07-28 21:38:20 -07002537 r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel,
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302538 scmd->device->id, scmd->device->lun,
Calvin Owens96902832016-07-28 21:38:20 -07002539 MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302540
2541 out:
2542 sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n",
2543 ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05302544
2545 if (sas_device)
2546 sas_device_put(sas_device);
2547
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302548 return r;
2549}
2550
2551/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05302552 * scsih_target_reset - eh threads main target reset routine
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302553 * @scmd: pointer to scsi command object
2554 *
2555 * Returns SUCCESS if command aborted else FAILED
2556 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07002557static int
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05302558scsih_target_reset(struct scsi_cmnd *scmd)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302559{
2560 struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
2561 struct MPT3SAS_DEVICE *sas_device_priv_data;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05302562 struct _sas_device *sas_device = NULL;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302563 u16 handle;
2564 int r;
2565 struct scsi_target *starget = scmd->device->sdev_target;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05302566 struct MPT3SAS_TARGET *target_priv_data = starget->hostdata;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302567
2568 starget_printk(KERN_INFO, starget, "attempting target reset! scmd(%p)\n",
2569 scmd);
2570 _scsih_tm_display_info(ioc, scmd);
2571
2572 sas_device_priv_data = scmd->device->hostdata;
2573 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
2574 starget_printk(KERN_INFO, starget, "target been deleted! scmd(%p)\n",
2575 scmd);
2576 scmd->result = DID_NO_CONNECT << 16;
2577 scmd->scsi_done(scmd);
2578 r = SUCCESS;
2579 goto out;
2580 }
2581
2582 /* for hidden raid components obtain the volume_handle */
2583 handle = 0;
2584 if (sas_device_priv_data->sas_target->flags &
2585 MPT_TARGET_FLAGS_RAID_COMPONENT) {
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05302586 sas_device = mpt3sas_get_sdev_from_target(ioc,
2587 target_priv_data);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302588 if (sas_device)
2589 handle = sas_device->volume_handle;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302590 } else
2591 handle = sas_device_priv_data->sas_target->handle;
2592
2593 if (!handle) {
2594 scmd->result = DID_RESET << 16;
2595 r = FAILED;
2596 goto out;
2597 }
2598
Calvin Owens96902832016-07-28 21:38:20 -07002599 r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel,
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302600 scmd->device->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
Calvin Owens96902832016-07-28 21:38:20 -07002601 30);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302602
2603 out:
2604 starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n",
2605 ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05302606
2607 if (sas_device)
2608 sas_device_put(sas_device);
2609
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302610 return r;
2611}
2612
2613
2614/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05302615 * scsih_host_reset - eh threads main host reset routine
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302616 * @scmd: pointer to scsi command object
2617 *
2618 * Returns SUCCESS if command aborted else FAILED
2619 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07002620static int
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05302621scsih_host_reset(struct scsi_cmnd *scmd)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302622{
2623 struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
2624 int r, retval;
2625
2626 pr_info(MPT3SAS_FMT "attempting host reset! scmd(%p)\n",
2627 ioc->name, scmd);
2628 scsi_print_command(scmd);
2629
Sreekanth Reddyddb588b2015-01-12 11:38:57 +05302630 if (ioc->is_driver_loading) {
2631 pr_info(MPT3SAS_FMT "Blocking the host reset\n",
2632 ioc->name);
2633 r = FAILED;
2634 goto out;
2635 }
2636
Calvin Owens98c56ad2016-07-28 21:38:21 -07002637 retval = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302638 r = (retval < 0) ? FAILED : SUCCESS;
Sreekanth Reddyddb588b2015-01-12 11:38:57 +05302639out:
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302640 pr_info(MPT3SAS_FMT "host reset: %s scmd(%p)\n",
2641 ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
2642
2643 return r;
2644}
2645
2646/**
2647 * _scsih_fw_event_add - insert and queue up fw_event
2648 * @ioc: per adapter object
2649 * @fw_event: object describing the event
2650 * Context: This function will acquire ioc->fw_event_lock.
2651 *
2652 * This adds the firmware event object into link list, then queues it up to
2653 * be processed from user context.
2654 *
2655 * Return nothing.
2656 */
2657static void
2658_scsih_fw_event_add(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
2659{
2660 unsigned long flags;
2661
2662 if (ioc->firmware_event_thread == NULL)
2663 return;
2664
2665 spin_lock_irqsave(&ioc->fw_event_lock, flags);
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302666 fw_event_work_get(fw_event);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302667 INIT_LIST_HEAD(&fw_event->list);
2668 list_add_tail(&fw_event->list, &ioc->fw_event_list);
2669 INIT_WORK(&fw_event->work, _firmware_event_work);
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302670 fw_event_work_get(fw_event);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302671 queue_work(ioc->firmware_event_thread, &fw_event->work);
2672 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2673}
2674
2675/**
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302676 * _scsih_fw_event_del_from_list - delete fw_event from the list
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302677 * @ioc: per adapter object
2678 * @fw_event: object describing the event
2679 * Context: This function will acquire ioc->fw_event_lock.
2680 *
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302681 * If the fw_event is on the fw_event_list, remove it and do a put.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302682 *
2683 * Return nothing.
2684 */
2685static void
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302686_scsih_fw_event_del_from_list(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302687 *fw_event)
2688{
2689 unsigned long flags;
2690
2691 spin_lock_irqsave(&ioc->fw_event_lock, flags);
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302692 if (!list_empty(&fw_event->list)) {
2693 list_del_init(&fw_event->list);
2694 fw_event_work_put(fw_event);
2695 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302696 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2697}
2698
2699
2700 /**
2701 * mpt3sas_send_trigger_data_event - send event for processing trigger data
2702 * @ioc: per adapter object
2703 * @event_data: trigger event data
2704 *
2705 * Return nothing.
2706 */
2707void
2708mpt3sas_send_trigger_data_event(struct MPT3SAS_ADAPTER *ioc,
2709 struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data)
2710{
2711 struct fw_event_work *fw_event;
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302712 u16 sz;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302713
2714 if (ioc->is_driver_loading)
2715 return;
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302716 sz = sizeof(*event_data);
2717 fw_event = alloc_fw_event_work(sz);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302718 if (!fw_event)
2719 return;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302720 fw_event->event = MPT3SAS_PROCESS_TRIGGER_DIAG;
2721 fw_event->ioc = ioc;
2722 memcpy(fw_event->event_data, event_data, sizeof(*event_data));
2723 _scsih_fw_event_add(ioc, fw_event);
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302724 fw_event_work_put(fw_event);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302725}
2726
2727/**
2728 * _scsih_error_recovery_delete_devices - remove devices not responding
2729 * @ioc: per adapter object
2730 *
2731 * Return nothing.
2732 */
2733static void
2734_scsih_error_recovery_delete_devices(struct MPT3SAS_ADAPTER *ioc)
2735{
2736 struct fw_event_work *fw_event;
2737
2738 if (ioc->is_driver_loading)
2739 return;
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302740 fw_event = alloc_fw_event_work(0);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302741 if (!fw_event)
2742 return;
2743 fw_event->event = MPT3SAS_REMOVE_UNRESPONDING_DEVICES;
2744 fw_event->ioc = ioc;
2745 _scsih_fw_event_add(ioc, fw_event);
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302746 fw_event_work_put(fw_event);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302747}
2748
2749/**
2750 * mpt3sas_port_enable_complete - port enable completed (fake event)
2751 * @ioc: per adapter object
2752 *
2753 * Return nothing.
2754 */
2755void
2756mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc)
2757{
2758 struct fw_event_work *fw_event;
2759
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302760 fw_event = alloc_fw_event_work(0);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302761 if (!fw_event)
2762 return;
2763 fw_event->event = MPT3SAS_PORT_ENABLE_COMPLETE;
2764 fw_event->ioc = ioc;
2765 _scsih_fw_event_add(ioc, fw_event);
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302766 fw_event_work_put(fw_event);
2767}
2768
2769static struct fw_event_work *dequeue_next_fw_event(struct MPT3SAS_ADAPTER *ioc)
2770{
2771 unsigned long flags;
2772 struct fw_event_work *fw_event = NULL;
2773
2774 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2775 if (!list_empty(&ioc->fw_event_list)) {
2776 fw_event = list_first_entry(&ioc->fw_event_list,
2777 struct fw_event_work, list);
2778 list_del_init(&fw_event->list);
2779 }
2780 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2781
2782 return fw_event;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302783}
2784
2785/**
2786 * _scsih_fw_event_cleanup_queue - cleanup event queue
2787 * @ioc: per adapter object
2788 *
2789 * Walk the firmware event queue, either killing timers, or waiting
2790 * for outstanding events to complete
2791 *
2792 * Return nothing.
2793 */
2794static void
2795_scsih_fw_event_cleanup_queue(struct MPT3SAS_ADAPTER *ioc)
2796{
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302797 struct fw_event_work *fw_event;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302798
2799 if (list_empty(&ioc->fw_event_list) ||
2800 !ioc->firmware_event_thread || in_interrupt())
2801 return;
2802
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302803 while ((fw_event = dequeue_next_fw_event(ioc))) {
2804 /*
2805 * Wait on the fw_event to complete. If this returns 1, then
2806 * the event was never executed, and we need a put for the
Joe Lawrenceb8ac0cc2016-04-18 10:50:12 -04002807 * reference the work had on the fw_event.
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302808 *
2809 * If it did execute, we wait for it to finish, and the put will
2810 * happen from _firmware_event_work()
2811 */
Joe Lawrenceb8ac0cc2016-04-18 10:50:12 -04002812 if (cancel_work_sync(&fw_event->work))
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05302813 fw_event_work_put(fw_event);
2814
2815 fw_event_work_put(fw_event);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302816 }
2817}
2818
2819/**
Sreekanth Reddydf838f92015-06-30 12:25:05 +05302820 * _scsih_internal_device_block - block the sdev device
2821 * @sdev: per device object
2822 * @sas_device_priv_data : per device driver private data
2823 *
2824 * make sure device is blocked without error, if not
2825 * print an error
2826 */
2827static void
2828_scsih_internal_device_block(struct scsi_device *sdev,
2829 struct MPT3SAS_DEVICE *sas_device_priv_data)
2830{
2831 int r = 0;
2832
2833 sdev_printk(KERN_INFO, sdev, "device_block, handle(0x%04x)\n",
2834 sas_device_priv_data->sas_target->handle);
2835 sas_device_priv_data->block = 1;
2836
2837 r = scsi_internal_device_block(sdev);
2838 if (r == -EINVAL)
2839 sdev_printk(KERN_WARNING, sdev,
2840 "device_block failed with return(%d) for handle(0x%04x)\n",
2841 sas_device_priv_data->sas_target->handle, r);
2842}
2843
2844/**
2845 * _scsih_internal_device_unblock - unblock the sdev device
2846 * @sdev: per device object
2847 * @sas_device_priv_data : per device driver private data
2848 * make sure device is unblocked without error, if not retry
2849 * by blocking and then unblocking
2850 */
2851
2852static void
2853_scsih_internal_device_unblock(struct scsi_device *sdev,
2854 struct MPT3SAS_DEVICE *sas_device_priv_data)
2855{
2856 int r = 0;
2857
2858 sdev_printk(KERN_WARNING, sdev, "device_unblock and setting to running, "
2859 "handle(0x%04x)\n", sas_device_priv_data->sas_target->handle);
2860 sas_device_priv_data->block = 0;
2861 r = scsi_internal_device_unblock(sdev, SDEV_RUNNING);
2862 if (r == -EINVAL) {
2863 /* The device has been set to SDEV_RUNNING by SD layer during
2864 * device addition but the request queue is still stopped by
2865 * our earlier block call. We need to perform a block again
2866 * to get the device to SDEV_BLOCK and then to SDEV_RUNNING */
2867
2868 sdev_printk(KERN_WARNING, sdev,
2869 "device_unblock failed with return(%d) for handle(0x%04x) "
2870 "performing a block followed by an unblock\n",
2871 sas_device_priv_data->sas_target->handle, r);
2872 sas_device_priv_data->block = 1;
2873 r = scsi_internal_device_block(sdev);
2874 if (r)
2875 sdev_printk(KERN_WARNING, sdev, "retried device_block "
2876 "failed with return(%d) for handle(0x%04x)\n",
2877 sas_device_priv_data->sas_target->handle, r);
2878
2879 sas_device_priv_data->block = 0;
2880 r = scsi_internal_device_unblock(sdev, SDEV_RUNNING);
2881 if (r)
2882 sdev_printk(KERN_WARNING, sdev, "retried device_unblock"
2883 " failed with return(%d) for handle(0x%04x)\n",
2884 sas_device_priv_data->sas_target->handle, r);
2885 }
2886}
2887
2888/**
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302889 * _scsih_ublock_io_all_device - unblock every device
2890 * @ioc: per adapter object
2891 *
2892 * change the device state from block to running
2893 */
2894static void
2895_scsih_ublock_io_all_device(struct MPT3SAS_ADAPTER *ioc)
2896{
2897 struct MPT3SAS_DEVICE *sas_device_priv_data;
2898 struct scsi_device *sdev;
2899
2900 shost_for_each_device(sdev, ioc->shost) {
2901 sas_device_priv_data = sdev->hostdata;
2902 if (!sas_device_priv_data)
2903 continue;
2904 if (!sas_device_priv_data->block)
2905 continue;
2906
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302907 dewtprintk(ioc, sdev_printk(KERN_INFO, sdev,
2908 "device_running, handle(0x%04x)\n",
2909 sas_device_priv_data->sas_target->handle));
Sreekanth Reddydf838f92015-06-30 12:25:05 +05302910 _scsih_internal_device_unblock(sdev, sas_device_priv_data);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302911 }
2912}
2913
2914
2915/**
2916 * _scsih_ublock_io_device - prepare device to be deleted
2917 * @ioc: per adapter object
2918 * @sas_addr: sas address
2919 *
2920 * unblock then put device in offline state
2921 */
2922static void
2923_scsih_ublock_io_device(struct MPT3SAS_ADAPTER *ioc, u64 sas_address)
2924{
2925 struct MPT3SAS_DEVICE *sas_device_priv_data;
2926 struct scsi_device *sdev;
2927
2928 shost_for_each_device(sdev, ioc->shost) {
2929 sas_device_priv_data = sdev->hostdata;
2930 if (!sas_device_priv_data)
2931 continue;
2932 if (sas_device_priv_data->sas_target->sas_address
2933 != sas_address)
2934 continue;
Sreekanth Reddydf838f92015-06-30 12:25:05 +05302935 if (sas_device_priv_data->block)
2936 _scsih_internal_device_unblock(sdev,
2937 sas_device_priv_data);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302938 }
2939}
2940
2941/**
2942 * _scsih_block_io_all_device - set the device state to SDEV_BLOCK
2943 * @ioc: per adapter object
2944 * @handle: device handle
2945 *
2946 * During device pull we need to appropiately set the sdev state.
2947 */
2948static void
2949_scsih_block_io_all_device(struct MPT3SAS_ADAPTER *ioc)
2950{
2951 struct MPT3SAS_DEVICE *sas_device_priv_data;
2952 struct scsi_device *sdev;
2953
2954 shost_for_each_device(sdev, ioc->shost) {
2955 sas_device_priv_data = sdev->hostdata;
2956 if (!sas_device_priv_data)
2957 continue;
2958 if (sas_device_priv_data->block)
2959 continue;
Suganath prabu Subramani30158dc2016-01-28 12:07:01 +05302960 if (sas_device_priv_data->ignore_delay_remove) {
2961 sdev_printk(KERN_INFO, sdev,
2962 "%s skip device_block for SES handle(0x%04x)\n",
2963 __func__, sas_device_priv_data->sas_target->handle);
2964 continue;
2965 }
Sreekanth Reddydf838f92015-06-30 12:25:05 +05302966 _scsih_internal_device_block(sdev, sas_device_priv_data);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302967 }
2968}
2969
2970/**
2971 * _scsih_block_io_device - set the device state to SDEV_BLOCK
2972 * @ioc: per adapter object
2973 * @handle: device handle
2974 *
2975 * During device pull we need to appropiately set the sdev state.
2976 */
2977static void
2978_scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
2979{
2980 struct MPT3SAS_DEVICE *sas_device_priv_data;
2981 struct scsi_device *sdev;
Sreekanth Reddye4bc7f52015-06-30 12:24:49 +05302982 struct _sas_device *sas_device;
2983
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05302984 sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
Sreekanth Reddye4bc7f52015-06-30 12:24:49 +05302985 if (!sas_device)
2986 return;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302987
2988 shost_for_each_device(sdev, ioc->shost) {
2989 sas_device_priv_data = sdev->hostdata;
2990 if (!sas_device_priv_data)
2991 continue;
2992 if (sas_device_priv_data->sas_target->handle != handle)
2993 continue;
2994 if (sas_device_priv_data->block)
2995 continue;
Sreekanth Reddye4bc7f52015-06-30 12:24:49 +05302996 if (sas_device->pend_sas_rphy_add)
2997 continue;
Suganath prabu Subramani30158dc2016-01-28 12:07:01 +05302998 if (sas_device_priv_data->ignore_delay_remove) {
2999 sdev_printk(KERN_INFO, sdev,
3000 "%s skip device_block for SES handle(0x%04x)\n",
3001 __func__, sas_device_priv_data->sas_target->handle);
3002 continue;
3003 }
Sreekanth Reddydf838f92015-06-30 12:25:05 +05303004 _scsih_internal_device_block(sdev, sas_device_priv_data);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303005 }
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05303006
3007 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303008}
3009
3010/**
3011 * _scsih_block_io_to_children_attached_to_ex
3012 * @ioc: per adapter object
3013 * @sas_expander: the sas_device object
3014 *
3015 * This routine set sdev state to SDEV_BLOCK for all devices
3016 * attached to this expander. This function called when expander is
3017 * pulled.
3018 */
3019static void
3020_scsih_block_io_to_children_attached_to_ex(struct MPT3SAS_ADAPTER *ioc,
3021 struct _sas_node *sas_expander)
3022{
3023 struct _sas_port *mpt3sas_port;
3024 struct _sas_device *sas_device;
3025 struct _sas_node *expander_sibling;
3026 unsigned long flags;
3027
3028 if (!sas_expander)
3029 return;
3030
3031 list_for_each_entry(mpt3sas_port,
3032 &sas_expander->sas_port_list, port_list) {
3033 if (mpt3sas_port->remote_identify.device_type ==
3034 SAS_END_DEVICE) {
3035 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05303036 sas_device = __mpt3sas_get_sdev_by_addr(ioc,
3037 mpt3sas_port->remote_identify.sas_address);
3038 if (sas_device) {
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303039 set_bit(sas_device->handle,
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05303040 ioc->blocking_handles);
3041 sas_device_put(sas_device);
3042 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303043 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3044 }
3045 }
3046
3047 list_for_each_entry(mpt3sas_port,
3048 &sas_expander->sas_port_list, port_list) {
3049
3050 if (mpt3sas_port->remote_identify.device_type ==
3051 SAS_EDGE_EXPANDER_DEVICE ||
3052 mpt3sas_port->remote_identify.device_type ==
3053 SAS_FANOUT_EXPANDER_DEVICE) {
3054 expander_sibling =
3055 mpt3sas_scsih_expander_find_by_sas_address(
3056 ioc, mpt3sas_port->remote_identify.sas_address);
3057 _scsih_block_io_to_children_attached_to_ex(ioc,
3058 expander_sibling);
3059 }
3060 }
3061}
3062
3063/**
3064 * _scsih_block_io_to_children_attached_directly
3065 * @ioc: per adapter object
3066 * @event_data: topology change event data
3067 *
3068 * This routine set sdev state to SDEV_BLOCK for all devices
3069 * direct attached during device pull.
3070 */
3071static void
3072_scsih_block_io_to_children_attached_directly(struct MPT3SAS_ADAPTER *ioc,
3073 Mpi2EventDataSasTopologyChangeList_t *event_data)
3074{
3075 int i;
3076 u16 handle;
3077 u16 reason_code;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303078
3079 for (i = 0; i < event_data->NumEntries; i++) {
3080 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
3081 if (!handle)
3082 continue;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303083 reason_code = event_data->PHY[i].PhyStatus &
3084 MPI2_EVENT_SAS_TOPO_RC_MASK;
3085 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING)
3086 _scsih_block_io_device(ioc, handle);
3087 }
3088}
3089
3090/**
3091 * _scsih_tm_tr_send - send task management request
3092 * @ioc: per adapter object
3093 * @handle: device handle
3094 * Context: interrupt time.
3095 *
3096 * This code is to initiate the device removal handshake protocol
3097 * with controller firmware. This function will issue target reset
3098 * using high priority request queue. It will send a sas iounit
3099 * control request (MPI2_SAS_OP_REMOVE_DEVICE) from this completion.
3100 *
3101 * This is designed to send muliple task management request at the same
3102 * time to the fifo. If the fifo is full, we will append the request,
3103 * and process it in a future completion.
3104 */
3105static void
3106_scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
3107{
3108 Mpi2SCSITaskManagementRequest_t *mpi_request;
3109 u16 smid;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05303110 struct _sas_device *sas_device = NULL;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303111 struct MPT3SAS_TARGET *sas_target_priv_data = NULL;
3112 u64 sas_address = 0;
3113 unsigned long flags;
3114 struct _tr_list *delayed_tr;
3115 u32 ioc_state;
3116
3117 if (ioc->remove_host) {
3118 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3119 "%s: host has been removed: handle(0x%04x)\n",
3120 __func__, ioc->name, handle));
3121 return;
3122 } else if (ioc->pci_error_recovery) {
3123 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3124 "%s: host in pci error recovery: handle(0x%04x)\n",
3125 __func__, ioc->name,
3126 handle));
3127 return;
3128 }
3129 ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
3130 if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
3131 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3132 "%s: host is not operational: handle(0x%04x)\n",
3133 __func__, ioc->name,
3134 handle));
3135 return;
3136 }
3137
3138 /* if PD, then return */
3139 if (test_bit(handle, ioc->pd_handles))
3140 return;
3141
3142 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05303143 sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303144 if (sas_device && sas_device->starget &&
3145 sas_device->starget->hostdata) {
3146 sas_target_priv_data = sas_device->starget->hostdata;
3147 sas_target_priv_data->deleted = 1;
3148 sas_address = sas_device->sas_address;
3149 }
3150 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3151
3152 if (sas_target_priv_data) {
3153 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3154 "setting delete flag: handle(0x%04x), sas_addr(0x%016llx)\n",
3155 ioc->name, handle,
3156 (unsigned long long)sas_address));
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05303157 if (sas_device->enclosure_handle != 0)
3158 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3159 "setting delete flag:enclosure logical id(0x%016llx),"
3160 " slot(%d)\n", ioc->name, (unsigned long long)
3161 sas_device->enclosure_logical_id,
3162 sas_device->slot));
Suganath prabu Subramani869817f2016-01-28 12:07:00 +05303163 if (sas_device->connector_name[0] != '\0')
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05303164 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3165 "setting delete flag: enclosure level(0x%04x),"
3166 " connector name( %s)\n", ioc->name,
3167 sas_device->enclosure_level,
3168 sas_device->connector_name));
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303169 _scsih_ublock_io_device(ioc, sas_address);
3170 sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE;
3171 }
3172
3173 smid = mpt3sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
3174 if (!smid) {
3175 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
3176 if (!delayed_tr)
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05303177 goto out;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303178 INIT_LIST_HEAD(&delayed_tr->list);
3179 delayed_tr->handle = handle;
3180 list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list);
3181 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3182 "DELAYED:tr:handle(0x%04x), (open)\n",
3183 ioc->name, handle));
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05303184 goto out;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303185 }
3186
3187 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3188 "tr_send:handle(0x%04x), (open), smid(%d), cb(%d)\n",
3189 ioc->name, handle, smid,
3190 ioc->tm_tr_cb_idx));
3191 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
3192 memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
3193 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
3194 mpi_request->DevHandle = cpu_to_le16(handle);
3195 mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
Suganath prabu Subramani03d1fb32016-01-28 12:07:06 +05303196 mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303197 mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05303198
3199out:
3200 if (sas_device)
3201 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303202}
3203
3204/**
3205 * _scsih_tm_tr_complete -
3206 * @ioc: per adapter object
3207 * @smid: system request message index
3208 * @msix_index: MSIX table index supplied by the OS
3209 * @reply: reply message frame(lower 32bit addr)
3210 * Context: interrupt time.
3211 *
3212 * This is the target reset completion routine.
3213 * This code is part of the code to initiate the device removal
3214 * handshake protocol with controller firmware.
3215 * It will send a sas iounit control request (MPI2_SAS_OP_REMOVE_DEVICE)
3216 *
3217 * Return 1 meaning mf should be freed from _base_interrupt
3218 * 0 means the mf is freed from this function.
3219 */
3220static u8
3221_scsih_tm_tr_complete(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
3222 u32 reply)
3223{
3224 u16 handle;
3225 Mpi2SCSITaskManagementRequest_t *mpi_request_tm;
3226 Mpi2SCSITaskManagementReply_t *mpi_reply =
3227 mpt3sas_base_get_reply_virt_addr(ioc, reply);
3228 Mpi2SasIoUnitControlRequest_t *mpi_request;
3229 u16 smid_sas_ctrl;
3230 u32 ioc_state;
Suganath prabu Subramanifd0331b2016-01-28 12:07:02 +05303231 struct _sc_list *delayed_sc;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303232
3233 if (ioc->remove_host) {
3234 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3235 "%s: host has been removed\n", __func__, ioc->name));
3236 return 1;
3237 } else if (ioc->pci_error_recovery) {
3238 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3239 "%s: host in pci error recovery\n", __func__,
3240 ioc->name));
3241 return 1;
3242 }
3243 ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
3244 if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
3245 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3246 "%s: host is not operational\n", __func__, ioc->name));
3247 return 1;
3248 }
3249 if (unlikely(!mpi_reply)) {
3250 pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n",
3251 ioc->name, __FILE__, __LINE__, __func__);
3252 return 1;
3253 }
3254 mpi_request_tm = mpt3sas_base_get_msg_frame(ioc, smid);
3255 handle = le16_to_cpu(mpi_request_tm->DevHandle);
3256 if (handle != le16_to_cpu(mpi_reply->DevHandle)) {
3257 dewtprintk(ioc, pr_err(MPT3SAS_FMT
3258 "spurious interrupt: handle(0x%04x:0x%04x), smid(%d)!!!\n",
3259 ioc->name, handle,
3260 le16_to_cpu(mpi_reply->DevHandle), smid));
3261 return 0;
3262 }
3263
3264 mpt3sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT);
3265 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3266 "tr_complete:handle(0x%04x), (open) smid(%d), ioc_status(0x%04x), "
3267 "loginfo(0x%08x), completed(%d)\n", ioc->name,
3268 handle, smid, le16_to_cpu(mpi_reply->IOCStatus),
3269 le32_to_cpu(mpi_reply->IOCLogInfo),
3270 le32_to_cpu(mpi_reply->TerminationCount)));
3271
3272 smid_sas_ctrl = mpt3sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx);
3273 if (!smid_sas_ctrl) {
Suganath prabu Subramanifd0331b2016-01-28 12:07:02 +05303274 delayed_sc = kzalloc(sizeof(*delayed_sc), GFP_ATOMIC);
3275 if (!delayed_sc)
3276 return _scsih_check_for_pending_tm(ioc, smid);
3277 INIT_LIST_HEAD(&delayed_sc->list);
3278 delayed_sc->handle = mpi_request_tm->DevHandle;
3279 list_add_tail(&delayed_sc->list, &ioc->delayed_sc_list);
3280 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3281 "DELAYED:sc:handle(0x%04x), (open)\n",
3282 ioc->name, handle));
3283 return _scsih_check_for_pending_tm(ioc, smid);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303284 }
3285
3286 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3287 "sc_send:handle(0x%04x), (open), smid(%d), cb(%d)\n",
3288 ioc->name, handle, smid_sas_ctrl,
3289 ioc->tm_sas_control_cb_idx));
3290 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid_sas_ctrl);
3291 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
3292 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
3293 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
3294 mpi_request->DevHandle = mpi_request_tm->DevHandle;
3295 mpt3sas_base_put_smid_default(ioc, smid_sas_ctrl);
3296
3297 return _scsih_check_for_pending_tm(ioc, smid);
3298}
3299
3300
3301/**
3302 * _scsih_sas_control_complete - completion routine
3303 * @ioc: per adapter object
3304 * @smid: system request message index
3305 * @msix_index: MSIX table index supplied by the OS
3306 * @reply: reply message frame(lower 32bit addr)
3307 * Context: interrupt time.
3308 *
3309 * This is the sas iounit control completion routine.
3310 * This code is part of the code to initiate the device removal
3311 * handshake protocol with controller firmware.
3312 *
3313 * Return 1 meaning mf should be freed from _base_interrupt
3314 * 0 means the mf is freed from this function.
3315 */
3316static u8
3317_scsih_sas_control_complete(struct MPT3SAS_ADAPTER *ioc, u16 smid,
3318 u8 msix_index, u32 reply)
3319{
3320 Mpi2SasIoUnitControlReply_t *mpi_reply =
3321 mpt3sas_base_get_reply_virt_addr(ioc, reply);
3322
3323 if (likely(mpi_reply)) {
3324 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3325 "sc_complete:handle(0x%04x), (open) "
3326 "smid(%d), ioc_status(0x%04x), loginfo(0x%08x)\n",
3327 ioc->name, le16_to_cpu(mpi_reply->DevHandle), smid,
3328 le16_to_cpu(mpi_reply->IOCStatus),
3329 le32_to_cpu(mpi_reply->IOCLogInfo)));
3330 } else {
3331 pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n",
3332 ioc->name, __FILE__, __LINE__, __func__);
3333 }
Suganath prabu Subramanifd0331b2016-01-28 12:07:02 +05303334 return mpt3sas_check_for_pending_internal_cmds(ioc, smid);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303335}
3336
3337/**
3338 * _scsih_tm_tr_volume_send - send target reset request for volumes
3339 * @ioc: per adapter object
3340 * @handle: device handle
3341 * Context: interrupt time.
3342 *
3343 * This is designed to send muliple task management request at the same
3344 * time to the fifo. If the fifo is full, we will append the request,
3345 * and process it in a future completion.
3346 */
3347static void
3348_scsih_tm_tr_volume_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
3349{
3350 Mpi2SCSITaskManagementRequest_t *mpi_request;
3351 u16 smid;
3352 struct _tr_list *delayed_tr;
3353
3354 if (ioc->shost_recovery || ioc->remove_host ||
3355 ioc->pci_error_recovery) {
3356 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3357 "%s: host reset in progress!\n",
3358 __func__, ioc->name));
3359 return;
3360 }
3361
3362 smid = mpt3sas_base_get_smid_hpr(ioc, ioc->tm_tr_volume_cb_idx);
3363 if (!smid) {
3364 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
3365 if (!delayed_tr)
3366 return;
3367 INIT_LIST_HEAD(&delayed_tr->list);
3368 delayed_tr->handle = handle;
3369 list_add_tail(&delayed_tr->list, &ioc->delayed_tr_volume_list);
3370 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3371 "DELAYED:tr:handle(0x%04x), (open)\n",
3372 ioc->name, handle));
3373 return;
3374 }
3375
3376 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3377 "tr_send:handle(0x%04x), (open), smid(%d), cb(%d)\n",
3378 ioc->name, handle, smid,
3379 ioc->tm_tr_volume_cb_idx));
3380 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
3381 memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
3382 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
3383 mpi_request->DevHandle = cpu_to_le16(handle);
3384 mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
Suganath prabu Subramani03d1fb32016-01-28 12:07:06 +05303385 mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303386}
3387
3388/**
3389 * _scsih_tm_volume_tr_complete - target reset completion
3390 * @ioc: per adapter object
3391 * @smid: system request message index
3392 * @msix_index: MSIX table index supplied by the OS
3393 * @reply: reply message frame(lower 32bit addr)
3394 * Context: interrupt time.
3395 *
3396 * Return 1 meaning mf should be freed from _base_interrupt
3397 * 0 means the mf is freed from this function.
3398 */
3399static u8
3400_scsih_tm_volume_tr_complete(struct MPT3SAS_ADAPTER *ioc, u16 smid,
3401 u8 msix_index, u32 reply)
3402{
3403 u16 handle;
3404 Mpi2SCSITaskManagementRequest_t *mpi_request_tm;
3405 Mpi2SCSITaskManagementReply_t *mpi_reply =
3406 mpt3sas_base_get_reply_virt_addr(ioc, reply);
3407
3408 if (ioc->shost_recovery || ioc->remove_host ||
3409 ioc->pci_error_recovery) {
3410 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3411 "%s: host reset in progress!\n",
3412 __func__, ioc->name));
3413 return 1;
3414 }
3415 if (unlikely(!mpi_reply)) {
3416 pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n",
3417 ioc->name, __FILE__, __LINE__, __func__);
3418 return 1;
3419 }
3420
3421 mpi_request_tm = mpt3sas_base_get_msg_frame(ioc, smid);
3422 handle = le16_to_cpu(mpi_request_tm->DevHandle);
3423 if (handle != le16_to_cpu(mpi_reply->DevHandle)) {
3424 dewtprintk(ioc, pr_err(MPT3SAS_FMT
3425 "spurious interrupt: handle(0x%04x:0x%04x), smid(%d)!!!\n",
3426 ioc->name, handle,
3427 le16_to_cpu(mpi_reply->DevHandle), smid));
3428 return 0;
3429 }
3430
3431 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3432 "tr_complete:handle(0x%04x), (open) smid(%d), ioc_status(0x%04x), "
3433 "loginfo(0x%08x), completed(%d)\n", ioc->name,
3434 handle, smid, le16_to_cpu(mpi_reply->IOCStatus),
3435 le32_to_cpu(mpi_reply->IOCLogInfo),
3436 le32_to_cpu(mpi_reply->TerminationCount)));
3437
3438 return _scsih_check_for_pending_tm(ioc, smid);
3439}
3440
Suganath prabu Subramanifd0331b2016-01-28 12:07:02 +05303441/**
3442 * _scsih_issue_delayed_event_ack - issue delayed Event ACK messages
3443 * @ioc: per adapter object
3444 * @smid: system request message index
3445 * @event: Event ID
3446 * @event_context: used to track events uniquely
3447 *
3448 * Context - processed in interrupt context.
3449 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07003450static void
Suganath prabu Subramanifd0331b2016-01-28 12:07:02 +05303451_scsih_issue_delayed_event_ack(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 event,
3452 u32 event_context)
3453{
3454 Mpi2EventAckRequest_t *ack_request;
3455 int i = smid - ioc->internal_smid;
3456 unsigned long flags;
3457
3458 /* Without releasing the smid just update the
3459 * call back index and reuse the same smid for
3460 * processing this delayed request
3461 */
3462 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
3463 ioc->internal_lookup[i].cb_idx = ioc->base_cb_idx;
3464 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
3465
3466 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3467 "EVENT ACK: event(0x%04x), smid(%d), cb(%d)\n",
3468 ioc->name, le16_to_cpu(event), smid,
3469 ioc->base_cb_idx));
3470 ack_request = mpt3sas_base_get_msg_frame(ioc, smid);
3471 memset(ack_request, 0, sizeof(Mpi2EventAckRequest_t));
3472 ack_request->Function = MPI2_FUNCTION_EVENT_ACK;
3473 ack_request->Event = event;
3474 ack_request->EventContext = event_context;
3475 ack_request->VF_ID = 0; /* TODO */
3476 ack_request->VP_ID = 0;
3477 mpt3sas_base_put_smid_default(ioc, smid);
3478}
3479
3480/**
3481 * _scsih_issue_delayed_sas_io_unit_ctrl - issue delayed
3482 * sas_io_unit_ctrl messages
3483 * @ioc: per adapter object
3484 * @smid: system request message index
3485 * @handle: device handle
3486 *
3487 * Context - processed in interrupt context.
3488 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07003489static void
Suganath prabu Subramanifd0331b2016-01-28 12:07:02 +05303490_scsih_issue_delayed_sas_io_unit_ctrl(struct MPT3SAS_ADAPTER *ioc,
3491 u16 smid, u16 handle)
3492 {
3493 Mpi2SasIoUnitControlRequest_t *mpi_request;
3494 u32 ioc_state;
3495 int i = smid - ioc->internal_smid;
3496 unsigned long flags;
3497
3498 if (ioc->remove_host) {
3499 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3500 "%s: host has been removed\n",
3501 __func__, ioc->name));
3502 return;
3503 } else if (ioc->pci_error_recovery) {
3504 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3505 "%s: host in pci error recovery\n",
3506 __func__, ioc->name));
3507 return;
3508 }
3509 ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
3510 if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
3511 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3512 "%s: host is not operational\n",
3513 __func__, ioc->name));
3514 return;
3515 }
3516
3517 /* Without releasing the smid just update the
3518 * call back index and reuse the same smid for
3519 * processing this delayed request
3520 */
3521 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
3522 ioc->internal_lookup[i].cb_idx = ioc->tm_sas_control_cb_idx;
3523 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
3524
3525 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3526 "sc_send:handle(0x%04x), (open), smid(%d), cb(%d)\n",
3527 ioc->name, le16_to_cpu(handle), smid,
3528 ioc->tm_sas_control_cb_idx));
3529 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
3530 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
3531 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
3532 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
3533 mpi_request->DevHandle = handle;
3534 mpt3sas_base_put_smid_default(ioc, smid);
3535}
3536
3537/**
3538 * _scsih_check_for_pending_internal_cmds - check for pending internal messages
3539 * @ioc: per adapter object
3540 * @smid: system request message index
3541 *
3542 * Context: Executed in interrupt context
3543 *
3544 * This will check delayed internal messages list, and process the
3545 * next request.
3546 *
3547 * Return 1 meaning mf should be freed from _base_interrupt
3548 * 0 means the mf is freed from this function.
3549 */
3550u8
3551mpt3sas_check_for_pending_internal_cmds(struct MPT3SAS_ADAPTER *ioc, u16 smid)
3552{
3553 struct _sc_list *delayed_sc;
3554 struct _event_ack_list *delayed_event_ack;
3555
3556 if (!list_empty(&ioc->delayed_event_ack_list)) {
3557 delayed_event_ack = list_entry(ioc->delayed_event_ack_list.next,
3558 struct _event_ack_list, list);
3559 _scsih_issue_delayed_event_ack(ioc, smid,
3560 delayed_event_ack->Event, delayed_event_ack->EventContext);
3561 list_del(&delayed_event_ack->list);
3562 kfree(delayed_event_ack);
3563 return 0;
3564 }
3565
3566 if (!list_empty(&ioc->delayed_sc_list)) {
3567 delayed_sc = list_entry(ioc->delayed_sc_list.next,
3568 struct _sc_list, list);
3569 _scsih_issue_delayed_sas_io_unit_ctrl(ioc, smid,
3570 delayed_sc->handle);
3571 list_del(&delayed_sc->list);
3572 kfree(delayed_sc);
3573 return 0;
3574 }
3575 return 1;
3576}
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303577
3578/**
3579 * _scsih_check_for_pending_tm - check for pending task management
3580 * @ioc: per adapter object
3581 * @smid: system request message index
3582 *
3583 * This will check delayed target reset list, and feed the
3584 * next reqeust.
3585 *
3586 * Return 1 meaning mf should be freed from _base_interrupt
3587 * 0 means the mf is freed from this function.
3588 */
3589static u8
3590_scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid)
3591{
3592 struct _tr_list *delayed_tr;
3593
3594 if (!list_empty(&ioc->delayed_tr_volume_list)) {
3595 delayed_tr = list_entry(ioc->delayed_tr_volume_list.next,
3596 struct _tr_list, list);
3597 mpt3sas_base_free_smid(ioc, smid);
3598 _scsih_tm_tr_volume_send(ioc, delayed_tr->handle);
3599 list_del(&delayed_tr->list);
3600 kfree(delayed_tr);
3601 return 0;
3602 }
3603
3604 if (!list_empty(&ioc->delayed_tr_list)) {
3605 delayed_tr = list_entry(ioc->delayed_tr_list.next,
3606 struct _tr_list, list);
3607 mpt3sas_base_free_smid(ioc, smid);
3608 _scsih_tm_tr_send(ioc, delayed_tr->handle);
3609 list_del(&delayed_tr->list);
3610 kfree(delayed_tr);
3611 return 0;
3612 }
3613
3614 return 1;
3615}
3616
3617/**
3618 * _scsih_check_topo_delete_events - sanity check on topo events
3619 * @ioc: per adapter object
3620 * @event_data: the event data payload
3621 *
3622 * This routine added to better handle cable breaker.
3623 *
3624 * This handles the case where driver receives multiple expander
3625 * add and delete events in a single shot. When there is a delete event
3626 * the routine will void any pending add events waiting in the event queue.
3627 *
3628 * Return nothing.
3629 */
3630static void
3631_scsih_check_topo_delete_events(struct MPT3SAS_ADAPTER *ioc,
3632 Mpi2EventDataSasTopologyChangeList_t *event_data)
3633{
3634 struct fw_event_work *fw_event;
3635 Mpi2EventDataSasTopologyChangeList_t *local_event_data;
3636 u16 expander_handle;
3637 struct _sas_node *sas_expander;
3638 unsigned long flags;
3639 int i, reason_code;
3640 u16 handle;
3641
3642 for (i = 0 ; i < event_data->NumEntries; i++) {
3643 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
3644 if (!handle)
3645 continue;
3646 reason_code = event_data->PHY[i].PhyStatus &
3647 MPI2_EVENT_SAS_TOPO_RC_MASK;
3648 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)
3649 _scsih_tm_tr_send(ioc, handle);
3650 }
3651
3652 expander_handle = le16_to_cpu(event_data->ExpanderDevHandle);
3653 if (expander_handle < ioc->sas_hba.num_phys) {
3654 _scsih_block_io_to_children_attached_directly(ioc, event_data);
3655 return;
3656 }
3657 if (event_data->ExpStatus ==
3658 MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING) {
3659 /* put expander attached devices into blocking state */
3660 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3661 sas_expander = mpt3sas_scsih_expander_find_by_handle(ioc,
3662 expander_handle);
3663 _scsih_block_io_to_children_attached_to_ex(ioc, sas_expander);
3664 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
3665 do {
3666 handle = find_first_bit(ioc->blocking_handles,
3667 ioc->facts.MaxDevHandle);
3668 if (handle < ioc->facts.MaxDevHandle)
3669 _scsih_block_io_device(ioc, handle);
3670 } while (test_and_clear_bit(handle, ioc->blocking_handles));
3671 } else if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_RESPONDING)
3672 _scsih_block_io_to_children_attached_directly(ioc, event_data);
3673
3674 if (event_data->ExpStatus != MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING)
3675 return;
3676
3677 /* mark ignore flag for pending events */
3678 spin_lock_irqsave(&ioc->fw_event_lock, flags);
3679 list_for_each_entry(fw_event, &ioc->fw_event_list, list) {
3680 if (fw_event->event != MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||
3681 fw_event->ignore)
3682 continue;
Joe Lawrence35b62362014-06-25 17:05:34 -04003683 local_event_data = (Mpi2EventDataSasTopologyChangeList_t *)
3684 fw_event->event_data;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303685 if (local_event_data->ExpStatus ==
3686 MPI2_EVENT_SAS_TOPO_ES_ADDED ||
3687 local_event_data->ExpStatus ==
3688 MPI2_EVENT_SAS_TOPO_ES_RESPONDING) {
3689 if (le16_to_cpu(local_event_data->ExpanderDevHandle) ==
3690 expander_handle) {
3691 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3692 "setting ignoring flag\n", ioc->name));
3693 fw_event->ignore = 1;
3694 }
3695 }
3696 }
3697 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
3698}
3699
3700/**
3701 * _scsih_set_volume_delete_flag - setting volume delete flag
3702 * @ioc: per adapter object
3703 * @handle: device handle
3704 *
3705 * This returns nothing.
3706 */
3707static void
3708_scsih_set_volume_delete_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle)
3709{
3710 struct _raid_device *raid_device;
3711 struct MPT3SAS_TARGET *sas_target_priv_data;
3712 unsigned long flags;
3713
3714 spin_lock_irqsave(&ioc->raid_device_lock, flags);
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05303715 raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303716 if (raid_device && raid_device->starget &&
3717 raid_device->starget->hostdata) {
3718 sas_target_priv_data =
3719 raid_device->starget->hostdata;
3720 sas_target_priv_data->deleted = 1;
3721 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3722 "setting delete flag: handle(0x%04x), "
3723 "wwid(0x%016llx)\n", ioc->name, handle,
3724 (unsigned long long) raid_device->wwid));
3725 }
3726 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
3727}
3728
3729/**
3730 * _scsih_set_volume_handle_for_tr - set handle for target reset to volume
3731 * @handle: input handle
3732 * @a: handle for volume a
3733 * @b: handle for volume b
3734 *
3735 * IR firmware only supports two raid volumes. The purpose of this
3736 * routine is to set the volume handle in either a or b. When the given
3737 * input handle is non-zero, or when a and b have not been set before.
3738 */
3739static void
3740_scsih_set_volume_handle_for_tr(u16 handle, u16 *a, u16 *b)
3741{
3742 if (!handle || handle == *a || handle == *b)
3743 return;
3744 if (!*a)
3745 *a = handle;
3746 else if (!*b)
3747 *b = handle;
3748}
3749
3750/**
3751 * _scsih_check_ir_config_unhide_events - check for UNHIDE events
3752 * @ioc: per adapter object
3753 * @event_data: the event data payload
3754 * Context: interrupt time.
3755 *
3756 * This routine will send target reset to volume, followed by target
3757 * resets to the PDs. This is called when a PD has been removed, or
3758 * volume has been deleted or removed. When the target reset is sent
3759 * to volume, the PD target resets need to be queued to start upon
3760 * completion of the volume target reset.
3761 *
3762 * Return nothing.
3763 */
3764static void
3765_scsih_check_ir_config_unhide_events(struct MPT3SAS_ADAPTER *ioc,
3766 Mpi2EventDataIrConfigChangeList_t *event_data)
3767{
3768 Mpi2EventIrConfigElement_t *element;
3769 int i;
3770 u16 handle, volume_handle, a, b;
3771 struct _tr_list *delayed_tr;
3772
3773 a = 0;
3774 b = 0;
3775
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05303776 if (ioc->is_warpdrive)
3777 return;
3778
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303779 /* Volume Resets for Deleted or Removed */
3780 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
3781 for (i = 0; i < event_data->NumElements; i++, element++) {
3782 if (le32_to_cpu(event_data->Flags) &
3783 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG)
3784 continue;
3785 if (element->ReasonCode ==
3786 MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED ||
3787 element->ReasonCode ==
3788 MPI2_EVENT_IR_CHANGE_RC_REMOVED) {
3789 volume_handle = le16_to_cpu(element->VolDevHandle);
3790 _scsih_set_volume_delete_flag(ioc, volume_handle);
3791 _scsih_set_volume_handle_for_tr(volume_handle, &a, &b);
3792 }
3793 }
3794
3795 /* Volume Resets for UNHIDE events */
3796 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
3797 for (i = 0; i < event_data->NumElements; i++, element++) {
3798 if (le32_to_cpu(event_data->Flags) &
3799 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG)
3800 continue;
3801 if (element->ReasonCode == MPI2_EVENT_IR_CHANGE_RC_UNHIDE) {
3802 volume_handle = le16_to_cpu(element->VolDevHandle);
3803 _scsih_set_volume_handle_for_tr(volume_handle, &a, &b);
3804 }
3805 }
3806
3807 if (a)
3808 _scsih_tm_tr_volume_send(ioc, a);
3809 if (b)
3810 _scsih_tm_tr_volume_send(ioc, b);
3811
3812 /* PD target resets */
3813 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
3814 for (i = 0; i < event_data->NumElements; i++, element++) {
3815 if (element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_UNHIDE)
3816 continue;
3817 handle = le16_to_cpu(element->PhysDiskDevHandle);
3818 volume_handle = le16_to_cpu(element->VolDevHandle);
3819 clear_bit(handle, ioc->pd_handles);
3820 if (!volume_handle)
3821 _scsih_tm_tr_send(ioc, handle);
3822 else if (volume_handle == a || volume_handle == b) {
3823 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
3824 BUG_ON(!delayed_tr);
3825 INIT_LIST_HEAD(&delayed_tr->list);
3826 delayed_tr->handle = handle;
3827 list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list);
3828 dewtprintk(ioc, pr_info(MPT3SAS_FMT
3829 "DELAYED:tr:handle(0x%04x), (open)\n", ioc->name,
3830 handle));
3831 } else
3832 _scsih_tm_tr_send(ioc, handle);
3833 }
3834}
3835
3836
3837/**
3838 * _scsih_check_volume_delete_events - set delete flag for volumes
3839 * @ioc: per adapter object
3840 * @event_data: the event data payload
3841 * Context: interrupt time.
3842 *
3843 * This will handle the case when the cable connected to entire volume is
3844 * pulled. We will take care of setting the deleted flag so normal IO will
3845 * not be sent.
3846 *
3847 * Return nothing.
3848 */
3849static void
3850_scsih_check_volume_delete_events(struct MPT3SAS_ADAPTER *ioc,
3851 Mpi2EventDataIrVolume_t *event_data)
3852{
3853 u32 state;
3854
3855 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
3856 return;
3857 state = le32_to_cpu(event_data->NewValue);
3858 if (state == MPI2_RAID_VOL_STATE_MISSING || state ==
3859 MPI2_RAID_VOL_STATE_FAILED)
3860 _scsih_set_volume_delete_flag(ioc,
3861 le16_to_cpu(event_data->VolDevHandle));
3862}
3863
3864/**
Sreekanth Reddy2d8ce8c2015-01-12 11:38:56 +05303865 * _scsih_temp_threshold_events - display temperature threshold exceeded events
3866 * @ioc: per adapter object
3867 * @event_data: the temp threshold event data
3868 * Context: interrupt time.
3869 *
3870 * Return nothing.
3871 */
3872static void
3873_scsih_temp_threshold_events(struct MPT3SAS_ADAPTER *ioc,
3874 Mpi2EventDataTemperature_t *event_data)
3875{
3876 if (ioc->temp_sensors_count >= event_data->SensorNum) {
3877 pr_err(MPT3SAS_FMT "Temperature Threshold flags %s%s%s%s"
3878 " exceeded for Sensor: %d !!!\n", ioc->name,
3879 ((le16_to_cpu(event_data->Status) & 0x1) == 1) ? "0 " : " ",
3880 ((le16_to_cpu(event_data->Status) & 0x2) == 2) ? "1 " : " ",
3881 ((le16_to_cpu(event_data->Status) & 0x4) == 4) ? "2 " : " ",
3882 ((le16_to_cpu(event_data->Status) & 0x8) == 8) ? "3 " : " ",
3883 event_data->SensorNum);
3884 pr_err(MPT3SAS_FMT "Current Temp In Celsius: %d\n",
3885 ioc->name, event_data->CurrentTemperature);
3886 }
3887}
3888
James Bottomley16236802017-01-01 09:39:24 -08003889static int _scsih_set_satl_pending(struct scsi_cmnd *scmd, bool pending)
Suganath Prabu S7ff723a2016-11-17 16:15:58 +05303890{
James Bottomley16236802017-01-01 09:39:24 -08003891 struct MPT3SAS_DEVICE *priv = scmd->device->hostdata;
3892
3893 if (scmd->cmnd[0] != ATA_12 && scmd->cmnd[0] != ATA_16)
3894 return 0;
3895
3896 if (pending)
3897 return test_and_set_bit(0, &priv->ata_command_pending);
3898
3899 clear_bit(0, &priv->ata_command_pending);
3900 return 0;
Suganath Prabu S7ff723a2016-11-17 16:15:58 +05303901}
3902
Sreekanth Reddy2d8ce8c2015-01-12 11:38:56 +05303903/**
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303904 * _scsih_flush_running_cmds - completing outstanding commands.
3905 * @ioc: per adapter object
3906 *
3907 * The flushing out of all pending scmd commands following host reset,
3908 * where all IO is dropped to the floor.
3909 *
3910 * Return nothing.
3911 */
3912static void
3913_scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc)
3914{
3915 struct scsi_cmnd *scmd;
3916 u16 smid;
3917 u16 count = 0;
3918
3919 for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
3920 scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
3921 if (!scmd)
3922 continue;
3923 count++;
James Bottomley16236802017-01-01 09:39:24 -08003924 _scsih_set_satl_pending(scmd, false);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303925 mpt3sas_base_free_smid(ioc, smid);
3926 scsi_dma_unmap(scmd);
3927 if (ioc->pci_error_recovery)
3928 scmd->result = DID_NO_CONNECT << 16;
3929 else
3930 scmd->result = DID_RESET << 16;
3931 scmd->scsi_done(scmd);
3932 }
3933 dtmprintk(ioc, pr_info(MPT3SAS_FMT "completing %d cmds\n",
3934 ioc->name, count));
3935}
3936
3937/**
3938 * _scsih_setup_eedp - setup MPI request for EEDP transfer
3939 * @ioc: per adapter object
3940 * @scmd: pointer to scsi command object
3941 * @mpi_request: pointer to the SCSI_IO reqest message frame
3942 *
3943 * Supporting protection 1 and 3.
3944 *
3945 * Returns nothing
3946 */
3947static void
3948_scsih_setup_eedp(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
3949 Mpi2SCSIIORequest_t *mpi_request)
3950{
3951 u16 eedp_flags;
3952 unsigned char prot_op = scsi_get_prot_op(scmd);
3953 unsigned char prot_type = scsi_get_prot_type(scmd);
3954 Mpi25SCSIIORequest_t *mpi_request_3v =
3955 (Mpi25SCSIIORequest_t *)mpi_request;
3956
3957 if (prot_type == SCSI_PROT_DIF_TYPE0 || prot_op == SCSI_PROT_NORMAL)
3958 return;
3959
3960 if (prot_op == SCSI_PROT_READ_STRIP)
3961 eedp_flags = MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP;
3962 else if (prot_op == SCSI_PROT_WRITE_INSERT)
3963 eedp_flags = MPI2_SCSIIO_EEDPFLAGS_INSERT_OP;
3964 else
3965 return;
3966
3967 switch (prot_type) {
3968 case SCSI_PROT_DIF_TYPE1:
3969 case SCSI_PROT_DIF_TYPE2:
3970
3971 /*
3972 * enable ref/guard checking
3973 * auto increment ref tag
3974 */
3975 eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
3976 MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
3977 MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
3978 mpi_request->CDB.EEDP32.PrimaryReferenceTag =
Chaitra P B648512cc2016-05-06 14:29:28 +05303979 cpu_to_be32(scsi_prot_ref_tag(scmd));
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05303980 break;
3981
3982 case SCSI_PROT_DIF_TYPE3:
3983
3984 /*
3985 * enable guard checking
3986 */
3987 eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
3988
3989 break;
3990 }
3991
3992 mpi_request_3v->EEDPBlockSize =
3993 cpu_to_le16(scmd->device->sector_size);
3994 mpi_request->EEDPFlags = cpu_to_le16(eedp_flags);
3995}
3996
3997/**
3998 * _scsih_eedp_error_handling - return sense code for EEDP errors
3999 * @scmd: pointer to scsi command object
4000 * @ioc_status: ioc status
4001 *
4002 * Returns nothing
4003 */
4004static void
4005_scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
4006{
4007 u8 ascq;
4008
4009 switch (ioc_status) {
4010 case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
4011 ascq = 0x01;
4012 break;
4013 case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
4014 ascq = 0x02;
4015 break;
4016 case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR:
4017 ascq = 0x03;
4018 break;
4019 default:
4020 ascq = 0x00;
4021 break;
4022 }
4023 scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, 0x10,
4024 ascq);
4025 scmd->result = DRIVER_SENSE << 24 | (DID_ABORT << 16) |
4026 SAM_STAT_CHECK_CONDITION;
4027}
4028
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304029/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05304030 * scsih_qcmd - main scsi request entry point
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304031 * @scmd: pointer to scsi command object
4032 * @done: function pointer to be invoked on completion
4033 *
4034 * The callback index is set inside `ioc->scsi_io_cb_idx`.
4035 *
4036 * Returns 0 on success. If there's a failure, return either:
4037 * SCSI_MLQUEUE_DEVICE_BUSY if the device queue is full, or
4038 * SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full
4039 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07004040static int
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05304041scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304042{
Matthew Wilcoxd8bfbd82014-03-27 16:40:31 -04004043 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304044 struct MPT3SAS_DEVICE *sas_device_priv_data;
4045 struct MPT3SAS_TARGET *sas_target_priv_data;
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05304046 struct _raid_device *raid_device;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304047 Mpi2SCSIIORequest_t *mpi_request;
4048 u32 mpi_control;
4049 u16 smid;
4050 u16 handle;
4051
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304052 if (ioc->logging_level & MPT_DEBUG_SCSI)
4053 scsi_print_command(scmd);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304054
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304055 sas_device_priv_data = scmd->device->hostdata;
4056 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
4057 scmd->result = DID_NO_CONNECT << 16;
4058 scmd->scsi_done(scmd);
4059 return 0;
4060 }
4061
4062 if (ioc->pci_error_recovery || ioc->remove_host) {
4063 scmd->result = DID_NO_CONNECT << 16;
4064 scmd->scsi_done(scmd);
4065 return 0;
4066 }
4067
4068 sas_target_priv_data = sas_device_priv_data->sas_target;
4069
4070 /* invalid device handle */
4071 handle = sas_target_priv_data->handle;
4072 if (handle == MPT3SAS_INVALID_DEVICE_HANDLE) {
4073 scmd->result = DID_NO_CONNECT << 16;
4074 scmd->scsi_done(scmd);
4075 return 0;
4076 }
4077
4078
4079 /* host recovery or link resets sent via IOCTLs */
4080 if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
4081 return SCSI_MLQUEUE_HOST_BUSY;
4082
4083 /* device has been deleted */
4084 else if (sas_target_priv_data->deleted) {
4085 scmd->result = DID_NO_CONNECT << 16;
4086 scmd->scsi_done(scmd);
4087 return 0;
4088 /* device busy with task managment */
4089 } else if (sas_target_priv_data->tm_busy ||
4090 sas_device_priv_data->block)
4091 return SCSI_MLQUEUE_DEVICE_BUSY;
4092
Chaitra P B388f0c82017-12-27 23:09:11 -08004093 /*
4094 * Bug work around for firmware SATL handling. The loop
4095 * is based on atomic operations and ensures consistency
4096 * since we're lockless at this point
4097 */
4098 do {
4099 if (test_bit(0, &sas_device_priv_data->ata_command_pending)) {
4100 scmd->result = SAM_STAT_BUSY;
4101 scmd->scsi_done(scmd);
4102 return 0;
4103 }
4104 } while (_scsih_set_satl_pending(scmd, true));
4105
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304106 if (scmd->sc_data_direction == DMA_FROM_DEVICE)
4107 mpi_control = MPI2_SCSIIO_CONTROL_READ;
4108 else if (scmd->sc_data_direction == DMA_TO_DEVICE)
4109 mpi_control = MPI2_SCSIIO_CONTROL_WRITE;
4110 else
4111 mpi_control = MPI2_SCSIIO_CONTROL_NODATATRANSFER;
4112
4113 /* set tags */
Christoph Hellwig609aa222014-10-30 11:54:58 +01004114 mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304115
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05304116 /* Make sure Device is not raid volume.
4117 * We do not expose raid functionality to upper layer for warpdrive.
4118 */
4119 if (!ioc->is_warpdrive && !scsih_is_raid(&scmd->device->sdev_gendev)
Sreekanth Reddy15de0de2015-11-12 23:40:37 +05304120 && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304121 mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
4122
4123 smid = mpt3sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd);
4124 if (!smid) {
4125 pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
4126 ioc->name, __func__);
Chaitra P B388f0c82017-12-27 23:09:11 -08004127 _scsih_set_satl_pending(scmd, false);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304128 goto out;
4129 }
4130 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
4131 memset(mpi_request, 0, sizeof(Mpi2SCSIIORequest_t));
4132 _scsih_setup_eedp(ioc, scmd, mpi_request);
4133
4134 if (scmd->cmd_len == 32)
4135 mpi_control |= 4 << MPI2_SCSIIO_CONTROL_ADDCDBLEN_SHIFT;
4136 mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
4137 if (sas_device_priv_data->sas_target->flags &
4138 MPT_TARGET_FLAGS_RAID_COMPONENT)
4139 mpi_request->Function = MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
4140 else
4141 mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
4142 mpi_request->DevHandle = cpu_to_le16(handle);
4143 mpi_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
4144 mpi_request->Control = cpu_to_le32(mpi_control);
4145 mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len);
4146 mpi_request->MsgFlags = MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR;
4147 mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
4148 mpi_request->SenseBufferLowAddress =
4149 mpt3sas_base_get_sense_buffer_dma(ioc, smid);
4150 mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4;
4151 int_to_scsilun(sas_device_priv_data->lun, (struct scsi_lun *)
4152 mpi_request->LUN);
4153 memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
4154
4155 if (mpi_request->DataLength) {
4156 if (ioc->build_sg_scmd(ioc, scmd, smid)) {
4157 mpt3sas_base_free_smid(ioc, smid);
Chaitra P B388f0c82017-12-27 23:09:11 -08004158 _scsih_set_satl_pending(scmd, false);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304159 goto out;
4160 }
4161 } else
4162 ioc->build_zero_len_sge(ioc, &mpi_request->SGL);
4163
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05304164 raid_device = sas_target_priv_data->raid_device;
4165 if (raid_device && raid_device->direct_io_enabled)
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05304166 mpt3sas_setup_direct_io(ioc, scmd, raid_device, mpi_request,
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05304167 smid);
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05304168
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304169 if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)) {
4170 if (sas_target_priv_data->flags & MPT_TARGET_FASTPATH_IO) {
4171 mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len |
4172 MPI25_SCSIIO_IOFLAGS_FAST_PATH);
4173 mpt3sas_base_put_smid_fast_path(ioc, smid, handle);
4174 } else
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05304175 mpt3sas_base_put_smid_scsi_io(ioc, smid,
4176 le16_to_cpu(mpi_request->DevHandle));
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304177 } else
4178 mpt3sas_base_put_smid_default(ioc, smid);
4179 return 0;
4180
4181 out:
4182 return SCSI_MLQUEUE_HOST_BUSY;
4183}
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304184
4185/**
4186 * _scsih_normalize_sense - normalize descriptor and fixed format sense data
4187 * @sense_buffer: sense data returned by target
4188 * @data: normalized skey/asc/ascq
4189 *
4190 * Return nothing.
4191 */
4192static void
4193_scsih_normalize_sense(char *sense_buffer, struct sense_info *data)
4194{
4195 if ((sense_buffer[0] & 0x7F) >= 0x72) {
4196 /* descriptor format */
4197 data->skey = sense_buffer[1] & 0x0F;
4198 data->asc = sense_buffer[2];
4199 data->ascq = sense_buffer[3];
4200 } else {
4201 /* fixed format */
4202 data->skey = sense_buffer[2] & 0x0F;
4203 data->asc = sense_buffer[12];
4204 data->ascq = sense_buffer[13];
4205 }
4206}
4207
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304208/**
4209 * _scsih_scsi_ioc_info - translated non-succesfull SCSI_IO request
4210 * @ioc: per adapter object
4211 * @scmd: pointer to scsi command object
4212 * @mpi_reply: reply mf payload returned from firmware
4213 *
4214 * scsi_status - SCSI Status code returned from target device
4215 * scsi_state - state info associated with SCSI_IO determined by ioc
4216 * ioc_status - ioc supplied status info
4217 *
4218 * Return nothing.
4219 */
4220static void
4221_scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
4222 Mpi2SCSIIOReply_t *mpi_reply, u16 smid)
4223{
4224 u32 response_info;
4225 u8 *response_bytes;
4226 u16 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) &
4227 MPI2_IOCSTATUS_MASK;
4228 u8 scsi_state = mpi_reply->SCSIState;
4229 u8 scsi_status = mpi_reply->SCSIStatus;
4230 char *desc_ioc_state = NULL;
4231 char *desc_scsi_status = NULL;
4232 char *desc_scsi_state = ioc->tmp_string;
4233 u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
4234 struct _sas_device *sas_device = NULL;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304235 struct scsi_target *starget = scmd->device->sdev_target;
4236 struct MPT3SAS_TARGET *priv_target = starget->hostdata;
4237 char *device_str = NULL;
4238
4239 if (!priv_target)
4240 return;
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05304241 if (ioc->hide_ir_msg)
4242 device_str = "WarpDrive";
4243 else
4244 device_str = "volume";
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304245
4246 if (log_info == 0x31170000)
4247 return;
4248
4249 switch (ioc_status) {
4250 case MPI2_IOCSTATUS_SUCCESS:
4251 desc_ioc_state = "success";
4252 break;
4253 case MPI2_IOCSTATUS_INVALID_FUNCTION:
4254 desc_ioc_state = "invalid function";
4255 break;
4256 case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
4257 desc_ioc_state = "scsi recovered error";
4258 break;
4259 case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE:
4260 desc_ioc_state = "scsi invalid dev handle";
4261 break;
4262 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
4263 desc_ioc_state = "scsi device not there";
4264 break;
4265 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
4266 desc_ioc_state = "scsi data overrun";
4267 break;
4268 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
4269 desc_ioc_state = "scsi data underrun";
4270 break;
4271 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
4272 desc_ioc_state = "scsi io data error";
4273 break;
4274 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
4275 desc_ioc_state = "scsi protocol error";
4276 break;
4277 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
4278 desc_ioc_state = "scsi task terminated";
4279 break;
4280 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
4281 desc_ioc_state = "scsi residual mismatch";
4282 break;
4283 case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
4284 desc_ioc_state = "scsi task mgmt failed";
4285 break;
4286 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
4287 desc_ioc_state = "scsi ioc terminated";
4288 break;
4289 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
4290 desc_ioc_state = "scsi ext terminated";
4291 break;
4292 case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
4293 desc_ioc_state = "eedp guard error";
4294 break;
4295 case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR:
4296 desc_ioc_state = "eedp ref tag error";
4297 break;
4298 case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
4299 desc_ioc_state = "eedp app tag error";
4300 break;
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05304301 case MPI2_IOCSTATUS_INSUFFICIENT_POWER:
4302 desc_ioc_state = "insufficient power";
4303 break;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304304 default:
4305 desc_ioc_state = "unknown";
4306 break;
4307 }
4308
4309 switch (scsi_status) {
4310 case MPI2_SCSI_STATUS_GOOD:
4311 desc_scsi_status = "good";
4312 break;
4313 case MPI2_SCSI_STATUS_CHECK_CONDITION:
4314 desc_scsi_status = "check condition";
4315 break;
4316 case MPI2_SCSI_STATUS_CONDITION_MET:
4317 desc_scsi_status = "condition met";
4318 break;
4319 case MPI2_SCSI_STATUS_BUSY:
4320 desc_scsi_status = "busy";
4321 break;
4322 case MPI2_SCSI_STATUS_INTERMEDIATE:
4323 desc_scsi_status = "intermediate";
4324 break;
4325 case MPI2_SCSI_STATUS_INTERMEDIATE_CONDMET:
4326 desc_scsi_status = "intermediate condmet";
4327 break;
4328 case MPI2_SCSI_STATUS_RESERVATION_CONFLICT:
4329 desc_scsi_status = "reservation conflict";
4330 break;
4331 case MPI2_SCSI_STATUS_COMMAND_TERMINATED:
4332 desc_scsi_status = "command terminated";
4333 break;
4334 case MPI2_SCSI_STATUS_TASK_SET_FULL:
4335 desc_scsi_status = "task set full";
4336 break;
4337 case MPI2_SCSI_STATUS_ACA_ACTIVE:
4338 desc_scsi_status = "aca active";
4339 break;
4340 case MPI2_SCSI_STATUS_TASK_ABORTED:
4341 desc_scsi_status = "task aborted";
4342 break;
4343 default:
4344 desc_scsi_status = "unknown";
4345 break;
4346 }
4347
4348 desc_scsi_state[0] = '\0';
4349 if (!scsi_state)
4350 desc_scsi_state = " ";
4351 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
4352 strcat(desc_scsi_state, "response info ");
4353 if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
4354 strcat(desc_scsi_state, "state terminated ");
4355 if (scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS)
4356 strcat(desc_scsi_state, "no status ");
4357 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_FAILED)
4358 strcat(desc_scsi_state, "autosense failed ");
4359 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID)
4360 strcat(desc_scsi_state, "autosense valid ");
4361
4362 scsi_print_command(scmd);
4363
4364 if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
4365 pr_warn(MPT3SAS_FMT "\t%s wwid(0x%016llx)\n", ioc->name,
4366 device_str, (unsigned long long)priv_target->sas_address);
4367 } else {
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05304368 sas_device = mpt3sas_get_sdev_from_target(ioc, priv_target);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304369 if (sas_device) {
4370 pr_warn(MPT3SAS_FMT
4371 "\tsas_address(0x%016llx), phy(%d)\n",
4372 ioc->name, (unsigned long long)
4373 sas_device->sas_address, sas_device->phy);
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05304374 if (sas_device->enclosure_handle != 0)
4375 pr_warn(MPT3SAS_FMT
4376 "\tenclosure_logical_id(0x%016llx),"
4377 "slot(%d)\n", ioc->name,
4378 (unsigned long long)
4379 sas_device->enclosure_logical_id,
4380 sas_device->slot);
4381 if (sas_device->connector_name[0])
4382 pr_warn(MPT3SAS_FMT
4383 "\tenclosure level(0x%04x),"
4384 " connector name( %s)\n", ioc->name,
4385 sas_device->enclosure_level,
4386 sas_device->connector_name);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05304387
4388 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304389 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304390 }
4391
4392 pr_warn(MPT3SAS_FMT
4393 "\thandle(0x%04x), ioc_status(%s)(0x%04x), smid(%d)\n",
4394 ioc->name, le16_to_cpu(mpi_reply->DevHandle),
4395 desc_ioc_state, ioc_status, smid);
4396 pr_warn(MPT3SAS_FMT
4397 "\trequest_len(%d), underflow(%d), resid(%d)\n",
4398 ioc->name, scsi_bufflen(scmd), scmd->underflow,
4399 scsi_get_resid(scmd));
4400 pr_warn(MPT3SAS_FMT
4401 "\ttag(%d), transfer_count(%d), sc->result(0x%08x)\n",
4402 ioc->name, le16_to_cpu(mpi_reply->TaskTag),
4403 le32_to_cpu(mpi_reply->TransferCount), scmd->result);
4404 pr_warn(MPT3SAS_FMT
4405 "\tscsi_status(%s)(0x%02x), scsi_state(%s)(0x%02x)\n",
4406 ioc->name, desc_scsi_status,
4407 scsi_status, desc_scsi_state, scsi_state);
4408
4409 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
4410 struct sense_info data;
4411 _scsih_normalize_sense(scmd->sense_buffer, &data);
4412 pr_warn(MPT3SAS_FMT
4413 "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], count(%d)\n",
4414 ioc->name, data.skey,
4415 data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
4416 }
4417
4418 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
4419 response_info = le32_to_cpu(mpi_reply->ResponseInfo);
4420 response_bytes = (u8 *)&response_info;
4421 _scsih_response_code(ioc, response_bytes[0]);
4422 }
4423}
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304424
4425/**
Sreekanth Reddy0f624c32014-09-12 15:35:26 +05304426 * _scsih_turn_on_pfa_led - illuminate PFA LED
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304427 * @ioc: per adapter object
4428 * @handle: device handle
4429 * Context: process
4430 *
4431 * Return nothing.
4432 */
4433static void
Sreekanth Reddy0f624c32014-09-12 15:35:26 +05304434_scsih_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304435{
4436 Mpi2SepReply_t mpi_reply;
4437 Mpi2SepRequest_t mpi_request;
Sreekanth Reddy0f624c32014-09-12 15:35:26 +05304438 struct _sas_device *sas_device;
4439
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05304440 sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
Sreekanth Reddy0f624c32014-09-12 15:35:26 +05304441 if (!sas_device)
4442 return;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304443
4444 memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t));
4445 mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
4446 mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS;
4447 mpi_request.SlotStatus =
4448 cpu_to_le32(MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
4449 mpi_request.DevHandle = cpu_to_le16(handle);
4450 mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS;
4451 if ((mpt3sas_base_scsi_enclosure_processor(ioc, &mpi_reply,
4452 &mpi_request)) != 0) {
4453 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name,
4454 __FILE__, __LINE__, __func__);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05304455 goto out;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304456 }
Sreekanth Reddy0f624c32014-09-12 15:35:26 +05304457 sas_device->pfa_led_on = 1;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304458
4459 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) {
4460 dewtprintk(ioc, pr_info(MPT3SAS_FMT
4461 "enclosure_processor: ioc_status (0x%04x), loginfo(0x%08x)\n",
4462 ioc->name, le16_to_cpu(mpi_reply.IOCStatus),
4463 le32_to_cpu(mpi_reply.IOCLogInfo)));
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05304464 goto out;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304465 }
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05304466out:
4467 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304468}
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05304469
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304470/**
Sreekanth Reddy0f624c32014-09-12 15:35:26 +05304471 * _scsih_turn_off_pfa_led - turn off Fault LED
4472 * @ioc: per adapter object
4473 * @sas_device: sas device whose PFA LED has to turned off
4474 * Context: process
4475 *
4476 * Return nothing.
4477 */
4478static void
4479_scsih_turn_off_pfa_led(struct MPT3SAS_ADAPTER *ioc,
4480 struct _sas_device *sas_device)
4481{
4482 Mpi2SepReply_t mpi_reply;
4483 Mpi2SepRequest_t mpi_request;
4484
4485 memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t));
4486 mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
4487 mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS;
4488 mpi_request.SlotStatus = 0;
4489 mpi_request.Slot = cpu_to_le16(sas_device->slot);
4490 mpi_request.DevHandle = 0;
4491 mpi_request.EnclosureHandle = cpu_to_le16(sas_device->enclosure_handle);
4492 mpi_request.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS;
4493 if ((mpt3sas_base_scsi_enclosure_processor(ioc, &mpi_reply,
4494 &mpi_request)) != 0) {
4495 printk(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name,
4496 __FILE__, __LINE__, __func__);
4497 return;
4498 }
4499
4500 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) {
4501 dewtprintk(ioc, printk(MPT3SAS_FMT
4502 "enclosure_processor: ioc_status (0x%04x), loginfo(0x%08x)\n",
4503 ioc->name, le16_to_cpu(mpi_reply.IOCStatus),
4504 le32_to_cpu(mpi_reply.IOCLogInfo)));
4505 return;
4506 }
4507}
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05304508
Sreekanth Reddy0f624c32014-09-12 15:35:26 +05304509/**
4510 * _scsih_send_event_to_turn_on_pfa_led - fire delayed event
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304511 * @ioc: per adapter object
4512 * @handle: device handle
4513 * Context: interrupt.
4514 *
4515 * Return nothing.
4516 */
4517static void
Sreekanth Reddy0f624c32014-09-12 15:35:26 +05304518_scsih_send_event_to_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304519{
4520 struct fw_event_work *fw_event;
4521
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05304522 fw_event = alloc_fw_event_work(0);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304523 if (!fw_event)
4524 return;
Sreekanth Reddy0f624c32014-09-12 15:35:26 +05304525 fw_event->event = MPT3SAS_TURN_ON_PFA_LED;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304526 fw_event->device_handle = handle;
4527 fw_event->ioc = ioc;
4528 _scsih_fw_event_add(ioc, fw_event);
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05304529 fw_event_work_put(fw_event);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304530}
4531
4532/**
4533 * _scsih_smart_predicted_fault - process smart errors
4534 * @ioc: per adapter object
4535 * @handle: device handle
4536 * Context: interrupt.
4537 *
4538 * Return nothing.
4539 */
4540static void
4541_scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle)
4542{
4543 struct scsi_target *starget;
4544 struct MPT3SAS_TARGET *sas_target_priv_data;
4545 Mpi2EventNotificationReply_t *event_reply;
4546 Mpi2EventDataSasDeviceStatusChange_t *event_data;
4547 struct _sas_device *sas_device;
4548 ssize_t sz;
4549 unsigned long flags;
4550
4551 /* only handle non-raid devices */
4552 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05304553 sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
4554 if (!sas_device)
4555 goto out_unlock;
4556
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304557 starget = sas_device->starget;
4558 sas_target_priv_data = starget->hostdata;
4559
4560 if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) ||
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05304561 ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)))
4562 goto out_unlock;
4563
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05304564 if (sas_device->enclosure_handle != 0)
4565 starget_printk(KERN_INFO, starget, "predicted fault, "
4566 "enclosure logical id(0x%016llx), slot(%d)\n",
4567 (unsigned long long)sas_device->enclosure_logical_id,
4568 sas_device->slot);
4569 if (sas_device->connector_name[0] != '\0')
4570 starget_printk(KERN_WARNING, starget, "predicted fault, "
4571 "enclosure level(0x%04x), connector name( %s)\n",
4572 sas_device->enclosure_level,
4573 sas_device->connector_name);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304574 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4575
4576 if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM)
Sreekanth Reddy0f624c32014-09-12 15:35:26 +05304577 _scsih_send_event_to_turn_on_pfa_led(ioc, handle);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304578
4579 /* insert into event log */
4580 sz = offsetof(Mpi2EventNotificationReply_t, EventData) +
4581 sizeof(Mpi2EventDataSasDeviceStatusChange_t);
4582 event_reply = kzalloc(sz, GFP_KERNEL);
4583 if (!event_reply) {
4584 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
4585 ioc->name, __FILE__, __LINE__, __func__);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05304586 goto out;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304587 }
4588
4589 event_reply->Function = MPI2_FUNCTION_EVENT_NOTIFICATION;
4590 event_reply->Event =
4591 cpu_to_le16(MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE);
4592 event_reply->MsgLength = sz/4;
4593 event_reply->EventDataLength =
4594 cpu_to_le16(sizeof(Mpi2EventDataSasDeviceStatusChange_t)/4);
4595 event_data = (Mpi2EventDataSasDeviceStatusChange_t *)
4596 event_reply->EventData;
4597 event_data->ReasonCode = MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA;
4598 event_data->ASC = 0x5D;
4599 event_data->DevHandle = cpu_to_le16(handle);
4600 event_data->SASAddress = cpu_to_le64(sas_target_priv_data->sas_address);
4601 mpt3sas_ctl_add_to_event_log(ioc, event_reply);
4602 kfree(event_reply);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05304603out:
4604 if (sas_device)
4605 sas_device_put(sas_device);
4606 return;
4607
4608out_unlock:
4609 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4610 goto out;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304611}
4612
4613/**
4614 * _scsih_io_done - scsi request callback
4615 * @ioc: per adapter object
4616 * @smid: system request message index
4617 * @msix_index: MSIX table index supplied by the OS
4618 * @reply: reply message frame(lower 32bit addr)
4619 *
4620 * Callback handler when using _scsih_qcmd.
4621 *
4622 * Return 1 meaning mf should be freed from _base_interrupt
4623 * 0 means the mf is freed from this function.
4624 */
4625static u8
4626_scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
4627{
4628 Mpi2SCSIIORequest_t *mpi_request;
4629 Mpi2SCSIIOReply_t *mpi_reply;
4630 struct scsi_cmnd *scmd;
4631 u16 ioc_status;
4632 u32 xfer_cnt;
4633 u8 scsi_state;
4634 u8 scsi_status;
4635 u32 log_info;
4636 struct MPT3SAS_DEVICE *sas_device_priv_data;
4637 u32 response_code = 0;
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05304638 unsigned long flags;
Ram Pai9869fb42017-01-26 16:37:01 -02004639 unsigned int sector_sz;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304640
4641 mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
4642 scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
4643 if (scmd == NULL)
4644 return 1;
4645
James Bottomley16236802017-01-01 09:39:24 -08004646 _scsih_set_satl_pending(scmd, false);
Andrey Grodzovsky18f60842016-11-10 09:35:27 -05004647
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304648 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
4649
4650 if (mpi_reply == NULL) {
4651 scmd->result = DID_OK << 16;
4652 goto out;
4653 }
4654
4655 sas_device_priv_data = scmd->device->hostdata;
4656 if (!sas_device_priv_data || !sas_device_priv_data->sas_target ||
4657 sas_device_priv_data->sas_target->deleted) {
4658 scmd->result = DID_NO_CONNECT << 16;
4659 goto out;
4660 }
4661 ioc_status = le16_to_cpu(mpi_reply->IOCStatus);
4662
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05304663 /*
4664 * WARPDRIVE: If direct_io is set then it is directIO,
4665 * the failed direct I/O should be redirected to volume
4666 */
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05304667 if (mpt3sas_scsi_direct_io_get(ioc, smid) &&
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05304668 ((ioc_status & MPI2_IOCSTATUS_MASK)
4669 != MPI2_IOCSTATUS_SCSI_TASK_TERMINATED)) {
4670 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
4671 ioc->scsi_lookup[smid - 1].scmd = scmd;
4672 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05304673 mpt3sas_scsi_direct_io_set(ioc, smid, 0);
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05304674 memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
4675 mpi_request->DevHandle =
4676 cpu_to_le16(sas_device_priv_data->sas_target->handle);
4677 mpt3sas_base_put_smid_scsi_io(ioc, smid,
4678 sas_device_priv_data->sas_target->handle);
4679 return 0;
4680 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304681 /* turning off TLR */
4682 scsi_state = mpi_reply->SCSIState;
4683 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
4684 response_code =
4685 le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
4686 if (!sas_device_priv_data->tlr_snoop_check) {
4687 sas_device_priv_data->tlr_snoop_check++;
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05304688 if (!ioc->is_warpdrive &&
4689 !scsih_is_raid(&scmd->device->sdev_gendev) &&
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05304690 sas_is_tlr_enabled(scmd->device) &&
4691 response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) {
4692 sas_disable_tlr(scmd->device);
4693 sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n");
4694 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304695 }
4696
4697 xfer_cnt = le32_to_cpu(mpi_reply->TransferCount);
Ram Pai9869fb42017-01-26 16:37:01 -02004698
4699 /* In case of bogus fw or device, we could end up having
4700 * unaligned partial completion. We can force alignment here,
4701 * then scsi-ml does not need to handle this misbehavior.
4702 */
4703 sector_sz = scmd->device->sector_size;
4704 if (unlikely(scmd->request->cmd_type == REQ_TYPE_FS && sector_sz &&
4705 xfer_cnt % sector_sz)) {
4706 sdev_printk(KERN_INFO, scmd->device,
4707 "unaligned partial completion avoided (xfer_cnt=%u, sector_sz=%u)\n",
4708 xfer_cnt, sector_sz);
4709 xfer_cnt = round_down(xfer_cnt, sector_sz);
4710 }
4711
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304712 scsi_set_resid(scmd, scsi_bufflen(scmd) - xfer_cnt);
4713 if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
4714 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
4715 else
4716 log_info = 0;
4717 ioc_status &= MPI2_IOCSTATUS_MASK;
4718 scsi_status = mpi_reply->SCSIStatus;
4719
4720 if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
4721 (scsi_status == MPI2_SCSI_STATUS_BUSY ||
4722 scsi_status == MPI2_SCSI_STATUS_RESERVATION_CONFLICT ||
4723 scsi_status == MPI2_SCSI_STATUS_TASK_SET_FULL)) {
4724 ioc_status = MPI2_IOCSTATUS_SUCCESS;
4725 }
4726
4727 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
4728 struct sense_info data;
4729 const void *sense_data = mpt3sas_base_get_sense_buffer(ioc,
4730 smid);
4731 u32 sz = min_t(u32, SCSI_SENSE_BUFFERSIZE,
4732 le32_to_cpu(mpi_reply->SenseCount));
4733 memcpy(scmd->sense_buffer, sense_data, sz);
4734 _scsih_normalize_sense(scmd->sense_buffer, &data);
4735 /* failure prediction threshold exceeded */
4736 if (data.asc == 0x5D)
4737 _scsih_smart_predicted_fault(ioc,
4738 le16_to_cpu(mpi_reply->DevHandle));
4739 mpt3sas_trigger_scsi(ioc, data.skey, data.asc, data.ascq);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304740
Johannes Thumshirn0d667f72016-08-03 15:00:18 +02004741 if ((ioc->logging_level & MPT_DEBUG_REPLY) &&
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05304742 ((scmd->sense_buffer[2] == UNIT_ATTENTION) ||
4743 (scmd->sense_buffer[2] == MEDIUM_ERROR) ||
4744 (scmd->sense_buffer[2] == HARDWARE_ERROR)))
4745 _scsih_scsi_ioc_info(ioc, scmd, mpi_reply, smid);
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05304746 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304747 switch (ioc_status) {
4748 case MPI2_IOCSTATUS_BUSY:
4749 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
4750 scmd->result = SAM_STAT_BUSY;
4751 break;
4752
4753 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
4754 scmd->result = DID_NO_CONNECT << 16;
4755 break;
4756
4757 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
4758 if (sas_device_priv_data->block) {
4759 scmd->result = DID_TRANSPORT_DISRUPTED << 16;
4760 goto out;
4761 }
4762 if (log_info == 0x31110630) {
4763 if (scmd->retries > 2) {
4764 scmd->result = DID_NO_CONNECT << 16;
4765 scsi_device_set_state(scmd->device,
4766 SDEV_OFFLINE);
4767 } else {
4768 scmd->result = DID_SOFT_ERROR << 16;
4769 scmd->device->expecting_cc_ua = 1;
4770 }
4771 break;
Sreekanth Reddy3898f082015-06-30 12:25:00 +05304772 } else if (log_info == VIRTUAL_IO_FAILED_RETRY) {
4773 scmd->result = DID_RESET << 16;
4774 break;
Sreekanth Reddyb40eeea2017-10-10 18:41:18 +05304775 } else if ((scmd->device->channel == RAID_CHANNEL) &&
4776 (scsi_state == (MPI2_SCSI_STATE_TERMINATED |
4777 MPI2_SCSI_STATE_NO_SCSI_STATUS))) {
4778 scmd->result = DID_RESET << 16;
4779 break;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304780 }
4781 scmd->result = DID_SOFT_ERROR << 16;
4782 break;
4783 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
4784 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
4785 scmd->result = DID_RESET << 16;
4786 break;
4787
4788 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
4789 if ((xfer_cnt == 0) || (scmd->underflow > xfer_cnt))
4790 scmd->result = DID_SOFT_ERROR << 16;
4791 else
4792 scmd->result = (DID_OK << 16) | scsi_status;
4793 break;
4794
4795 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
4796 scmd->result = (DID_OK << 16) | scsi_status;
4797
4798 if ((scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID))
4799 break;
4800
4801 if (xfer_cnt < scmd->underflow) {
4802 if (scsi_status == SAM_STAT_BUSY)
4803 scmd->result = SAM_STAT_BUSY;
4804 else
4805 scmd->result = DID_SOFT_ERROR << 16;
4806 } else if (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED |
4807 MPI2_SCSI_STATE_NO_SCSI_STATUS))
4808 scmd->result = DID_SOFT_ERROR << 16;
4809 else if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
4810 scmd->result = DID_RESET << 16;
4811 else if (!xfer_cnt && scmd->cmnd[0] == REPORT_LUNS) {
4812 mpi_reply->SCSIState = MPI2_SCSI_STATE_AUTOSENSE_VALID;
4813 mpi_reply->SCSIStatus = SAM_STAT_CHECK_CONDITION;
4814 scmd->result = (DRIVER_SENSE << 24) |
4815 SAM_STAT_CHECK_CONDITION;
4816 scmd->sense_buffer[0] = 0x70;
4817 scmd->sense_buffer[2] = ILLEGAL_REQUEST;
4818 scmd->sense_buffer[12] = 0x20;
4819 scmd->sense_buffer[13] = 0;
4820 }
4821 break;
4822
4823 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
4824 scsi_set_resid(scmd, 0);
4825 case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
4826 case MPI2_IOCSTATUS_SUCCESS:
4827 scmd->result = (DID_OK << 16) | scsi_status;
4828 if (response_code ==
4829 MPI2_SCSITASKMGMT_RSP_INVALID_FRAME ||
4830 (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED |
4831 MPI2_SCSI_STATE_NO_SCSI_STATUS)))
4832 scmd->result = DID_SOFT_ERROR << 16;
4833 else if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
4834 scmd->result = DID_RESET << 16;
4835 break;
4836
4837 case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
4838 case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR:
4839 case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
4840 _scsih_eedp_error_handling(scmd, ioc_status);
4841 break;
4842
4843 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
4844 case MPI2_IOCSTATUS_INVALID_FUNCTION:
4845 case MPI2_IOCSTATUS_INVALID_SGL:
4846 case MPI2_IOCSTATUS_INTERNAL_ERROR:
4847 case MPI2_IOCSTATUS_INVALID_FIELD:
4848 case MPI2_IOCSTATUS_INVALID_STATE:
4849 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
4850 case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05304851 case MPI2_IOCSTATUS_INSUFFICIENT_POWER:
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304852 default:
4853 scmd->result = DID_SOFT_ERROR << 16;
4854 break;
4855
4856 }
4857
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304858 if (scmd->result && (ioc->logging_level & MPT_DEBUG_REPLY))
4859 _scsih_scsi_ioc_info(ioc , scmd, mpi_reply, smid);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304860
4861 out:
4862
4863 scsi_dma_unmap(scmd);
4864
4865 scmd->scsi_done(scmd);
4866 return 1;
4867}
4868
4869/**
4870 * _scsih_sas_host_refresh - refreshing sas host object contents
4871 * @ioc: per adapter object
4872 * Context: user
4873 *
4874 * During port enable, fw will send topology events for every device. Its
4875 * possible that the handles may change from the previous setting, so this
4876 * code keeping handles updating if changed.
4877 *
4878 * Return nothing.
4879 */
4880static void
4881_scsih_sas_host_refresh(struct MPT3SAS_ADAPTER *ioc)
4882{
4883 u16 sz;
4884 u16 ioc_status;
4885 int i;
4886 Mpi2ConfigReply_t mpi_reply;
4887 Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
4888 u16 attached_handle;
4889 u8 link_rate;
4890
4891 dtmprintk(ioc, pr_info(MPT3SAS_FMT
4892 "updating handles for sas_host(0x%016llx)\n",
4893 ioc->name, (unsigned long long)ioc->sas_hba.sas_address));
4894
4895 sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys
4896 * sizeof(Mpi2SasIOUnit0PhyData_t));
4897 sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL);
4898 if (!sas_iounit_pg0) {
4899 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
4900 ioc->name, __FILE__, __LINE__, __func__);
4901 return;
4902 }
4903
4904 if ((mpt3sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
4905 sas_iounit_pg0, sz)) != 0)
4906 goto out;
4907 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
4908 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
4909 goto out;
4910 for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
4911 link_rate = sas_iounit_pg0->PhyData[i].NegotiatedLinkRate >> 4;
4912 if (i == 0)
4913 ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
4914 PhyData[0].ControllerDevHandle);
4915 ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
4916 attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i].
4917 AttachedDevHandle);
4918 if (attached_handle && link_rate < MPI2_SAS_NEG_LINK_RATE_1_5)
4919 link_rate = MPI2_SAS_NEG_LINK_RATE_1_5;
4920 mpt3sas_transport_update_links(ioc, ioc->sas_hba.sas_address,
4921 attached_handle, i, link_rate);
4922 }
4923 out:
4924 kfree(sas_iounit_pg0);
4925}
4926
4927/**
4928 * _scsih_sas_host_add - create sas host object
4929 * @ioc: per adapter object
4930 *
4931 * Creating host side data object, stored in ioc->sas_hba
4932 *
4933 * Return nothing.
4934 */
4935static void
4936_scsih_sas_host_add(struct MPT3SAS_ADAPTER *ioc)
4937{
4938 int i;
4939 Mpi2ConfigReply_t mpi_reply;
4940 Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
4941 Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
4942 Mpi2SasPhyPage0_t phy_pg0;
4943 Mpi2SasDevicePage0_t sas_device_pg0;
4944 Mpi2SasEnclosurePage0_t enclosure_pg0;
4945 u16 ioc_status;
4946 u16 sz;
4947 u8 device_missing_delay;
Joe Lawrence87aa95d2016-05-25 15:14:28 -04004948 u8 num_phys;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304949
Joe Lawrence87aa95d2016-05-25 15:14:28 -04004950 mpt3sas_config_get_number_hba_phys(ioc, &num_phys);
4951 if (!num_phys) {
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304952 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
4953 ioc->name, __FILE__, __LINE__, __func__);
4954 return;
4955 }
Joe Lawrence87aa95d2016-05-25 15:14:28 -04004956 ioc->sas_hba.phy = kcalloc(num_phys,
4957 sizeof(struct _sas_phy), GFP_KERNEL);
4958 if (!ioc->sas_hba.phy) {
4959 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
4960 ioc->name, __FILE__, __LINE__, __func__);
4961 goto out;
4962 }
4963 ioc->sas_hba.num_phys = num_phys;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05304964
4965 /* sas_iounit page 0 */
4966 sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys *
4967 sizeof(Mpi2SasIOUnit0PhyData_t));
4968 sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL);
4969 if (!sas_iounit_pg0) {
4970 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
4971 ioc->name, __FILE__, __LINE__, __func__);
4972 return;
4973 }
4974 if ((mpt3sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
4975 sas_iounit_pg0, sz))) {
4976 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
4977 ioc->name, __FILE__, __LINE__, __func__);
4978 goto out;
4979 }
4980 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
4981 MPI2_IOCSTATUS_MASK;
4982 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
4983 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
4984 ioc->name, __FILE__, __LINE__, __func__);
4985 goto out;
4986 }
4987
4988 /* sas_iounit page 1 */
4989 sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
4990 sizeof(Mpi2SasIOUnit1PhyData_t));
4991 sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
4992 if (!sas_iounit_pg1) {
4993 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
4994 ioc->name, __FILE__, __LINE__, __func__);
4995 goto out;
4996 }
4997 if ((mpt3sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
4998 sas_iounit_pg1, sz))) {
4999 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5000 ioc->name, __FILE__, __LINE__, __func__);
5001 goto out;
5002 }
5003 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
5004 MPI2_IOCSTATUS_MASK;
5005 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
5006 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5007 ioc->name, __FILE__, __LINE__, __func__);
5008 goto out;
5009 }
5010
5011 ioc->io_missing_delay =
5012 sas_iounit_pg1->IODeviceMissingDelay;
5013 device_missing_delay =
5014 sas_iounit_pg1->ReportDeviceMissingDelay;
5015 if (device_missing_delay & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16)
5016 ioc->device_missing_delay = (device_missing_delay &
5017 MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16;
5018 else
5019 ioc->device_missing_delay = device_missing_delay &
5020 MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
5021
5022 ioc->sas_hba.parent_dev = &ioc->shost->shost_gendev;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305023 for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
5024 if ((mpt3sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0,
5025 i))) {
5026 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5027 ioc->name, __FILE__, __LINE__, __func__);
5028 goto out;
5029 }
5030 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
5031 MPI2_IOCSTATUS_MASK;
5032 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
5033 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5034 ioc->name, __FILE__, __LINE__, __func__);
5035 goto out;
5036 }
5037
5038 if (i == 0)
5039 ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
5040 PhyData[0].ControllerDevHandle);
5041 ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
5042 ioc->sas_hba.phy[i].phy_id = i;
5043 mpt3sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i],
5044 phy_pg0, ioc->sas_hba.parent_dev);
5045 }
5046 if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
5047 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.handle))) {
5048 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5049 ioc->name, __FILE__, __LINE__, __func__);
5050 goto out;
5051 }
5052 ioc->sas_hba.enclosure_handle =
5053 le16_to_cpu(sas_device_pg0.EnclosureHandle);
5054 ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
5055 pr_info(MPT3SAS_FMT
5056 "host_add: handle(0x%04x), sas_addr(0x%016llx), phys(%d)\n",
5057 ioc->name, ioc->sas_hba.handle,
5058 (unsigned long long) ioc->sas_hba.sas_address,
5059 ioc->sas_hba.num_phys) ;
5060
5061 if (ioc->sas_hba.enclosure_handle) {
5062 if (!(mpt3sas_config_get_enclosure_pg0(ioc, &mpi_reply,
5063 &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
5064 ioc->sas_hba.enclosure_handle)))
5065 ioc->sas_hba.enclosure_logical_id =
5066 le64_to_cpu(enclosure_pg0.EnclosureLogicalID);
5067 }
5068
5069 out:
5070 kfree(sas_iounit_pg1);
5071 kfree(sas_iounit_pg0);
5072}
5073
5074/**
5075 * _scsih_expander_add - creating expander object
5076 * @ioc: per adapter object
5077 * @handle: expander handle
5078 *
5079 * Creating expander object, stored in ioc->sas_expander_list.
5080 *
5081 * Return 0 for success, else error.
5082 */
5083static int
5084_scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle)
5085{
5086 struct _sas_node *sas_expander;
5087 Mpi2ConfigReply_t mpi_reply;
5088 Mpi2ExpanderPage0_t expander_pg0;
5089 Mpi2ExpanderPage1_t expander_pg1;
5090 Mpi2SasEnclosurePage0_t enclosure_pg0;
5091 u32 ioc_status;
5092 u16 parent_handle;
5093 u64 sas_address, sas_address_parent = 0;
5094 int i;
5095 unsigned long flags;
5096 struct _sas_port *mpt3sas_port = NULL;
5097
5098 int rc = 0;
5099
5100 if (!handle)
5101 return -1;
5102
5103 if (ioc->shost_recovery || ioc->pci_error_recovery)
5104 return -1;
5105
5106 if ((mpt3sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
5107 MPI2_SAS_EXPAND_PGAD_FORM_HNDL, handle))) {
5108 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5109 ioc->name, __FILE__, __LINE__, __func__);
5110 return -1;
5111 }
5112
5113 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
5114 MPI2_IOCSTATUS_MASK;
5115 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
5116 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5117 ioc->name, __FILE__, __LINE__, __func__);
5118 return -1;
5119 }
5120
5121 /* handle out of order topology events */
5122 parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle);
5123 if (_scsih_get_sas_address(ioc, parent_handle, &sas_address_parent)
5124 != 0) {
5125 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5126 ioc->name, __FILE__, __LINE__, __func__);
5127 return -1;
5128 }
5129 if (sas_address_parent != ioc->sas_hba.sas_address) {
5130 spin_lock_irqsave(&ioc->sas_node_lock, flags);
5131 sas_expander = mpt3sas_scsih_expander_find_by_sas_address(ioc,
5132 sas_address_parent);
5133 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
5134 if (!sas_expander) {
5135 rc = _scsih_expander_add(ioc, parent_handle);
5136 if (rc != 0)
5137 return rc;
5138 }
5139 }
5140
5141 spin_lock_irqsave(&ioc->sas_node_lock, flags);
5142 sas_address = le64_to_cpu(expander_pg0.SASAddress);
5143 sas_expander = mpt3sas_scsih_expander_find_by_sas_address(ioc,
5144 sas_address);
5145 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
5146
5147 if (sas_expander)
5148 return 0;
5149
5150 sas_expander = kzalloc(sizeof(struct _sas_node),
5151 GFP_KERNEL);
5152 if (!sas_expander) {
5153 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5154 ioc->name, __FILE__, __LINE__, __func__);
5155 return -1;
5156 }
5157
5158 sas_expander->handle = handle;
5159 sas_expander->num_phys = expander_pg0.NumPhys;
5160 sas_expander->sas_address_parent = sas_address_parent;
5161 sas_expander->sas_address = sas_address;
5162
5163 pr_info(MPT3SAS_FMT "expander_add: handle(0x%04x)," \
5164 " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name,
5165 handle, parent_handle, (unsigned long long)
5166 sas_expander->sas_address, sas_expander->num_phys);
5167
5168 if (!sas_expander->num_phys)
5169 goto out_fail;
5170 sas_expander->phy = kcalloc(sas_expander->num_phys,
5171 sizeof(struct _sas_phy), GFP_KERNEL);
5172 if (!sas_expander->phy) {
5173 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5174 ioc->name, __FILE__, __LINE__, __func__);
5175 rc = -1;
5176 goto out_fail;
5177 }
5178
5179 INIT_LIST_HEAD(&sas_expander->sas_port_list);
5180 mpt3sas_port = mpt3sas_transport_port_add(ioc, handle,
5181 sas_address_parent);
5182 if (!mpt3sas_port) {
5183 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5184 ioc->name, __FILE__, __LINE__, __func__);
5185 rc = -1;
5186 goto out_fail;
5187 }
5188 sas_expander->parent_dev = &mpt3sas_port->rphy->dev;
5189
5190 for (i = 0 ; i < sas_expander->num_phys ; i++) {
5191 if ((mpt3sas_config_get_expander_pg1(ioc, &mpi_reply,
5192 &expander_pg1, i, handle))) {
5193 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5194 ioc->name, __FILE__, __LINE__, __func__);
5195 rc = -1;
5196 goto out_fail;
5197 }
5198 sas_expander->phy[i].handle = handle;
5199 sas_expander->phy[i].phy_id = i;
5200
5201 if ((mpt3sas_transport_add_expander_phy(ioc,
5202 &sas_expander->phy[i], expander_pg1,
5203 sas_expander->parent_dev))) {
5204 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5205 ioc->name, __FILE__, __LINE__, __func__);
5206 rc = -1;
5207 goto out_fail;
5208 }
5209 }
5210
5211 if (sas_expander->enclosure_handle) {
5212 if (!(mpt3sas_config_get_enclosure_pg0(ioc, &mpi_reply,
5213 &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
5214 sas_expander->enclosure_handle)))
5215 sas_expander->enclosure_logical_id =
5216 le64_to_cpu(enclosure_pg0.EnclosureLogicalID);
5217 }
5218
5219 _scsih_expander_node_add(ioc, sas_expander);
5220 return 0;
5221
5222 out_fail:
5223
5224 if (mpt3sas_port)
5225 mpt3sas_transport_port_remove(ioc, sas_expander->sas_address,
5226 sas_address_parent);
5227 kfree(sas_expander);
5228 return rc;
5229}
5230
5231/**
5232 * mpt3sas_expander_remove - removing expander object
5233 * @ioc: per adapter object
5234 * @sas_address: expander sas_address
5235 *
5236 * Return nothing.
5237 */
5238void
5239mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address)
5240{
5241 struct _sas_node *sas_expander;
5242 unsigned long flags;
5243
5244 if (ioc->shost_recovery)
5245 return;
5246
5247 spin_lock_irqsave(&ioc->sas_node_lock, flags);
5248 sas_expander = mpt3sas_scsih_expander_find_by_sas_address(ioc,
5249 sas_address);
5250 if (sas_expander)
5251 list_del(&sas_expander->list);
5252 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
5253 if (sas_expander)
5254 _scsih_expander_node_remove(ioc, sas_expander);
5255}
5256
5257/**
5258 * _scsih_done - internal SCSI_IO callback handler.
5259 * @ioc: per adapter object
5260 * @smid: system request message index
5261 * @msix_index: MSIX table index supplied by the OS
5262 * @reply: reply message frame(lower 32bit addr)
5263 *
5264 * Callback handler when sending internal generated SCSI_IO.
5265 * The callback index passed is `ioc->scsih_cb_idx`
5266 *
5267 * Return 1 meaning mf should be freed from _base_interrupt
5268 * 0 means the mf is freed from this function.
5269 */
5270static u8
5271_scsih_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
5272{
5273 MPI2DefaultReply_t *mpi_reply;
5274
5275 mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
5276 if (ioc->scsih_cmds.status == MPT3_CMD_NOT_USED)
5277 return 1;
5278 if (ioc->scsih_cmds.smid != smid)
5279 return 1;
5280 ioc->scsih_cmds.status |= MPT3_CMD_COMPLETE;
5281 if (mpi_reply) {
5282 memcpy(ioc->scsih_cmds.reply, mpi_reply,
5283 mpi_reply->MsgLength*4);
5284 ioc->scsih_cmds.status |= MPT3_CMD_REPLY_VALID;
5285 }
5286 ioc->scsih_cmds.status &= ~MPT3_CMD_PENDING;
5287 complete(&ioc->scsih_cmds.done);
5288 return 1;
5289}
5290
5291
5292
5293
5294#define MPT3_MAX_LUNS (255)
5295
5296
5297/**
5298 * _scsih_check_access_status - check access flags
5299 * @ioc: per adapter object
5300 * @sas_address: sas address
5301 * @handle: sas device handle
5302 * @access_flags: errors returned during discovery of the device
5303 *
5304 * Return 0 for success, else failure
5305 */
5306static u8
5307_scsih_check_access_status(struct MPT3SAS_ADAPTER *ioc, u64 sas_address,
5308 u16 handle, u8 access_status)
5309{
5310 u8 rc = 1;
5311 char *desc = NULL;
5312
5313 switch (access_status) {
5314 case MPI2_SAS_DEVICE0_ASTATUS_NO_ERRORS:
5315 case MPI2_SAS_DEVICE0_ASTATUS_SATA_NEEDS_INITIALIZATION:
5316 rc = 0;
5317 break;
5318 case MPI2_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED:
5319 desc = "sata capability failed";
5320 break;
5321 case MPI2_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT:
5322 desc = "sata affiliation conflict";
5323 break;
5324 case MPI2_SAS_DEVICE0_ASTATUS_ROUTE_NOT_ADDRESSABLE:
5325 desc = "route not addressable";
5326 break;
5327 case MPI2_SAS_DEVICE0_ASTATUS_SMP_ERROR_NOT_ADDRESSABLE:
5328 desc = "smp error not addressable";
5329 break;
5330 case MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED:
5331 desc = "device blocked";
5332 break;
5333 case MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED:
5334 case MPI2_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN:
5335 case MPI2_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT:
5336 case MPI2_SAS_DEVICE0_ASTATUS_SIF_DIAG:
5337 case MPI2_SAS_DEVICE0_ASTATUS_SIF_IDENTIFICATION:
5338 case MPI2_SAS_DEVICE0_ASTATUS_SIF_CHECK_POWER:
5339 case MPI2_SAS_DEVICE0_ASTATUS_SIF_PIO_SN:
5340 case MPI2_SAS_DEVICE0_ASTATUS_SIF_MDMA_SN:
5341 case MPI2_SAS_DEVICE0_ASTATUS_SIF_UDMA_SN:
5342 case MPI2_SAS_DEVICE0_ASTATUS_SIF_ZONING_VIOLATION:
5343 case MPI2_SAS_DEVICE0_ASTATUS_SIF_NOT_ADDRESSABLE:
5344 case MPI2_SAS_DEVICE0_ASTATUS_SIF_MAX:
5345 desc = "sata initialization failed";
5346 break;
5347 default:
5348 desc = "unknown";
5349 break;
5350 }
5351
5352 if (!rc)
5353 return 0;
5354
5355 pr_err(MPT3SAS_FMT
5356 "discovery errors(%s): sas_address(0x%016llx), handle(0x%04x)\n",
5357 ioc->name, desc, (unsigned long long)sas_address, handle);
5358 return rc;
5359}
5360
5361/**
5362 * _scsih_check_device - checking device responsiveness
5363 * @ioc: per adapter object
5364 * @parent_sas_address: sas address of parent expander or sas host
5365 * @handle: attached device handle
5366 * @phy_numberv: phy number
5367 * @link_rate: new link rate
5368 *
5369 * Returns nothing.
5370 */
5371static void
5372_scsih_check_device(struct MPT3SAS_ADAPTER *ioc,
5373 u64 parent_sas_address, u16 handle, u8 phy_number, u8 link_rate)
5374{
5375 Mpi2ConfigReply_t mpi_reply;
5376 Mpi2SasDevicePage0_t sas_device_pg0;
5377 struct _sas_device *sas_device;
5378 u32 ioc_status;
5379 unsigned long flags;
5380 u64 sas_address;
5381 struct scsi_target *starget;
5382 struct MPT3SAS_TARGET *sas_target_priv_data;
5383 u32 device_info;
5384
5385
5386 if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
5387 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle)))
5388 return;
5389
5390 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
5391 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
5392 return;
5393
5394 /* wide port handling ~ we need only handle device once for the phy that
5395 * is matched in sas device page zero
5396 */
5397 if (phy_number != sas_device_pg0.PhyNum)
5398 return;
5399
5400 /* check if this is end device */
5401 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
5402 if (!(_scsih_is_end_device(device_info)))
5403 return;
5404
5405 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5406 sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05305407 sas_device = __mpt3sas_get_sdev_by_addr(ioc,
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305408 sas_address);
5409
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05305410 if (!sas_device)
5411 goto out_unlock;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305412
5413 if (unlikely(sas_device->handle != handle)) {
5414 starget = sas_device->starget;
5415 sas_target_priv_data = starget->hostdata;
5416 starget_printk(KERN_INFO, starget,
5417 "handle changed from(0x%04x) to (0x%04x)!!!\n",
5418 sas_device->handle, handle);
5419 sas_target_priv_data->handle = handle;
5420 sas_device->handle = handle;
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05305421 if (sas_device_pg0.Flags &
5422 MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) {
5423 sas_device->enclosure_level =
5424 le16_to_cpu(sas_device_pg0.EnclosureLevel);
Calvin Owens310c8e42016-07-27 21:45:51 -07005425 memcpy(sas_device->connector_name,
5426 sas_device_pg0.ConnectorName, 4);
5427 sas_device->connector_name[4] = '\0';
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05305428 } else {
5429 sas_device->enclosure_level = 0;
5430 sas_device->connector_name[0] = '\0';
5431 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305432 }
5433
5434 /* check if device is present */
5435 if (!(le16_to_cpu(sas_device_pg0.Flags) &
5436 MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) {
5437 pr_err(MPT3SAS_FMT
5438 "device is not present handle(0x%04x), flags!!!\n",
5439 ioc->name, handle);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05305440 goto out_unlock;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305441 }
5442
5443 /* check if there were any issues with discovery */
5444 if (_scsih_check_access_status(ioc, sas_address, handle,
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05305445 sas_device_pg0.AccessStatus))
5446 goto out_unlock;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305447
5448 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5449 _scsih_ublock_io_device(ioc, sas_address);
5450
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05305451 if (sas_device)
5452 sas_device_put(sas_device);
5453 return;
5454
5455out_unlock:
5456 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5457 if (sas_device)
5458 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305459}
5460
5461/**
5462 * _scsih_add_device - creating sas device object
5463 * @ioc: per adapter object
5464 * @handle: sas device handle
5465 * @phy_num: phy number end device attached to
5466 * @is_pd: is this hidden raid component
5467 *
5468 * Creating end device object, stored in ioc->sas_device_list.
5469 *
5470 * Returns 0 for success, non-zero for failure.
5471 */
5472static int
5473_scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num,
5474 u8 is_pd)
5475{
5476 Mpi2ConfigReply_t mpi_reply;
5477 Mpi2SasDevicePage0_t sas_device_pg0;
5478 Mpi2SasEnclosurePage0_t enclosure_pg0;
5479 struct _sas_device *sas_device;
5480 u32 ioc_status;
5481 u64 sas_address;
5482 u32 device_info;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305483
5484 if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
5485 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
5486 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5487 ioc->name, __FILE__, __LINE__, __func__);
5488 return -1;
5489 }
5490
5491 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
5492 MPI2_IOCSTATUS_MASK;
5493 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
5494 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5495 ioc->name, __FILE__, __LINE__, __func__);
5496 return -1;
5497 }
5498
5499 /* check if this is end device */
5500 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
5501 if (!(_scsih_is_end_device(device_info)))
5502 return -1;
5503 sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
5504
5505 /* check if device is present */
5506 if (!(le16_to_cpu(sas_device_pg0.Flags) &
5507 MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) {
5508 pr_err(MPT3SAS_FMT "device is not present handle(0x04%x)!!!\n",
5509 ioc->name, handle);
5510 return -1;
5511 }
5512
5513 /* check if there were any issues with discovery */
5514 if (_scsih_check_access_status(ioc, sas_address, handle,
5515 sas_device_pg0.AccessStatus))
5516 return -1;
5517
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05305518 sas_device = mpt3sas_get_sdev_by_addr(ioc,
5519 sas_address);
5520 if (sas_device) {
5521 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305522 return -1;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05305523 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305524
5525 sas_device = kzalloc(sizeof(struct _sas_device),
5526 GFP_KERNEL);
5527 if (!sas_device) {
5528 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5529 ioc->name, __FILE__, __LINE__, __func__);
5530 return 0;
5531 }
5532
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05305533 kref_init(&sas_device->refcount);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305534 sas_device->handle = handle;
5535 if (_scsih_get_sas_address(ioc,
5536 le16_to_cpu(sas_device_pg0.ParentDevHandle),
5537 &sas_device->sas_address_parent) != 0)
5538 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
5539 ioc->name, __FILE__, __LINE__, __func__);
5540 sas_device->enclosure_handle =
5541 le16_to_cpu(sas_device_pg0.EnclosureHandle);
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05305542 if (sas_device->enclosure_handle != 0)
5543 sas_device->slot =
5544 le16_to_cpu(sas_device_pg0.Slot);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305545 sas_device->device_info = device_info;
5546 sas_device->sas_address = sas_address;
5547 sas_device->phy = sas_device_pg0.PhyNum;
5548 sas_device->fast_path = (le16_to_cpu(sas_device_pg0.Flags) &
5549 MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) ? 1 : 0;
5550
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05305551 if (sas_device_pg0.Flags & MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) {
5552 sas_device->enclosure_level =
5553 le16_to_cpu(sas_device_pg0.EnclosureLevel);
Calvin Owens310c8e42016-07-27 21:45:51 -07005554 memcpy(sas_device->connector_name,
5555 sas_device_pg0.ConnectorName, 4);
5556 sas_device->connector_name[4] = '\0';
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05305557 } else {
5558 sas_device->enclosure_level = 0;
5559 sas_device->connector_name[0] = '\0';
5560 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305561 /* get enclosure_logical_id */
5562 if (sas_device->enclosure_handle && !(mpt3sas_config_get_enclosure_pg0(
5563 ioc, &mpi_reply, &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
5564 sas_device->enclosure_handle)))
5565 sas_device->enclosure_logical_id =
5566 le64_to_cpu(enclosure_pg0.EnclosureLogicalID);
5567
5568 /* get device name */
5569 sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName);
5570
5571 if (ioc->wait_for_discovery_to_complete)
5572 _scsih_sas_device_init_add(ioc, sas_device);
5573 else
5574 _scsih_sas_device_add(ioc, sas_device);
5575
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05305576 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305577 return 0;
5578}
5579
5580/**
5581 * _scsih_remove_device - removing sas device object
5582 * @ioc: per adapter object
5583 * @sas_device_delete: the sas_device object
5584 *
5585 * Return nothing.
5586 */
5587static void
5588_scsih_remove_device(struct MPT3SAS_ADAPTER *ioc,
5589 struct _sas_device *sas_device)
5590{
5591 struct MPT3SAS_TARGET *sas_target_priv_data;
5592
Sreekanth Reddy0f624c32014-09-12 15:35:26 +05305593 if ((ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) &&
5594 (sas_device->pfa_led_on)) {
5595 _scsih_turn_off_pfa_led(ioc, sas_device);
5596 sas_device->pfa_led_on = 0;
5597 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305598 dewtprintk(ioc, pr_info(MPT3SAS_FMT
5599 "%s: enter: handle(0x%04x), sas_addr(0x%016llx)\n",
5600 ioc->name, __func__,
5601 sas_device->handle, (unsigned long long)
5602 sas_device->sas_address));
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05305603 if (sas_device->enclosure_handle != 0)
5604 dewtprintk(ioc, pr_info(MPT3SAS_FMT
5605 "%s: enter: enclosure logical id(0x%016llx), slot(%d)\n",
5606 ioc->name, __func__,
5607 (unsigned long long)sas_device->enclosure_logical_id,
5608 sas_device->slot));
5609 if (sas_device->connector_name[0] != '\0')
5610 dewtprintk(ioc, pr_info(MPT3SAS_FMT
5611 "%s: enter: enclosure level(0x%04x), connector name( %s)\n",
5612 ioc->name, __func__,
5613 sas_device->enclosure_level,
5614 sas_device->connector_name));
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305615
5616 if (sas_device->starget && sas_device->starget->hostdata) {
5617 sas_target_priv_data = sas_device->starget->hostdata;
5618 sas_target_priv_data->deleted = 1;
5619 _scsih_ublock_io_device(ioc, sas_device->sas_address);
5620 sas_target_priv_data->handle =
5621 MPT3SAS_INVALID_DEVICE_HANDLE;
5622 }
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05305623
5624 if (!ioc->hide_drives)
5625 mpt3sas_transport_port_remove(ioc,
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305626 sas_device->sas_address,
5627 sas_device->sas_address_parent);
5628
5629 pr_info(MPT3SAS_FMT
5630 "removing handle(0x%04x), sas_addr(0x%016llx)\n",
5631 ioc->name, sas_device->handle,
5632 (unsigned long long) sas_device->sas_address);
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05305633 if (sas_device->enclosure_handle != 0)
5634 pr_info(MPT3SAS_FMT
5635 "removing : enclosure logical id(0x%016llx), slot(%d)\n",
5636 ioc->name,
5637 (unsigned long long)sas_device->enclosure_logical_id,
5638 sas_device->slot);
5639 if (sas_device->connector_name[0] != '\0')
5640 pr_info(MPT3SAS_FMT
5641 "removing enclosure level(0x%04x), connector name( %s)\n",
5642 ioc->name, sas_device->enclosure_level,
5643 sas_device->connector_name);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305644
5645 dewtprintk(ioc, pr_info(MPT3SAS_FMT
5646 "%s: exit: handle(0x%04x), sas_addr(0x%016llx)\n",
5647 ioc->name, __func__,
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05305648 sas_device->handle, (unsigned long long)
5649 sas_device->sas_address));
5650 if (sas_device->enclosure_handle != 0)
5651 dewtprintk(ioc, pr_info(MPT3SAS_FMT
5652 "%s: exit: enclosure logical id(0x%016llx), slot(%d)\n",
5653 ioc->name, __func__,
5654 (unsigned long long)sas_device->enclosure_logical_id,
5655 sas_device->slot));
5656 if (sas_device->connector_name[0] != '\0')
5657 dewtprintk(ioc, pr_info(MPT3SAS_FMT
5658 "%s: exit: enclosure level(0x%04x), connector name(%s)\n",
5659 ioc->name, __func__, sas_device->enclosure_level,
5660 sas_device->connector_name));
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305661}
5662
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305663/**
5664 * _scsih_sas_topology_change_event_debug - debug for topology event
5665 * @ioc: per adapter object
5666 * @event_data: event data payload
5667 * Context: user.
5668 */
5669static void
5670_scsih_sas_topology_change_event_debug(struct MPT3SAS_ADAPTER *ioc,
5671 Mpi2EventDataSasTopologyChangeList_t *event_data)
5672{
5673 int i;
5674 u16 handle;
5675 u16 reason_code;
5676 u8 phy_number;
5677 char *status_str = NULL;
5678 u8 link_rate, prev_link_rate;
5679
5680 switch (event_data->ExpStatus) {
5681 case MPI2_EVENT_SAS_TOPO_ES_ADDED:
5682 status_str = "add";
5683 break;
5684 case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING:
5685 status_str = "remove";
5686 break;
5687 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
5688 case 0:
5689 status_str = "responding";
5690 break;
5691 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
5692 status_str = "remove delay";
5693 break;
5694 default:
5695 status_str = "unknown status";
5696 break;
5697 }
5698 pr_info(MPT3SAS_FMT "sas topology change: (%s)\n",
5699 ioc->name, status_str);
5700 pr_info("\thandle(0x%04x), enclosure_handle(0x%04x) " \
5701 "start_phy(%02d), count(%d)\n",
5702 le16_to_cpu(event_data->ExpanderDevHandle),
5703 le16_to_cpu(event_data->EnclosureHandle),
5704 event_data->StartPhyNum, event_data->NumEntries);
5705 for (i = 0; i < event_data->NumEntries; i++) {
5706 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
5707 if (!handle)
5708 continue;
5709 phy_number = event_data->StartPhyNum + i;
5710 reason_code = event_data->PHY[i].PhyStatus &
5711 MPI2_EVENT_SAS_TOPO_RC_MASK;
5712 switch (reason_code) {
5713 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
5714 status_str = "target add";
5715 break;
5716 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
5717 status_str = "target remove";
5718 break;
5719 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
5720 status_str = "delay target remove";
5721 break;
5722 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
5723 status_str = "link rate change";
5724 break;
5725 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
5726 status_str = "target responding";
5727 break;
5728 default:
5729 status_str = "unknown";
5730 break;
5731 }
5732 link_rate = event_data->PHY[i].LinkRate >> 4;
5733 prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
5734 pr_info("\tphy(%02d), attached_handle(0x%04x): %s:" \
5735 " link rate: new(0x%02x), old(0x%02x)\n", phy_number,
5736 handle, status_str, link_rate, prev_link_rate);
5737
5738 }
5739}
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305740
5741/**
5742 * _scsih_sas_topology_change_event - handle topology changes
5743 * @ioc: per adapter object
5744 * @fw_event: The fw_event_work object
5745 * Context: user.
5746 *
5747 */
5748static int
5749_scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc,
5750 struct fw_event_work *fw_event)
5751{
5752 int i;
5753 u16 parent_handle, handle;
5754 u16 reason_code;
5755 u8 phy_number, max_phys;
5756 struct _sas_node *sas_expander;
5757 u64 sas_address;
5758 unsigned long flags;
5759 u8 link_rate, prev_link_rate;
Joe Lawrence35b62362014-06-25 17:05:34 -04005760 Mpi2EventDataSasTopologyChangeList_t *event_data =
5761 (Mpi2EventDataSasTopologyChangeList_t *)
5762 fw_event->event_data;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305763
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305764 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
5765 _scsih_sas_topology_change_event_debug(ioc, event_data);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305766
5767 if (ioc->shost_recovery || ioc->remove_host || ioc->pci_error_recovery)
5768 return 0;
5769
5770 if (!ioc->sas_hba.num_phys)
5771 _scsih_sas_host_add(ioc);
5772 else
5773 _scsih_sas_host_refresh(ioc);
5774
5775 if (fw_event->ignore) {
5776 dewtprintk(ioc, pr_info(MPT3SAS_FMT
5777 "ignoring expander event\n", ioc->name));
5778 return 0;
5779 }
5780
5781 parent_handle = le16_to_cpu(event_data->ExpanderDevHandle);
5782
5783 /* handle expander add */
5784 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_ADDED)
5785 if (_scsih_expander_add(ioc, parent_handle) != 0)
5786 return 0;
5787
5788 spin_lock_irqsave(&ioc->sas_node_lock, flags);
5789 sas_expander = mpt3sas_scsih_expander_find_by_handle(ioc,
5790 parent_handle);
5791 if (sas_expander) {
5792 sas_address = sas_expander->sas_address;
5793 max_phys = sas_expander->num_phys;
5794 } else if (parent_handle < ioc->sas_hba.num_phys) {
5795 sas_address = ioc->sas_hba.sas_address;
5796 max_phys = ioc->sas_hba.num_phys;
5797 } else {
5798 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
5799 return 0;
5800 }
5801 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
5802
5803 /* handle siblings events */
5804 for (i = 0; i < event_data->NumEntries; i++) {
5805 if (fw_event->ignore) {
5806 dewtprintk(ioc, pr_info(MPT3SAS_FMT
5807 "ignoring expander event\n", ioc->name));
5808 return 0;
5809 }
5810 if (ioc->remove_host || ioc->pci_error_recovery)
5811 return 0;
5812 phy_number = event_data->StartPhyNum + i;
5813 if (phy_number >= max_phys)
5814 continue;
5815 reason_code = event_data->PHY[i].PhyStatus &
5816 MPI2_EVENT_SAS_TOPO_RC_MASK;
5817 if ((event_data->PHY[i].PhyStatus &
5818 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) && (reason_code !=
5819 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING))
5820 continue;
5821 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
5822 if (!handle)
5823 continue;
5824 link_rate = event_data->PHY[i].LinkRate >> 4;
5825 prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
5826 switch (reason_code) {
5827 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
5828
5829 if (ioc->shost_recovery)
5830 break;
5831
5832 if (link_rate == prev_link_rate)
5833 break;
5834
5835 mpt3sas_transport_update_links(ioc, sas_address,
5836 handle, phy_number, link_rate);
5837
5838 if (link_rate < MPI2_SAS_NEG_LINK_RATE_1_5)
5839 break;
5840
5841 _scsih_check_device(ioc, sas_address, handle,
5842 phy_number, link_rate);
5843
5844
5845 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
5846
5847 if (ioc->shost_recovery)
5848 break;
5849
5850 mpt3sas_transport_update_links(ioc, sas_address,
5851 handle, phy_number, link_rate);
5852
5853 _scsih_add_device(ioc, handle, phy_number, 0);
5854
5855 break;
5856 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
5857
5858 _scsih_device_remove_by_handle(ioc, handle);
5859 break;
5860 }
5861 }
5862
5863 /* handle expander removal */
5864 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING &&
5865 sas_expander)
5866 mpt3sas_expander_remove(ioc, sas_address);
5867
5868 return 0;
5869}
5870
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305871/**
5872 * _scsih_sas_device_status_change_event_debug - debug for device event
5873 * @event_data: event data payload
5874 * Context: user.
5875 *
5876 * Return nothing.
5877 */
5878static void
5879_scsih_sas_device_status_change_event_debug(struct MPT3SAS_ADAPTER *ioc,
5880 Mpi2EventDataSasDeviceStatusChange_t *event_data)
5881{
5882 char *reason_str = NULL;
5883
5884 switch (event_data->ReasonCode) {
5885 case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
5886 reason_str = "smart data";
5887 break;
5888 case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
5889 reason_str = "unsupported device discovered";
5890 break;
5891 case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
5892 reason_str = "internal device reset";
5893 break;
5894 case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
5895 reason_str = "internal task abort";
5896 break;
5897 case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
5898 reason_str = "internal task abort set";
5899 break;
5900 case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
5901 reason_str = "internal clear task set";
5902 break;
5903 case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
5904 reason_str = "internal query task";
5905 break;
5906 case MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE:
5907 reason_str = "sata init failure";
5908 break;
5909 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET:
5910 reason_str = "internal device reset complete";
5911 break;
5912 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL:
5913 reason_str = "internal task abort complete";
5914 break;
5915 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION:
5916 reason_str = "internal async notification";
5917 break;
5918 case MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY:
5919 reason_str = "expander reduced functionality";
5920 break;
5921 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY:
5922 reason_str = "expander reduced functionality complete";
5923 break;
5924 default:
5925 reason_str = "unknown reason";
5926 break;
5927 }
5928 pr_info(MPT3SAS_FMT "device status change: (%s)\n"
5929 "\thandle(0x%04x), sas address(0x%016llx), tag(%d)",
5930 ioc->name, reason_str, le16_to_cpu(event_data->DevHandle),
5931 (unsigned long long)le64_to_cpu(event_data->SASAddress),
5932 le16_to_cpu(event_data->TaskTag));
5933 if (event_data->ReasonCode == MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA)
5934 pr_info(MPT3SAS_FMT ", ASC(0x%x), ASCQ(0x%x)\n", ioc->name,
5935 event_data->ASC, event_data->ASCQ);
5936 pr_info("\n");
5937}
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305938
5939/**
5940 * _scsih_sas_device_status_change_event - handle device status change
5941 * @ioc: per adapter object
5942 * @fw_event: The fw_event_work object
5943 * Context: user.
5944 *
5945 * Return nothing.
5946 */
5947static void
5948_scsih_sas_device_status_change_event(struct MPT3SAS_ADAPTER *ioc,
5949 struct fw_event_work *fw_event)
5950{
5951 struct MPT3SAS_TARGET *target_priv_data;
5952 struct _sas_device *sas_device;
5953 u64 sas_address;
5954 unsigned long flags;
5955 Mpi2EventDataSasDeviceStatusChange_t *event_data =
Joe Lawrence35b62362014-06-25 17:05:34 -04005956 (Mpi2EventDataSasDeviceStatusChange_t *)
5957 fw_event->event_data;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305958
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305959 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
5960 _scsih_sas_device_status_change_event_debug(ioc,
5961 event_data);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305962
5963 /* In MPI Revision K (0xC), the internal device reset complete was
5964 * implemented, so avoid setting tm_busy flag for older firmware.
5965 */
5966 if ((ioc->facts.HeaderVersion >> 8) < 0xC)
5967 return;
5968
5969 if (event_data->ReasonCode !=
5970 MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
5971 event_data->ReasonCode !=
5972 MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET)
5973 return;
5974
5975 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5976 sas_address = le64_to_cpu(event_data->SASAddress);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05305977 sas_device = __mpt3sas_get_sdev_by_addr(ioc,
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305978 sas_address);
5979
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05305980 if (!sas_device || !sas_device->starget)
5981 goto out;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305982
5983 target_priv_data = sas_device->starget->hostdata;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05305984 if (!target_priv_data)
5985 goto out;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305986
5987 if (event_data->ReasonCode ==
5988 MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET)
5989 target_priv_data->tm_busy = 1;
5990 else
5991 target_priv_data->tm_busy = 0;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05305992
5993out:
5994 if (sas_device)
5995 sas_device_put(sas_device);
5996
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305997 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05305998
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05305999}
6000
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306001/**
6002 * _scsih_sas_enclosure_dev_status_change_event_debug - debug for enclosure
6003 * event
6004 * @ioc: per adapter object
6005 * @event_data: event data payload
6006 * Context: user.
6007 *
6008 * Return nothing.
6009 */
6010static void
6011_scsih_sas_enclosure_dev_status_change_event_debug(struct MPT3SAS_ADAPTER *ioc,
6012 Mpi2EventDataSasEnclDevStatusChange_t *event_data)
6013{
6014 char *reason_str = NULL;
6015
6016 switch (event_data->ReasonCode) {
6017 case MPI2_EVENT_SAS_ENCL_RC_ADDED:
6018 reason_str = "enclosure add";
6019 break;
6020 case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING:
6021 reason_str = "enclosure remove";
6022 break;
6023 default:
6024 reason_str = "unknown reason";
6025 break;
6026 }
6027
6028 pr_info(MPT3SAS_FMT "enclosure status change: (%s)\n"
6029 "\thandle(0x%04x), enclosure logical id(0x%016llx)"
6030 " number slots(%d)\n", ioc->name, reason_str,
6031 le16_to_cpu(event_data->EnclosureHandle),
6032 (unsigned long long)le64_to_cpu(event_data->EnclosureLogicalID),
6033 le16_to_cpu(event_data->StartSlot));
6034}
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306035
6036/**
6037 * _scsih_sas_enclosure_dev_status_change_event - handle enclosure events
6038 * @ioc: per adapter object
6039 * @fw_event: The fw_event_work object
6040 * Context: user.
6041 *
6042 * Return nothing.
6043 */
6044static void
6045_scsih_sas_enclosure_dev_status_change_event(struct MPT3SAS_ADAPTER *ioc,
6046 struct fw_event_work *fw_event)
6047{
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306048 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
6049 _scsih_sas_enclosure_dev_status_change_event_debug(ioc,
Joe Lawrence35b62362014-06-25 17:05:34 -04006050 (Mpi2EventDataSasEnclDevStatusChange_t *)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306051 fw_event->event_data);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306052}
6053
6054/**
6055 * _scsih_sas_broadcast_primitive_event - handle broadcast events
6056 * @ioc: per adapter object
6057 * @fw_event: The fw_event_work object
6058 * Context: user.
6059 *
6060 * Return nothing.
6061 */
6062static void
6063_scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc,
6064 struct fw_event_work *fw_event)
6065{
6066 struct scsi_cmnd *scmd;
6067 struct scsi_device *sdev;
6068 u16 smid, handle;
6069 u32 lun;
6070 struct MPT3SAS_DEVICE *sas_device_priv_data;
6071 u32 termination_count;
6072 u32 query_count;
6073 Mpi2SCSITaskManagementReply_t *mpi_reply;
Joe Lawrence35b62362014-06-25 17:05:34 -04006074 Mpi2EventDataSasBroadcastPrimitive_t *event_data =
6075 (Mpi2EventDataSasBroadcastPrimitive_t *)
6076 fw_event->event_data;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306077 u16 ioc_status;
6078 unsigned long flags;
6079 int r;
6080 u8 max_retries = 0;
6081 u8 task_abort_retries;
6082
6083 mutex_lock(&ioc->tm_cmds.mutex);
6084 pr_info(MPT3SAS_FMT
6085 "%s: enter: phy number(%d), width(%d)\n",
6086 ioc->name, __func__, event_data->PhyNum,
6087 event_data->PortWidth);
6088
6089 _scsih_block_io_all_device(ioc);
6090
6091 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
6092 mpi_reply = ioc->tm_cmds.reply;
6093 broadcast_aen_retry:
6094
6095 /* sanity checks for retrying this loop */
6096 if (max_retries++ == 5) {
6097 dewtprintk(ioc, pr_info(MPT3SAS_FMT "%s: giving up\n",
6098 ioc->name, __func__));
6099 goto out;
6100 } else if (max_retries > 1)
6101 dewtprintk(ioc, pr_info(MPT3SAS_FMT "%s: %d retry\n",
6102 ioc->name, __func__, max_retries - 1));
6103
6104 termination_count = 0;
6105 query_count = 0;
6106 for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
6107 if (ioc->shost_recovery)
6108 goto out;
6109 scmd = _scsih_scsi_lookup_get(ioc, smid);
6110 if (!scmd)
6111 continue;
6112 sdev = scmd->device;
6113 sas_device_priv_data = sdev->hostdata;
6114 if (!sas_device_priv_data || !sas_device_priv_data->sas_target)
6115 continue;
6116 /* skip hidden raid components */
6117 if (sas_device_priv_data->sas_target->flags &
6118 MPT_TARGET_FLAGS_RAID_COMPONENT)
6119 continue;
6120 /* skip volumes */
6121 if (sas_device_priv_data->sas_target->flags &
6122 MPT_TARGET_FLAGS_VOLUME)
6123 continue;
6124
6125 handle = sas_device_priv_data->sas_target->handle;
6126 lun = sas_device_priv_data->lun;
6127 query_count++;
6128
6129 if (ioc->shost_recovery)
6130 goto out;
6131
6132 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
6133 r = mpt3sas_scsih_issue_tm(ioc, handle, 0, 0, lun,
Calvin Owens96902832016-07-28 21:38:20 -07006134 MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306135 if (r == FAILED) {
6136 sdev_printk(KERN_WARNING, sdev,
6137 "mpt3sas_scsih_issue_tm: FAILED when sending "
6138 "QUERY_TASK: scmd(%p)\n", scmd);
6139 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
6140 goto broadcast_aen_retry;
6141 }
6142 ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
6143 & MPI2_IOCSTATUS_MASK;
6144 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
6145 sdev_printk(KERN_WARNING, sdev,
6146 "query task: FAILED with IOCSTATUS(0x%04x), scmd(%p)\n",
6147 ioc_status, scmd);
6148 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
6149 goto broadcast_aen_retry;
6150 }
6151
6152 /* see if IO is still owned by IOC and target */
6153 if (mpi_reply->ResponseCode ==
6154 MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
6155 mpi_reply->ResponseCode ==
6156 MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC) {
6157 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
6158 continue;
6159 }
6160 task_abort_retries = 0;
6161 tm_retry:
6162 if (task_abort_retries++ == 60) {
6163 dewtprintk(ioc, pr_info(MPT3SAS_FMT
6164 "%s: ABORT_TASK: giving up\n", ioc->name,
6165 __func__));
6166 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
6167 goto broadcast_aen_retry;
6168 }
6169
6170 if (ioc->shost_recovery)
6171 goto out_no_lock;
6172
6173 r = mpt3sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
Calvin Owens96902832016-07-28 21:38:20 -07006174 sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid,
6175 30);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306176 if (r == FAILED) {
6177 sdev_printk(KERN_WARNING, sdev,
6178 "mpt3sas_scsih_issue_tm: ABORT_TASK: FAILED : "
6179 "scmd(%p)\n", scmd);
6180 goto tm_retry;
6181 }
6182
6183 if (task_abort_retries > 1)
6184 sdev_printk(KERN_WARNING, sdev,
6185 "mpt3sas_scsih_issue_tm: ABORT_TASK: RETRIES (%d):"
6186 " scmd(%p)\n",
6187 task_abort_retries - 1, scmd);
6188
6189 termination_count += le32_to_cpu(mpi_reply->TerminationCount);
6190 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
6191 }
6192
6193 if (ioc->broadcast_aen_pending) {
6194 dewtprintk(ioc, pr_info(MPT3SAS_FMT
6195 "%s: loop back due to pending AEN\n",
6196 ioc->name, __func__));
6197 ioc->broadcast_aen_pending = 0;
6198 goto broadcast_aen_retry;
6199 }
6200
6201 out:
6202 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
6203 out_no_lock:
6204
6205 dewtprintk(ioc, pr_info(MPT3SAS_FMT
6206 "%s - exit, query_count = %d termination_count = %d\n",
6207 ioc->name, __func__, query_count, termination_count));
6208
6209 ioc->broadcast_aen_busy = 0;
6210 if (!ioc->shost_recovery)
6211 _scsih_ublock_io_all_device(ioc);
6212 mutex_unlock(&ioc->tm_cmds.mutex);
6213}
6214
6215/**
6216 * _scsih_sas_discovery_event - handle discovery events
6217 * @ioc: per adapter object
6218 * @fw_event: The fw_event_work object
6219 * Context: user.
6220 *
6221 * Return nothing.
6222 */
6223static void
6224_scsih_sas_discovery_event(struct MPT3SAS_ADAPTER *ioc,
6225 struct fw_event_work *fw_event)
6226{
Joe Lawrence35b62362014-06-25 17:05:34 -04006227 Mpi2EventDataSasDiscovery_t *event_data =
6228 (Mpi2EventDataSasDiscovery_t *) fw_event->event_data;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306229
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306230 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) {
6231 pr_info(MPT3SAS_FMT "discovery event: (%s)", ioc->name,
6232 (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ?
6233 "start" : "stop");
Sreekanth Reddyaf009412015-11-11 17:30:23 +05306234 if (event_data->DiscoveryStatus)
6235 pr_info("discovery_status(0x%08x)",
6236 le32_to_cpu(event_data->DiscoveryStatus));
6237 pr_info("\n");
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306238 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306239
6240 if (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED &&
6241 !ioc->sas_hba.num_phys) {
6242 if (disable_discovery > 0 && ioc->shost_recovery) {
6243 /* Wait for the reset to complete */
6244 while (ioc->shost_recovery)
6245 ssleep(1);
6246 }
6247 _scsih_sas_host_add(ioc);
6248 }
6249}
6250
6251/**
6252 * _scsih_ir_fastpath - turn on fastpath for IR physdisk
6253 * @ioc: per adapter object
6254 * @handle: device handle for physical disk
6255 * @phys_disk_num: physical disk number
6256 *
6257 * Return 0 for success, else failure.
6258 */
6259static int
6260_scsih_ir_fastpath(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phys_disk_num)
6261{
6262 Mpi2RaidActionRequest_t *mpi_request;
6263 Mpi2RaidActionReply_t *mpi_reply;
6264 u16 smid;
6265 u8 issue_reset = 0;
6266 int rc = 0;
6267 u16 ioc_status;
6268 u32 log_info;
6269
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05306270 if (ioc->hba_mpi_version_belonged == MPI2_VERSION)
6271 return rc;
6272
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306273 mutex_lock(&ioc->scsih_cmds.mutex);
6274
6275 if (ioc->scsih_cmds.status != MPT3_CMD_NOT_USED) {
6276 pr_err(MPT3SAS_FMT "%s: scsih_cmd in use\n",
6277 ioc->name, __func__);
6278 rc = -EAGAIN;
6279 goto out;
6280 }
6281 ioc->scsih_cmds.status = MPT3_CMD_PENDING;
6282
6283 smid = mpt3sas_base_get_smid(ioc, ioc->scsih_cb_idx);
6284 if (!smid) {
6285 pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
6286 ioc->name, __func__);
6287 ioc->scsih_cmds.status = MPT3_CMD_NOT_USED;
6288 rc = -EAGAIN;
6289 goto out;
6290 }
6291
6292 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
6293 ioc->scsih_cmds.smid = smid;
6294 memset(mpi_request, 0, sizeof(Mpi2RaidActionRequest_t));
6295
6296 mpi_request->Function = MPI2_FUNCTION_RAID_ACTION;
6297 mpi_request->Action = MPI2_RAID_ACTION_PHYSDISK_HIDDEN;
6298 mpi_request->PhysDiskNum = phys_disk_num;
6299
6300 dewtprintk(ioc, pr_info(MPT3SAS_FMT "IR RAID_ACTION: turning fast "\
6301 "path on for handle(0x%04x), phys_disk_num (0x%02x)\n", ioc->name,
6302 handle, phys_disk_num));
6303
6304 init_completion(&ioc->scsih_cmds.done);
6305 mpt3sas_base_put_smid_default(ioc, smid);
6306 wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ);
6307
6308 if (!(ioc->scsih_cmds.status & MPT3_CMD_COMPLETE)) {
6309 pr_err(MPT3SAS_FMT "%s: timeout\n",
6310 ioc->name, __func__);
6311 if (!(ioc->scsih_cmds.status & MPT3_CMD_RESET))
6312 issue_reset = 1;
6313 rc = -EFAULT;
6314 goto out;
6315 }
6316
6317 if (ioc->scsih_cmds.status & MPT3_CMD_REPLY_VALID) {
6318
6319 mpi_reply = ioc->scsih_cmds.reply;
6320 ioc_status = le16_to_cpu(mpi_reply->IOCStatus);
6321 if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
6322 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
6323 else
6324 log_info = 0;
6325 ioc_status &= MPI2_IOCSTATUS_MASK;
6326 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
6327 dewtprintk(ioc, pr_info(MPT3SAS_FMT
6328 "IR RAID_ACTION: failed: ioc_status(0x%04x), "
6329 "loginfo(0x%08x)!!!\n", ioc->name, ioc_status,
6330 log_info));
6331 rc = -EFAULT;
6332 } else
6333 dewtprintk(ioc, pr_info(MPT3SAS_FMT
6334 "IR RAID_ACTION: completed successfully\n",
6335 ioc->name));
6336 }
6337
6338 out:
6339 ioc->scsih_cmds.status = MPT3_CMD_NOT_USED;
6340 mutex_unlock(&ioc->scsih_cmds.mutex);
6341
6342 if (issue_reset)
Calvin Owens98c56ad2016-07-28 21:38:21 -07006343 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306344 return rc;
6345}
6346
6347/**
6348 * _scsih_reprobe_lun - reprobing lun
6349 * @sdev: scsi device struct
6350 * @no_uld_attach: sdev->no_uld_attach flag setting
6351 *
6352 **/
6353static void
6354_scsih_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach)
6355{
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306356 sdev->no_uld_attach = no_uld_attach ? 1 : 0;
6357 sdev_printk(KERN_INFO, sdev, "%s raid component\n",
6358 sdev->no_uld_attach ? "hidding" : "exposing");
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07006359 WARN_ON(scsi_device_reprobe(sdev));
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306360}
6361
6362/**
6363 * _scsih_sas_volume_add - add new volume
6364 * @ioc: per adapter object
6365 * @element: IR config element data
6366 * Context: user.
6367 *
6368 * Return nothing.
6369 */
6370static void
6371_scsih_sas_volume_add(struct MPT3SAS_ADAPTER *ioc,
6372 Mpi2EventIrConfigElement_t *element)
6373{
6374 struct _raid_device *raid_device;
6375 unsigned long flags;
6376 u64 wwid;
6377 u16 handle = le16_to_cpu(element->VolDevHandle);
6378 int rc;
6379
6380 mpt3sas_config_get_volume_wwid(ioc, handle, &wwid);
6381 if (!wwid) {
6382 pr_err(MPT3SAS_FMT
6383 "failure at %s:%d/%s()!\n", ioc->name,
6384 __FILE__, __LINE__, __func__);
6385 return;
6386 }
6387
6388 spin_lock_irqsave(&ioc->raid_device_lock, flags);
6389 raid_device = _scsih_raid_device_find_by_wwid(ioc, wwid);
6390 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
6391
6392 if (raid_device)
6393 return;
6394
6395 raid_device = kzalloc(sizeof(struct _raid_device), GFP_KERNEL);
6396 if (!raid_device) {
6397 pr_err(MPT3SAS_FMT
6398 "failure at %s:%d/%s()!\n", ioc->name,
6399 __FILE__, __LINE__, __func__);
6400 return;
6401 }
6402
6403 raid_device->id = ioc->sas_id++;
6404 raid_device->channel = RAID_CHANNEL;
6405 raid_device->handle = handle;
6406 raid_device->wwid = wwid;
6407 _scsih_raid_device_add(ioc, raid_device);
6408 if (!ioc->wait_for_discovery_to_complete) {
6409 rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
6410 raid_device->id, 0);
6411 if (rc)
6412 _scsih_raid_device_remove(ioc, raid_device);
6413 } else {
6414 spin_lock_irqsave(&ioc->raid_device_lock, flags);
6415 _scsih_determine_boot_device(ioc, raid_device, 1);
6416 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
6417 }
6418}
6419
6420/**
6421 * _scsih_sas_volume_delete - delete volume
6422 * @ioc: per adapter object
6423 * @handle: volume device handle
6424 * Context: user.
6425 *
6426 * Return nothing.
6427 */
6428static void
6429_scsih_sas_volume_delete(struct MPT3SAS_ADAPTER *ioc, u16 handle)
6430{
6431 struct _raid_device *raid_device;
6432 unsigned long flags;
6433 struct MPT3SAS_TARGET *sas_target_priv_data;
6434 struct scsi_target *starget = NULL;
6435
6436 spin_lock_irqsave(&ioc->raid_device_lock, flags);
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05306437 raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306438 if (raid_device) {
6439 if (raid_device->starget) {
6440 starget = raid_device->starget;
6441 sas_target_priv_data = starget->hostdata;
6442 sas_target_priv_data->deleted = 1;
6443 }
6444 pr_info(MPT3SAS_FMT "removing handle(0x%04x), wwid(0x%016llx)\n",
6445 ioc->name, raid_device->handle,
6446 (unsigned long long) raid_device->wwid);
6447 list_del(&raid_device->list);
6448 kfree(raid_device);
6449 }
6450 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
6451 if (starget)
6452 scsi_remove_target(&starget->dev);
6453}
6454
6455/**
6456 * _scsih_sas_pd_expose - expose pd component to /dev/sdX
6457 * @ioc: per adapter object
6458 * @element: IR config element data
6459 * Context: user.
6460 *
6461 * Return nothing.
6462 */
6463static void
6464_scsih_sas_pd_expose(struct MPT3SAS_ADAPTER *ioc,
6465 Mpi2EventIrConfigElement_t *element)
6466{
6467 struct _sas_device *sas_device;
6468 struct scsi_target *starget = NULL;
6469 struct MPT3SAS_TARGET *sas_target_priv_data;
6470 unsigned long flags;
6471 u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
6472
6473 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05306474 sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306475 if (sas_device) {
6476 sas_device->volume_handle = 0;
6477 sas_device->volume_wwid = 0;
6478 clear_bit(handle, ioc->pd_handles);
6479 if (sas_device->starget && sas_device->starget->hostdata) {
6480 starget = sas_device->starget;
6481 sas_target_priv_data = starget->hostdata;
6482 sas_target_priv_data->flags &=
6483 ~MPT_TARGET_FLAGS_RAID_COMPONENT;
6484 }
6485 }
6486 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
6487 if (!sas_device)
6488 return;
6489
6490 /* exposing raid component */
6491 if (starget)
6492 starget_for_each_device(starget, NULL, _scsih_reprobe_lun);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05306493
6494 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306495}
6496
6497/**
6498 * _scsih_sas_pd_hide - hide pd component from /dev/sdX
6499 * @ioc: per adapter object
6500 * @element: IR config element data
6501 * Context: user.
6502 *
6503 * Return nothing.
6504 */
6505static void
6506_scsih_sas_pd_hide(struct MPT3SAS_ADAPTER *ioc,
6507 Mpi2EventIrConfigElement_t *element)
6508{
6509 struct _sas_device *sas_device;
6510 struct scsi_target *starget = NULL;
6511 struct MPT3SAS_TARGET *sas_target_priv_data;
6512 unsigned long flags;
6513 u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
6514 u16 volume_handle = 0;
6515 u64 volume_wwid = 0;
6516
6517 mpt3sas_config_get_volume_handle(ioc, handle, &volume_handle);
6518 if (volume_handle)
6519 mpt3sas_config_get_volume_wwid(ioc, volume_handle,
6520 &volume_wwid);
6521
6522 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05306523 sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306524 if (sas_device) {
6525 set_bit(handle, ioc->pd_handles);
6526 if (sas_device->starget && sas_device->starget->hostdata) {
6527 starget = sas_device->starget;
6528 sas_target_priv_data = starget->hostdata;
6529 sas_target_priv_data->flags |=
6530 MPT_TARGET_FLAGS_RAID_COMPONENT;
6531 sas_device->volume_handle = volume_handle;
6532 sas_device->volume_wwid = volume_wwid;
6533 }
6534 }
6535 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
6536 if (!sas_device)
6537 return;
6538
6539 /* hiding raid component */
6540 _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum);
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05306541
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306542 if (starget)
6543 starget_for_each_device(starget, (void *)1, _scsih_reprobe_lun);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05306544
6545 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306546}
6547
6548/**
6549 * _scsih_sas_pd_delete - delete pd component
6550 * @ioc: per adapter object
6551 * @element: IR config element data
6552 * Context: user.
6553 *
6554 * Return nothing.
6555 */
6556static void
6557_scsih_sas_pd_delete(struct MPT3SAS_ADAPTER *ioc,
6558 Mpi2EventIrConfigElement_t *element)
6559{
6560 u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
6561
6562 _scsih_device_remove_by_handle(ioc, handle);
6563}
6564
6565/**
6566 * _scsih_sas_pd_add - remove pd component
6567 * @ioc: per adapter object
6568 * @element: IR config element data
6569 * Context: user.
6570 *
6571 * Return nothing.
6572 */
6573static void
6574_scsih_sas_pd_add(struct MPT3SAS_ADAPTER *ioc,
6575 Mpi2EventIrConfigElement_t *element)
6576{
6577 struct _sas_device *sas_device;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306578 u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
6579 Mpi2ConfigReply_t mpi_reply;
6580 Mpi2SasDevicePage0_t sas_device_pg0;
6581 u32 ioc_status;
6582 u64 sas_address;
6583 u16 parent_handle;
6584
6585 set_bit(handle, ioc->pd_handles);
6586
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05306587 sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306588 if (sas_device) {
6589 _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05306590 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306591 return;
6592 }
6593
6594 if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
6595 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
6596 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
6597 ioc->name, __FILE__, __LINE__, __func__);
6598 return;
6599 }
6600
6601 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
6602 MPI2_IOCSTATUS_MASK;
6603 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
6604 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
6605 ioc->name, __FILE__, __LINE__, __func__);
6606 return;
6607 }
6608
6609 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
6610 if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address))
6611 mpt3sas_transport_update_links(ioc, sas_address, handle,
6612 sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
6613
6614 _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum);
6615 _scsih_add_device(ioc, handle, 0, 1);
6616}
6617
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306618/**
6619 * _scsih_sas_ir_config_change_event_debug - debug for IR Config Change events
6620 * @ioc: per adapter object
6621 * @event_data: event data payload
6622 * Context: user.
6623 *
6624 * Return nothing.
6625 */
6626static void
6627_scsih_sas_ir_config_change_event_debug(struct MPT3SAS_ADAPTER *ioc,
6628 Mpi2EventDataIrConfigChangeList_t *event_data)
6629{
6630 Mpi2EventIrConfigElement_t *element;
6631 u8 element_type;
6632 int i;
6633 char *reason_str = NULL, *element_str = NULL;
6634
6635 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
6636
6637 pr_info(MPT3SAS_FMT "raid config change: (%s), elements(%d)\n",
6638 ioc->name, (le32_to_cpu(event_data->Flags) &
6639 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ?
6640 "foreign" : "native", event_data->NumElements);
6641 for (i = 0; i < event_data->NumElements; i++, element++) {
6642 switch (element->ReasonCode) {
6643 case MPI2_EVENT_IR_CHANGE_RC_ADDED:
6644 reason_str = "add";
6645 break;
6646 case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
6647 reason_str = "remove";
6648 break;
6649 case MPI2_EVENT_IR_CHANGE_RC_NO_CHANGE:
6650 reason_str = "no change";
6651 break;
6652 case MPI2_EVENT_IR_CHANGE_RC_HIDE:
6653 reason_str = "hide";
6654 break;
6655 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
6656 reason_str = "unhide";
6657 break;
6658 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
6659 reason_str = "volume_created";
6660 break;
6661 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
6662 reason_str = "volume_deleted";
6663 break;
6664 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
6665 reason_str = "pd_created";
6666 break;
6667 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
6668 reason_str = "pd_deleted";
6669 break;
6670 default:
6671 reason_str = "unknown reason";
6672 break;
6673 }
6674 element_type = le16_to_cpu(element->ElementFlags) &
6675 MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK;
6676 switch (element_type) {
6677 case MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT:
6678 element_str = "volume";
6679 break;
6680 case MPI2_EVENT_IR_CHANGE_EFLAGS_VOLPHYSDISK_ELEMENT:
6681 element_str = "phys disk";
6682 break;
6683 case MPI2_EVENT_IR_CHANGE_EFLAGS_HOTSPARE_ELEMENT:
6684 element_str = "hot spare";
6685 break;
6686 default:
6687 element_str = "unknown element";
6688 break;
6689 }
6690 pr_info("\t(%s:%s), vol handle(0x%04x), " \
6691 "pd handle(0x%04x), pd num(0x%02x)\n", element_str,
6692 reason_str, le16_to_cpu(element->VolDevHandle),
6693 le16_to_cpu(element->PhysDiskDevHandle),
6694 element->PhysDiskNum);
6695 }
6696}
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306697
6698/**
6699 * _scsih_sas_ir_config_change_event - handle ir configuration change events
6700 * @ioc: per adapter object
6701 * @fw_event: The fw_event_work object
6702 * Context: user.
6703 *
6704 * Return nothing.
6705 */
6706static void
6707_scsih_sas_ir_config_change_event(struct MPT3SAS_ADAPTER *ioc,
6708 struct fw_event_work *fw_event)
6709{
6710 Mpi2EventIrConfigElement_t *element;
6711 int i;
6712 u8 foreign_config;
Joe Lawrence35b62362014-06-25 17:05:34 -04006713 Mpi2EventDataIrConfigChangeList_t *event_data =
6714 (Mpi2EventDataIrConfigChangeList_t *)
6715 fw_event->event_data;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306716
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05306717 if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) &&
6718 (!ioc->hide_ir_msg))
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306719 _scsih_sas_ir_config_change_event_debug(ioc, event_data);
6720
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306721 foreign_config = (le32_to_cpu(event_data->Flags) &
6722 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0;
6723
6724 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05306725 if (ioc->shost_recovery &&
6726 ioc->hba_mpi_version_belonged != MPI2_VERSION) {
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306727 for (i = 0; i < event_data->NumElements; i++, element++) {
6728 if (element->ReasonCode == MPI2_EVENT_IR_CHANGE_RC_HIDE)
6729 _scsih_ir_fastpath(ioc,
6730 le16_to_cpu(element->PhysDiskDevHandle),
6731 element->PhysDiskNum);
6732 }
6733 return;
6734 }
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05306735
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306736 for (i = 0; i < event_data->NumElements; i++, element++) {
6737
6738 switch (element->ReasonCode) {
6739 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
6740 case MPI2_EVENT_IR_CHANGE_RC_ADDED:
6741 if (!foreign_config)
6742 _scsih_sas_volume_add(ioc, element);
6743 break;
6744 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
6745 case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
6746 if (!foreign_config)
6747 _scsih_sas_volume_delete(ioc,
6748 le16_to_cpu(element->VolDevHandle));
6749 break;
6750 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05306751 if (!ioc->is_warpdrive)
6752 _scsih_sas_pd_hide(ioc, element);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306753 break;
6754 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05306755 if (!ioc->is_warpdrive)
6756 _scsih_sas_pd_expose(ioc, element);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306757 break;
6758 case MPI2_EVENT_IR_CHANGE_RC_HIDE:
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05306759 if (!ioc->is_warpdrive)
6760 _scsih_sas_pd_add(ioc, element);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306761 break;
6762 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05306763 if (!ioc->is_warpdrive)
6764 _scsih_sas_pd_delete(ioc, element);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306765 break;
6766 }
6767 }
6768}
6769
6770/**
6771 * _scsih_sas_ir_volume_event - IR volume event
6772 * @ioc: per adapter object
6773 * @fw_event: The fw_event_work object
6774 * Context: user.
6775 *
6776 * Return nothing.
6777 */
6778static void
6779_scsih_sas_ir_volume_event(struct MPT3SAS_ADAPTER *ioc,
6780 struct fw_event_work *fw_event)
6781{
6782 u64 wwid;
6783 unsigned long flags;
6784 struct _raid_device *raid_device;
6785 u16 handle;
6786 u32 state;
6787 int rc;
Joe Lawrence35b62362014-06-25 17:05:34 -04006788 Mpi2EventDataIrVolume_t *event_data =
6789 (Mpi2EventDataIrVolume_t *) fw_event->event_data;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306790
6791 if (ioc->shost_recovery)
6792 return;
6793
6794 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
6795 return;
6796
6797 handle = le16_to_cpu(event_data->VolDevHandle);
6798 state = le32_to_cpu(event_data->NewValue);
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05306799 if (!ioc->hide_ir_msg)
6800 dewtprintk(ioc, pr_info(MPT3SAS_FMT
6801 "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n",
6802 ioc->name, __func__, handle,
6803 le32_to_cpu(event_data->PreviousValue), state));
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306804 switch (state) {
6805 case MPI2_RAID_VOL_STATE_MISSING:
6806 case MPI2_RAID_VOL_STATE_FAILED:
6807 _scsih_sas_volume_delete(ioc, handle);
6808 break;
6809
6810 case MPI2_RAID_VOL_STATE_ONLINE:
6811 case MPI2_RAID_VOL_STATE_DEGRADED:
6812 case MPI2_RAID_VOL_STATE_OPTIMAL:
6813
6814 spin_lock_irqsave(&ioc->raid_device_lock, flags);
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05306815 raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306816 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
6817
6818 if (raid_device)
6819 break;
6820
6821 mpt3sas_config_get_volume_wwid(ioc, handle, &wwid);
6822 if (!wwid) {
6823 pr_err(MPT3SAS_FMT
6824 "failure at %s:%d/%s()!\n", ioc->name,
6825 __FILE__, __LINE__, __func__);
6826 break;
6827 }
6828
6829 raid_device = kzalloc(sizeof(struct _raid_device), GFP_KERNEL);
6830 if (!raid_device) {
6831 pr_err(MPT3SAS_FMT
6832 "failure at %s:%d/%s()!\n", ioc->name,
6833 __FILE__, __LINE__, __func__);
6834 break;
6835 }
6836
6837 raid_device->id = ioc->sas_id++;
6838 raid_device->channel = RAID_CHANNEL;
6839 raid_device->handle = handle;
6840 raid_device->wwid = wwid;
6841 _scsih_raid_device_add(ioc, raid_device);
6842 rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
6843 raid_device->id, 0);
6844 if (rc)
6845 _scsih_raid_device_remove(ioc, raid_device);
6846 break;
6847
6848 case MPI2_RAID_VOL_STATE_INITIALIZING:
6849 default:
6850 break;
6851 }
6852}
6853
6854/**
6855 * _scsih_sas_ir_physical_disk_event - PD event
6856 * @ioc: per adapter object
6857 * @fw_event: The fw_event_work object
6858 * Context: user.
6859 *
6860 * Return nothing.
6861 */
6862static void
6863_scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc,
6864 struct fw_event_work *fw_event)
6865{
6866 u16 handle, parent_handle;
6867 u32 state;
6868 struct _sas_device *sas_device;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306869 Mpi2ConfigReply_t mpi_reply;
6870 Mpi2SasDevicePage0_t sas_device_pg0;
6871 u32 ioc_status;
Joe Lawrence35b62362014-06-25 17:05:34 -04006872 Mpi2EventDataIrPhysicalDisk_t *event_data =
6873 (Mpi2EventDataIrPhysicalDisk_t *) fw_event->event_data;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306874 u64 sas_address;
6875
6876 if (ioc->shost_recovery)
6877 return;
6878
6879 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
6880 return;
6881
6882 handle = le16_to_cpu(event_data->PhysDiskDevHandle);
6883 state = le32_to_cpu(event_data->NewValue);
6884
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05306885 if (!ioc->hide_ir_msg)
6886 dewtprintk(ioc, pr_info(MPT3SAS_FMT
6887 "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n",
6888 ioc->name, __func__, handle,
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306889 le32_to_cpu(event_data->PreviousValue), state));
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05306890
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306891 switch (state) {
6892 case MPI2_RAID_PD_STATE_ONLINE:
6893 case MPI2_RAID_PD_STATE_DEGRADED:
6894 case MPI2_RAID_PD_STATE_REBUILDING:
6895 case MPI2_RAID_PD_STATE_OPTIMAL:
6896 case MPI2_RAID_PD_STATE_HOT_SPARE:
6897
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05306898 if (!ioc->is_warpdrive)
6899 set_bit(handle, ioc->pd_handles);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306900
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05306901 sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
6902 if (sas_device) {
6903 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306904 return;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05306905 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306906
6907 if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply,
6908 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
6909 handle))) {
6910 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
6911 ioc->name, __FILE__, __LINE__, __func__);
6912 return;
6913 }
6914
6915 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
6916 MPI2_IOCSTATUS_MASK;
6917 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
6918 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
6919 ioc->name, __FILE__, __LINE__, __func__);
6920 return;
6921 }
6922
6923 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
6924 if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address))
6925 mpt3sas_transport_update_links(ioc, sas_address, handle,
6926 sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
6927
6928 _scsih_add_device(ioc, handle, 0, 1);
6929
6930 break;
6931
6932 case MPI2_RAID_PD_STATE_OFFLINE:
6933 case MPI2_RAID_PD_STATE_NOT_CONFIGURED:
6934 case MPI2_RAID_PD_STATE_NOT_COMPATIBLE:
6935 default:
6936 break;
6937 }
6938}
6939
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306940/**
6941 * _scsih_sas_ir_operation_status_event_debug - debug for IR op event
6942 * @ioc: per adapter object
6943 * @event_data: event data payload
6944 * Context: user.
6945 *
6946 * Return nothing.
6947 */
6948static void
6949_scsih_sas_ir_operation_status_event_debug(struct MPT3SAS_ADAPTER *ioc,
6950 Mpi2EventDataIrOperationStatus_t *event_data)
6951{
6952 char *reason_str = NULL;
6953
6954 switch (event_data->RAIDOperation) {
6955 case MPI2_EVENT_IR_RAIDOP_RESYNC:
6956 reason_str = "resync";
6957 break;
6958 case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION:
6959 reason_str = "online capacity expansion";
6960 break;
6961 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK:
6962 reason_str = "consistency check";
6963 break;
6964 case MPI2_EVENT_IR_RAIDOP_BACKGROUND_INIT:
6965 reason_str = "background init";
6966 break;
6967 case MPI2_EVENT_IR_RAIDOP_MAKE_DATA_CONSISTENT:
6968 reason_str = "make data consistent";
6969 break;
6970 }
6971
6972 if (!reason_str)
6973 return;
6974
6975 pr_info(MPT3SAS_FMT "raid operational status: (%s)" \
6976 "\thandle(0x%04x), percent complete(%d)\n",
6977 ioc->name, reason_str,
6978 le16_to_cpu(event_data->VolDevHandle),
6979 event_data->PercentComplete);
6980}
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306981
6982/**
6983 * _scsih_sas_ir_operation_status_event - handle RAID operation events
6984 * @ioc: per adapter object
6985 * @fw_event: The fw_event_work object
6986 * Context: user.
6987 *
6988 * Return nothing.
6989 */
6990static void
6991_scsih_sas_ir_operation_status_event(struct MPT3SAS_ADAPTER *ioc,
6992 struct fw_event_work *fw_event)
6993{
Joe Lawrence35b62362014-06-25 17:05:34 -04006994 Mpi2EventDataIrOperationStatus_t *event_data =
6995 (Mpi2EventDataIrOperationStatus_t *)
6996 fw_event->event_data;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05306997 static struct _raid_device *raid_device;
6998 unsigned long flags;
6999 u16 handle;
7000
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05307001 if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) &&
7002 (!ioc->hide_ir_msg))
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307003 _scsih_sas_ir_operation_status_event_debug(ioc,
7004 event_data);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307005
7006 /* code added for raid transport support */
7007 if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) {
7008
7009 spin_lock_irqsave(&ioc->raid_device_lock, flags);
7010 handle = le16_to_cpu(event_data->VolDevHandle);
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05307011 raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307012 if (raid_device)
7013 raid_device->percent_complete =
7014 event_data->PercentComplete;
7015 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
7016 }
7017}
7018
7019/**
7020 * _scsih_prep_device_scan - initialize parameters prior to device scan
7021 * @ioc: per adapter object
7022 *
7023 * Set the deleted flag prior to device scan. If the device is found during
7024 * the scan, then we clear the deleted flag.
7025 */
7026static void
7027_scsih_prep_device_scan(struct MPT3SAS_ADAPTER *ioc)
7028{
7029 struct MPT3SAS_DEVICE *sas_device_priv_data;
7030 struct scsi_device *sdev;
7031
7032 shost_for_each_device(sdev, ioc->shost) {
7033 sas_device_priv_data = sdev->hostdata;
7034 if (sas_device_priv_data && sas_device_priv_data->sas_target)
7035 sas_device_priv_data->sas_target->deleted = 1;
7036 }
7037}
7038
7039/**
7040 * _scsih_mark_responding_sas_device - mark a sas_devices as responding
7041 * @ioc: per adapter object
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05307042 * @sas_device_pg0: SAS Device page 0
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307043 *
7044 * After host reset, find out whether devices are still responding.
7045 * Used in _scsih_remove_unresponsive_sas_devices.
7046 *
7047 * Return nothing.
7048 */
7049static void
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05307050_scsih_mark_responding_sas_device(struct MPT3SAS_ADAPTER *ioc,
7051Mpi2SasDevicePage0_t *sas_device_pg0)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307052{
7053 struct MPT3SAS_TARGET *sas_target_priv_data = NULL;
7054 struct scsi_target *starget;
7055 struct _sas_device *sas_device;
7056 unsigned long flags;
7057
7058 spin_lock_irqsave(&ioc->sas_device_lock, flags);
7059 list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05307060 if ((sas_device->sas_address == sas_device_pg0->SASAddress) &&
7061 (sas_device->slot == sas_device_pg0->Slot)) {
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307062 sas_device->responding = 1;
7063 starget = sas_device->starget;
7064 if (starget && starget->hostdata) {
7065 sas_target_priv_data = starget->hostdata;
7066 sas_target_priv_data->tm_busy = 0;
7067 sas_target_priv_data->deleted = 0;
7068 } else
7069 sas_target_priv_data = NULL;
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05307070 if (starget) {
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307071 starget_printk(KERN_INFO, starget,
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05307072 "handle(0x%04x), sas_addr(0x%016llx)\n",
7073 sas_device_pg0->DevHandle,
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307074 (unsigned long long)
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05307075 sas_device->sas_address);
7076
7077 if (sas_device->enclosure_handle != 0)
7078 starget_printk(KERN_INFO, starget,
7079 "enclosure logical id(0x%016llx),"
7080 " slot(%d)\n",
7081 (unsigned long long)
7082 sas_device->enclosure_logical_id,
7083 sas_device->slot);
7084 }
7085 if (sas_device_pg0->Flags &
7086 MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) {
7087 sas_device->enclosure_level =
7088 le16_to_cpu(sas_device_pg0->EnclosureLevel);
7089 memcpy(&sas_device->connector_name[0],
7090 &sas_device_pg0->ConnectorName[0], 4);
7091 } else {
7092 sas_device->enclosure_level = 0;
7093 sas_device->connector_name[0] = '\0';
7094 }
7095
7096 if (sas_device->handle == sas_device_pg0->DevHandle)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307097 goto out;
7098 pr_info("\thandle changed from(0x%04x)!!!\n",
7099 sas_device->handle);
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05307100 sas_device->handle = sas_device_pg0->DevHandle;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307101 if (sas_target_priv_data)
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05307102 sas_target_priv_data->handle =
7103 sas_device_pg0->DevHandle;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307104 goto out;
7105 }
7106 }
7107 out:
7108 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
7109}
7110
7111/**
7112 * _scsih_search_responding_sas_devices -
7113 * @ioc: per adapter object
7114 *
7115 * After host reset, find out whether devices are still responding.
7116 * If not remove.
7117 *
7118 * Return nothing.
7119 */
7120static void
7121_scsih_search_responding_sas_devices(struct MPT3SAS_ADAPTER *ioc)
7122{
7123 Mpi2SasDevicePage0_t sas_device_pg0;
7124 Mpi2ConfigReply_t mpi_reply;
7125 u16 ioc_status;
7126 u16 handle;
7127 u32 device_info;
7128
7129 pr_info(MPT3SAS_FMT "search for end-devices: start\n", ioc->name);
7130
7131 if (list_empty(&ioc->sas_device_list))
7132 goto out;
7133
7134 handle = 0xFFFF;
7135 while (!(mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply,
7136 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
7137 handle))) {
7138 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7139 MPI2_IOCSTATUS_MASK;
Sreekanth Reddy14be49a2013-06-29 03:53:02 +05307140 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307141 break;
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05307142 handle = sas_device_pg0.DevHandle =
7143 le16_to_cpu(sas_device_pg0.DevHandle);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307144 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
7145 if (!(_scsih_is_end_device(device_info)))
7146 continue;
Sreekanth Reddye6d45e32015-06-30 12:24:52 +05307147 sas_device_pg0.SASAddress =
7148 le64_to_cpu(sas_device_pg0.SASAddress);
7149 sas_device_pg0.Slot = le16_to_cpu(sas_device_pg0.Slot);
7150 _scsih_mark_responding_sas_device(ioc, &sas_device_pg0);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307151 }
7152
7153 out:
7154 pr_info(MPT3SAS_FMT "search for end-devices: complete\n",
7155 ioc->name);
7156}
7157
7158/**
7159 * _scsih_mark_responding_raid_device - mark a raid_device as responding
7160 * @ioc: per adapter object
7161 * @wwid: world wide identifier for raid volume
7162 * @handle: device handle
7163 *
7164 * After host reset, find out whether devices are still responding.
7165 * Used in _scsih_remove_unresponsive_raid_devices.
7166 *
7167 * Return nothing.
7168 */
7169static void
7170_scsih_mark_responding_raid_device(struct MPT3SAS_ADAPTER *ioc, u64 wwid,
7171 u16 handle)
7172{
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05307173 struct MPT3SAS_TARGET *sas_target_priv_data = NULL;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307174 struct scsi_target *starget;
7175 struct _raid_device *raid_device;
7176 unsigned long flags;
7177
7178 spin_lock_irqsave(&ioc->raid_device_lock, flags);
7179 list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
7180 if (raid_device->wwid == wwid && raid_device->starget) {
7181 starget = raid_device->starget;
7182 if (starget && starget->hostdata) {
7183 sas_target_priv_data = starget->hostdata;
7184 sas_target_priv_data->deleted = 0;
7185 } else
7186 sas_target_priv_data = NULL;
7187 raid_device->responding = 1;
7188 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
7189 starget_printk(KERN_INFO, raid_device->starget,
7190 "handle(0x%04x), wwid(0x%016llx)\n", handle,
7191 (unsigned long long)raid_device->wwid);
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05307192
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05307193 /*
7194 * WARPDRIVE: The handles of the PDs might have changed
7195 * across the host reset so re-initialize the
7196 * required data for Direct IO
7197 */
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05307198 mpt3sas_init_warpdrive_properties(ioc, raid_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307199 spin_lock_irqsave(&ioc->raid_device_lock, flags);
7200 if (raid_device->handle == handle) {
7201 spin_unlock_irqrestore(&ioc->raid_device_lock,
7202 flags);
7203 return;
7204 }
7205 pr_info("\thandle changed from(0x%04x)!!!\n",
7206 raid_device->handle);
7207 raid_device->handle = handle;
7208 if (sas_target_priv_data)
7209 sas_target_priv_data->handle = handle;
7210 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
7211 return;
7212 }
7213 }
7214 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
7215}
7216
7217/**
7218 * _scsih_search_responding_raid_devices -
7219 * @ioc: per adapter object
7220 *
7221 * After host reset, find out whether devices are still responding.
7222 * If not remove.
7223 *
7224 * Return nothing.
7225 */
7226static void
7227_scsih_search_responding_raid_devices(struct MPT3SAS_ADAPTER *ioc)
7228{
7229 Mpi2RaidVolPage1_t volume_pg1;
7230 Mpi2RaidVolPage0_t volume_pg0;
7231 Mpi2RaidPhysDiskPage0_t pd_pg0;
7232 Mpi2ConfigReply_t mpi_reply;
7233 u16 ioc_status;
7234 u16 handle;
7235 u8 phys_disk_num;
7236
7237 if (!ioc->ir_firmware)
7238 return;
7239
7240 pr_info(MPT3SAS_FMT "search for raid volumes: start\n",
7241 ioc->name);
7242
7243 if (list_empty(&ioc->raid_device_list))
7244 goto out;
7245
7246 handle = 0xFFFF;
7247 while (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
7248 &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
7249 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7250 MPI2_IOCSTATUS_MASK;
Sreekanth Reddy14be49a2013-06-29 03:53:02 +05307251 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307252 break;
7253 handle = le16_to_cpu(volume_pg1.DevHandle);
7254
7255 if (mpt3sas_config_get_raid_volume_pg0(ioc, &mpi_reply,
7256 &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
7257 sizeof(Mpi2RaidVolPage0_t)))
7258 continue;
7259
7260 if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL ||
7261 volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE ||
7262 volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED)
7263 _scsih_mark_responding_raid_device(ioc,
7264 le64_to_cpu(volume_pg1.WWID), handle);
7265 }
7266
7267 /* refresh the pd_handles */
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05307268 if (!ioc->is_warpdrive) {
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307269 phys_disk_num = 0xFF;
7270 memset(ioc->pd_handles, 0, ioc->pd_handles_sz);
7271 while (!(mpt3sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
7272 &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM,
7273 phys_disk_num))) {
7274 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7275 MPI2_IOCSTATUS_MASK;
Sreekanth Reddy14be49a2013-06-29 03:53:02 +05307276 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307277 break;
7278 phys_disk_num = pd_pg0.PhysDiskNum;
7279 handle = le16_to_cpu(pd_pg0.DevHandle);
7280 set_bit(handle, ioc->pd_handles);
7281 }
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05307282 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307283 out:
7284 pr_info(MPT3SAS_FMT "search for responding raid volumes: complete\n",
7285 ioc->name);
7286}
7287
7288/**
7289 * _scsih_mark_responding_expander - mark a expander as responding
7290 * @ioc: per adapter object
7291 * @sas_address: sas address
7292 * @handle:
7293 *
7294 * After host reset, find out whether devices are still responding.
7295 * Used in _scsih_remove_unresponsive_expanders.
7296 *
7297 * Return nothing.
7298 */
7299static void
7300_scsih_mark_responding_expander(struct MPT3SAS_ADAPTER *ioc, u64 sas_address,
7301 u16 handle)
7302{
7303 struct _sas_node *sas_expander;
7304 unsigned long flags;
7305 int i;
7306
7307 spin_lock_irqsave(&ioc->sas_node_lock, flags);
7308 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
7309 if (sas_expander->sas_address != sas_address)
7310 continue;
7311 sas_expander->responding = 1;
7312 if (sas_expander->handle == handle)
7313 goto out;
7314 pr_info("\texpander(0x%016llx): handle changed" \
7315 " from(0x%04x) to (0x%04x)!!!\n",
7316 (unsigned long long)sas_expander->sas_address,
7317 sas_expander->handle, handle);
7318 sas_expander->handle = handle;
7319 for (i = 0 ; i < sas_expander->num_phys ; i++)
7320 sas_expander->phy[i].handle = handle;
7321 goto out;
7322 }
7323 out:
7324 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
7325}
7326
7327/**
7328 * _scsih_search_responding_expanders -
7329 * @ioc: per adapter object
7330 *
7331 * After host reset, find out whether devices are still responding.
7332 * If not remove.
7333 *
7334 * Return nothing.
7335 */
7336static void
7337_scsih_search_responding_expanders(struct MPT3SAS_ADAPTER *ioc)
7338{
7339 Mpi2ExpanderPage0_t expander_pg0;
7340 Mpi2ConfigReply_t mpi_reply;
7341 u16 ioc_status;
7342 u64 sas_address;
7343 u16 handle;
7344
7345 pr_info(MPT3SAS_FMT "search for expanders: start\n", ioc->name);
7346
7347 if (list_empty(&ioc->sas_expander_list))
7348 goto out;
7349
7350 handle = 0xFFFF;
7351 while (!(mpt3sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
7352 MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) {
7353
7354 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7355 MPI2_IOCSTATUS_MASK;
Sreekanth Reddy14be49a2013-06-29 03:53:02 +05307356 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307357 break;
7358
7359 handle = le16_to_cpu(expander_pg0.DevHandle);
7360 sas_address = le64_to_cpu(expander_pg0.SASAddress);
7361 pr_info("\texpander present: handle(0x%04x), sas_addr(0x%016llx)\n",
7362 handle,
7363 (unsigned long long)sas_address);
7364 _scsih_mark_responding_expander(ioc, sas_address, handle);
7365 }
7366
7367 out:
7368 pr_info(MPT3SAS_FMT "search for expanders: complete\n", ioc->name);
7369}
7370
7371/**
7372 * _scsih_remove_unresponding_sas_devices - removing unresponding devices
7373 * @ioc: per adapter object
7374 *
7375 * Return nothing.
7376 */
7377static void
7378_scsih_remove_unresponding_sas_devices(struct MPT3SAS_ADAPTER *ioc)
7379{
7380 struct _sas_device *sas_device, *sas_device_next;
7381 struct _sas_node *sas_expander, *sas_expander_next;
7382 struct _raid_device *raid_device, *raid_device_next;
7383 struct list_head tmp_list;
7384 unsigned long flags;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05307385 LIST_HEAD(head);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307386
7387 pr_info(MPT3SAS_FMT "removing unresponding devices: start\n",
7388 ioc->name);
7389
7390 /* removing unresponding end devices */
7391 pr_info(MPT3SAS_FMT "removing unresponding devices: end-devices\n",
7392 ioc->name);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05307393 /*
7394 * Iterate, pulling off devices marked as non-responding. We become the
7395 * owner for the reference the list had on any object we prune.
7396 */
7397 spin_lock_irqsave(&ioc->sas_device_lock, flags);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307398 list_for_each_entry_safe(sas_device, sas_device_next,
7399 &ioc->sas_device_list, list) {
7400 if (!sas_device->responding)
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05307401 list_move_tail(&sas_device->list, &head);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307402 else
7403 sas_device->responding = 0;
7404 }
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05307405 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
7406
7407 /*
7408 * Now, uninitialize and remove the unresponding devices we pruned.
7409 */
7410 list_for_each_entry_safe(sas_device, sas_device_next, &head, list) {
7411 _scsih_remove_device(ioc, sas_device);
7412 list_del_init(&sas_device->list);
7413 sas_device_put(sas_device);
7414 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307415
7416 /* removing unresponding volumes */
7417 if (ioc->ir_firmware) {
7418 pr_info(MPT3SAS_FMT "removing unresponding devices: volumes\n",
7419 ioc->name);
7420 list_for_each_entry_safe(raid_device, raid_device_next,
7421 &ioc->raid_device_list, list) {
7422 if (!raid_device->responding)
7423 _scsih_sas_volume_delete(ioc,
7424 raid_device->handle);
7425 else
7426 raid_device->responding = 0;
7427 }
7428 }
7429
7430 /* removing unresponding expanders */
7431 pr_info(MPT3SAS_FMT "removing unresponding devices: expanders\n",
7432 ioc->name);
7433 spin_lock_irqsave(&ioc->sas_node_lock, flags);
7434 INIT_LIST_HEAD(&tmp_list);
7435 list_for_each_entry_safe(sas_expander, sas_expander_next,
7436 &ioc->sas_expander_list, list) {
7437 if (!sas_expander->responding)
7438 list_move_tail(&sas_expander->list, &tmp_list);
7439 else
7440 sas_expander->responding = 0;
7441 }
7442 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
7443 list_for_each_entry_safe(sas_expander, sas_expander_next, &tmp_list,
7444 list) {
7445 list_del(&sas_expander->list);
7446 _scsih_expander_node_remove(ioc, sas_expander);
7447 }
7448
7449 pr_info(MPT3SAS_FMT "removing unresponding devices: complete\n",
7450 ioc->name);
7451
7452 /* unblock devices */
7453 _scsih_ublock_io_all_device(ioc);
7454}
7455
7456static void
7457_scsih_refresh_expander_links(struct MPT3SAS_ADAPTER *ioc,
7458 struct _sas_node *sas_expander, u16 handle)
7459{
7460 Mpi2ExpanderPage1_t expander_pg1;
7461 Mpi2ConfigReply_t mpi_reply;
7462 int i;
7463
7464 for (i = 0 ; i < sas_expander->num_phys ; i++) {
7465 if ((mpt3sas_config_get_expander_pg1(ioc, &mpi_reply,
7466 &expander_pg1, i, handle))) {
7467 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
7468 ioc->name, __FILE__, __LINE__, __func__);
7469 return;
7470 }
7471
7472 mpt3sas_transport_update_links(ioc, sas_expander->sas_address,
7473 le16_to_cpu(expander_pg1.AttachedDevHandle), i,
7474 expander_pg1.NegotiatedLinkRate >> 4);
7475 }
7476}
7477
7478/**
7479 * _scsih_scan_for_devices_after_reset - scan for devices after host reset
7480 * @ioc: per adapter object
7481 *
7482 * Return nothing.
7483 */
7484static void
7485_scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
7486{
7487 Mpi2ExpanderPage0_t expander_pg0;
7488 Mpi2SasDevicePage0_t sas_device_pg0;
7489 Mpi2RaidVolPage1_t volume_pg1;
7490 Mpi2RaidVolPage0_t volume_pg0;
7491 Mpi2RaidPhysDiskPage0_t pd_pg0;
7492 Mpi2EventIrConfigElement_t element;
7493 Mpi2ConfigReply_t mpi_reply;
7494 u8 phys_disk_num;
7495 u16 ioc_status;
7496 u16 handle, parent_handle;
7497 u64 sas_address;
7498 struct _sas_device *sas_device;
7499 struct _sas_node *expander_device;
7500 static struct _raid_device *raid_device;
7501 u8 retry_count;
7502 unsigned long flags;
7503
7504 pr_info(MPT3SAS_FMT "scan devices: start\n", ioc->name);
7505
7506 _scsih_sas_host_refresh(ioc);
7507
7508 pr_info(MPT3SAS_FMT "\tscan devices: expanders start\n", ioc->name);
7509
7510 /* expanders */
7511 handle = 0xFFFF;
7512 while (!(mpt3sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
7513 MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) {
7514 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7515 MPI2_IOCSTATUS_MASK;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307516 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
7517 pr_info(MPT3SAS_FMT "\tbreak from expander scan: " \
7518 "ioc_status(0x%04x), loginfo(0x%08x)\n",
7519 ioc->name, ioc_status,
7520 le32_to_cpu(mpi_reply.IOCLogInfo));
7521 break;
7522 }
7523 handle = le16_to_cpu(expander_pg0.DevHandle);
7524 spin_lock_irqsave(&ioc->sas_node_lock, flags);
7525 expander_device = mpt3sas_scsih_expander_find_by_sas_address(
7526 ioc, le64_to_cpu(expander_pg0.SASAddress));
7527 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
7528 if (expander_device)
7529 _scsih_refresh_expander_links(ioc, expander_device,
7530 handle);
7531 else {
7532 pr_info(MPT3SAS_FMT "\tBEFORE adding expander: " \
7533 "handle (0x%04x), sas_addr(0x%016llx)\n", ioc->name,
7534 handle, (unsigned long long)
7535 le64_to_cpu(expander_pg0.SASAddress));
7536 _scsih_expander_add(ioc, handle);
7537 pr_info(MPT3SAS_FMT "\tAFTER adding expander: " \
7538 "handle (0x%04x), sas_addr(0x%016llx)\n", ioc->name,
7539 handle, (unsigned long long)
7540 le64_to_cpu(expander_pg0.SASAddress));
7541 }
7542 }
7543
7544 pr_info(MPT3SAS_FMT "\tscan devices: expanders complete\n",
7545 ioc->name);
7546
7547 if (!ioc->ir_firmware)
7548 goto skip_to_sas;
7549
7550 pr_info(MPT3SAS_FMT "\tscan devices: phys disk start\n", ioc->name);
7551
7552 /* phys disk */
7553 phys_disk_num = 0xFF;
7554 while (!(mpt3sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
7555 &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM,
7556 phys_disk_num))) {
7557 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7558 MPI2_IOCSTATUS_MASK;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307559 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
7560 pr_info(MPT3SAS_FMT "\tbreak from phys disk scan: "\
7561 "ioc_status(0x%04x), loginfo(0x%08x)\n",
7562 ioc->name, ioc_status,
7563 le32_to_cpu(mpi_reply.IOCLogInfo));
7564 break;
7565 }
7566 phys_disk_num = pd_pg0.PhysDiskNum;
7567 handle = le16_to_cpu(pd_pg0.DevHandle);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05307568 sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
7569 if (sas_device) {
7570 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307571 continue;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05307572 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307573 if (mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply,
7574 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
7575 handle) != 0)
7576 continue;
7577 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7578 MPI2_IOCSTATUS_MASK;
7579 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
7580 pr_info(MPT3SAS_FMT "\tbreak from phys disk scan " \
7581 "ioc_status(0x%04x), loginfo(0x%08x)\n",
7582 ioc->name, ioc_status,
7583 le32_to_cpu(mpi_reply.IOCLogInfo));
7584 break;
7585 }
7586 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
7587 if (!_scsih_get_sas_address(ioc, parent_handle,
7588 &sas_address)) {
7589 pr_info(MPT3SAS_FMT "\tBEFORE adding phys disk: " \
7590 " handle (0x%04x), sas_addr(0x%016llx)\n",
7591 ioc->name, handle, (unsigned long long)
7592 le64_to_cpu(sas_device_pg0.SASAddress));
7593 mpt3sas_transport_update_links(ioc, sas_address,
7594 handle, sas_device_pg0.PhyNum,
7595 MPI2_SAS_NEG_LINK_RATE_1_5);
7596 set_bit(handle, ioc->pd_handles);
7597 retry_count = 0;
7598 /* This will retry adding the end device.
7599 * _scsih_add_device() will decide on retries and
7600 * return "1" when it should be retried
7601 */
7602 while (_scsih_add_device(ioc, handle, retry_count++,
7603 1)) {
7604 ssleep(1);
7605 }
7606 pr_info(MPT3SAS_FMT "\tAFTER adding phys disk: " \
7607 " handle (0x%04x), sas_addr(0x%016llx)\n",
7608 ioc->name, handle, (unsigned long long)
7609 le64_to_cpu(sas_device_pg0.SASAddress));
7610 }
7611 }
7612
7613 pr_info(MPT3SAS_FMT "\tscan devices: phys disk complete\n",
7614 ioc->name);
7615
7616 pr_info(MPT3SAS_FMT "\tscan devices: volumes start\n", ioc->name);
7617
7618 /* volumes */
7619 handle = 0xFFFF;
7620 while (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
7621 &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
7622 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7623 MPI2_IOCSTATUS_MASK;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307624 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
7625 pr_info(MPT3SAS_FMT "\tbreak from volume scan: " \
7626 "ioc_status(0x%04x), loginfo(0x%08x)\n",
7627 ioc->name, ioc_status,
7628 le32_to_cpu(mpi_reply.IOCLogInfo));
7629 break;
7630 }
7631 handle = le16_to_cpu(volume_pg1.DevHandle);
7632 spin_lock_irqsave(&ioc->raid_device_lock, flags);
7633 raid_device = _scsih_raid_device_find_by_wwid(ioc,
7634 le64_to_cpu(volume_pg1.WWID));
7635 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
7636 if (raid_device)
7637 continue;
7638 if (mpt3sas_config_get_raid_volume_pg0(ioc, &mpi_reply,
7639 &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
7640 sizeof(Mpi2RaidVolPage0_t)))
7641 continue;
7642 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7643 MPI2_IOCSTATUS_MASK;
7644 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
7645 pr_info(MPT3SAS_FMT "\tbreak from volume scan: " \
7646 "ioc_status(0x%04x), loginfo(0x%08x)\n",
7647 ioc->name, ioc_status,
7648 le32_to_cpu(mpi_reply.IOCLogInfo));
7649 break;
7650 }
7651 if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL ||
7652 volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE ||
7653 volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED) {
7654 memset(&element, 0, sizeof(Mpi2EventIrConfigElement_t));
7655 element.ReasonCode = MPI2_EVENT_IR_CHANGE_RC_ADDED;
7656 element.VolDevHandle = volume_pg1.DevHandle;
7657 pr_info(MPT3SAS_FMT
7658 "\tBEFORE adding volume: handle (0x%04x)\n",
7659 ioc->name, volume_pg1.DevHandle);
7660 _scsih_sas_volume_add(ioc, &element);
7661 pr_info(MPT3SAS_FMT
7662 "\tAFTER adding volume: handle (0x%04x)\n",
7663 ioc->name, volume_pg1.DevHandle);
7664 }
7665 }
7666
7667 pr_info(MPT3SAS_FMT "\tscan devices: volumes complete\n",
7668 ioc->name);
7669
7670 skip_to_sas:
7671
7672 pr_info(MPT3SAS_FMT "\tscan devices: end devices start\n",
7673 ioc->name);
7674
7675 /* sas devices */
7676 handle = 0xFFFF;
7677 while (!(mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply,
7678 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
7679 handle))) {
7680 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7681 MPI2_IOCSTATUS_MASK;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307682 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
7683 pr_info(MPT3SAS_FMT "\tbreak from end device scan:"\
7684 " ioc_status(0x%04x), loginfo(0x%08x)\n",
7685 ioc->name, ioc_status,
7686 le32_to_cpu(mpi_reply.IOCLogInfo));
7687 break;
7688 }
7689 handle = le16_to_cpu(sas_device_pg0.DevHandle);
7690 if (!(_scsih_is_end_device(
7691 le32_to_cpu(sas_device_pg0.DeviceInfo))))
7692 continue;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05307693 sas_device = mpt3sas_get_sdev_by_addr(ioc,
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307694 le64_to_cpu(sas_device_pg0.SASAddress));
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05307695 if (sas_device) {
7696 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307697 continue;
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05307698 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307699 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
7700 if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) {
7701 pr_info(MPT3SAS_FMT "\tBEFORE adding end device: " \
7702 "handle (0x%04x), sas_addr(0x%016llx)\n", ioc->name,
7703 handle, (unsigned long long)
7704 le64_to_cpu(sas_device_pg0.SASAddress));
7705 mpt3sas_transport_update_links(ioc, sas_address, handle,
7706 sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
7707 retry_count = 0;
7708 /* This will retry adding the end device.
7709 * _scsih_add_device() will decide on retries and
7710 * return "1" when it should be retried
7711 */
7712 while (_scsih_add_device(ioc, handle, retry_count++,
7713 0)) {
7714 ssleep(1);
7715 }
7716 pr_info(MPT3SAS_FMT "\tAFTER adding end device: " \
7717 "handle (0x%04x), sas_addr(0x%016llx)\n", ioc->name,
7718 handle, (unsigned long long)
7719 le64_to_cpu(sas_device_pg0.SASAddress));
7720 }
7721 }
7722 pr_info(MPT3SAS_FMT "\tscan devices: end devices complete\n",
7723 ioc->name);
7724
7725 pr_info(MPT3SAS_FMT "scan devices: complete\n", ioc->name);
7726}
7727/**
7728 * mpt3sas_scsih_reset_handler - reset callback handler (for scsih)
7729 * @ioc: per adapter object
7730 * @reset_phase: phase
7731 *
7732 * The handler for doing any required cleanup or initialization.
7733 *
7734 * The reset phase can be MPT3_IOC_PRE_RESET, MPT3_IOC_AFTER_RESET,
7735 * MPT3_IOC_DONE_RESET
7736 *
7737 * Return nothing.
7738 */
7739void
7740mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
7741{
7742 switch (reset_phase) {
7743 case MPT3_IOC_PRE_RESET:
7744 dtmprintk(ioc, pr_info(MPT3SAS_FMT
7745 "%s: MPT3_IOC_PRE_RESET\n", ioc->name, __func__));
7746 break;
7747 case MPT3_IOC_AFTER_RESET:
7748 dtmprintk(ioc, pr_info(MPT3SAS_FMT
7749 "%s: MPT3_IOC_AFTER_RESET\n", ioc->name, __func__));
7750 if (ioc->scsih_cmds.status & MPT3_CMD_PENDING) {
7751 ioc->scsih_cmds.status |= MPT3_CMD_RESET;
7752 mpt3sas_base_free_smid(ioc, ioc->scsih_cmds.smid);
7753 complete(&ioc->scsih_cmds.done);
7754 }
7755 if (ioc->tm_cmds.status & MPT3_CMD_PENDING) {
7756 ioc->tm_cmds.status |= MPT3_CMD_RESET;
7757 mpt3sas_base_free_smid(ioc, ioc->tm_cmds.smid);
7758 complete(&ioc->tm_cmds.done);
7759 }
7760
7761 _scsih_fw_event_cleanup_queue(ioc);
7762 _scsih_flush_running_cmds(ioc);
7763 break;
7764 case MPT3_IOC_DONE_RESET:
7765 dtmprintk(ioc, pr_info(MPT3SAS_FMT
7766 "%s: MPT3_IOC_DONE_RESET\n", ioc->name, __func__));
7767 if ((!ioc->is_driver_loading) && !(disable_discovery > 0 &&
7768 !ioc->sas_hba.num_phys)) {
7769 _scsih_prep_device_scan(ioc);
7770 _scsih_search_responding_sas_devices(ioc);
7771 _scsih_search_responding_raid_devices(ioc);
7772 _scsih_search_responding_expanders(ioc);
7773 _scsih_error_recovery_delete_devices(ioc);
7774 }
7775 break;
7776 }
7777}
7778
7779/**
7780 * _mpt3sas_fw_work - delayed task for processing firmware events
7781 * @ioc: per adapter object
7782 * @fw_event: The fw_event_work object
7783 * Context: user.
7784 *
7785 * Return nothing.
7786 */
7787static void
7788_mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
7789{
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05307790 _scsih_fw_event_del_from_list(ioc, fw_event);
7791
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307792 /* the queue is being flushed so ignore this event */
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05307793 if (ioc->remove_host || ioc->pci_error_recovery) {
7794 fw_event_work_put(fw_event);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307795 return;
7796 }
7797
7798 switch (fw_event->event) {
7799 case MPT3SAS_PROCESS_TRIGGER_DIAG:
Joe Lawrence35b62362014-06-25 17:05:34 -04007800 mpt3sas_process_trigger_data(ioc,
7801 (struct SL_WH_TRIGGERS_EVENT_DATA_T *)
7802 fw_event->event_data);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307803 break;
7804 case MPT3SAS_REMOVE_UNRESPONDING_DEVICES:
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05307805 while (scsi_host_in_recovery(ioc->shost) ||
7806 ioc->shost_recovery) {
7807 /*
7808 * If we're unloading, bail. Otherwise, this can become
7809 * an infinite loop.
7810 */
7811 if (ioc->remove_host)
7812 goto out;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307813 ssleep(1);
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05307814 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307815 _scsih_remove_unresponding_sas_devices(ioc);
7816 _scsih_scan_for_devices_after_reset(ioc);
7817 break;
7818 case MPT3SAS_PORT_ENABLE_COMPLETE:
7819 ioc->start_scan = 0;
7820 if (missing_delay[0] != -1 && missing_delay[1] != -1)
7821 mpt3sas_base_update_missing_delay(ioc, missing_delay[0],
7822 missing_delay[1]);
7823 dewtprintk(ioc, pr_info(MPT3SAS_FMT
7824 "port enable: complete from worker thread\n",
7825 ioc->name));
7826 break;
Sreekanth Reddy0f624c32014-09-12 15:35:26 +05307827 case MPT3SAS_TURN_ON_PFA_LED:
7828 _scsih_turn_on_pfa_led(ioc, fw_event->device_handle);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307829 break;
7830 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
7831 _scsih_sas_topology_change_event(ioc, fw_event);
7832 break;
7833 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
7834 _scsih_sas_device_status_change_event(ioc, fw_event);
7835 break;
7836 case MPI2_EVENT_SAS_DISCOVERY:
7837 _scsih_sas_discovery_event(ioc, fw_event);
7838 break;
7839 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
7840 _scsih_sas_broadcast_primitive_event(ioc, fw_event);
7841 break;
7842 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
7843 _scsih_sas_enclosure_dev_status_change_event(ioc,
7844 fw_event);
7845 break;
7846 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
7847 _scsih_sas_ir_config_change_event(ioc, fw_event);
7848 break;
7849 case MPI2_EVENT_IR_VOLUME:
7850 _scsih_sas_ir_volume_event(ioc, fw_event);
7851 break;
7852 case MPI2_EVENT_IR_PHYSICAL_DISK:
7853 _scsih_sas_ir_physical_disk_event(ioc, fw_event);
7854 break;
7855 case MPI2_EVENT_IR_OPERATION_STATUS:
7856 _scsih_sas_ir_operation_status_event(ioc, fw_event);
7857 break;
7858 }
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05307859out:
7860 fw_event_work_put(fw_event);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307861}
7862
7863/**
7864 * _firmware_event_work
7865 * @ioc: per adapter object
7866 * @work: The fw_event_work object
7867 * Context: user.
7868 *
7869 * wrappers for the work thread handling firmware events
7870 *
7871 * Return nothing.
7872 */
7873
7874static void
7875_firmware_event_work(struct work_struct *work)
7876{
7877 struct fw_event_work *fw_event = container_of(work,
7878 struct fw_event_work, work);
7879
7880 _mpt3sas_fw_work(fw_event->ioc, fw_event);
7881}
7882
7883/**
7884 * mpt3sas_scsih_event_callback - firmware event handler (called at ISR time)
7885 * @ioc: per adapter object
7886 * @msix_index: MSIX table index supplied by the OS
7887 * @reply: reply message frame(lower 32bit addr)
7888 * Context: interrupt.
7889 *
7890 * This function merely adds a new work task into ioc->firmware_event_thread.
7891 * The tasks are worked from _firmware_event_work in user context.
7892 *
7893 * Return 1 meaning mf should be freed from _base_interrupt
7894 * 0 means the mf is freed from this function.
7895 */
7896u8
7897mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
7898 u32 reply)
7899{
7900 struct fw_event_work *fw_event;
7901 Mpi2EventNotificationReply_t *mpi_reply;
7902 u16 event;
7903 u16 sz;
Chaitra P Ba470a512016-05-06 14:29:27 +05307904 Mpi26EventDataActiveCableExcept_t *ActiveCableEventData;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307905
7906 /* events turned off due to host reset or driver unloading */
7907 if (ioc->remove_host || ioc->pci_error_recovery)
7908 return 1;
7909
7910 mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
7911
7912 if (unlikely(!mpi_reply)) {
7913 pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n",
7914 ioc->name, __FILE__, __LINE__, __func__);
7915 return 1;
7916 }
7917
7918 event = le16_to_cpu(mpi_reply->Event);
7919
7920 if (event != MPI2_EVENT_LOG_ENTRY_ADDED)
7921 mpt3sas_trigger_event(ioc, event, 0);
7922
7923 switch (event) {
7924 /* handle these */
7925 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
7926 {
7927 Mpi2EventDataSasBroadcastPrimitive_t *baen_data =
7928 (Mpi2EventDataSasBroadcastPrimitive_t *)
7929 mpi_reply->EventData;
7930
7931 if (baen_data->Primitive !=
7932 MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
7933 return 1;
7934
7935 if (ioc->broadcast_aen_busy) {
7936 ioc->broadcast_aen_pending++;
7937 return 1;
7938 } else
7939 ioc->broadcast_aen_busy = 1;
7940 break;
7941 }
7942
7943 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
7944 _scsih_check_topo_delete_events(ioc,
7945 (Mpi2EventDataSasTopologyChangeList_t *)
7946 mpi_reply->EventData);
7947 break;
7948 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
7949 _scsih_check_ir_config_unhide_events(ioc,
7950 (Mpi2EventDataIrConfigChangeList_t *)
7951 mpi_reply->EventData);
7952 break;
7953 case MPI2_EVENT_IR_VOLUME:
7954 _scsih_check_volume_delete_events(ioc,
7955 (Mpi2EventDataIrVolume_t *)
7956 mpi_reply->EventData);
7957 break;
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05307958 case MPI2_EVENT_LOG_ENTRY_ADDED:
7959 {
7960 Mpi2EventDataLogEntryAdded_t *log_entry;
7961 u32 *log_code;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05307962
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05307963 if (!ioc->is_warpdrive)
7964 break;
7965
7966 log_entry = (Mpi2EventDataLogEntryAdded_t *)
7967 mpi_reply->EventData;
7968 log_code = (u32 *)log_entry->LogData;
7969
7970 if (le16_to_cpu(log_entry->LogEntryQualifier)
7971 != MPT2_WARPDRIVE_LOGENTRY)
7972 break;
7973
7974 switch (le32_to_cpu(*log_code)) {
7975 case MPT2_WARPDRIVE_LC_SSDT:
7976 pr_warn(MPT3SAS_FMT "WarpDrive Warning: "
7977 "IO Throttling has occurred in the WarpDrive "
7978 "subsystem. Check WarpDrive documentation for "
7979 "additional details.\n", ioc->name);
7980 break;
7981 case MPT2_WARPDRIVE_LC_SSDLW:
7982 pr_warn(MPT3SAS_FMT "WarpDrive Warning: "
7983 "Program/Erase Cycles for the WarpDrive subsystem "
7984 "in degraded range. Check WarpDrive documentation "
7985 "for additional details.\n", ioc->name);
7986 break;
7987 case MPT2_WARPDRIVE_LC_SSDLF:
7988 pr_err(MPT3SAS_FMT "WarpDrive Fatal Error: "
7989 "There are no Program/Erase Cycles for the "
7990 "WarpDrive subsystem. The storage device will be "
7991 "in read-only mode. Check WarpDrive documentation "
7992 "for additional details.\n", ioc->name);
7993 break;
7994 case MPT2_WARPDRIVE_LC_BRMF:
7995 pr_err(MPT3SAS_FMT "WarpDrive Fatal Error: "
7996 "The Backup Rail Monitor has failed on the "
7997 "WarpDrive subsystem. Check WarpDrive "
7998 "documentation for additional details.\n",
7999 ioc->name);
8000 break;
8001 }
8002
8003 break;
8004 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308005 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
8006 case MPI2_EVENT_IR_OPERATION_STATUS:
8007 case MPI2_EVENT_SAS_DISCOVERY:
8008 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
8009 case MPI2_EVENT_IR_PHYSICAL_DISK:
8010 break;
8011
Sreekanth Reddy2d8ce8c2015-01-12 11:38:56 +05308012 case MPI2_EVENT_TEMP_THRESHOLD:
8013 _scsih_temp_threshold_events(ioc,
8014 (Mpi2EventDataTemperature_t *)
8015 mpi_reply->EventData);
8016 break;
Chaitra P Ba470a512016-05-06 14:29:27 +05308017 case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
8018 ActiveCableEventData =
8019 (Mpi26EventDataActiveCableExcept_t *) mpi_reply->EventData;
8020 if (ActiveCableEventData->ReasonCode ==
Dan Carpenter7ebd67e2016-05-12 23:37:38 +03008021 MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER) {
Chaitra P Ba470a512016-05-06 14:29:27 +05308022 pr_info(MPT3SAS_FMT "Currently an active cable with ReceptacleID %d",
8023 ioc->name, ActiveCableEventData->ReceptacleID);
8024 pr_info("cannot be powered and devices connected to this active cable");
8025 pr_info("will not be seen. This active cable");
8026 pr_info("requires %d mW of power",
8027 ActiveCableEventData->ActiveCablePowerRequirement);
Dan Carpenter7ebd67e2016-05-12 23:37:38 +03008028 }
Chaitra P Ba470a512016-05-06 14:29:27 +05308029 break;
Sreekanth Reddy2d8ce8c2015-01-12 11:38:56 +05308030
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308031 default: /* ignore the rest */
8032 return 1;
8033 }
8034
Joe Lawrence35b62362014-06-25 17:05:34 -04008035 sz = le16_to_cpu(mpi_reply->EventDataLength) * 4;
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05308036 fw_event = alloc_fw_event_work(sz);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308037 if (!fw_event) {
8038 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
8039 ioc->name, __FILE__, __LINE__, __func__);
8040 return 1;
8041 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308042
8043 memcpy(fw_event->event_data, mpi_reply->EventData, sz);
8044 fw_event->ioc = ioc;
8045 fw_event->VF_ID = mpi_reply->VF_ID;
8046 fw_event->VP_ID = mpi_reply->VP_ID;
8047 fw_event->event = event;
8048 _scsih_fw_event_add(ioc, fw_event);
Sreekanth Reddy146b16c2015-11-11 17:30:31 +05308049 fw_event_work_put(fw_event);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308050 return 1;
8051}
8052
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308053/**
8054 * _scsih_expander_node_remove - removing expander device from list.
8055 * @ioc: per adapter object
8056 * @sas_expander: the sas_device object
8057 * Context: Calling function should acquire ioc->sas_node_lock.
8058 *
8059 * Removing object and freeing associated memory from the
8060 * ioc->sas_expander_list.
8061 *
8062 * Return nothing.
8063 */
8064static void
8065_scsih_expander_node_remove(struct MPT3SAS_ADAPTER *ioc,
8066 struct _sas_node *sas_expander)
8067{
8068 struct _sas_port *mpt3sas_port, *next;
8069
8070 /* remove sibling ports attached to this expander */
8071 list_for_each_entry_safe(mpt3sas_port, next,
8072 &sas_expander->sas_port_list, port_list) {
8073 if (ioc->shost_recovery)
8074 return;
8075 if (mpt3sas_port->remote_identify.device_type ==
8076 SAS_END_DEVICE)
8077 mpt3sas_device_remove_by_sas_address(ioc,
8078 mpt3sas_port->remote_identify.sas_address);
8079 else if (mpt3sas_port->remote_identify.device_type ==
8080 SAS_EDGE_EXPANDER_DEVICE ||
8081 mpt3sas_port->remote_identify.device_type ==
8082 SAS_FANOUT_EXPANDER_DEVICE)
8083 mpt3sas_expander_remove(ioc,
8084 mpt3sas_port->remote_identify.sas_address);
8085 }
8086
8087 mpt3sas_transport_port_remove(ioc, sas_expander->sas_address,
8088 sas_expander->sas_address_parent);
8089
8090 pr_info(MPT3SAS_FMT
8091 "expander_remove: handle(0x%04x), sas_addr(0x%016llx)\n",
8092 ioc->name,
8093 sas_expander->handle, (unsigned long long)
8094 sas_expander->sas_address);
8095
8096 kfree(sas_expander->phy);
8097 kfree(sas_expander);
8098}
8099
8100/**
8101 * _scsih_ir_shutdown - IR shutdown notification
8102 * @ioc: per adapter object
8103 *
8104 * Sending RAID Action to alert the Integrated RAID subsystem of the IOC that
8105 * the host system is shutting down.
8106 *
8107 * Return nothing.
8108 */
8109static void
8110_scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc)
8111{
8112 Mpi2RaidActionRequest_t *mpi_request;
8113 Mpi2RaidActionReply_t *mpi_reply;
8114 u16 smid;
8115
8116 /* is IR firmware build loaded ? */
8117 if (!ioc->ir_firmware)
8118 return;
8119
8120 /* are there any volumes ? */
8121 if (list_empty(&ioc->raid_device_list))
8122 return;
8123
8124 mutex_lock(&ioc->scsih_cmds.mutex);
8125
8126 if (ioc->scsih_cmds.status != MPT3_CMD_NOT_USED) {
8127 pr_err(MPT3SAS_FMT "%s: scsih_cmd in use\n",
8128 ioc->name, __func__);
8129 goto out;
8130 }
8131 ioc->scsih_cmds.status = MPT3_CMD_PENDING;
8132
8133 smid = mpt3sas_base_get_smid(ioc, ioc->scsih_cb_idx);
8134 if (!smid) {
8135 pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
8136 ioc->name, __func__);
8137 ioc->scsih_cmds.status = MPT3_CMD_NOT_USED;
8138 goto out;
8139 }
8140
8141 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
8142 ioc->scsih_cmds.smid = smid;
8143 memset(mpi_request, 0, sizeof(Mpi2RaidActionRequest_t));
8144
8145 mpi_request->Function = MPI2_FUNCTION_RAID_ACTION;
8146 mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
8147
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05308148 if (!ioc->hide_ir_msg)
8149 pr_info(MPT3SAS_FMT "IR shutdown (sending)\n", ioc->name);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308150 init_completion(&ioc->scsih_cmds.done);
8151 mpt3sas_base_put_smid_default(ioc, smid);
8152 wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ);
8153
8154 if (!(ioc->scsih_cmds.status & MPT3_CMD_COMPLETE)) {
8155 pr_err(MPT3SAS_FMT "%s: timeout\n",
8156 ioc->name, __func__);
8157 goto out;
8158 }
8159
8160 if (ioc->scsih_cmds.status & MPT3_CMD_REPLY_VALID) {
8161 mpi_reply = ioc->scsih_cmds.reply;
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05308162 if (!ioc->hide_ir_msg)
8163 pr_info(MPT3SAS_FMT "IR shutdown "
8164 "(complete): ioc_status(0x%04x), loginfo(0x%08x)\n",
8165 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
8166 le32_to_cpu(mpi_reply->IOCLogInfo));
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308167 }
8168
8169 out:
8170 ioc->scsih_cmds.status = MPT3_CMD_NOT_USED;
8171 mutex_unlock(&ioc->scsih_cmds.mutex);
8172}
8173
8174/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05308175 * scsih_remove - detach and remove add host
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308176 * @pdev: PCI device struct
8177 *
8178 * Routine called when unloading the driver.
8179 * Return nothing.
8180 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07008181static void scsih_remove(struct pci_dev *pdev)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308182{
8183 struct Scsi_Host *shost = pci_get_drvdata(pdev);
8184 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
8185 struct _sas_port *mpt3sas_port, *next_port;
8186 struct _raid_device *raid_device, *next;
8187 struct MPT3SAS_TARGET *sas_target_priv_data;
8188 struct workqueue_struct *wq;
8189 unsigned long flags;
8190
8191 ioc->remove_host = 1;
8192 _scsih_fw_event_cleanup_queue(ioc);
8193
8194 spin_lock_irqsave(&ioc->fw_event_lock, flags);
8195 wq = ioc->firmware_event_thread;
8196 ioc->firmware_event_thread = NULL;
8197 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
8198 if (wq)
8199 destroy_workqueue(wq);
8200
8201 /* release all the volumes */
8202 _scsih_ir_shutdown(ioc);
8203 list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list,
8204 list) {
8205 if (raid_device->starget) {
8206 sas_target_priv_data =
8207 raid_device->starget->hostdata;
8208 sas_target_priv_data->deleted = 1;
8209 scsi_remove_target(&raid_device->starget->dev);
8210 }
8211 pr_info(MPT3SAS_FMT "removing handle(0x%04x), wwid(0x%016llx)\n",
8212 ioc->name, raid_device->handle,
8213 (unsigned long long) raid_device->wwid);
8214 _scsih_raid_device_remove(ioc, raid_device);
8215 }
8216
8217 /* free ports attached to the sas_host */
8218 list_for_each_entry_safe(mpt3sas_port, next_port,
8219 &ioc->sas_hba.sas_port_list, port_list) {
8220 if (mpt3sas_port->remote_identify.device_type ==
8221 SAS_END_DEVICE)
8222 mpt3sas_device_remove_by_sas_address(ioc,
8223 mpt3sas_port->remote_identify.sas_address);
8224 else if (mpt3sas_port->remote_identify.device_type ==
8225 SAS_EDGE_EXPANDER_DEVICE ||
8226 mpt3sas_port->remote_identify.device_type ==
8227 SAS_FANOUT_EXPANDER_DEVICE)
8228 mpt3sas_expander_remove(ioc,
8229 mpt3sas_port->remote_identify.sas_address);
8230 }
8231
8232 /* free phys attached to the sas_host */
8233 if (ioc->sas_hba.num_phys) {
8234 kfree(ioc->sas_hba.phy);
8235 ioc->sas_hba.phy = NULL;
8236 ioc->sas_hba.num_phys = 0;
8237 }
8238
8239 sas_remove_host(shost);
Reddy, Sreekanth4dc06fd2014-07-14 12:01:35 +05308240 scsi_remove_host(shost);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308241 mpt3sas_base_detach(ioc);
Sreekanth Reddy08c4d552015-11-11 17:30:33 +05308242 spin_lock(&gioc_lock);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308243 list_del(&ioc->list);
Sreekanth Reddy08c4d552015-11-11 17:30:33 +05308244 spin_unlock(&gioc_lock);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308245 scsi_host_put(shost);
8246}
8247
8248/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05308249 * scsih_shutdown - routine call during system shutdown
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308250 * @pdev: PCI device struct
8251 *
8252 * Return nothing.
8253 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07008254static void
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05308255scsih_shutdown(struct pci_dev *pdev)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308256{
8257 struct Scsi_Host *shost = pci_get_drvdata(pdev);
8258 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
8259 struct workqueue_struct *wq;
8260 unsigned long flags;
8261
8262 ioc->remove_host = 1;
8263 _scsih_fw_event_cleanup_queue(ioc);
8264
8265 spin_lock_irqsave(&ioc->fw_event_lock, flags);
8266 wq = ioc->firmware_event_thread;
8267 ioc->firmware_event_thread = NULL;
8268 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
8269 if (wq)
8270 destroy_workqueue(wq);
8271
8272 _scsih_ir_shutdown(ioc);
8273 mpt3sas_base_detach(ioc);
8274}
8275
8276
8277/**
8278 * _scsih_probe_boot_devices - reports 1st device
8279 * @ioc: per adapter object
8280 *
8281 * If specified in bios page 2, this routine reports the 1st
8282 * device scsi-ml or sas transport for persistent boot device
8283 * purposes. Please refer to function _scsih_determine_boot_device()
8284 */
8285static void
8286_scsih_probe_boot_devices(struct MPT3SAS_ADAPTER *ioc)
8287{
8288 u8 is_raid;
8289 void *device;
8290 struct _sas_device *sas_device;
8291 struct _raid_device *raid_device;
8292 u16 handle;
8293 u64 sas_address_parent;
8294 u64 sas_address;
8295 unsigned long flags;
8296 int rc;
8297
8298 /* no Bios, return immediately */
8299 if (!ioc->bios_pg3.BiosVersion)
8300 return;
8301
8302 device = NULL;
8303 is_raid = 0;
8304 if (ioc->req_boot_device.device) {
8305 device = ioc->req_boot_device.device;
8306 is_raid = ioc->req_boot_device.is_raid;
8307 } else if (ioc->req_alt_boot_device.device) {
8308 device = ioc->req_alt_boot_device.device;
8309 is_raid = ioc->req_alt_boot_device.is_raid;
8310 } else if (ioc->current_boot_device.device) {
8311 device = ioc->current_boot_device.device;
8312 is_raid = ioc->current_boot_device.is_raid;
8313 }
8314
8315 if (!device)
8316 return;
8317
8318 if (is_raid) {
8319 raid_device = device;
8320 rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
8321 raid_device->id, 0);
8322 if (rc)
8323 _scsih_raid_device_remove(ioc, raid_device);
8324 } else {
8325 spin_lock_irqsave(&ioc->sas_device_lock, flags);
8326 sas_device = device;
8327 handle = sas_device->handle;
8328 sas_address_parent = sas_device->sas_address_parent;
8329 sas_address = sas_device->sas_address;
8330 list_move_tail(&sas_device->list, &ioc->sas_device_list);
8331 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
8332
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05308333 if (ioc->hide_drives)
8334 return;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308335 if (!mpt3sas_transport_port_add(ioc, handle,
8336 sas_address_parent)) {
8337 _scsih_sas_device_remove(ioc, sas_device);
8338 } else if (!sas_device->starget) {
Sreekanth Reddyf5edbe72013-06-29 03:54:51 +05308339 if (!ioc->is_driver_loading) {
8340 mpt3sas_transport_port_remove(ioc,
8341 sas_address,
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308342 sas_address_parent);
Sreekanth Reddyf5edbe72013-06-29 03:54:51 +05308343 _scsih_sas_device_remove(ioc, sas_device);
8344 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308345 }
8346 }
8347}
8348
8349/**
8350 * _scsih_probe_raid - reporting raid volumes to scsi-ml
8351 * @ioc: per adapter object
8352 *
8353 * Called during initial loading of the driver.
8354 */
8355static void
8356_scsih_probe_raid(struct MPT3SAS_ADAPTER *ioc)
8357{
8358 struct _raid_device *raid_device, *raid_next;
8359 int rc;
8360
8361 list_for_each_entry_safe(raid_device, raid_next,
8362 &ioc->raid_device_list, list) {
8363 if (raid_device->starget)
8364 continue;
8365 rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
8366 raid_device->id, 0);
8367 if (rc)
8368 _scsih_raid_device_remove(ioc, raid_device);
8369 }
8370}
8371
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05308372static struct _sas_device *get_next_sas_device(struct MPT3SAS_ADAPTER *ioc)
8373{
8374 struct _sas_device *sas_device = NULL;
8375 unsigned long flags;
8376
8377 spin_lock_irqsave(&ioc->sas_device_lock, flags);
8378 if (!list_empty(&ioc->sas_device_init_list)) {
8379 sas_device = list_first_entry(&ioc->sas_device_init_list,
8380 struct _sas_device, list);
8381 sas_device_get(sas_device);
8382 }
8383 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
8384
8385 return sas_device;
8386}
8387
8388static void sas_device_make_active(struct MPT3SAS_ADAPTER *ioc,
8389 struct _sas_device *sas_device)
8390{
8391 unsigned long flags;
8392
8393 spin_lock_irqsave(&ioc->sas_device_lock, flags);
8394
8395 /*
8396 * Since we dropped the lock during the call to port_add(), we need to
8397 * be careful here that somebody else didn't move or delete this item
8398 * while we were busy with other things.
8399 *
8400 * If it was on the list, we need a put() for the reference the list
8401 * had. Either way, we need a get() for the destination list.
8402 */
8403 if (!list_empty(&sas_device->list)) {
8404 list_del_init(&sas_device->list);
8405 sas_device_put(sas_device);
8406 }
8407
8408 sas_device_get(sas_device);
8409 list_add_tail(&sas_device->list, &ioc->sas_device_list);
8410
8411 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
8412}
8413
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308414/**
8415 * _scsih_probe_sas - reporting sas devices to sas transport
8416 * @ioc: per adapter object
8417 *
8418 * Called during initial loading of the driver.
8419 */
8420static void
8421_scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc)
8422{
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05308423 struct _sas_device *sas_device;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308424
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05308425 if (ioc->hide_drives)
8426 return;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308427
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05308428 while ((sas_device = get_next_sas_device(ioc))) {
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308429 if (!mpt3sas_transport_port_add(ioc, sas_device->handle,
8430 sas_device->sas_address_parent)) {
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05308431 _scsih_sas_device_remove(ioc, sas_device);
8432 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308433 continue;
8434 } else if (!sas_device->starget) {
8435 /*
8436 * When asyn scanning is enabled, its not possible to
8437 * remove devices while scanning is turned on due to an
8438 * oops in scsi_sysfs_add_sdev()->add_device()->
8439 * sysfs_addrm_start()
8440 */
Sreekanth Reddyf5edbe72013-06-29 03:54:51 +05308441 if (!ioc->is_driver_loading) {
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308442 mpt3sas_transport_port_remove(ioc,
8443 sas_device->sas_address,
8444 sas_device->sas_address_parent);
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05308445 _scsih_sas_device_remove(ioc, sas_device);
8446 sas_device_put(sas_device);
Sreekanth Reddyf5edbe72013-06-29 03:54:51 +05308447 continue;
8448 }
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308449 }
Sreekanth Reddyd1cb5e42015-11-11 17:30:30 +05308450 sas_device_make_active(ioc, sas_device);
8451 sas_device_put(sas_device);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308452 }
8453}
8454
8455/**
8456 * _scsih_probe_devices - probing for devices
8457 * @ioc: per adapter object
8458 *
8459 * Called during initial loading of the driver.
8460 */
8461static void
8462_scsih_probe_devices(struct MPT3SAS_ADAPTER *ioc)
8463{
8464 u16 volume_mapping_flags;
8465
8466 if (!(ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR))
8467 return; /* return when IOC doesn't support initiator mode */
8468
8469 _scsih_probe_boot_devices(ioc);
8470
8471 if (ioc->ir_firmware) {
8472 volume_mapping_flags =
8473 le16_to_cpu(ioc->ioc_pg8.IRVolumeMappingFlags) &
8474 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
8475 if (volume_mapping_flags ==
8476 MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) {
8477 _scsih_probe_raid(ioc);
8478 _scsih_probe_sas(ioc);
8479 } else {
8480 _scsih_probe_sas(ioc);
8481 _scsih_probe_raid(ioc);
8482 }
8483 } else
8484 _scsih_probe_sas(ioc);
8485}
8486
8487/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05308488 * scsih_scan_start - scsi lld callback for .scan_start
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308489 * @shost: SCSI host pointer
8490 *
8491 * The shost has the ability to discover targets on its own instead
8492 * of scanning the entire bus. In our implemention, we will kick off
8493 * firmware discovery.
8494 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07008495static void
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05308496scsih_scan_start(struct Scsi_Host *shost)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308497{
8498 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
8499 int rc;
8500 if (diag_buffer_enable != -1 && diag_buffer_enable != 0)
8501 mpt3sas_enable_diag_buffer(ioc, diag_buffer_enable);
8502
8503 if (disable_discovery > 0)
8504 return;
8505
8506 ioc->start_scan = 1;
8507 rc = mpt3sas_port_enable(ioc);
8508
8509 if (rc != 0)
8510 pr_info(MPT3SAS_FMT "port enable: FAILED\n", ioc->name);
8511}
8512
8513/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05308514 * scsih_scan_finished - scsi lld callback for .scan_finished
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308515 * @shost: SCSI host pointer
8516 * @time: elapsed time of the scan in jiffies
8517 *
8518 * This function will be called periodicallyn until it returns 1 with the
8519 * scsi_host and the elapsed time of the scan in jiffies. In our implemention,
8520 * we wait for firmware discovery to complete, then return 1.
8521 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07008522static int
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05308523scsih_scan_finished(struct Scsi_Host *shost, unsigned long time)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308524{
8525 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
8526
8527 if (disable_discovery > 0) {
8528 ioc->is_driver_loading = 0;
8529 ioc->wait_for_discovery_to_complete = 0;
8530 return 1;
8531 }
8532
8533 if (time >= (300 * HZ)) {
8534 ioc->base_cmds.status = MPT3_CMD_NOT_USED;
8535 pr_info(MPT3SAS_FMT
8536 "port enable: FAILED with timeout (timeout=300s)\n",
8537 ioc->name);
8538 ioc->is_driver_loading = 0;
8539 return 1;
8540 }
8541
8542 if (ioc->start_scan)
8543 return 0;
8544
8545 if (ioc->start_scan_failed) {
8546 pr_info(MPT3SAS_FMT
8547 "port enable: FAILED with (ioc_status=0x%08x)\n",
8548 ioc->name, ioc->start_scan_failed);
8549 ioc->is_driver_loading = 0;
8550 ioc->wait_for_discovery_to_complete = 0;
8551 ioc->remove_host = 1;
8552 return 1;
8553 }
8554
8555 pr_info(MPT3SAS_FMT "port enable: SUCCESS\n", ioc->name);
8556 ioc->base_cmds.status = MPT3_CMD_NOT_USED;
8557
8558 if (ioc->wait_for_discovery_to_complete) {
8559 ioc->wait_for_discovery_to_complete = 0;
8560 _scsih_probe_devices(ioc);
8561 }
8562 mpt3sas_base_start_watchdog(ioc);
8563 ioc->is_driver_loading = 0;
8564 return 1;
8565}
8566
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308567/* shost template for SAS 2.0 HBA devices */
8568static struct scsi_host_template mpt2sas_driver_template = {
8569 .module = THIS_MODULE,
8570 .name = "Fusion MPT SAS Host",
8571 .proc_name = MPT2SAS_DRIVER_NAME,
8572 .queuecommand = scsih_qcmd,
8573 .target_alloc = scsih_target_alloc,
8574 .slave_alloc = scsih_slave_alloc,
8575 .slave_configure = scsih_slave_configure,
8576 .target_destroy = scsih_target_destroy,
8577 .slave_destroy = scsih_slave_destroy,
8578 .scan_finished = scsih_scan_finished,
8579 .scan_start = scsih_scan_start,
8580 .change_queue_depth = scsih_change_queue_depth,
8581 .eh_abort_handler = scsih_abort,
8582 .eh_device_reset_handler = scsih_dev_reset,
8583 .eh_target_reset_handler = scsih_target_reset,
8584 .eh_host_reset_handler = scsih_host_reset,
8585 .bios_param = scsih_bios_param,
8586 .can_queue = 1,
8587 .this_id = -1,
8588 .sg_tablesize = MPT2SAS_SG_DEPTH,
8589 .max_sectors = 32767,
8590 .cmd_per_lun = 7,
8591 .use_clustering = ENABLE_CLUSTERING,
8592 .shost_attrs = mpt3sas_host_attrs,
8593 .sdev_attrs = mpt3sas_dev_attrs,
8594 .track_queue_depth = 1,
8595};
Sreekanth Reddyd357e842015-11-11 17:30:22 +05308596
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308597/* raid transport support for SAS 2.0 HBA devices */
8598static struct raid_function_template mpt2sas_raid_functions = {
8599 .cookie = &mpt2sas_driver_template,
8600 .is_raid = scsih_is_raid,
8601 .get_resync = scsih_get_resync,
8602 .get_state = scsih_get_state,
8603};
8604
8605/* shost template for SAS 3.0 HBA devices */
8606static struct scsi_host_template mpt3sas_driver_template = {
8607 .module = THIS_MODULE,
8608 .name = "Fusion MPT SAS Host",
8609 .proc_name = MPT3SAS_DRIVER_NAME,
8610 .queuecommand = scsih_qcmd,
8611 .target_alloc = scsih_target_alloc,
8612 .slave_alloc = scsih_slave_alloc,
8613 .slave_configure = scsih_slave_configure,
8614 .target_destroy = scsih_target_destroy,
8615 .slave_destroy = scsih_slave_destroy,
8616 .scan_finished = scsih_scan_finished,
8617 .scan_start = scsih_scan_start,
8618 .change_queue_depth = scsih_change_queue_depth,
8619 .eh_abort_handler = scsih_abort,
8620 .eh_device_reset_handler = scsih_dev_reset,
8621 .eh_target_reset_handler = scsih_target_reset,
8622 .eh_host_reset_handler = scsih_host_reset,
8623 .bios_param = scsih_bios_param,
8624 .can_queue = 1,
8625 .this_id = -1,
8626 .sg_tablesize = MPT3SAS_SG_DEPTH,
8627 .max_sectors = 32767,
8628 .cmd_per_lun = 7,
8629 .use_clustering = ENABLE_CLUSTERING,
8630 .shost_attrs = mpt3sas_host_attrs,
8631 .sdev_attrs = mpt3sas_dev_attrs,
8632 .track_queue_depth = 1,
8633};
8634
8635/* raid transport support for SAS 3.0 HBA devices */
8636static struct raid_function_template mpt3sas_raid_functions = {
8637 .cookie = &mpt3sas_driver_template,
8638 .is_raid = scsih_is_raid,
8639 .get_resync = scsih_get_resync,
8640 .get_state = scsih_get_state,
8641};
8642
8643/**
8644 * _scsih_determine_hba_mpi_version - determine in which MPI version class
8645 * this device belongs to.
8646 * @pdev: PCI device struct
8647 *
8648 * return MPI2_VERSION for SAS 2.0 HBA devices,
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05308649 * MPI25_VERSION for SAS 3.0 HBA devices, and
8650 * MPI26 VERSION for Cutlass & Invader SAS 3.0 HBA devices
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308651 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07008652static u16
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308653_scsih_determine_hba_mpi_version(struct pci_dev *pdev)
8654{
8655
8656 switch (pdev->device) {
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05308657 case MPI2_MFGPAGE_DEVID_SSS6200:
Sreekanth Reddyd357e842015-11-11 17:30:22 +05308658 case MPI2_MFGPAGE_DEVID_SAS2004:
8659 case MPI2_MFGPAGE_DEVID_SAS2008:
8660 case MPI2_MFGPAGE_DEVID_SAS2108_1:
8661 case MPI2_MFGPAGE_DEVID_SAS2108_2:
8662 case MPI2_MFGPAGE_DEVID_SAS2108_3:
8663 case MPI2_MFGPAGE_DEVID_SAS2116_1:
8664 case MPI2_MFGPAGE_DEVID_SAS2116_2:
8665 case MPI2_MFGPAGE_DEVID_SAS2208_1:
8666 case MPI2_MFGPAGE_DEVID_SAS2208_2:
8667 case MPI2_MFGPAGE_DEVID_SAS2208_3:
8668 case MPI2_MFGPAGE_DEVID_SAS2208_4:
8669 case MPI2_MFGPAGE_DEVID_SAS2208_5:
8670 case MPI2_MFGPAGE_DEVID_SAS2208_6:
8671 case MPI2_MFGPAGE_DEVID_SAS2308_1:
8672 case MPI2_MFGPAGE_DEVID_SAS2308_2:
8673 case MPI2_MFGPAGE_DEVID_SAS2308_3:
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308674 return MPI2_VERSION;
Sreekanth Reddyd357e842015-11-11 17:30:22 +05308675 case MPI25_MFGPAGE_DEVID_SAS3004:
8676 case MPI25_MFGPAGE_DEVID_SAS3008:
8677 case MPI25_MFGPAGE_DEVID_SAS3108_1:
8678 case MPI25_MFGPAGE_DEVID_SAS3108_2:
8679 case MPI25_MFGPAGE_DEVID_SAS3108_5:
8680 case MPI25_MFGPAGE_DEVID_SAS3108_6:
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308681 return MPI25_VERSION;
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05308682 case MPI26_MFGPAGE_DEVID_SAS3216:
8683 case MPI26_MFGPAGE_DEVID_SAS3224:
8684 case MPI26_MFGPAGE_DEVID_SAS3316_1:
8685 case MPI26_MFGPAGE_DEVID_SAS3316_2:
8686 case MPI26_MFGPAGE_DEVID_SAS3316_3:
8687 case MPI26_MFGPAGE_DEVID_SAS3316_4:
8688 case MPI26_MFGPAGE_DEVID_SAS3324_1:
8689 case MPI26_MFGPAGE_DEVID_SAS3324_2:
8690 case MPI26_MFGPAGE_DEVID_SAS3324_3:
8691 case MPI26_MFGPAGE_DEVID_SAS3324_4:
8692 return MPI26_VERSION;
Sreekanth Reddyd357e842015-11-11 17:30:22 +05308693 }
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308694 return 0;
Sreekanth Reddyd357e842015-11-11 17:30:22 +05308695}
8696
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308697/**
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308698 * _scsih_probe - attach and add scsi host
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308699 * @pdev: PCI device struct
8700 * @id: pci device id
8701 *
8702 * Returns 0 success, anything else error.
8703 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07008704static int
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308705_scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308706{
8707 struct MPT3SAS_ADAPTER *ioc;
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308708 struct Scsi_Host *shost = NULL;
Sreekanth Reddyb65f1d42014-09-12 15:35:33 +05308709 int rv;
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308710 u16 hba_mpi_version;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308711
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308712 /* Determine in which MPI version class this pci device belongs */
8713 hba_mpi_version = _scsih_determine_hba_mpi_version(pdev);
8714 if (hba_mpi_version == 0)
8715 return -ENODEV;
8716
8717 /* Enumerate only SAS 2.0 HBA's if hbas_to_enumerate is one,
8718 * for other generation HBA's return with -ENODEV
8719 */
8720 if ((hbas_to_enumerate == 1) && (hba_mpi_version != MPI2_VERSION))
8721 return -ENODEV;
8722
8723 /* Enumerate only SAS 3.0 HBA's if hbas_to_enumerate is two,
8724 * for other generation HBA's return with -ENODEV
8725 */
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05308726 if ((hbas_to_enumerate == 2) && (!(hba_mpi_version == MPI25_VERSION
8727 || hba_mpi_version == MPI26_VERSION)))
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308728 return -ENODEV;
8729
8730 switch (hba_mpi_version) {
8731 case MPI2_VERSION:
ojabb5d5f282016-12-28 11:05:24 +00008732 pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S |
8733 PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM);
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308734 /* Use mpt2sas driver host template for SAS 2.0 HBA's */
8735 shost = scsi_host_alloc(&mpt2sas_driver_template,
8736 sizeof(struct MPT3SAS_ADAPTER));
8737 if (!shost)
8738 return -ENODEV;
8739 ioc = shost_priv(shost);
8740 memset(ioc, 0, sizeof(struct MPT3SAS_ADAPTER));
8741 ioc->hba_mpi_version_belonged = hba_mpi_version;
8742 ioc->id = mpt2_ids++;
8743 sprintf(ioc->driver_name, "%s", MPT2SAS_DRIVER_NAME);
8744 if (pdev->device == MPI2_MFGPAGE_DEVID_SSS6200) {
8745 ioc->is_warpdrive = 1;
8746 ioc->hide_ir_msg = 1;
8747 } else
8748 ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS;
8749 break;
8750 case MPI25_VERSION:
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05308751 case MPI26_VERSION:
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308752 /* Use mpt3sas driver host template for SAS 3.0 HBA's */
8753 shost = scsi_host_alloc(&mpt3sas_driver_template,
8754 sizeof(struct MPT3SAS_ADAPTER));
8755 if (!shost)
8756 return -ENODEV;
8757 ioc = shost_priv(shost);
8758 memset(ioc, 0, sizeof(struct MPT3SAS_ADAPTER));
8759 ioc->hba_mpi_version_belonged = hba_mpi_version;
8760 ioc->id = mpt3_ids++;
8761 sprintf(ioc->driver_name, "%s", MPT3SAS_DRIVER_NAME);
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05308762 if ((ioc->hba_mpi_version_belonged == MPI25_VERSION &&
8763 pdev->revision >= SAS3_PCI_DEVICE_C0_REVISION) ||
8764 (ioc->hba_mpi_version_belonged == MPI26_VERSION))
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308765 ioc->msix96_vector = 1;
8766 break;
8767 default:
8768 return -ENODEV;
8769 }
8770
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308771 INIT_LIST_HEAD(&ioc->list);
Sreekanth Reddy08c4d552015-11-11 17:30:33 +05308772 spin_lock(&gioc_lock);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308773 list_add_tail(&ioc->list, &mpt3sas_ioc_list);
Sreekanth Reddy08c4d552015-11-11 17:30:33 +05308774 spin_unlock(&gioc_lock);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308775 ioc->shost = shost;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308776 ioc->pdev = pdev;
8777 ioc->scsi_io_cb_idx = scsi_io_cb_idx;
8778 ioc->tm_cb_idx = tm_cb_idx;
8779 ioc->ctl_cb_idx = ctl_cb_idx;
8780 ioc->base_cb_idx = base_cb_idx;
8781 ioc->port_enable_cb_idx = port_enable_cb_idx;
8782 ioc->transport_cb_idx = transport_cb_idx;
8783 ioc->scsih_cb_idx = scsih_cb_idx;
8784 ioc->config_cb_idx = config_cb_idx;
8785 ioc->tm_tr_cb_idx = tm_tr_cb_idx;
8786 ioc->tm_tr_volume_cb_idx = tm_tr_volume_cb_idx;
8787 ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx;
8788 ioc->logging_level = logging_level;
8789 ioc->schedule_dead_ioc_flush_running_cmds = &_scsih_flush_running_cmds;
8790 /* misc semaphores and spin locks */
8791 mutex_init(&ioc->reset_in_progress_mutex);
Sreekanth Reddy08c4d552015-11-11 17:30:33 +05308792 /* initializing pci_access_mutex lock */
8793 mutex_init(&ioc->pci_access_mutex);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308794 spin_lock_init(&ioc->ioc_reset_in_progress_lock);
8795 spin_lock_init(&ioc->scsi_lookup_lock);
8796 spin_lock_init(&ioc->sas_device_lock);
8797 spin_lock_init(&ioc->sas_node_lock);
8798 spin_lock_init(&ioc->fw_event_lock);
8799 spin_lock_init(&ioc->raid_device_lock);
8800 spin_lock_init(&ioc->diag_trigger_lock);
8801
8802 INIT_LIST_HEAD(&ioc->sas_device_list);
8803 INIT_LIST_HEAD(&ioc->sas_device_init_list);
8804 INIT_LIST_HEAD(&ioc->sas_expander_list);
8805 INIT_LIST_HEAD(&ioc->fw_event_list);
8806 INIT_LIST_HEAD(&ioc->raid_device_list);
8807 INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list);
8808 INIT_LIST_HEAD(&ioc->delayed_tr_list);
Suganath prabu Subramanifd0331b2016-01-28 12:07:02 +05308809 INIT_LIST_HEAD(&ioc->delayed_sc_list);
8810 INIT_LIST_HEAD(&ioc->delayed_event_ack_list);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308811 INIT_LIST_HEAD(&ioc->delayed_tr_volume_list);
Joe Lawrencecf9bd21a2013-08-08 16:45:39 -04008812 INIT_LIST_HEAD(&ioc->reply_queue_list);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308813
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308814 sprintf(ioc->name, "%s_cm%d", ioc->driver_name, ioc->id);
Sreekanth Reddyd357e842015-11-11 17:30:22 +05308815
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308816 /* init shost parameters */
8817 shost->max_cmd_len = 32;
8818 shost->max_lun = max_lun;
8819 shost->transportt = mpt3sas_transport_template;
8820 shost->unique_id = ioc->id;
8821
8822 if (max_sectors != 0xFFFF) {
8823 if (max_sectors < 64) {
8824 shost->max_sectors = 64;
8825 pr_warn(MPT3SAS_FMT "Invalid value %d passed " \
8826 "for max_sectors, range is 64 to 32767. Assigning "
8827 "value of 64.\n", ioc->name, max_sectors);
8828 } else if (max_sectors > 32767) {
8829 shost->max_sectors = 32767;
8830 pr_warn(MPT3SAS_FMT "Invalid value %d passed " \
8831 "for max_sectors, range is 64 to 32767. Assigning "
8832 "default value of 32767.\n", ioc->name,
8833 max_sectors);
8834 } else {
8835 shost->max_sectors = max_sectors & 0xFFFE;
8836 pr_info(MPT3SAS_FMT
8837 "The max_sectors value is set to %d\n",
8838 ioc->name, shost->max_sectors);
8839 }
8840 }
8841
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308842 /* register EEDP capabilities with SCSI layer */
8843 if (prot_mask > 0)
8844 scsi_host_set_prot(shost, prot_mask);
8845 else
8846 scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION
8847 | SHOST_DIF_TYPE2_PROTECTION
8848 | SHOST_DIF_TYPE3_PROTECTION);
8849
8850 scsi_host_set_guard(shost, SHOST_DIX_GUARD_CRC);
8851
8852 /* event thread */
8853 snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name),
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308854 "fw_event_%s%d", ioc->driver_name, ioc->id);
Sreekanth Reddybdff7852015-06-30 12:25:03 +05308855 ioc->firmware_event_thread = alloc_ordered_workqueue(
Hannes Reinecke4a8907d2018-02-26 15:26:01 +01008856 ioc->firmware_event_name, 0);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308857 if (!ioc->firmware_event_thread) {
8858 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
8859 ioc->name, __FILE__, __LINE__, __func__);
Sreekanth Reddyb65f1d42014-09-12 15:35:33 +05308860 rv = -ENODEV;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308861 goto out_thread_fail;
8862 }
8863
8864 ioc->is_driver_loading = 1;
8865 if ((mpt3sas_base_attach(ioc))) {
8866 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
8867 ioc->name, __FILE__, __LINE__, __func__);
Sreekanth Reddyb65f1d42014-09-12 15:35:33 +05308868 rv = -ENODEV;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308869 goto out_attach_fail;
8870 }
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05308871
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05308872 if (ioc->is_warpdrive) {
8873 if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS)
8874 ioc->hide_drives = 0;
8875 else if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_HIDE_ALL_DISKS)
8876 ioc->hide_drives = 1;
8877 else {
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05308878 if (mpt3sas_get_num_volumes(ioc))
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05308879 ioc->hide_drives = 1;
8880 else
8881 ioc->hide_drives = 0;
8882 }
8883 } else
8884 ioc->hide_drives = 0;
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05308885
Sreekanth Reddyb65f1d42014-09-12 15:35:33 +05308886 rv = scsi_add_host(shost, &pdev->dev);
8887 if (rv) {
Reddy, Sreekanth4dc06fd2014-07-14 12:01:35 +05308888 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
8889 ioc->name, __FILE__, __LINE__, __func__);
Reddy, Sreekanth4dc06fd2014-07-14 12:01:35 +05308890 goto out_add_shost_fail;
8891 }
8892
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308893 scsi_scan_host(shost);
8894 return 0;
Reddy, Sreekanth4dc06fd2014-07-14 12:01:35 +05308895out_add_shost_fail:
8896 mpt3sas_base_detach(ioc);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308897 out_attach_fail:
8898 destroy_workqueue(ioc->firmware_event_thread);
8899 out_thread_fail:
Sreekanth Reddy08c4d552015-11-11 17:30:33 +05308900 spin_lock(&gioc_lock);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308901 list_del(&ioc->list);
Sreekanth Reddy08c4d552015-11-11 17:30:33 +05308902 spin_unlock(&gioc_lock);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308903 scsi_host_put(shost);
Sreekanth Reddyb65f1d42014-09-12 15:35:33 +05308904 return rv;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308905}
8906
8907#ifdef CONFIG_PM
8908/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05308909 * scsih_suspend - power management suspend main entry point
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308910 * @pdev: PCI device struct
8911 * @state: PM state change to (usually PCI_D3)
8912 *
8913 * Returns 0 success, anything else error.
8914 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07008915static int
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05308916scsih_suspend(struct pci_dev *pdev, pm_message_t state)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308917{
8918 struct Scsi_Host *shost = pci_get_drvdata(pdev);
8919 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
8920 pci_power_t device_state;
8921
8922 mpt3sas_base_stop_watchdog(ioc);
8923 flush_scheduled_work();
8924 scsi_block_requests(shost);
8925 device_state = pci_choose_state(pdev, state);
8926 pr_info(MPT3SAS_FMT
8927 "pdev=0x%p, slot=%s, entering operating state [D%d]\n",
8928 ioc->name, pdev, pci_name(pdev), device_state);
8929
8930 pci_save_state(pdev);
8931 mpt3sas_base_free_resources(ioc);
8932 pci_set_power_state(pdev, device_state);
8933 return 0;
8934}
8935
8936/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05308937 * scsih_resume - power management resume main entry point
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308938 * @pdev: PCI device struct
8939 *
8940 * Returns 0 success, anything else error.
8941 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07008942static int
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05308943scsih_resume(struct pci_dev *pdev)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308944{
8945 struct Scsi_Host *shost = pci_get_drvdata(pdev);
8946 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
8947 pci_power_t device_state = pdev->current_state;
8948 int r;
8949
8950 pr_info(MPT3SAS_FMT
8951 "pdev=0x%p, slot=%s, previous operating state [D%d]\n",
8952 ioc->name, pdev, pci_name(pdev), device_state);
8953
8954 pci_set_power_state(pdev, PCI_D0);
8955 pci_enable_wake(pdev, PCI_D0, 0);
8956 pci_restore_state(pdev);
8957 ioc->pdev = pdev;
8958 r = mpt3sas_base_map_resources(ioc);
8959 if (r)
8960 return r;
8961
Calvin Owens98c56ad2016-07-28 21:38:21 -07008962 mpt3sas_base_hard_reset_handler(ioc, SOFT_RESET);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308963 scsi_unblock_requests(shost);
8964 mpt3sas_base_start_watchdog(ioc);
8965 return 0;
8966}
8967#endif /* CONFIG_PM */
8968
8969/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05308970 * scsih_pci_error_detected - Called when a PCI error is detected.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308971 * @pdev: PCI device struct
8972 * @state: PCI channel state
8973 *
8974 * Description: Called when a PCI error is detected.
8975 *
8976 * Return value:
8977 * PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT
8978 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07008979static pci_ers_result_t
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05308980scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05308981{
8982 struct Scsi_Host *shost = pci_get_drvdata(pdev);
8983 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
8984
8985 pr_info(MPT3SAS_FMT "PCI error: detected callback, state(%d)!!\n",
8986 ioc->name, state);
8987
8988 switch (state) {
8989 case pci_channel_io_normal:
8990 return PCI_ERS_RESULT_CAN_RECOVER;
8991 case pci_channel_io_frozen:
8992 /* Fatal error, prepare for slot reset */
8993 ioc->pci_error_recovery = 1;
8994 scsi_block_requests(ioc->shost);
8995 mpt3sas_base_stop_watchdog(ioc);
8996 mpt3sas_base_free_resources(ioc);
8997 return PCI_ERS_RESULT_NEED_RESET;
8998 case pci_channel_io_perm_failure:
8999 /* Permanent error, prepare for device removal */
9000 ioc->pci_error_recovery = 1;
9001 mpt3sas_base_stop_watchdog(ioc);
9002 _scsih_flush_running_cmds(ioc);
9003 return PCI_ERS_RESULT_DISCONNECT;
9004 }
9005 return PCI_ERS_RESULT_NEED_RESET;
9006}
9007
9008/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05309009 * scsih_pci_slot_reset - Called when PCI slot has been reset.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309010 * @pdev: PCI device struct
9011 *
9012 * Description: This routine is called by the pci error recovery
9013 * code after the PCI slot has been reset, just before we
9014 * should resume normal operations.
9015 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07009016static pci_ers_result_t
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05309017scsih_pci_slot_reset(struct pci_dev *pdev)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309018{
9019 struct Scsi_Host *shost = pci_get_drvdata(pdev);
9020 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
9021 int rc;
9022
9023 pr_info(MPT3SAS_FMT "PCI error: slot reset callback!!\n",
9024 ioc->name);
9025
9026 ioc->pci_error_recovery = 0;
9027 ioc->pdev = pdev;
9028 pci_restore_state(pdev);
9029 rc = mpt3sas_base_map_resources(ioc);
9030 if (rc)
9031 return PCI_ERS_RESULT_DISCONNECT;
9032
Calvin Owens98c56ad2016-07-28 21:38:21 -07009033 rc = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309034
9035 pr_warn(MPT3SAS_FMT "hard reset: %s\n", ioc->name,
9036 (rc == 0) ? "success" : "failed");
9037
9038 if (!rc)
9039 return PCI_ERS_RESULT_RECOVERED;
9040 else
9041 return PCI_ERS_RESULT_DISCONNECT;
9042}
9043
9044/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05309045 * scsih_pci_resume() - resume normal ops after PCI reset
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309046 * @pdev: pointer to PCI device
9047 *
9048 * Called when the error recovery driver tells us that its
9049 * OK to resume normal operation. Use completion to allow
9050 * halted scsi ops to resume.
9051 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07009052static void
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05309053scsih_pci_resume(struct pci_dev *pdev)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309054{
9055 struct Scsi_Host *shost = pci_get_drvdata(pdev);
9056 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
9057
9058 pr_info(MPT3SAS_FMT "PCI error: resume callback!!\n", ioc->name);
9059
9060 pci_cleanup_aer_uncorrect_error_status(pdev);
9061 mpt3sas_base_start_watchdog(ioc);
9062 scsi_unblock_requests(ioc->shost);
9063}
9064
9065/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05309066 * scsih_pci_mmio_enabled - Enable MMIO and dump debug registers
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309067 * @pdev: pointer to PCI device
9068 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07009069static pci_ers_result_t
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05309070scsih_pci_mmio_enabled(struct pci_dev *pdev)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309071{
9072 struct Scsi_Host *shost = pci_get_drvdata(pdev);
9073 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
9074
9075 pr_info(MPT3SAS_FMT "PCI error: mmio enabled callback!!\n",
9076 ioc->name);
9077
9078 /* TODO - dump whatever for debugging purposes */
9079
Kefeng Wang83c3d342016-07-12 17:43:25 +08009080 /* This called only if scsih_pci_error_detected returns
9081 * PCI_ERS_RESULT_CAN_RECOVER. Read/write to the device still
9082 * works, no need to reset slot.
9083 */
9084 return PCI_ERS_RESULT_RECOVERED;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309085}
9086
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05309087/*
9088 * The pci device ids are defined in mpi/mpi2_cnfg.h.
9089 */
9090static const struct pci_device_id mpt3sas_pci_table[] = {
9091 /* Spitfire ~ 2004 */
9092 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2004,
9093 PCI_ANY_ID, PCI_ANY_ID },
9094 /* Falcon ~ 2008 */
9095 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2008,
9096 PCI_ANY_ID, PCI_ANY_ID },
9097 /* Liberator ~ 2108 */
9098 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_1,
9099 PCI_ANY_ID, PCI_ANY_ID },
9100 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_2,
9101 PCI_ANY_ID, PCI_ANY_ID },
9102 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3,
9103 PCI_ANY_ID, PCI_ANY_ID },
9104 /* Meteor ~ 2116 */
9105 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1,
9106 PCI_ANY_ID, PCI_ANY_ID },
9107 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2,
9108 PCI_ANY_ID, PCI_ANY_ID },
9109 /* Thunderbolt ~ 2208 */
9110 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1,
9111 PCI_ANY_ID, PCI_ANY_ID },
9112 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2,
9113 PCI_ANY_ID, PCI_ANY_ID },
9114 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3,
9115 PCI_ANY_ID, PCI_ANY_ID },
9116 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4,
9117 PCI_ANY_ID, PCI_ANY_ID },
9118 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5,
9119 PCI_ANY_ID, PCI_ANY_ID },
9120 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6,
9121 PCI_ANY_ID, PCI_ANY_ID },
9122 /* Mustang ~ 2308 */
9123 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_1,
9124 PCI_ANY_ID, PCI_ANY_ID },
9125 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_2,
9126 PCI_ANY_ID, PCI_ANY_ID },
9127 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3,
9128 PCI_ANY_ID, PCI_ANY_ID },
9129 /* SSS6200 */
9130 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200,
9131 PCI_ANY_ID, PCI_ANY_ID },
9132 /* Fury ~ 3004 and 3008 */
9133 { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3004,
9134 PCI_ANY_ID, PCI_ANY_ID },
9135 { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3008,
9136 PCI_ANY_ID, PCI_ANY_ID },
9137 /* Invader ~ 3108 */
9138 { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_1,
9139 PCI_ANY_ID, PCI_ANY_ID },
9140 { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_2,
9141 PCI_ANY_ID, PCI_ANY_ID },
9142 { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_5,
9143 PCI_ANY_ID, PCI_ANY_ID },
9144 { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6,
9145 PCI_ANY_ID, PCI_ANY_ID },
Suganath prabu Subramanib130b0d2016-01-28 12:06:58 +05309146 /* Cutlass ~ 3216 and 3224 */
9147 { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3216,
9148 PCI_ANY_ID, PCI_ANY_ID },
9149 { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3224,
9150 PCI_ANY_ID, PCI_ANY_ID },
9151 /* Intruder ~ 3316 and 3324 */
9152 { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_1,
9153 PCI_ANY_ID, PCI_ANY_ID },
9154 { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_2,
9155 PCI_ANY_ID, PCI_ANY_ID },
9156 { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_3,
9157 PCI_ANY_ID, PCI_ANY_ID },
9158 { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_4,
9159 PCI_ANY_ID, PCI_ANY_ID },
9160 { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_1,
9161 PCI_ANY_ID, PCI_ANY_ID },
9162 { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_2,
9163 PCI_ANY_ID, PCI_ANY_ID },
9164 { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_3,
9165 PCI_ANY_ID, PCI_ANY_ID },
9166 { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_4,
9167 PCI_ANY_ID, PCI_ANY_ID },
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05309168 {0} /* Terminating entry */
9169};
9170MODULE_DEVICE_TABLE(pci, mpt3sas_pci_table);
9171
9172static struct pci_error_handlers _mpt3sas_err_handler = {
9173 .error_detected = scsih_pci_error_detected,
9174 .mmio_enabled = scsih_pci_mmio_enabled,
9175 .slot_reset = scsih_pci_slot_reset,
9176 .resume = scsih_pci_resume,
9177};
9178
9179static struct pci_driver mpt3sas_driver = {
9180 .name = MPT3SAS_DRIVER_NAME,
9181 .id_table = mpt3sas_pci_table,
9182 .probe = _scsih_probe,
9183 .remove = scsih_remove,
9184 .shutdown = scsih_shutdown,
9185 .err_handler = &_mpt3sas_err_handler,
9186#ifdef CONFIG_PM
9187 .suspend = scsih_suspend,
9188 .resume = scsih_resume,
9189#endif
9190};
9191
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309192/**
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05309193 * scsih_init - main entry point for this driver.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309194 *
9195 * Returns 0 success, anything else error.
9196 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07009197static int
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05309198scsih_init(void)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309199{
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05309200 mpt2_ids = 0;
9201 mpt3_ids = 0;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309202
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309203 mpt3sas_base_initialize_callback_handler();
9204
9205 /* queuecommand callback hander */
9206 scsi_io_cb_idx = mpt3sas_base_register_callback_handler(_scsih_io_done);
9207
9208 /* task managment callback handler */
9209 tm_cb_idx = mpt3sas_base_register_callback_handler(_scsih_tm_done);
9210
9211 /* base internal commands callback handler */
9212 base_cb_idx = mpt3sas_base_register_callback_handler(mpt3sas_base_done);
9213 port_enable_cb_idx = mpt3sas_base_register_callback_handler(
9214 mpt3sas_port_enable_done);
9215
9216 /* transport internal commands callback handler */
9217 transport_cb_idx = mpt3sas_base_register_callback_handler(
9218 mpt3sas_transport_done);
9219
9220 /* scsih internal commands callback handler */
9221 scsih_cb_idx = mpt3sas_base_register_callback_handler(_scsih_done);
9222
9223 /* configuration page API internal commands callback handler */
9224 config_cb_idx = mpt3sas_base_register_callback_handler(
9225 mpt3sas_config_done);
9226
9227 /* ctl module callback handler */
9228 ctl_cb_idx = mpt3sas_base_register_callback_handler(mpt3sas_ctl_done);
9229
9230 tm_tr_cb_idx = mpt3sas_base_register_callback_handler(
9231 _scsih_tm_tr_complete);
9232
9233 tm_tr_volume_cb_idx = mpt3sas_base_register_callback_handler(
9234 _scsih_tm_volume_tr_complete);
9235
9236 tm_sas_control_cb_idx = mpt3sas_base_register_callback_handler(
9237 _scsih_sas_control_complete);
9238
Sreekanth Reddy7497392a2015-11-11 17:30:19 +05309239 return 0;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309240}
9241
9242/**
Sreekanth Reddy7497392a2015-11-11 17:30:19 +05309243 * scsih_exit - exit point for this driver (when it is a module).
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309244 *
9245 * Returns 0 success, anything else error.
9246 */
Calvin Owens8bbb1cf2016-07-28 21:38:22 -07009247static void
Sreekanth Reddy8a7e4c22015-11-11 17:30:18 +05309248scsih_exit(void)
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309249{
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309250
9251 mpt3sas_base_release_callback_handler(scsi_io_cb_idx);
9252 mpt3sas_base_release_callback_handler(tm_cb_idx);
9253 mpt3sas_base_release_callback_handler(base_cb_idx);
9254 mpt3sas_base_release_callback_handler(port_enable_cb_idx);
9255 mpt3sas_base_release_callback_handler(transport_cb_idx);
9256 mpt3sas_base_release_callback_handler(scsih_cb_idx);
9257 mpt3sas_base_release_callback_handler(config_cb_idx);
9258 mpt3sas_base_release_callback_handler(ctl_cb_idx);
9259
9260 mpt3sas_base_release_callback_handler(tm_tr_cb_idx);
9261 mpt3sas_base_release_callback_handler(tm_tr_volume_cb_idx);
9262 mpt3sas_base_release_callback_handler(tm_sas_control_cb_idx);
9263
9264/* raid transport support */
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05309265 if (hbas_to_enumerate != 1)
9266 raid_class_release(mpt3sas_raid_template);
9267 if (hbas_to_enumerate != 2)
9268 raid_class_release(mpt2sas_raid_template);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05309269 sas_release_transport(mpt3sas_transport_template);
9270}
Sreekanth Reddy7786ab62015-11-11 17:30:28 +05309271
Sreekanth Reddyc84b06a2015-11-11 17:30:35 +05309272/**
9273 * _mpt3sas_init - main entry point for this driver.
9274 *
9275 * Returns 0 success, anything else error.
9276 */
9277static int __init
9278_mpt3sas_init(void)
9279{
9280 int error;
9281
9282 pr_info("%s version %s loaded\n", MPT3SAS_DRIVER_NAME,
9283 MPT3SAS_DRIVER_VERSION);
9284
9285 mpt3sas_transport_template =
9286 sas_attach_transport(&mpt3sas_transport_functions);
9287 if (!mpt3sas_transport_template)
9288 return -ENODEV;
9289
9290 /* No need attach mpt3sas raid functions template
9291 * if hbas_to_enumarate value is one.
9292 */
9293 if (hbas_to_enumerate != 1) {
9294 mpt3sas_raid_template =
9295 raid_class_attach(&mpt3sas_raid_functions);
9296 if (!mpt3sas_raid_template) {
9297 sas_release_transport(mpt3sas_transport_template);
9298 return -ENODEV;
9299 }
9300 }
9301
9302 /* No need to attach mpt2sas raid functions template
9303 * if hbas_to_enumarate value is two
9304 */
9305 if (hbas_to_enumerate != 2) {
9306 mpt2sas_raid_template =
9307 raid_class_attach(&mpt2sas_raid_functions);
9308 if (!mpt2sas_raid_template) {
9309 sas_release_transport(mpt3sas_transport_template);
9310 return -ENODEV;
9311 }
9312 }
9313
9314 error = scsih_init();
9315 if (error) {
9316 scsih_exit();
9317 return error;
9318 }
9319
9320 mpt3sas_ctl_init(hbas_to_enumerate);
9321
9322 error = pci_register_driver(&mpt3sas_driver);
9323 if (error)
9324 scsih_exit();
9325
9326 return error;
9327}
9328
9329/**
9330 * _mpt3sas_exit - exit point for this driver (when it is a module).
9331 *
9332 */
9333static void __exit
9334_mpt3sas_exit(void)
9335{
9336 pr_info("mpt3sas version %s unloading\n",
9337 MPT3SAS_DRIVER_VERSION);
9338
9339 pci_unregister_driver(&mpt3sas_driver);
9340
9341 mpt3sas_ctl_exit(hbas_to_enumerate);
9342
9343 scsih_exit();
9344}
9345
9346module_init(_mpt3sas_init);
9347module_exit(_mpt3sas_exit);