]> git.ipfire.org Git - people/arne_f/kernel.git/blame - drivers/scsi/mpt2sas/mpt2sas_scsih.c
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[people/arne_f/kernel.git] / drivers / scsi / mpt2sas / mpt2sas_scsih.c
CommitLineData
635374e7
EM
1/*
2 * Scsi Host Layer for MPT (Message Passing Technology) based controllers
3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_scsih.c
19d3ebe3 5 * Copyright (C) 2007-2009 LSI Corporation
635374e7
EM
6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * NO WARRANTY
19 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
20 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
21 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
22 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
23 * solely responsible for determining the appropriateness of using and
24 * distributing the Program and assumes all risks associated with its
25 * exercise of rights under this Agreement, including but not limited to
26 * the risks and costs of program errors, damage to or loss of data,
27 * programs or equipment, and unavailability or interruption of operations.
28
29 * DISCLAIMER OF LIABILITY
30 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
31 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
33 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
34 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
36 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
37
38 * You should have received a copy of the GNU General Public License
39 * along with this program; if not, write to the Free Software
40 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
41 * USA.
42 */
43
44#include <linux/version.h>
45#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>
54#include <linux/interrupt.h>
f7c95ef0 55#include <linux/raid_class.h>
5a0e3ad6 56#include <linux/slab.h>
635374e7
EM
57
58#include "mpt2sas_base.h"
59
60MODULE_AUTHOR(MPT2SAS_AUTHOR);
61MODULE_DESCRIPTION(MPT2SAS_DESCRIPTION);
62MODULE_LICENSE("GPL");
63MODULE_VERSION(MPT2SAS_DRIVER_VERSION);
64
65#define RAID_CHANNEL 1
66
67/* forward proto's */
68static void _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
69 struct _sas_node *sas_expander);
70static void _firmware_event_work(struct work_struct *work);
71
72/* global parameters */
ba33fadf 73LIST_HEAD(mpt2sas_ioc_list);
635374e7
EM
74
75/* local parameters */
635374e7
EM
76static u8 scsi_io_cb_idx = -1;
77static u8 tm_cb_idx = -1;
78static u8 ctl_cb_idx = -1;
79static u8 base_cb_idx = -1;
80static u8 transport_cb_idx = -1;
744090d3 81static u8 scsih_cb_idx = -1;
635374e7
EM
82static u8 config_cb_idx = -1;
83static int mpt_ids;
84
77e63ed4
KD
85static u8 tm_tr_cb_idx = -1 ;
86static u8 tm_sas_control_cb_idx = -1;
87
635374e7 88/* command line options */
ba33fadf 89static u32 logging_level;
635374e7
EM
90MODULE_PARM_DESC(logging_level, " bits for enabling additional logging info "
91 "(default=0)");
92
93/* scsi-mid layer global parmeter is max_report_luns, which is 511 */
94#define MPT2SAS_MAX_LUN (16895)
95static int max_lun = MPT2SAS_MAX_LUN;
96module_param(max_lun, int, 0);
97MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
98
99/**
100 * struct sense_info - common structure for obtaining sense keys
101 * @skey: sense key
102 * @asc: additional sense code
103 * @ascq: additional sense code qualifier
104 */
105struct sense_info {
106 u8 skey;
107 u8 asc;
108 u8 ascq;
109};
110
111
635374e7
EM
112/**
113 * struct fw_event_work - firmware event struct
114 * @list: link list framework
115 * @work: work object (ioc->fault_reset_work_q)
116 * @ioc: per adapter object
117 * @VF_ID: virtual function id
7b936b02 118 * @VP_ID: virtual port id
635374e7
EM
119 * @host_reset_handling: handling events during host reset
120 * @ignore: flag meaning this event has been marked to ignore
121 * @event: firmware event MPI2_EVENT_XXX defined in mpt2_ioc.h
122 * @event_data: reply event data payload follows
123 *
124 * This object stored on ioc->fw_event_list.
125 */
126struct fw_event_work {
127 struct list_head list;
6f92a7a0 128 struct work_struct work;
635374e7
EM
129 struct MPT2SAS_ADAPTER *ioc;
130 u8 VF_ID;
7b936b02 131 u8 VP_ID;
635374e7
EM
132 u8 host_reset_handling;
133 u8 ignore;
134 u16 event;
135 void *event_data;
136};
137
f7c95ef0
KD
138/* raid transport support */
139static struct raid_template *mpt2sas_raid_template;
140
635374e7
EM
141/**
142 * struct _scsi_io_transfer - scsi io transfer
143 * @handle: sas device handle (assigned by firmware)
144 * @is_raid: flag set for hidden raid components
145 * @dir: DMA_TO_DEVICE, DMA_FROM_DEVICE,
146 * @data_length: data transfer length
147 * @data_dma: dma pointer to data
148 * @sense: sense data
149 * @lun: lun number
150 * @cdb_length: cdb length
151 * @cdb: cdb contents
635374e7 152 * @timeout: timeout for this command
7b936b02
KD
153 * @VF_ID: virtual function id
154 * @VP_ID: virtual port id
155 * @valid_reply: flag set for reply message
635374e7
EM
156 * @sense_length: sense length
157 * @ioc_status: ioc status
158 * @scsi_state: scsi state
159 * @scsi_status: scsi staus
160 * @log_info: log information
161 * @transfer_length: data length transfer when there is a reply message
162 *
163 * Used for sending internal scsi commands to devices within this module.
164 * Refer to _scsi_send_scsi_io().
165 */
166struct _scsi_io_transfer {
167 u16 handle;
168 u8 is_raid;
169 enum dma_data_direction dir;
170 u32 data_length;
171 dma_addr_t data_dma;
172 u8 sense[SCSI_SENSE_BUFFERSIZE];
173 u32 lun;
174 u8 cdb_length;
175 u8 cdb[32];
176 u8 timeout;
7b936b02
KD
177 u8 VF_ID;
178 u8 VP_ID;
635374e7
EM
179 u8 valid_reply;
180 /* the following bits are only valid when 'valid_reply = 1' */
181 u32 sense_length;
182 u16 ioc_status;
183 u8 scsi_state;
184 u8 scsi_status;
185 u32 log_info;
186 u32 transfer_length;
187};
188
189/*
190 * The pci device ids are defined in mpi/mpi2_cnfg.h.
191 */
192static struct pci_device_id scsih_pci_table[] = {
193 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2004,
194 PCI_ANY_ID, PCI_ANY_ID },
195 /* Falcon ~ 2008*/
196 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2008,
197 PCI_ANY_ID, PCI_ANY_ID },
198 /* Liberator ~ 2108 */
199 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_1,
200 PCI_ANY_ID, PCI_ANY_ID },
201 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_2,
202 PCI_ANY_ID, PCI_ANY_ID },
203 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3,
204 PCI_ANY_ID, PCI_ANY_ID },
db27136a 205 /* Meteor ~ 2116 */
635374e7
EM
206 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1,
207 PCI_ANY_ID, PCI_ANY_ID },
208 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2,
209 PCI_ANY_ID, PCI_ANY_ID },
db27136a
KD
210 /* Thunderbolt ~ 2208 */
211 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1,
212 PCI_ANY_ID, PCI_ANY_ID },
213 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2,
214 PCI_ANY_ID, PCI_ANY_ID },
215 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3,
216 PCI_ANY_ID, PCI_ANY_ID },
217 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4,
218 PCI_ANY_ID, PCI_ANY_ID },
219 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5,
220 PCI_ANY_ID, PCI_ANY_ID },
221 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6,
222 PCI_ANY_ID, PCI_ANY_ID },
223 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_7,
224 PCI_ANY_ID, PCI_ANY_ID },
225 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_8,
226 PCI_ANY_ID, PCI_ANY_ID },
635374e7
EM
227 {0} /* Terminating entry */
228};
229MODULE_DEVICE_TABLE(pci, scsih_pci_table);
230
231/**
d5d135b3 232 * _scsih_set_debug_level - global setting of ioc->logging_level.
635374e7
EM
233 *
234 * Note: The logging levels are defined in mpt2sas_debug.h.
235 */
236static int
d5d135b3 237_scsih_set_debug_level(const char *val, struct kernel_param *kp)
635374e7
EM
238{
239 int ret = param_set_int(val, kp);
240 struct MPT2SAS_ADAPTER *ioc;
241
242 if (ret)
243 return ret;
244
245 printk(KERN_INFO "setting logging_level(0x%08x)\n", logging_level);
ba33fadf 246 list_for_each_entry(ioc, &mpt2sas_ioc_list, list)
635374e7
EM
247 ioc->logging_level = logging_level;
248 return 0;
249}
d5d135b3 250module_param_call(logging_level, _scsih_set_debug_level, param_get_int,
635374e7
EM
251 &logging_level, 0644);
252
253/**
254 * _scsih_srch_boot_sas_address - search based on sas_address
255 * @sas_address: sas address
256 * @boot_device: boot device object from bios page 2
257 *
258 * Returns 1 when there's a match, 0 means no match.
259 */
260static inline int
261_scsih_srch_boot_sas_address(u64 sas_address,
262 Mpi2BootDeviceSasWwid_t *boot_device)
263{
264 return (sas_address == le64_to_cpu(boot_device->SASAddress)) ? 1 : 0;
265}
266
267/**
268 * _scsih_srch_boot_device_name - search based on device name
269 * @device_name: device name specified in INDENTIFY fram
270 * @boot_device: boot device object from bios page 2
271 *
272 * Returns 1 when there's a match, 0 means no match.
273 */
274static inline int
275_scsih_srch_boot_device_name(u64 device_name,
276 Mpi2BootDeviceDeviceName_t *boot_device)
277{
278 return (device_name == le64_to_cpu(boot_device->DeviceName)) ? 1 : 0;
279}
280
281/**
282 * _scsih_srch_boot_encl_slot - search based on enclosure_logical_id/slot
283 * @enclosure_logical_id: enclosure logical id
284 * @slot_number: slot number
285 * @boot_device: boot device object from bios page 2
286 *
287 * Returns 1 when there's a match, 0 means no match.
288 */
289static inline int
290_scsih_srch_boot_encl_slot(u64 enclosure_logical_id, u16 slot_number,
291 Mpi2BootDeviceEnclosureSlot_t *boot_device)
292{
293 return (enclosure_logical_id == le64_to_cpu(boot_device->
294 EnclosureLogicalID) && slot_number == le16_to_cpu(boot_device->
295 SlotNumber)) ? 1 : 0;
296}
297
298/**
299 * _scsih_is_boot_device - search for matching boot device.
300 * @sas_address: sas address
301 * @device_name: device name specified in INDENTIFY fram
302 * @enclosure_logical_id: enclosure logical id
303 * @slot_number: slot number
304 * @form: specifies boot device form
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 int
310_scsih_is_boot_device(u64 sas_address, u64 device_name,
311 u64 enclosure_logical_id, u16 slot, u8 form,
312 Mpi2BiosPage2BootDevice_t *boot_device)
313{
314 int rc = 0;
315
316 switch (form) {
317 case MPI2_BIOSPAGE2_FORM_SAS_WWID:
318 if (!sas_address)
319 break;
320 rc = _scsih_srch_boot_sas_address(
321 sas_address, &boot_device->SasWwid);
322 break;
323 case MPI2_BIOSPAGE2_FORM_ENCLOSURE_SLOT:
324 if (!enclosure_logical_id)
325 break;
326 rc = _scsih_srch_boot_encl_slot(
327 enclosure_logical_id,
328 slot, &boot_device->EnclosureSlot);
329 break;
330 case MPI2_BIOSPAGE2_FORM_DEVICE_NAME:
331 if (!device_name)
332 break;
333 rc = _scsih_srch_boot_device_name(
334 device_name, &boot_device->DeviceName);
335 break;
336 case MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED:
337 break;
338 }
339
340 return rc;
341}
342
c5e039be
KD
343/**
344 * _scsih_get_sas_address - set the sas_address for given device handle
345 * @handle: device handle
346 * @sas_address: sas address
347 *
348 * Returns 0 success, non-zero when failure
349 */
350static int
351_scsih_get_sas_address(struct MPT2SAS_ADAPTER *ioc, u16 handle,
352 u64 *sas_address)
353{
354 Mpi2SasDevicePage0_t sas_device_pg0;
355 Mpi2ConfigReply_t mpi_reply;
356 u32 ioc_status;
357
358 if (handle <= ioc->sas_hba.num_phys) {
359 *sas_address = ioc->sas_hba.sas_address;
360 return 0;
361 } else
362 *sas_address = 0;
363
364 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
365 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
366 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
367 ioc->name, __FILE__, __LINE__, __func__);
368 return -ENXIO;
369 }
370
371 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
372 MPI2_IOCSTATUS_MASK;
373 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
374 printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)"
375 "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
376 __FILE__, __LINE__, __func__);
377 return -EIO;
378 }
379
380 *sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
381 return 0;
382}
383
635374e7
EM
384/**
385 * _scsih_determine_boot_device - determine boot device.
386 * @ioc: per adapter object
387 * @device: either sas_device or raid_device object
388 * @is_raid: [flag] 1 = raid object, 0 = sas object
389 *
390 * Determines whether this device should be first reported device to
391 * to scsi-ml or sas transport, this purpose is for persistant boot device.
392 * There are primary, alternate, and current entries in bios page 2. The order
393 * priority is primary, alternate, then current. This routine saves
394 * the corresponding device object and is_raid flag in the ioc object.
395 * The saved data to be used later in _scsih_probe_boot_devices().
396 */
397static void
398_scsih_determine_boot_device(struct MPT2SAS_ADAPTER *ioc,
399 void *device, u8 is_raid)
400{
401 struct _sas_device *sas_device;
402 struct _raid_device *raid_device;
403 u64 sas_address;
404 u64 device_name;
405 u64 enclosure_logical_id;
406 u16 slot;
407
408 /* only process this function when driver loads */
409 if (!ioc->wait_for_port_enable_to_complete)
410 return;
411
412 if (!is_raid) {
413 sas_device = device;
414 sas_address = sas_device->sas_address;
415 device_name = sas_device->device_name;
416 enclosure_logical_id = sas_device->enclosure_logical_id;
417 slot = sas_device->slot;
418 } else {
419 raid_device = device;
420 sas_address = raid_device->wwid;
421 device_name = 0;
422 enclosure_logical_id = 0;
423 slot = 0;
424 }
425
426 if (!ioc->req_boot_device.device) {
427 if (_scsih_is_boot_device(sas_address, device_name,
428 enclosure_logical_id, slot,
429 (ioc->bios_pg2.ReqBootDeviceForm &
430 MPI2_BIOSPAGE2_FORM_MASK),
431 &ioc->bios_pg2.RequestedBootDevice)) {
432 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT
433 "%s: req_boot_device(0x%016llx)\n",
434 ioc->name, __func__,
435 (unsigned long long)sas_address));
436 ioc->req_boot_device.device = device;
437 ioc->req_boot_device.is_raid = is_raid;
438 }
439 }
440
441 if (!ioc->req_alt_boot_device.device) {
442 if (_scsih_is_boot_device(sas_address, device_name,
443 enclosure_logical_id, slot,
444 (ioc->bios_pg2.ReqAltBootDeviceForm &
445 MPI2_BIOSPAGE2_FORM_MASK),
446 &ioc->bios_pg2.RequestedAltBootDevice)) {
447 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT
448 "%s: req_alt_boot_device(0x%016llx)\n",
449 ioc->name, __func__,
450 (unsigned long long)sas_address));
451 ioc->req_alt_boot_device.device = device;
452 ioc->req_alt_boot_device.is_raid = is_raid;
453 }
454 }
455
456 if (!ioc->current_boot_device.device) {
457 if (_scsih_is_boot_device(sas_address, device_name,
458 enclosure_logical_id, slot,
459 (ioc->bios_pg2.CurrentBootDeviceForm &
460 MPI2_BIOSPAGE2_FORM_MASK),
461 &ioc->bios_pg2.CurrentBootDevice)) {
462 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT
463 "%s: current_boot_device(0x%016llx)\n",
464 ioc->name, __func__,
465 (unsigned long long)sas_address));
466 ioc->current_boot_device.device = device;
467 ioc->current_boot_device.is_raid = is_raid;
468 }
469 }
470}
471
472/**
473 * mpt2sas_scsih_sas_device_find_by_sas_address - sas device search
474 * @ioc: per adapter object
475 * @sas_address: sas address
476 * Context: Calling function should acquire ioc->sas_device_lock
477 *
478 * This searches for sas_device based on sas_address, then return sas_device
479 * object.
480 */
481struct _sas_device *
482mpt2sas_scsih_sas_device_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
483 u64 sas_address)
484{
485 struct _sas_device *sas_device, *r;
486
487 r = NULL;
488 /* check the sas_device_init_list */
489 list_for_each_entry(sas_device, &ioc->sas_device_init_list,
490 list) {
491 if (sas_device->sas_address != sas_address)
492 continue;
493 r = sas_device;
494 goto out;
495 }
496
497 /* then check the sas_device_list */
498 list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
499 if (sas_device->sas_address != sas_address)
500 continue;
501 r = sas_device;
502 goto out;
503 }
504 out:
505 return r;
506}
507
508/**
509 * _scsih_sas_device_find_by_handle - sas device search
510 * @ioc: per adapter object
511 * @handle: sas device handle (assigned by firmware)
512 * Context: Calling function should acquire ioc->sas_device_lock
513 *
514 * This searches for sas_device based on sas_address, then return sas_device
515 * object.
516 */
517static struct _sas_device *
518_scsih_sas_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
519{
520 struct _sas_device *sas_device, *r;
521
522 r = NULL;
523 if (ioc->wait_for_port_enable_to_complete) {
524 list_for_each_entry(sas_device, &ioc->sas_device_init_list,
525 list) {
526 if (sas_device->handle != handle)
527 continue;
528 r = sas_device;
529 goto out;
530 }
531 } else {
532 list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
533 if (sas_device->handle != handle)
534 continue;
535 r = sas_device;
536 goto out;
537 }
538 }
539
540 out:
541 return r;
542}
543
544/**
545 * _scsih_sas_device_remove - remove sas_device from list.
546 * @ioc: per adapter object
547 * @sas_device: the sas_device object
548 * Context: This function will acquire ioc->sas_device_lock.
549 *
550 * Removing object and freeing associated memory from the ioc->sas_device_list.
551 */
552static void
553_scsih_sas_device_remove(struct MPT2SAS_ADAPTER *ioc,
554 struct _sas_device *sas_device)
555{
556 unsigned long flags;
557
558 spin_lock_irqsave(&ioc->sas_device_lock, flags);
559 list_del(&sas_device->list);
560 memset(sas_device, 0, sizeof(struct _sas_device));
561 kfree(sas_device);
562 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
563}
564
565/**
566 * _scsih_sas_device_add - insert sas_device to the list.
567 * @ioc: per adapter object
568 * @sas_device: the sas_device object
569 * Context: This function will acquire ioc->sas_device_lock.
570 *
571 * Adding new object to the ioc->sas_device_list.
572 */
573static void
574_scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc,
575 struct _sas_device *sas_device)
576{
577 unsigned long flags;
635374e7
EM
578
579 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle"
580 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
581 sas_device->handle, (unsigned long long)sas_device->sas_address));
582
583 spin_lock_irqsave(&ioc->sas_device_lock, flags);
584 list_add_tail(&sas_device->list, &ioc->sas_device_list);
585 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
586
c5e039be
KD
587 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
588 sas_device->sas_address_parent))
635374e7 589 _scsih_sas_device_remove(ioc, sas_device);
635374e7
EM
590}
591
592/**
593 * _scsih_sas_device_init_add - insert sas_device to the list.
594 * @ioc: per adapter object
595 * @sas_device: the sas_device object
596 * Context: This function will acquire ioc->sas_device_lock.
597 *
598 * Adding new object at driver load time to the ioc->sas_device_init_list.
599 */
600static void
601_scsih_sas_device_init_add(struct MPT2SAS_ADAPTER *ioc,
602 struct _sas_device *sas_device)
603{
604 unsigned long flags;
605
606 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle"
607 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
608 sas_device->handle, (unsigned long long)sas_device->sas_address));
609
610 spin_lock_irqsave(&ioc->sas_device_lock, flags);
611 list_add_tail(&sas_device->list, &ioc->sas_device_init_list);
612 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
613 _scsih_determine_boot_device(ioc, sas_device, 0);
614}
615
635374e7
EM
616/**
617 * _scsih_raid_device_find_by_id - raid device search
618 * @ioc: per adapter object
619 * @id: sas device target id
620 * @channel: sas device channel
621 * Context: Calling function should acquire ioc->raid_device_lock
622 *
623 * This searches for raid_device based on target id, then return raid_device
624 * object.
625 */
626static struct _raid_device *
627_scsih_raid_device_find_by_id(struct MPT2SAS_ADAPTER *ioc, int id, int channel)
628{
629 struct _raid_device *raid_device, *r;
630
631 r = NULL;
632 list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
633 if (raid_device->id == id && raid_device->channel == channel) {
634 r = raid_device;
635 goto out;
636 }
637 }
638
639 out:
640 return r;
641}
642
643/**
644 * _scsih_raid_device_find_by_handle - raid device search
645 * @ioc: per adapter object
646 * @handle: sas device handle (assigned by firmware)
647 * Context: Calling function should acquire ioc->raid_device_lock
648 *
649 * This searches for raid_device based on handle, then return raid_device
650 * object.
651 */
652static struct _raid_device *
653_scsih_raid_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
654{
655 struct _raid_device *raid_device, *r;
656
657 r = NULL;
658 list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
659 if (raid_device->handle != handle)
660 continue;
661 r = raid_device;
662 goto out;
663 }
664
665 out:
666 return r;
667}
668
669/**
670 * _scsih_raid_device_find_by_wwid - raid device search
671 * @ioc: per adapter object
672 * @handle: sas device handle (assigned by firmware)
673 * Context: Calling function should acquire ioc->raid_device_lock
674 *
675 * This searches for raid_device based on wwid, then return raid_device
676 * object.
677 */
678static struct _raid_device *
679_scsih_raid_device_find_by_wwid(struct MPT2SAS_ADAPTER *ioc, u64 wwid)
680{
681 struct _raid_device *raid_device, *r;
682
683 r = NULL;
684 list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
685 if (raid_device->wwid != wwid)
686 continue;
687 r = raid_device;
688 goto out;
689 }
690
691 out:
692 return r;
693}
694
695/**
696 * _scsih_raid_device_add - add raid_device object
697 * @ioc: per adapter object
698 * @raid_device: raid_device object
699 *
700 * This is added to the raid_device_list link list.
701 */
702static void
703_scsih_raid_device_add(struct MPT2SAS_ADAPTER *ioc,
704 struct _raid_device *raid_device)
705{
706 unsigned long flags;
707
708 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle"
709 "(0x%04x), wwid(0x%016llx)\n", ioc->name, __func__,
710 raid_device->handle, (unsigned long long)raid_device->wwid));
711
712 spin_lock_irqsave(&ioc->raid_device_lock, flags);
713 list_add_tail(&raid_device->list, &ioc->raid_device_list);
714 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
715}
716
717/**
718 * _scsih_raid_device_remove - delete raid_device object
719 * @ioc: per adapter object
720 * @raid_device: raid_device object
721 *
722 * This is removed from the raid_device_list link list.
723 */
724static void
725_scsih_raid_device_remove(struct MPT2SAS_ADAPTER *ioc,
726 struct _raid_device *raid_device)
727{
728 unsigned long flags;
729
730 spin_lock_irqsave(&ioc->raid_device_lock, flags);
731 list_del(&raid_device->list);
732 memset(raid_device, 0, sizeof(struct _raid_device));
733 kfree(raid_device);
734 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
735}
736
c5e039be
KD
737/**
738 * mpt2sas_scsih_expander_find_by_handle - expander device search
739 * @ioc: per adapter object
740 * @handle: expander handle (assigned by firmware)
741 * Context: Calling function should acquire ioc->sas_device_lock
742 *
743 * This searches for expander device based on handle, then returns the
744 * sas_node object.
745 */
746struct _sas_node *
747mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
748{
749 struct _sas_node *sas_expander, *r;
750
751 r = NULL;
752 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
753 if (sas_expander->handle != handle)
754 continue;
755 r = sas_expander;
756 goto out;
757 }
758 out:
759 return r;
760}
761
635374e7
EM
762/**
763 * mpt2sas_scsih_expander_find_by_sas_address - expander device search
764 * @ioc: per adapter object
765 * @sas_address: sas address
766 * Context: Calling function should acquire ioc->sas_node_lock.
767 *
768 * This searches for expander device based on sas_address, then returns the
769 * sas_node object.
770 */
771struct _sas_node *
772mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
773 u64 sas_address)
774{
775 struct _sas_node *sas_expander, *r;
776
777 r = NULL;
778 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
779 if (sas_expander->sas_address != sas_address)
780 continue;
781 r = sas_expander;
782 goto out;
783 }
784 out:
785 return r;
786}
787
788/**
789 * _scsih_expander_node_add - insert expander device to the list.
790 * @ioc: per adapter object
791 * @sas_expander: the sas_device object
792 * Context: This function will acquire ioc->sas_node_lock.
793 *
794 * Adding new object to the ioc->sas_expander_list.
795 *
796 * Return nothing.
797 */
798static void
799_scsih_expander_node_add(struct MPT2SAS_ADAPTER *ioc,
800 struct _sas_node *sas_expander)
801{
802 unsigned long flags;
803
804 spin_lock_irqsave(&ioc->sas_node_lock, flags);
805 list_add_tail(&sas_expander->list, &ioc->sas_expander_list);
806 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
807}
808
809/**
810 * _scsih_is_end_device - determines if device is an end device
811 * @device_info: bitfield providing information about the device.
812 * Context: none
813 *
814 * Returns 1 if end device.
815 */
816static int
817_scsih_is_end_device(u32 device_info)
818{
819 if (device_info & MPI2_SAS_DEVICE_INFO_END_DEVICE &&
820 ((device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) |
821 (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET) |
822 (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)))
823 return 1;
824 else
825 return 0;
826}
827
828/**
595bb0bd 829 * mptscsih_get_scsi_lookup - returns scmd entry
635374e7
EM
830 * @ioc: per adapter object
831 * @smid: system request message index
635374e7
EM
832 *
833 * Returns the smid stored scmd pointer.
834 */
835static struct scsi_cmnd *
836_scsih_scsi_lookup_get(struct MPT2SAS_ADAPTER *ioc, u16 smid)
837{
595bb0bd 838 return ioc->scsi_lookup[smid - 1].scmd;
635374e7
EM
839}
840
841/**
842 * _scsih_scsi_lookup_find_by_scmd - scmd lookup
843 * @ioc: per adapter object
844 * @smid: system request message index
845 * @scmd: pointer to scsi command object
846 * Context: This function will acquire ioc->scsi_lookup_lock.
847 *
848 * This will search for a scmd pointer in the scsi_lookup array,
849 * returning the revelent smid. A returned value of zero means invalid.
850 */
851static u16
852_scsih_scsi_lookup_find_by_scmd(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd
853 *scmd)
854{
855 u16 smid;
856 unsigned long flags;
857 int i;
858
859 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
860 smid = 0;
595bb0bd 861 for (i = 0; i < ioc->scsiio_depth; i++) {
635374e7 862 if (ioc->scsi_lookup[i].scmd == scmd) {
595bb0bd 863 smid = ioc->scsi_lookup[i].smid;
635374e7
EM
864 goto out;
865 }
866 }
867 out:
868 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
869 return smid;
870}
871
872/**
873 * _scsih_scsi_lookup_find_by_target - search for matching channel:id
874 * @ioc: per adapter object
875 * @id: target id
876 * @channel: channel
877 * Context: This function will acquire ioc->scsi_lookup_lock.
878 *
879 * This will search for a matching channel:id in the scsi_lookup array,
880 * returning 1 if found.
881 */
882static u8
883_scsih_scsi_lookup_find_by_target(struct MPT2SAS_ADAPTER *ioc, int id,
884 int channel)
885{
886 u8 found;
887 unsigned long flags;
888 int i;
889
890 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
891 found = 0;
595bb0bd 892 for (i = 0 ; i < ioc->scsiio_depth; i++) {
635374e7
EM
893 if (ioc->scsi_lookup[i].scmd &&
894 (ioc->scsi_lookup[i].scmd->device->id == id &&
895 ioc->scsi_lookup[i].scmd->device->channel == channel)) {
896 found = 1;
897 goto out;
898 }
899 }
900 out:
901 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
902 return found;
903}
904
993e0da7
EM
905/**
906 * _scsih_scsi_lookup_find_by_lun - search for matching channel:id:lun
907 * @ioc: per adapter object
908 * @id: target id
909 * @lun: lun number
910 * @channel: channel
911 * Context: This function will acquire ioc->scsi_lookup_lock.
912 *
913 * This will search for a matching channel:id:lun in the scsi_lookup array,
914 * returning 1 if found.
915 */
916static u8
917_scsih_scsi_lookup_find_by_lun(struct MPT2SAS_ADAPTER *ioc, int id,
918 unsigned int lun, int channel)
919{
920 u8 found;
921 unsigned long flags;
922 int i;
923
924 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
925 found = 0;
595bb0bd 926 for (i = 0 ; i < ioc->scsiio_depth; i++) {
993e0da7
EM
927 if (ioc->scsi_lookup[i].scmd &&
928 (ioc->scsi_lookup[i].scmd->device->id == id &&
929 ioc->scsi_lookup[i].scmd->device->channel == channel &&
930 ioc->scsi_lookup[i].scmd->device->lun == lun)) {
931 found = 1;
932 goto out;
933 }
934 }
935 out:
936 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
937 return found;
938}
939
635374e7
EM
940/**
941 * _scsih_get_chain_buffer_dma - obtain block of chains (dma address)
942 * @ioc: per adapter object
943 * @smid: system request message index
944 *
945 * Returns phys pointer to chain buffer.
946 */
947static dma_addr_t
948_scsih_get_chain_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid)
949{
950 return ioc->chain_dma + ((smid - 1) * (ioc->request_sz *
951 ioc->chains_needed_per_io));
952}
953
954/**
955 * _scsih_get_chain_buffer - obtain block of chains assigned to a mf request
956 * @ioc: per adapter object
957 * @smid: system request message index
958 *
959 * Returns virt pointer to chain buffer.
960 */
961static void *
962_scsih_get_chain_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid)
963{
964 return (void *)(ioc->chain + ((smid - 1) * (ioc->request_sz *
965 ioc->chains_needed_per_io)));
966}
967
968/**
969 * _scsih_build_scatter_gather - main sg creation routine
970 * @ioc: per adapter object
971 * @scmd: scsi command
972 * @smid: system request message index
973 * Context: none.
974 *
975 * The main routine that builds scatter gather table from a given
976 * scsi request sent via the .queuecommand main handler.
977 *
978 * Returns 0 success, anything else error
979 */
980static int
981_scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
982 struct scsi_cmnd *scmd, u16 smid)
983{
984 Mpi2SCSIIORequest_t *mpi_request;
985 dma_addr_t chain_dma;
986 struct scatterlist *sg_scmd;
987 void *sg_local, *chain;
988 u32 chain_offset;
989 u32 chain_length;
990 u32 chain_flags;
991 u32 sges_left;
992 u32 sges_in_segment;
993 u32 sgl_flags;
994 u32 sgl_flags_last_element;
995 u32 sgl_flags_end_buffer;
996
997 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
998
999 /* init scatter gather flags */
1000 sgl_flags = MPI2_SGE_FLAGS_SIMPLE_ELEMENT;
1001 if (scmd->sc_data_direction == DMA_TO_DEVICE)
1002 sgl_flags |= MPI2_SGE_FLAGS_HOST_TO_IOC;
1003 sgl_flags_last_element = (sgl_flags | MPI2_SGE_FLAGS_LAST_ELEMENT)
1004 << MPI2_SGE_FLAGS_SHIFT;
1005 sgl_flags_end_buffer = (sgl_flags | MPI2_SGE_FLAGS_LAST_ELEMENT |
1006 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_END_OF_LIST)
1007 << MPI2_SGE_FLAGS_SHIFT;
1008 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1009
1010 sg_scmd = scsi_sglist(scmd);
1011 sges_left = scsi_dma_map(scmd);
1012 if (!sges_left) {
1013 sdev_printk(KERN_ERR, scmd->device, "pci_map_sg"
1014 " failed: request for %d bytes!\n", scsi_bufflen(scmd));
1015 return -ENOMEM;
1016 }
1017
1018 sg_local = &mpi_request->SGL;
1019 sges_in_segment = ioc->max_sges_in_main_message;
1020 if (sges_left <= sges_in_segment)
1021 goto fill_in_last_segment;
1022
1023 mpi_request->ChainOffset = (offsetof(Mpi2SCSIIORequest_t, SGL) +
1024 (sges_in_segment * ioc->sge_size))/4;
1025
1026 /* fill in main message segment when there is a chain following */
1027 while (sges_in_segment) {
1028 if (sges_in_segment == 1)
1029 ioc->base_add_sg_single(sg_local,
1030 sgl_flags_last_element | sg_dma_len(sg_scmd),
1031 sg_dma_address(sg_scmd));
1032 else
1033 ioc->base_add_sg_single(sg_local, sgl_flags |
1034 sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));
1035 sg_scmd = sg_next(sg_scmd);
1036 sg_local += ioc->sge_size;
1037 sges_left--;
1038 sges_in_segment--;
1039 }
1040
1041 /* initializing the chain flags and pointers */
1042 chain_flags = MPI2_SGE_FLAGS_CHAIN_ELEMENT << MPI2_SGE_FLAGS_SHIFT;
1043 chain = _scsih_get_chain_buffer(ioc, smid);
1044 chain_dma = _scsih_get_chain_buffer_dma(ioc, smid);
1045 do {
1046 sges_in_segment = (sges_left <=
1047 ioc->max_sges_in_chain_message) ? sges_left :
1048 ioc->max_sges_in_chain_message;
1049 chain_offset = (sges_left == sges_in_segment) ?
1050 0 : (sges_in_segment * ioc->sge_size)/4;
1051 chain_length = sges_in_segment * ioc->sge_size;
1052 if (chain_offset) {
1053 chain_offset = chain_offset <<
1054 MPI2_SGE_CHAIN_OFFSET_SHIFT;
1055 chain_length += ioc->sge_size;
1056 }
1057 ioc->base_add_sg_single(sg_local, chain_flags | chain_offset |
1058 chain_length, chain_dma);
1059 sg_local = chain;
1060 if (!chain_offset)
1061 goto fill_in_last_segment;
1062
1063 /* fill in chain segments */
1064 while (sges_in_segment) {
1065 if (sges_in_segment == 1)
1066 ioc->base_add_sg_single(sg_local,
1067 sgl_flags_last_element |
1068 sg_dma_len(sg_scmd),
1069 sg_dma_address(sg_scmd));
1070 else
1071 ioc->base_add_sg_single(sg_local, sgl_flags |
1072 sg_dma_len(sg_scmd),
1073 sg_dma_address(sg_scmd));
1074 sg_scmd = sg_next(sg_scmd);
1075 sg_local += ioc->sge_size;
1076 sges_left--;
1077 sges_in_segment--;
1078 }
1079
1080 chain_dma += ioc->request_sz;
1081 chain += ioc->request_sz;
1082 } while (1);
1083
1084
1085 fill_in_last_segment:
1086
1087 /* fill the last segment */
1088 while (sges_left) {
1089 if (sges_left == 1)
1090 ioc->base_add_sg_single(sg_local, sgl_flags_end_buffer |
1091 sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));
1092 else
1093 ioc->base_add_sg_single(sg_local, sgl_flags |
1094 sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));
1095 sg_scmd = sg_next(sg_scmd);
1096 sg_local += ioc->sge_size;
1097 sges_left--;
1098 }
1099
1100 return 0;
1101}
1102
1103/**
d5d135b3 1104 * _scsih_change_queue_depth - setting device queue depth
635374e7
EM
1105 * @sdev: scsi device struct
1106 * @qdepth: requested queue depth
e881a172 1107 * @reason: calling context
635374e7
EM
1108 *
1109 * Returns queue depth.
1110 */
1111static int
e881a172 1112_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
635374e7
EM
1113{
1114 struct Scsi_Host *shost = sdev->host;
1115 int max_depth;
1116 int tag_type;
e0077d60
KD
1117 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
1118 struct MPT2SAS_DEVICE *sas_device_priv_data;
1119 struct MPT2SAS_TARGET *sas_target_priv_data;
1120 struct _sas_device *sas_device;
1121 unsigned long flags;
635374e7 1122
e881a172
MC
1123 if (reason != SCSI_QDEPTH_DEFAULT)
1124 return -EOPNOTSUPP;
1125
635374e7 1126 max_depth = shost->can_queue;
e0077d60
KD
1127
1128 /* limit max device queue for SATA to 32 */
1129 sas_device_priv_data = sdev->hostdata;
1130 if (!sas_device_priv_data)
1131 goto not_sata;
1132 sas_target_priv_data = sas_device_priv_data->sas_target;
1133 if (!sas_target_priv_data)
1134 goto not_sata;
1135 if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))
1136 goto not_sata;
1137 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1138 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1139 sas_device_priv_data->sas_target->sas_address);
1140 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1141 if (sas_device && sas_device->device_info &
1142 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
1143 max_depth = MPT2SAS_SATA_QUEUE_DEPTH;
1144
1145 not_sata:
1146
635374e7
EM
1147 if (!sdev->tagged_supported)
1148 max_depth = 1;
1149 if (qdepth > max_depth)
1150 qdepth = max_depth;
1151 tag_type = (qdepth == 1) ? 0 : MSG_SIMPLE_TAG;
1152 scsi_adjust_queue_depth(sdev, tag_type, qdepth);
1153
1154 if (sdev->inquiry_len > 7)
1155 sdev_printk(KERN_INFO, sdev, "qdepth(%d), tagged(%d), "
1156 "simple(%d), ordered(%d), scsi_level(%d), cmd_que(%d)\n",
1157 sdev->queue_depth, sdev->tagged_supported, sdev->simple_tags,
1158 sdev->ordered_tags, sdev->scsi_level,
1159 (sdev->inquiry[7] & 2) >> 1);
1160
1161 return sdev->queue_depth;
1162}
1163
1164/**
595bb0bd 1165 * _scsih_change_queue_type - changing device queue tag type
635374e7
EM
1166 * @sdev: scsi device struct
1167 * @tag_type: requested tag type
1168 *
1169 * Returns queue tag type.
1170 */
1171static int
d5d135b3 1172_scsih_change_queue_type(struct scsi_device *sdev, int tag_type)
635374e7
EM
1173{
1174 if (sdev->tagged_supported) {
1175 scsi_set_tag_type(sdev, tag_type);
1176 if (tag_type)
1177 scsi_activate_tcq(sdev, sdev->queue_depth);
1178 else
1179 scsi_deactivate_tcq(sdev, sdev->queue_depth);
1180 } else
1181 tag_type = 0;
1182
1183 return tag_type;
1184}
1185
1186/**
d5d135b3 1187 * _scsih_target_alloc - target add routine
635374e7
EM
1188 * @starget: scsi target struct
1189 *
1190 * Returns 0 if ok. Any other return is assumed to be an error and
1191 * the device is ignored.
1192 */
1193static int
d5d135b3 1194_scsih_target_alloc(struct scsi_target *starget)
635374e7
EM
1195{
1196 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
1197 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
1198 struct MPT2SAS_TARGET *sas_target_priv_data;
1199 struct _sas_device *sas_device;
1200 struct _raid_device *raid_device;
1201 unsigned long flags;
1202 struct sas_rphy *rphy;
1203
1204 sas_target_priv_data = kzalloc(sizeof(struct scsi_target), GFP_KERNEL);
1205 if (!sas_target_priv_data)
1206 return -ENOMEM;
1207
1208 starget->hostdata = sas_target_priv_data;
1209 sas_target_priv_data->starget = starget;
1210 sas_target_priv_data->handle = MPT2SAS_INVALID_DEVICE_HANDLE;
1211
1212 /* RAID volumes */
1213 if (starget->channel == RAID_CHANNEL) {
1214 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1215 raid_device = _scsih_raid_device_find_by_id(ioc, starget->id,
1216 starget->channel);
1217 if (raid_device) {
1218 sas_target_priv_data->handle = raid_device->handle;
1219 sas_target_priv_data->sas_address = raid_device->wwid;
1220 sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME;
1221 raid_device->starget = starget;
1222 }
1223 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1224 return 0;
1225 }
1226
1227 /* sas/sata devices */
1228 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1229 rphy = dev_to_rphy(starget->dev.parent);
1230 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1231 rphy->identify.sas_address);
1232
1233 if (sas_device) {
1234 sas_target_priv_data->handle = sas_device->handle;
1235 sas_target_priv_data->sas_address = sas_device->sas_address;
1236 sas_device->starget = starget;
1237 sas_device->id = starget->id;
1238 sas_device->channel = starget->channel;
1239 if (sas_device->hidden_raid_component)
1240 sas_target_priv_data->flags |=
1241 MPT_TARGET_FLAGS_RAID_COMPONENT;
1242 }
1243 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1244
1245 return 0;
1246}
1247
1248/**
d5d135b3 1249 * _scsih_target_destroy - target destroy routine
635374e7
EM
1250 * @starget: scsi target struct
1251 *
1252 * Returns nothing.
1253 */
1254static void
d5d135b3 1255_scsih_target_destroy(struct scsi_target *starget)
635374e7
EM
1256{
1257 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
1258 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
1259 struct MPT2SAS_TARGET *sas_target_priv_data;
1260 struct _sas_device *sas_device;
1261 struct _raid_device *raid_device;
1262 unsigned long flags;
1263 struct sas_rphy *rphy;
1264
1265 sas_target_priv_data = starget->hostdata;
1266 if (!sas_target_priv_data)
1267 return;
1268
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 raid_device->starget = NULL;
1275 raid_device->sdev = NULL;
1276 }
1277 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1278 goto out;
1279 }
1280
1281 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1282 rphy = dev_to_rphy(starget->dev.parent);
1283 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1284 rphy->identify.sas_address);
8901cbb4
EM
1285 if (sas_device && (sas_device->starget == starget) &&
1286 (sas_device->id == starget->id) &&
1287 (sas_device->channel == starget->channel))
635374e7
EM
1288 sas_device->starget = NULL;
1289
1290 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1291
1292 out:
1293 kfree(sas_target_priv_data);
1294 starget->hostdata = NULL;
1295}
1296
1297/**
d5d135b3 1298 * _scsih_slave_alloc - device add routine
635374e7
EM
1299 * @sdev: scsi device struct
1300 *
1301 * Returns 0 if ok. Any other return is assumed to be an error and
1302 * the device is ignored.
1303 */
1304static int
d5d135b3 1305_scsih_slave_alloc(struct scsi_device *sdev)
635374e7
EM
1306{
1307 struct Scsi_Host *shost;
1308 struct MPT2SAS_ADAPTER *ioc;
1309 struct MPT2SAS_TARGET *sas_target_priv_data;
1310 struct MPT2SAS_DEVICE *sas_device_priv_data;
1311 struct scsi_target *starget;
1312 struct _raid_device *raid_device;
635374e7
EM
1313 unsigned long flags;
1314
1315 sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL);
1316 if (!sas_device_priv_data)
1317 return -ENOMEM;
1318
1319 sas_device_priv_data->lun = sdev->lun;
1320 sas_device_priv_data->flags = MPT_DEVICE_FLAGS_INIT;
1321
1322 starget = scsi_target(sdev);
1323 sas_target_priv_data = starget->hostdata;
1324 sas_target_priv_data->num_luns++;
1325 sas_device_priv_data->sas_target = sas_target_priv_data;
1326 sdev->hostdata = sas_device_priv_data;
1327 if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT))
1328 sdev->no_uld_attach = 1;
1329
1330 shost = dev_to_shost(&starget->dev);
1331 ioc = shost_priv(shost);
1332 if (starget->channel == RAID_CHANNEL) {
1333 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1334 raid_device = _scsih_raid_device_find_by_id(ioc,
1335 starget->id, starget->channel);
1336 if (raid_device)
1337 raid_device->sdev = sdev; /* raid is single lun */
1338 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
635374e7
EM
1339 }
1340
635374e7
EM
1341 return 0;
1342}
1343
1344/**
d5d135b3 1345 * _scsih_slave_destroy - device destroy routine
635374e7
EM
1346 * @sdev: scsi device struct
1347 *
1348 * Returns nothing.
1349 */
1350static void
d5d135b3 1351_scsih_slave_destroy(struct scsi_device *sdev)
635374e7
EM
1352{
1353 struct MPT2SAS_TARGET *sas_target_priv_data;
1354 struct scsi_target *starget;
1355
1356 if (!sdev->hostdata)
1357 return;
1358
1359 starget = scsi_target(sdev);
1360 sas_target_priv_data = starget->hostdata;
1361 sas_target_priv_data->num_luns--;
1362 kfree(sdev->hostdata);
1363 sdev->hostdata = NULL;
1364}
1365
1366/**
d5d135b3 1367 * _scsih_display_sata_capabilities - sata capabilities
635374e7
EM
1368 * @ioc: per adapter object
1369 * @sas_device: the sas_device object
1370 * @sdev: scsi device struct
1371 */
1372static void
d5d135b3 1373_scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc,
635374e7
EM
1374 struct _sas_device *sas_device, struct scsi_device *sdev)
1375{
1376 Mpi2ConfigReply_t mpi_reply;
1377 Mpi2SasDevicePage0_t sas_device_pg0;
1378 u32 ioc_status;
1379 u16 flags;
1380 u32 device_info;
1381
1382 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
1383 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, sas_device->handle))) {
1384 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1385 ioc->name, __FILE__, __LINE__, __func__);
1386 return;
1387 }
1388
1389 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1390 MPI2_IOCSTATUS_MASK;
1391 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1392 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1393 ioc->name, __FILE__, __LINE__, __func__);
1394 return;
1395 }
1396
1397 flags = le16_to_cpu(sas_device_pg0.Flags);
1398 device_info = le16_to_cpu(sas_device_pg0.DeviceInfo);
1399
1400 sdev_printk(KERN_INFO, sdev,
1401 "atapi(%s), ncq(%s), asyn_notify(%s), smart(%s), fua(%s), "
1402 "sw_preserve(%s)\n",
1403 (device_info & MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE) ? "y" : "n",
1404 (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED) ? "y" : "n",
1405 (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY) ? "y" :
1406 "n",
1407 (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED) ? "y" : "n",
1408 (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED) ? "y" : "n",
1409 (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE) ? "y" : "n");
1410}
1411
f7c95ef0
KD
1412/**
1413 * _scsih_is_raid - return boolean indicating device is raid volume
1414 * @dev the device struct object
1415 */
1416static int
1417_scsih_is_raid(struct device *dev)
1418{
1419 struct scsi_device *sdev = to_scsi_device(dev);
1420
1421 return (sdev->channel == RAID_CHANNEL) ? 1 : 0;
1422}
1423
1424/**
1425 * _scsih_get_resync - get raid volume resync percent complete
1426 * @dev the device struct object
1427 */
1428static void
1429_scsih_get_resync(struct device *dev)
1430{
1431 struct scsi_device *sdev = to_scsi_device(dev);
1432 struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
1433 static struct _raid_device *raid_device;
1434 unsigned long flags;
1435 Mpi2RaidVolPage0_t vol_pg0;
1436 Mpi2ConfigReply_t mpi_reply;
1437 u32 volume_status_flags;
1438 u8 percent_complete = 0;
1439
1440 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1441 raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
1442 sdev->channel);
1443 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1444
1445 if (!raid_device)
1446 goto out;
1447
1448 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
1449 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle,
1450 sizeof(Mpi2RaidVolPage0_t))) {
1451 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1452 ioc->name, __FILE__, __LINE__, __func__);
1453 goto out;
1454 }
1455
1456 volume_status_flags = le32_to_cpu(vol_pg0.VolumeStatusFlags);
1457 if (volume_status_flags & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS)
1458 percent_complete = raid_device->percent_complete;
1459 out:
1460 raid_set_resync(mpt2sas_raid_template, dev, percent_complete);
1461}
1462
1463/**
1464 * _scsih_get_state - get raid volume level
1465 * @dev the device struct object
1466 */
1467static void
1468_scsih_get_state(struct device *dev)
1469{
1470 struct scsi_device *sdev = to_scsi_device(dev);
1471 struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
1472 static struct _raid_device *raid_device;
1473 unsigned long flags;
1474 Mpi2RaidVolPage0_t vol_pg0;
1475 Mpi2ConfigReply_t mpi_reply;
1476 u32 volstate;
1477 enum raid_state state = RAID_STATE_UNKNOWN;
1478
1479 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1480 raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
1481 sdev->channel);
1482 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1483
1484 if (!raid_device)
1485 goto out;
1486
1487 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
1488 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle,
1489 sizeof(Mpi2RaidVolPage0_t))) {
1490 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1491 ioc->name, __FILE__, __LINE__, __func__);
1492 goto out;
1493 }
1494
1495 volstate = le32_to_cpu(vol_pg0.VolumeStatusFlags);
1496 if (volstate & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) {
1497 state = RAID_STATE_RESYNCING;
1498 goto out;
1499 }
1500
1501 switch (vol_pg0.VolumeState) {
1502 case MPI2_RAID_VOL_STATE_OPTIMAL:
1503 case MPI2_RAID_VOL_STATE_ONLINE:
1504 state = RAID_STATE_ACTIVE;
1505 break;
1506 case MPI2_RAID_VOL_STATE_DEGRADED:
1507 state = RAID_STATE_DEGRADED;
1508 break;
1509 case MPI2_RAID_VOL_STATE_FAILED:
1510 case MPI2_RAID_VOL_STATE_MISSING:
1511 state = RAID_STATE_OFFLINE;
1512 break;
1513 }
1514 out:
1515 raid_set_state(mpt2sas_raid_template, dev, state);
1516}
1517
1518/**
1519 * _scsih_set_level - set raid level
1520 * @sdev: scsi device struct
1521 * @raid_device: raid_device object
1522 */
1523static void
1524_scsih_set_level(struct scsi_device *sdev, struct _raid_device *raid_device)
1525{
1526 enum raid_level level = RAID_LEVEL_UNKNOWN;
1527
1528 switch (raid_device->volume_type) {
1529 case MPI2_RAID_VOL_TYPE_RAID0:
1530 level = RAID_LEVEL_0;
1531 break;
1532 case MPI2_RAID_VOL_TYPE_RAID10:
1533 level = RAID_LEVEL_10;
1534 break;
1535 case MPI2_RAID_VOL_TYPE_RAID1E:
1536 level = RAID_LEVEL_1E;
1537 break;
1538 case MPI2_RAID_VOL_TYPE_RAID1:
1539 level = RAID_LEVEL_1;
1540 break;
1541 }
1542
1543 raid_set_level(mpt2sas_raid_template, &sdev->sdev_gendev, level);
1544}
1545
635374e7
EM
1546/**
1547 * _scsih_get_volume_capabilities - volume capabilities
1548 * @ioc: per adapter object
1549 * @sas_device: the raid_device object
1550 */
1551static void
1552_scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1553 struct _raid_device *raid_device)
1554{
1555 Mpi2RaidVolPage0_t *vol_pg0;
1556 Mpi2RaidPhysDiskPage0_t pd_pg0;
1557 Mpi2SasDevicePage0_t sas_device_pg0;
1558 Mpi2ConfigReply_t mpi_reply;
1559 u16 sz;
1560 u8 num_pds;
1561
1562 if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle,
1563 &num_pds)) || !num_pds) {
1564 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1565 ioc->name, __FILE__, __LINE__, __func__);
1566 return;
1567 }
1568
1569 raid_device->num_pds = num_pds;
1570 sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds *
1571 sizeof(Mpi2RaidVol0PhysDisk_t));
1572 vol_pg0 = kzalloc(sz, GFP_KERNEL);
1573 if (!vol_pg0) {
1574 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1575 ioc->name, __FILE__, __LINE__, __func__);
1576 return;
1577 }
1578
1579 if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0,
1580 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) {
1581 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1582 ioc->name, __FILE__, __LINE__, __func__);
1583 kfree(vol_pg0);
1584 return;
1585 }
1586
1587 raid_device->volume_type = vol_pg0->VolumeType;
1588
1589 /* figure out what the underlying devices are by
1590 * obtaining the device_info bits for the 1st device
1591 */
1592 if (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
1593 &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM,
1594 vol_pg0->PhysDisk[0].PhysDiskNum))) {
1595 if (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
1596 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
1597 le16_to_cpu(pd_pg0.DevHandle)))) {
1598 raid_device->device_info =
1599 le32_to_cpu(sas_device_pg0.DeviceInfo);
1600 }
1601 }
1602
1603 kfree(vol_pg0);
1604}
1605
84f0b04a
KD
1606/**
1607 * _scsih_enable_tlr - setting TLR flags
1608 * @ioc: per adapter object
1609 * @sdev: scsi device struct
1610 *
1611 * Enabling Transaction Layer Retries for tape devices when
1612 * vpd page 0x90 is present
1613 *
1614 */
1615static void
1616_scsih_enable_tlr(struct MPT2SAS_ADAPTER *ioc, struct scsi_device *sdev)
1617{
1618 /* only for TAPE */
1619 if (sdev->type != TYPE_TAPE)
1620 return;
1621
1622 if (!(ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR))
1623 return;
1624
1625 sas_enable_tlr(sdev);
1626 sdev_printk(KERN_INFO, sdev, "TLR %s\n",
1627 sas_is_tlr_enabled(sdev) ? "Enabled" : "Disabled");
1628 return;
1629
1630}
1631
635374e7 1632/**
d5d135b3 1633 * _scsih_slave_configure - device configure routine.
635374e7
EM
1634 * @sdev: scsi device struct
1635 *
1636 * Returns 0 if ok. Any other return is assumed to be an error and
1637 * the device is ignored.
1638 */
1639static int
d5d135b3 1640_scsih_slave_configure(struct scsi_device *sdev)
635374e7
EM
1641{
1642 struct Scsi_Host *shost = sdev->host;
1643 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
1644 struct MPT2SAS_DEVICE *sas_device_priv_data;
1645 struct MPT2SAS_TARGET *sas_target_priv_data;
1646 struct _sas_device *sas_device;
1647 struct _raid_device *raid_device;
1648 unsigned long flags;
1649 int qdepth;
1650 u8 ssp_target = 0;
1651 char *ds = "";
1652 char *r_level = "";
1653
1654 qdepth = 1;
1655 sas_device_priv_data = sdev->hostdata;
1656 sas_device_priv_data->configured_lun = 1;
1657 sas_device_priv_data->flags &= ~MPT_DEVICE_FLAGS_INIT;
1658 sas_target_priv_data = sas_device_priv_data->sas_target;
1659
1660 /* raid volume handling */
1661 if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME) {
1662
1663 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1664 raid_device = _scsih_raid_device_find_by_handle(ioc,
1665 sas_target_priv_data->handle);
1666 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1667 if (!raid_device) {
1668 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1669 ioc->name, __FILE__, __LINE__, __func__);
1670 return 0;
1671 }
1672
1673 _scsih_get_volume_capabilities(ioc, raid_device);
1674
1675 /* RAID Queue Depth Support
1676 * IS volume = underlying qdepth of drive type, either
1677 * MPT2SAS_SAS_QUEUE_DEPTH or MPT2SAS_SATA_QUEUE_DEPTH
1678 * IM/IME/R10 = 128 (MPT2SAS_RAID_QUEUE_DEPTH)
1679 */
1680 if (raid_device->device_info &
1681 MPI2_SAS_DEVICE_INFO_SSP_TARGET) {
1682 qdepth = MPT2SAS_SAS_QUEUE_DEPTH;
1683 ds = "SSP";
1684 } else {
1685 qdepth = MPT2SAS_SATA_QUEUE_DEPTH;
1686 if (raid_device->device_info &
1687 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
1688 ds = "SATA";
1689 else
1690 ds = "STP";
1691 }
1692
1693 switch (raid_device->volume_type) {
1694 case MPI2_RAID_VOL_TYPE_RAID0:
1695 r_level = "RAID0";
1696 break;
1697 case MPI2_RAID_VOL_TYPE_RAID1E:
1698 qdepth = MPT2SAS_RAID_QUEUE_DEPTH;
ed79f128
KD
1699 if (ioc->manu_pg10.OEMIdentifier &&
1700 (ioc->manu_pg10.GenericFlags0 &
1701 MFG10_GF0_R10_DISPLAY) &&
1702 !(raid_device->num_pds % 2))
1703 r_level = "RAID10";
1704 else
1705 r_level = "RAID1E";
635374e7
EM
1706 break;
1707 case MPI2_RAID_VOL_TYPE_RAID1:
1708 qdepth = MPT2SAS_RAID_QUEUE_DEPTH;
1709 r_level = "RAID1";
1710 break;
1711 case MPI2_RAID_VOL_TYPE_RAID10:
1712 qdepth = MPT2SAS_RAID_QUEUE_DEPTH;
1713 r_level = "RAID10";
1714 break;
1715 case MPI2_RAID_VOL_TYPE_UNKNOWN:
1716 default:
1717 qdepth = MPT2SAS_RAID_QUEUE_DEPTH;
1718 r_level = "RAIDX";
1719 break;
1720 }
1721
1722 sdev_printk(KERN_INFO, sdev, "%s: "
1723 "handle(0x%04x), wwid(0x%016llx), pd_count(%d), type(%s)\n",
1724 r_level, raid_device->handle,
1725 (unsigned long long)raid_device->wwid,
1726 raid_device->num_pds, ds);
e881a172 1727 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
f7c95ef0
KD
1728 /* raid transport support */
1729 _scsih_set_level(sdev, raid_device);
635374e7
EM
1730 return 0;
1731 }
1732
1733 /* non-raid handling */
1734 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1735 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1736 sas_device_priv_data->sas_target->sas_address);
1737 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1738 if (sas_device) {
1739 if (sas_target_priv_data->flags &
1740 MPT_TARGET_FLAGS_RAID_COMPONENT) {
1741 mpt2sas_config_get_volume_handle(ioc,
1742 sas_device->handle, &sas_device->volume_handle);
1743 mpt2sas_config_get_volume_wwid(ioc,
1744 sas_device->volume_handle,
1745 &sas_device->volume_wwid);
1746 }
1747 if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) {
1748 qdepth = MPT2SAS_SAS_QUEUE_DEPTH;
1749 ssp_target = 1;
1750 ds = "SSP";
1751 } else {
1752 qdepth = MPT2SAS_SATA_QUEUE_DEPTH;
1753 if (sas_device->device_info &
1754 MPI2_SAS_DEVICE_INFO_STP_TARGET)
1755 ds = "STP";
1756 else if (sas_device->device_info &
1757 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
1758 ds = "SATA";
1759 }
1760
1761 sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), "
1762 "sas_addr(0x%016llx), device_name(0x%016llx)\n",
1763 ds, sas_device->handle,
1764 (unsigned long long)sas_device->sas_address,
1765 (unsigned long long)sas_device->device_name);
1766 sdev_printk(KERN_INFO, sdev, "%s: "
1767 "enclosure_logical_id(0x%016llx), slot(%d)\n", ds,
1768 (unsigned long long) sas_device->enclosure_logical_id,
1769 sas_device->slot);
1770
1771 if (!ssp_target)
d5d135b3 1772 _scsih_display_sata_capabilities(ioc, sas_device, sdev);
635374e7
EM
1773 }
1774
e881a172 1775 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
635374e7 1776
84f0b04a 1777 if (ssp_target) {
635374e7 1778 sas_read_port_mode_page(sdev);
84f0b04a
KD
1779 _scsih_enable_tlr(ioc, sdev);
1780 }
635374e7
EM
1781 return 0;
1782}
1783
1784/**
d5d135b3 1785 * _scsih_bios_param - fetch head, sector, cylinder info for a disk
635374e7
EM
1786 * @sdev: scsi device struct
1787 * @bdev: pointer to block device context
1788 * @capacity: device size (in 512 byte sectors)
1789 * @params: three element array to place output:
1790 * params[0] number of heads (max 255)
1791 * params[1] number of sectors (max 63)
1792 * params[2] number of cylinders
1793 *
1794 * Return nothing.
1795 */
1796static int
d5d135b3 1797_scsih_bios_param(struct scsi_device *sdev, struct block_device *bdev,
635374e7
EM
1798 sector_t capacity, int params[])
1799{
1800 int heads;
1801 int sectors;
1802 sector_t cylinders;
1803 ulong dummy;
1804
1805 heads = 64;
1806 sectors = 32;
1807
1808 dummy = heads * sectors;
1809 cylinders = capacity;
1810 sector_div(cylinders, dummy);
1811
1812 /*
1813 * Handle extended translation size for logical drives
1814 * > 1Gb
1815 */
1816 if ((ulong)capacity >= 0x200000) {
1817 heads = 255;
1818 sectors = 63;
1819 dummy = heads * sectors;
1820 cylinders = capacity;
1821 sector_div(cylinders, dummy);
1822 }
1823
1824 /* return result */
1825 params[0] = heads;
1826 params[1] = sectors;
1827 params[2] = cylinders;
1828
1829 return 0;
1830}
1831
1832/**
1833 * _scsih_response_code - translation of device response code
1834 * @ioc: per adapter object
1835 * @response_code: response code returned by the device
1836 *
1837 * Return nothing.
1838 */
1839static void
1840_scsih_response_code(struct MPT2SAS_ADAPTER *ioc, u8 response_code)
1841{
1842 char *desc;
1843
1844 switch (response_code) {
1845 case MPI2_SCSITASKMGMT_RSP_TM_COMPLETE:
1846 desc = "task management request completed";
1847 break;
1848 case MPI2_SCSITASKMGMT_RSP_INVALID_FRAME:
1849 desc = "invalid frame";
1850 break;
1851 case MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
1852 desc = "task management request not supported";
1853 break;
1854 case MPI2_SCSITASKMGMT_RSP_TM_FAILED:
1855 desc = "task management request failed";
1856 break;
1857 case MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED:
1858 desc = "task management request succeeded";
1859 break;
1860 case MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN:
1861 desc = "invalid lun";
1862 break;
1863 case 0xA:
1864 desc = "overlapped tag attempted";
1865 break;
1866 case MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
1867 desc = "task queued, however not sent to target";
1868 break;
1869 default:
1870 desc = "unknown";
1871 break;
1872 }
1873 printk(MPT2SAS_WARN_FMT "response_code(0x%01x): %s\n",
1874 ioc->name, response_code, desc);
1875}
1876
1877/**
d5d135b3 1878 * _scsih_tm_done - tm completion routine
635374e7
EM
1879 * @ioc: per adapter object
1880 * @smid: system request message index
7b936b02 1881 * @msix_index: MSIX table index supplied by the OS
635374e7
EM
1882 * @reply: reply message frame(lower 32bit addr)
1883 * Context: none.
1884 *
1885 * The callback handler when using scsih_issue_tm.
1886 *
77e63ed4
KD
1887 * Return 1 meaning mf should be freed from _base_interrupt
1888 * 0 means the mf is freed from this function.
635374e7 1889 */
77e63ed4 1890static u8
7b936b02 1891_scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
635374e7
EM
1892{
1893 MPI2DefaultReply_t *mpi_reply;
1894
1895 if (ioc->tm_cmds.status == MPT2_CMD_NOT_USED)
77e63ed4 1896 return 1;
635374e7 1897 if (ioc->tm_cmds.smid != smid)
77e63ed4 1898 return 1;
635374e7
EM
1899 ioc->tm_cmds.status |= MPT2_CMD_COMPLETE;
1900 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
1901 if (mpi_reply) {
1902 memcpy(ioc->tm_cmds.reply, mpi_reply, mpi_reply->MsgLength*4);
1903 ioc->tm_cmds.status |= MPT2_CMD_REPLY_VALID;
1904 }
1905 ioc->tm_cmds.status &= ~MPT2_CMD_PENDING;
1906 complete(&ioc->tm_cmds.done);
77e63ed4 1907 return 1;
635374e7
EM
1908}
1909
1910/**
1911 * mpt2sas_scsih_set_tm_flag - set per target tm_busy
1912 * @ioc: per adapter object
1913 * @handle: device handle
1914 *
1915 * During taskmangement request, we need to freeze the device queue.
1916 */
1917void
1918mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle)
1919{
1920 struct MPT2SAS_DEVICE *sas_device_priv_data;
1921 struct scsi_device *sdev;
1922 u8 skip = 0;
1923
1924 shost_for_each_device(sdev, ioc->shost) {
1925 if (skip)
1926 continue;
1927 sas_device_priv_data = sdev->hostdata;
1928 if (!sas_device_priv_data)
1929 continue;
1930 if (sas_device_priv_data->sas_target->handle == handle) {
1931 sas_device_priv_data->sas_target->tm_busy = 1;
1932 skip = 1;
1933 ioc->ignore_loginfos = 1;
1934 }
1935 }
1936}
1937
1938/**
1939 * mpt2sas_scsih_clear_tm_flag - clear per target tm_busy
1940 * @ioc: per adapter object
1941 * @handle: device handle
1942 *
1943 * During taskmangement request, we need to freeze the device queue.
1944 */
1945void
1946mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle)
1947{
1948 struct MPT2SAS_DEVICE *sas_device_priv_data;
1949 struct scsi_device *sdev;
1950 u8 skip = 0;
1951
1952 shost_for_each_device(sdev, ioc->shost) {
1953 if (skip)
1954 continue;
1955 sas_device_priv_data = sdev->hostdata;
1956 if (!sas_device_priv_data)
1957 continue;
1958 if (sas_device_priv_data->sas_target->handle == handle) {
1959 sas_device_priv_data->sas_target->tm_busy = 0;
1960 skip = 1;
1961 ioc->ignore_loginfos = 0;
1962 }
1963 }
1964}
1965
1966/**
1967 * mpt2sas_scsih_issue_tm - main routine for sending tm requests
1968 * @ioc: per adapter struct
1969 * @device_handle: device handle
1970 * @lun: lun number
1971 * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
1972 * @smid_task: smid assigned to the task
1973 * @timeout: timeout in seconds
1974 * Context: The calling function needs to acquire the tm_cmds.mutex
1975 *
1976 * A generic API for sending task management requests to firmware.
1977 *
1978 * The ioc->tm_cmds.status flag should be MPT2_CMD_NOT_USED before calling
1979 * this API.
1980 *
1981 * The callback index is set inside `ioc->tm_cb_idx`.
1982 *
1983 * Return nothing.
1984 */
1985void
1986mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
1987 u8 type, u16 smid_task, ulong timeout)
1988{
1989 Mpi2SCSITaskManagementRequest_t *mpi_request;
1990 Mpi2SCSITaskManagementReply_t *mpi_reply;
1991 u16 smid = 0;
1992 u32 ioc_state;
1993 unsigned long timeleft;
635374e7 1994
155dd4c7
KD
1995 if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED) {
1996 printk(MPT2SAS_INFO_FMT "%s: tm_cmd busy!!!\n",
1997 __func__, ioc->name);
1998 return;
1999 }
2000
2001 if (ioc->shost_recovery) {
635374e7
EM
2002 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
2003 __func__, ioc->name);
2004 return;
2005 }
635374e7
EM
2006
2007 ioc_state = mpt2sas_base_get_iocstate(ioc, 0);
2008 if (ioc_state & MPI2_DOORBELL_USED) {
2009 dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "unexpected doorbell "
2010 "active!\n", ioc->name));
2011 goto issue_host_reset;
2012 }
2013
2014 if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
2015 mpt2sas_base_fault_info(ioc, ioc_state &
2016 MPI2_DOORBELL_DATA_MASK);
2017 goto issue_host_reset;
2018 }
2019
595bb0bd 2020 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_cb_idx);
635374e7
EM
2021 if (!smid) {
2022 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
2023 ioc->name, __func__);
2024 return;
2025 }
2026
2027 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "sending tm: handle(0x%04x),"
595bb0bd
KD
2028 " task_type(0x%02x), smid(%d)\n", ioc->name, handle, type,
2029 smid_task));
635374e7
EM
2030 ioc->tm_cmds.status = MPT2_CMD_PENDING;
2031 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2032 ioc->tm_cmds.smid = smid;
2033 memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
2034 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
2035 mpi_request->DevHandle = cpu_to_le16(handle);
2036 mpi_request->TaskType = type;
2037 mpi_request->TaskMID = cpu_to_le16(smid_task);
7b936b02
KD
2038 mpi_request->VP_ID = 0; /* TODO */
2039 mpi_request->VF_ID = 0;
635374e7
EM
2040 int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
2041 mpt2sas_scsih_set_tm_flag(ioc, handle);
5b768581 2042 init_completion(&ioc->tm_cmds.done);
7b936b02 2043 mpt2sas_base_put_smid_hi_priority(ioc, smid);
635374e7
EM
2044 timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ);
2045 mpt2sas_scsih_clear_tm_flag(ioc, handle);
2046 if (!(ioc->tm_cmds.status & MPT2_CMD_COMPLETE)) {
2047 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
2048 ioc->name, __func__);
2049 _debug_dump_mf(mpi_request,
2050 sizeof(Mpi2SCSITaskManagementRequest_t)/4);
2051 if (!(ioc->tm_cmds.status & MPT2_CMD_RESET))
2052 goto issue_host_reset;
2053 }
2054
2055 if (ioc->tm_cmds.status & MPT2_CMD_REPLY_VALID) {
2056 mpi_reply = ioc->tm_cmds.reply;
2057 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "complete tm: "
2058 "ioc_status(0x%04x), loginfo(0x%08x), term_count(0x%08x)\n",
2059 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
2060 le32_to_cpu(mpi_reply->IOCLogInfo),
2061 le32_to_cpu(mpi_reply->TerminationCount)));
2062 if (ioc->logging_level & MPT_DEBUG_TM)
2063 _scsih_response_code(ioc, mpi_reply->ResponseCode);
2064 }
2065 return;
2066 issue_host_reset:
2067 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, FORCE_BIG_HAMMER);
2068}
2069
2070/**
d5d135b3 2071 * _scsih_abort - eh threads main abort routine
635374e7
EM
2072 * @sdev: scsi device struct
2073 *
2074 * Returns SUCCESS if command aborted else FAILED
2075 */
2076static int
d5d135b3 2077_scsih_abort(struct scsi_cmnd *scmd)
635374e7
EM
2078{
2079 struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
2080 struct MPT2SAS_DEVICE *sas_device_priv_data;
2081 u16 smid;
2082 u16 handle;
2083 int r;
2084 struct scsi_cmnd *scmd_lookup;
2085
2086 printk(MPT2SAS_INFO_FMT "attempting task abort! scmd(%p)\n",
2087 ioc->name, scmd);
2088 scsi_print_command(scmd);
2089
2090 sas_device_priv_data = scmd->device->hostdata;
2091 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
2092 printk(MPT2SAS_INFO_FMT "device been deleted! scmd(%p)\n",
2093 ioc->name, scmd);
2094 scmd->result = DID_NO_CONNECT << 16;
2095 scmd->scsi_done(scmd);
2096 r = SUCCESS;
2097 goto out;
2098 }
2099
2100 /* search for the command */
2101 smid = _scsih_scsi_lookup_find_by_scmd(ioc, scmd);
2102 if (!smid) {
2103 scmd->result = DID_RESET << 16;
2104 r = SUCCESS;
2105 goto out;
2106 }
2107
2108 /* for hidden raid components and volumes this is not supported */
2109 if (sas_device_priv_data->sas_target->flags &
2110 MPT_TARGET_FLAGS_RAID_COMPONENT ||
2111 sas_device_priv_data->sas_target->flags & MPT_TARGET_FLAGS_VOLUME) {
2112 scmd->result = DID_RESET << 16;
2113 r = FAILED;
2114 goto out;
2115 }
2116
fa7f3167
KD
2117 mpt2sas_halt_firmware(ioc);
2118
635374e7
EM
2119 mutex_lock(&ioc->tm_cmds.mutex);
2120 handle = sas_device_priv_data->sas_target->handle;
2121 mpt2sas_scsih_issue_tm(ioc, handle, sas_device_priv_data->lun,
2122 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30);
2123
2124 /* sanity check - see whether command actually completed */
2125 scmd_lookup = _scsih_scsi_lookup_get(ioc, smid);
2126 if (scmd_lookup && (scmd_lookup->serial_number == scmd->serial_number))
2127 r = FAILED;
2128 else
2129 r = SUCCESS;
2130 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
2131 mutex_unlock(&ioc->tm_cmds.mutex);
2132
2133 out:
2134 printk(MPT2SAS_INFO_FMT "task abort: %s scmd(%p)\n",
2135 ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
2136 return r;
2137}
2138
635374e7 2139/**
d5d135b3 2140 * _scsih_dev_reset - eh threads main device reset routine
635374e7
EM
2141 * @sdev: scsi device struct
2142 *
2143 * Returns SUCCESS if command aborted else FAILED
2144 */
2145static int
d5d135b3 2146_scsih_dev_reset(struct scsi_cmnd *scmd)
635374e7
EM
2147{
2148 struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
2149 struct MPT2SAS_DEVICE *sas_device_priv_data;
2150 struct _sas_device *sas_device;
2151 unsigned long flags;
2152 u16 handle;
2153 int r;
2154
993e0da7 2155 printk(MPT2SAS_INFO_FMT "attempting device reset! scmd(%p)\n",
635374e7
EM
2156 ioc->name, scmd);
2157 scsi_print_command(scmd);
2158
2159 sas_device_priv_data = scmd->device->hostdata;
2160 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
2161 printk(MPT2SAS_INFO_FMT "device been deleted! scmd(%p)\n",
2162 ioc->name, scmd);
2163 scmd->result = DID_NO_CONNECT << 16;
2164 scmd->scsi_done(scmd);
2165 r = SUCCESS;
2166 goto out;
2167 }
2168
2169 /* for hidden raid components obtain the volume_handle */
2170 handle = 0;
2171 if (sas_device_priv_data->sas_target->flags &
2172 MPT_TARGET_FLAGS_RAID_COMPONENT) {
2173 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2174 sas_device = _scsih_sas_device_find_by_handle(ioc,
2175 sas_device_priv_data->sas_target->handle);
2176 if (sas_device)
2177 handle = sas_device->volume_handle;
2178 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2179 } else
2180 handle = sas_device_priv_data->sas_target->handle;
2181
2182 if (!handle) {
2183 scmd->result = DID_RESET << 16;
2184 r = FAILED;
2185 goto out;
2186 }
2187
993e0da7
EM
2188 mutex_lock(&ioc->tm_cmds.mutex);
2189 mpt2sas_scsih_issue_tm(ioc, handle, 0,
2190 MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, scmd->device->lun,
2191 30);
2192
2193 /*
2194 * sanity check see whether all commands to this device been
2195 * completed
2196 */
2197 if (_scsih_scsi_lookup_find_by_lun(ioc, scmd->device->id,
2198 scmd->device->lun, scmd->device->channel))
2199 r = FAILED;
2200 else
2201 r = SUCCESS;
2202 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
2203 mutex_unlock(&ioc->tm_cmds.mutex);
2204
2205 out:
2206 printk(MPT2SAS_INFO_FMT "device reset: %s scmd(%p)\n",
2207 ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
2208 return r;
2209}
2210
2211/**
d5d135b3 2212 * _scsih_target_reset - eh threads main target reset routine
993e0da7
EM
2213 * @sdev: scsi device struct
2214 *
2215 * Returns SUCCESS if command aborted else FAILED
2216 */
2217static int
d5d135b3 2218_scsih_target_reset(struct scsi_cmnd *scmd)
993e0da7
EM
2219{
2220 struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
2221 struct MPT2SAS_DEVICE *sas_device_priv_data;
2222 struct _sas_device *sas_device;
2223 unsigned long flags;
2224 u16 handle;
2225 int r;
2226
2227 printk(MPT2SAS_INFO_FMT "attempting target reset! scmd(%p)\n",
2228 ioc->name, scmd);
2229 scsi_print_command(scmd);
2230
2231 sas_device_priv_data = scmd->device->hostdata;
2232 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
2233 printk(MPT2SAS_INFO_FMT "target been deleted! scmd(%p)\n",
2234 ioc->name, scmd);
2235 scmd->result = DID_NO_CONNECT << 16;
2236 scmd->scsi_done(scmd);
2237 r = SUCCESS;
2238 goto out;
2239 }
2240
2241 /* for hidden raid components obtain the volume_handle */
2242 handle = 0;
2243 if (sas_device_priv_data->sas_target->flags &
2244 MPT_TARGET_FLAGS_RAID_COMPONENT) {
2245 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2246 sas_device = _scsih_sas_device_find_by_handle(ioc,
2247 sas_device_priv_data->sas_target->handle);
2248 if (sas_device)
2249 handle = sas_device->volume_handle;
2250 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2251 } else
2252 handle = sas_device_priv_data->sas_target->handle;
2253
2254 if (!handle) {
2255 scmd->result = DID_RESET << 16;
2256 r = FAILED;
2257 goto out;
2258 }
2259
635374e7
EM
2260 mutex_lock(&ioc->tm_cmds.mutex);
2261 mpt2sas_scsih_issue_tm(ioc, handle, 0,
2262 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30);
2263
2264 /*
2265 * sanity check see whether all commands to this target been
2266 * completed
2267 */
2268 if (_scsih_scsi_lookup_find_by_target(ioc, scmd->device->id,
2269 scmd->device->channel))
2270 r = FAILED;
2271 else
2272 r = SUCCESS;
2273 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
2274 mutex_unlock(&ioc->tm_cmds.mutex);
2275
2276 out:
2277 printk(MPT2SAS_INFO_FMT "target reset: %s scmd(%p)\n",
2278 ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
2279 return r;
2280}
2281
2282/**
595bb0bd 2283 * _scsih_host_reset - eh threads main host reset routine
635374e7
EM
2284 * @sdev: scsi device struct
2285 *
2286 * Returns SUCCESS if command aborted else FAILED
2287 */
2288static int
d5d135b3 2289_scsih_host_reset(struct scsi_cmnd *scmd)
635374e7
EM
2290{
2291 struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
2292 int r, retval;
2293
2294 printk(MPT2SAS_INFO_FMT "attempting host reset! scmd(%p)\n",
2295 ioc->name, scmd);
2296 scsi_print_command(scmd);
2297
2298 retval = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
2299 FORCE_BIG_HAMMER);
2300 r = (retval < 0) ? FAILED : SUCCESS;
2301 printk(MPT2SAS_INFO_FMT "host reset: %s scmd(%p)\n",
2302 ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
2303
2304 return r;
2305}
2306
2307/**
2308 * _scsih_fw_event_add - insert and queue up fw_event
2309 * @ioc: per adapter object
2310 * @fw_event: object describing the event
2311 * Context: This function will acquire ioc->fw_event_lock.
2312 *
2313 * This adds the firmware event object into link list, then queues it up to
2314 * be processed from user context.
2315 *
2316 * Return nothing.
2317 */
2318static void
2319_scsih_fw_event_add(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
2320{
2321 unsigned long flags;
2322
2323 if (ioc->firmware_event_thread == NULL)
2324 return;
2325
2326 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2327 list_add_tail(&fw_event->list, &ioc->fw_event_list);
6f92a7a0
EM
2328 INIT_WORK(&fw_event->work, _firmware_event_work);
2329 queue_work(ioc->firmware_event_thread, &fw_event->work);
635374e7
EM
2330 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2331}
2332
2333/**
2334 * _scsih_fw_event_free - delete fw_event
2335 * @ioc: per adapter object
2336 * @fw_event: object describing the event
2337 * Context: This function will acquire ioc->fw_event_lock.
2338 *
2339 * This removes firmware event object from link list, frees associated memory.
2340 *
2341 * Return nothing.
2342 */
2343static void
2344_scsih_fw_event_free(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
2345 *fw_event)
2346{
2347 unsigned long flags;
2348
2349 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2350 list_del(&fw_event->list);
2351 kfree(fw_event->event_data);
2352 kfree(fw_event);
2353 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2354}
2355
2356/**
2357 * _scsih_fw_event_add - requeue an event
2358 * @ioc: per adapter object
2359 * @fw_event: object describing the event
2360 * Context: This function will acquire ioc->fw_event_lock.
2361 *
2362 * Return nothing.
2363 */
2364static void
2365_scsih_fw_event_requeue(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
2366 *fw_event, unsigned long delay)
2367{
2368 unsigned long flags;
2369 if (ioc->firmware_event_thread == NULL)
2370 return;
2371
2372 spin_lock_irqsave(&ioc->fw_event_lock, flags);
6f92a7a0 2373 queue_work(ioc->firmware_event_thread, &fw_event->work);
635374e7
EM
2374 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2375}
2376
2377/**
2378 * _scsih_fw_event_off - turn flag off preventing event handling
2379 * @ioc: per adapter object
2380 *
2381 * Used to prevent handling of firmware events during adapter reset
2382 * driver unload.
2383 *
2384 * Return nothing.
2385 */
2386static void
2387_scsih_fw_event_off(struct MPT2SAS_ADAPTER *ioc)
2388{
2389 unsigned long flags;
2390
2391 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2392 ioc->fw_events_off = 1;
2393 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2394
2395}
2396
2397/**
2398 * _scsih_fw_event_on - turn flag on allowing firmware event handling
2399 * @ioc: per adapter object
2400 *
2401 * Returns nothing.
2402 */
2403static void
2404_scsih_fw_event_on(struct MPT2SAS_ADAPTER *ioc)
2405{
2406 unsigned long flags;
2407
2408 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2409 ioc->fw_events_off = 0;
2410 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2411}
2412
2413/**
2414 * _scsih_ublock_io_device - set the device state to SDEV_RUNNING
2415 * @ioc: per adapter object
2416 * @handle: device handle
2417 *
2418 * During device pull we need to appropiately set the sdev state.
2419 */
2420static void
2421_scsih_ublock_io_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2422{
2423 struct MPT2SAS_DEVICE *sas_device_priv_data;
2424 struct scsi_device *sdev;
2425
2426 shost_for_each_device(sdev, ioc->shost) {
2427 sas_device_priv_data = sdev->hostdata;
2428 if (!sas_device_priv_data)
2429 continue;
2430 if (!sas_device_priv_data->block)
2431 continue;
2432 if (sas_device_priv_data->sas_target->handle == handle) {
2433 dewtprintk(ioc, sdev_printk(KERN_INFO, sdev,
2434 MPT2SAS_INFO_FMT "SDEV_RUNNING: "
2435 "handle(0x%04x)\n", ioc->name, handle));
2436 sas_device_priv_data->block = 0;
34a03bef 2437 scsi_internal_device_unblock(sdev);
635374e7
EM
2438 }
2439 }
2440}
2441
2442/**
2443 * _scsih_block_io_device - set the device state to SDEV_BLOCK
2444 * @ioc: per adapter object
2445 * @handle: device handle
2446 *
2447 * During device pull we need to appropiately set the sdev state.
2448 */
2449static void
2450_scsih_block_io_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2451{
2452 struct MPT2SAS_DEVICE *sas_device_priv_data;
2453 struct scsi_device *sdev;
2454
2455 shost_for_each_device(sdev, ioc->shost) {
2456 sas_device_priv_data = sdev->hostdata;
2457 if (!sas_device_priv_data)
2458 continue;
2459 if (sas_device_priv_data->block)
2460 continue;
2461 if (sas_device_priv_data->sas_target->handle == handle) {
2462 dewtprintk(ioc, sdev_printk(KERN_INFO, sdev,
2463 MPT2SAS_INFO_FMT "SDEV_BLOCK: "
2464 "handle(0x%04x)\n", ioc->name, handle));
2465 sas_device_priv_data->block = 1;
34a03bef 2466 scsi_internal_device_block(sdev);
635374e7
EM
2467 }
2468 }
2469}
2470
2471/**
2472 * _scsih_block_io_to_children_attached_to_ex
2473 * @ioc: per adapter object
2474 * @sas_expander: the sas_device object
2475 *
2476 * This routine set sdev state to SDEV_BLOCK for all devices
2477 * attached to this expander. This function called when expander is
2478 * pulled.
2479 */
2480static void
2481_scsih_block_io_to_children_attached_to_ex(struct MPT2SAS_ADAPTER *ioc,
2482 struct _sas_node *sas_expander)
2483{
2484 struct _sas_port *mpt2sas_port;
2485 struct _sas_device *sas_device;
2486 struct _sas_node *expander_sibling;
2487 unsigned long flags;
2488
2489 if (!sas_expander)
2490 return;
2491
2492 list_for_each_entry(mpt2sas_port,
2493 &sas_expander->sas_port_list, port_list) {
2494 if (mpt2sas_port->remote_identify.device_type ==
2495 SAS_END_DEVICE) {
2496 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2497 sas_device =
2498 mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
2499 mpt2sas_port->remote_identify.sas_address);
2500 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2501 if (!sas_device)
2502 continue;
2503 _scsih_block_io_device(ioc, sas_device->handle);
2504 }
2505 }
2506
2507 list_for_each_entry(mpt2sas_port,
2508 &sas_expander->sas_port_list, port_list) {
2509
2510 if (mpt2sas_port->remote_identify.device_type ==
2511 MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
2512 mpt2sas_port->remote_identify.device_type ==
2513 MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
2514
2515 spin_lock_irqsave(&ioc->sas_node_lock, flags);
2516 expander_sibling =
2517 mpt2sas_scsih_expander_find_by_sas_address(
2518 ioc, mpt2sas_port->remote_identify.sas_address);
2519 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
2520 _scsih_block_io_to_children_attached_to_ex(ioc,
2521 expander_sibling);
2522 }
2523 }
2524}
2525
2526/**
2527 * _scsih_block_io_to_children_attached_directly
2528 * @ioc: per adapter object
2529 * @event_data: topology change event data
2530 *
2531 * This routine set sdev state to SDEV_BLOCK for all devices
2532 * direct attached during device pull.
2533 */
2534static void
2535_scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc,
2536 Mpi2EventDataSasTopologyChangeList_t *event_data)
2537{
2538 int i;
2539 u16 handle;
2540 u16 reason_code;
2541 u8 phy_number;
2542
2543 for (i = 0; i < event_data->NumEntries; i++) {
2544 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
2545 if (!handle)
2546 continue;
2547 phy_number = event_data->StartPhyNum + i;
2548 reason_code = event_data->PHY[i].PhyStatus &
2549 MPI2_EVENT_SAS_TOPO_RC_MASK;
2550 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING)
2551 _scsih_block_io_device(ioc, handle);
2552 }
2553}
2554
77e63ed4
KD
2555/**
2556 * _scsih_tm_tr_send - send task management request
2557 * @ioc: per adapter object
2558 * @handle: device handle
2559 * Context: interrupt time.
2560 *
2561 * This code is to initiate the device removal handshake protocal
2562 * with controller firmware. This function will issue target reset
2563 * using high priority request queue. It will send a sas iounit
2564 * controll request (MPI2_SAS_OP_REMOVE_DEVICE) from this completion.
2565 *
2566 * This is designed to send muliple task management request at the same
2567 * time to the fifo. If the fifo is full, we will append the request,
2568 * and process it in a future completion.
2569 */
2570static void
2571_scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2572{
2573 Mpi2SCSITaskManagementRequest_t *mpi_request;
2574 struct MPT2SAS_TARGET *sas_target_priv_data;
2575 u16 smid;
2576 struct _sas_device *sas_device;
2577 unsigned long flags;
2578 struct _tr_list *delayed_tr;
2579
2580 if (ioc->shost_recovery) {
2581 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
2582 __func__, ioc->name);
2583 return;
2584 }
2585
2586 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2587 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
77e63ed4
KD
2588 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2589
2590 /* skip is hidden raid component */
a28eb222 2591 if (sas_device && sas_device->hidden_raid_component)
77e63ed4
KD
2592 return;
2593
2594 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
2595 if (!smid) {
2596 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
2597 if (!delayed_tr)
2598 return;
2599 INIT_LIST_HEAD(&delayed_tr->list);
2600 delayed_tr->handle = handle;
2601 delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL;
2602 list_add_tail(&delayed_tr->list,
2603 &ioc->delayed_tr_list);
a28eb222 2604 if (sas_device && sas_device->starget) {
77e63ed4
KD
2605 dewtprintk(ioc, starget_printk(KERN_INFO,
2606 sas_device->starget, "DELAYED:tr:handle(0x%04x), "
a28eb222
KD
2607 "(open)\n", handle));
2608 } else {
2609 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2610 "DELAYED:tr:handle(0x%04x), (open)\n",
2611 ioc->name, handle));
2612 }
77e63ed4
KD
2613 return;
2614 }
2615
a28eb222
KD
2616 if (sas_device) {
2617 sas_device->state |= MPTSAS_STATE_TR_SEND;
2618 sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
2619 if (sas_device->starget && sas_device->starget->hostdata) {
2620 sas_target_priv_data = sas_device->starget->hostdata;
2621 sas_target_priv_data->tm_busy = 1;
2622 dewtprintk(ioc, starget_printk(KERN_INFO,
2623 sas_device->starget, "tr:handle(0x%04x), (open)\n",
2624 handle));
2625 }
2626 } else {
2627 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2628 "tr:handle(0x%04x), (open)\n", ioc->name, handle));
77e63ed4
KD
2629 }
2630
2631 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2632 memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
2633 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
2634 mpi_request->DevHandle = cpu_to_le16(handle);
2635 mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
77e63ed4
KD
2636 mpt2sas_base_put_smid_hi_priority(ioc, smid);
2637}
2638
2639
2640
2641/**
2642 * _scsih_sas_control_complete - completion routine
2643 * @ioc: per adapter object
2644 * @smid: system request message index
2645 * @msix_index: MSIX table index supplied by the OS
2646 * @reply: reply message frame(lower 32bit addr)
2647 * Context: interrupt time.
2648 *
2649 * This is the sas iounit controll completion routine.
2650 * This code is part of the code to initiate the device removal
2651 * handshake protocal with controller firmware.
2652 *
2653 * Return 1 meaning mf should be freed from _base_interrupt
2654 * 0 means the mf is freed from this function.
2655 */
2656static u8
2657_scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
2658 u8 msix_index, u32 reply)
2659{
2660 unsigned long flags;
2661 u16 handle;
2662 struct _sas_device *sas_device;
2663 Mpi2SasIoUnitControlReply_t *mpi_reply =
2664 mpt2sas_base_get_reply_virt_addr(ioc, reply);
2665
2666 handle = le16_to_cpu(mpi_reply->DevHandle);
2667
2668 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2669 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
77e63ed4
KD
2670 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2671
a28eb222
KD
2672 if (sas_device) {
2673 sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
2674 if (sas_device->starget)
2675 dewtprintk(ioc, starget_printk(KERN_INFO,
2676 sas_device->starget,
2677 "sc_complete:handle(0x%04x), "
2678 "ioc_status(0x%04x), loginfo(0x%08x)\n",
2679 handle, le16_to_cpu(mpi_reply->IOCStatus),
2680 le32_to_cpu(mpi_reply->IOCLogInfo)));
2681 } else {
2682 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
77e63ed4
KD
2683 "sc_complete:handle(0x%04x), "
2684 "ioc_status(0x%04x), loginfo(0x%08x)\n",
a28eb222 2685 ioc->name, handle, le16_to_cpu(mpi_reply->IOCStatus),
77e63ed4 2686 le32_to_cpu(mpi_reply->IOCLogInfo)));
a28eb222
KD
2687 }
2688
77e63ed4
KD
2689 return 1;
2690}
2691
2692/**
2693 * _scsih_tm_tr_complete -
2694 * @ioc: per adapter object
2695 * @smid: system request message index
2696 * @msix_index: MSIX table index supplied by the OS
2697 * @reply: reply message frame(lower 32bit addr)
2698 * Context: interrupt time.
2699 *
2700 * This is the target reset completion routine.
2701 * This code is part of the code to initiate the device removal
2702 * handshake protocal with controller firmware.
2703 * It will send a sas iounit controll request (MPI2_SAS_OP_REMOVE_DEVICE)
2704 *
2705 * Return 1 meaning mf should be freed from _base_interrupt
2706 * 0 means the mf is freed from this function.
2707 */
2708static u8
2709_scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2710 u32 reply)
2711{
2712 unsigned long flags;
2713 u16 handle;
2714 struct _sas_device *sas_device;
2715 Mpi2SCSITaskManagementReply_t *mpi_reply =
2716 mpt2sas_base_get_reply_virt_addr(ioc, reply);
2717 Mpi2SasIoUnitControlRequest_t *mpi_request;
2718 u16 smid_sas_ctrl;
2719 struct MPT2SAS_TARGET *sas_target_priv_data;
2720 struct _tr_list *delayed_tr;
2721 u8 rc;
2722
2723 handle = le16_to_cpu(mpi_reply->DevHandle);
2724 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2725 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
77e63ed4
KD
2726 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2727
a28eb222
KD
2728 if (sas_device) {
2729 sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
2730 if (sas_device->starget) {
2731 dewtprintk(ioc, starget_printk(KERN_INFO,
2732 sas_device->starget, "tr_complete:handle(0x%04x), "
2733 "(%s) ioc_status(0x%04x), loginfo(0x%08x), "
2734 "completed(%d)\n", sas_device->handle,
2735 (sas_device->state & MPT2SAS_REQ_SAS_CNTRL) ?
2736 "open" : "active",
2737 le16_to_cpu(mpi_reply->IOCStatus),
2738 le32_to_cpu(mpi_reply->IOCLogInfo),
2739 le32_to_cpu(mpi_reply->TerminationCount)));
2740 if (sas_device->starget->hostdata) {
2741 sas_target_priv_data =
2742 sas_device->starget->hostdata;
2743 sas_target_priv_data->tm_busy = 0;
2744 }
2745 }
2746 } else {
2747 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2748 "tr_complete:handle(0x%04x), (open) ioc_status(0x%04x), "
2749 "loginfo(0x%08x), completed(%d)\n", ioc->name,
2750 handle, le16_to_cpu(mpi_reply->IOCStatus),
77e63ed4
KD
2751 le32_to_cpu(mpi_reply->IOCLogInfo),
2752 le32_to_cpu(mpi_reply->TerminationCount)));
77e63ed4
KD
2753 }
2754
2755 if (!list_empty(&ioc->delayed_tr_list)) {
2756 delayed_tr = list_entry(ioc->delayed_tr_list.next,
2757 struct _tr_list, list);
2758 mpt2sas_base_free_smid(ioc, smid);
2759 if (delayed_tr->state & MPT2SAS_REQ_SAS_CNTRL)
2760 _scsih_tm_tr_send(ioc, delayed_tr->handle);
2761 list_del(&delayed_tr->list);
2762 kfree(delayed_tr);
2763 rc = 0; /* tells base_interrupt not to free mf */
2764 } else
2765 rc = 1;
2766
a28eb222 2767 if (sas_device && !(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
77e63ed4
KD
2768 return rc;
2769
2770 if (ioc->shost_recovery) {
2771 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
2772 __func__, ioc->name);
2773 return rc;
2774 }
2775
2776 smid_sas_ctrl = mpt2sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx);
2777 if (!smid_sas_ctrl) {
2778 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
2779 ioc->name, __func__);
2780 return rc;
2781 }
2782
a28eb222
KD
2783 if (sas_device)
2784 sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
2785
77e63ed4
KD
2786 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl);
2787 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
2788 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
2789 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
2790 mpi_request->DevHandle = mpi_reply->DevHandle;
77e63ed4
KD
2791 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl);
2792 return rc;
2793}
2794
635374e7
EM
2795/**
2796 * _scsih_check_topo_delete_events - sanity check on topo events
2797 * @ioc: per adapter object
2798 * @event_data: the event data payload
2799 *
2800 * This routine added to better handle cable breaker.
2801 *
2802 * This handles the case where driver recieves multiple expander
2803 * add and delete events in a single shot. When there is a delete event
2804 * the routine will void any pending add events waiting in the event queue.
2805 *
2806 * Return nothing.
2807 */
2808static void
2809_scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc,
2810 Mpi2EventDataSasTopologyChangeList_t *event_data)
2811{
2812 struct fw_event_work *fw_event;
2813 Mpi2EventDataSasTopologyChangeList_t *local_event_data;
2814 u16 expander_handle;
2815 struct _sas_node *sas_expander;
2816 unsigned long flags;
77e63ed4
KD
2817 int i, reason_code;
2818 u16 handle;
2819
2820 for (i = 0 ; i < event_data->NumEntries; i++) {
2821 if (event_data->PHY[i].PhyStatus &
2822 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT)
2823 continue;
2824 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
2825 if (!handle)
2826 continue;
2827 reason_code = event_data->PHY[i].PhyStatus &
2828 MPI2_EVENT_SAS_TOPO_RC_MASK;
2829 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)
2830 _scsih_tm_tr_send(ioc, handle);
2831 }
635374e7
EM
2832
2833 expander_handle = le16_to_cpu(event_data->ExpanderDevHandle);
2834 if (expander_handle < ioc->sas_hba.num_phys) {
2835 _scsih_block_io_to_children_attached_directly(ioc, event_data);
2836 return;
2837 }
2838
2839 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING
2840 || event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING) {
2841 spin_lock_irqsave(&ioc->sas_node_lock, flags);
2842 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
2843 expander_handle);
2844 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
2845 _scsih_block_io_to_children_attached_to_ex(ioc, sas_expander);
2846 } else if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_RESPONDING)
2847 _scsih_block_io_to_children_attached_directly(ioc, event_data);
2848
2849 if (event_data->ExpStatus != MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING)
2850 return;
2851
2852 /* mark ignore flag for pending events */
2853 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2854 list_for_each_entry(fw_event, &ioc->fw_event_list, list) {
2855 if (fw_event->event != MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||
2856 fw_event->ignore)
2857 continue;
2858 local_event_data = fw_event->event_data;
2859 if (local_event_data->ExpStatus ==
2860 MPI2_EVENT_SAS_TOPO_ES_ADDED ||
2861 local_event_data->ExpStatus ==
2862 MPI2_EVENT_SAS_TOPO_ES_RESPONDING) {
2863 if (le16_to_cpu(local_event_data->ExpanderDevHandle) ==
2864 expander_handle) {
2865 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT
2866 "setting ignoring flag\n", ioc->name));
2867 fw_event->ignore = 1;
2868 }
2869 }
2870 }
2871 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2872}
2873
635374e7
EM
2874/**
2875 * _scsih_flush_running_cmds - completing outstanding commands.
2876 * @ioc: per adapter object
2877 *
2878 * The flushing out of all pending scmd commands following host reset,
2879 * where all IO is dropped to the floor.
2880 *
2881 * Return nothing.
2882 */
2883static void
2884_scsih_flush_running_cmds(struct MPT2SAS_ADAPTER *ioc)
2885{
2886 struct scsi_cmnd *scmd;
2887 u16 smid;
2888 u16 count = 0;
2889
595bb0bd
KD
2890 for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
2891 scmd = _scsih_scsi_lookup_get(ioc, smid);
635374e7
EM
2892 if (!scmd)
2893 continue;
2894 count++;
2895 mpt2sas_base_free_smid(ioc, smid);
2896 scsi_dma_unmap(scmd);
2897 scmd->result = DID_RESET << 16;
2898 scmd->scsi_done(scmd);
2899 }
2900 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "completing %d cmds\n",
2901 ioc->name, count));
2902}
2903
3c621b3e
EM
2904/**
2905 * _scsih_setup_eedp - setup MPI request for EEDP transfer
2906 * @scmd: pointer to scsi command object
2907 * @mpi_request: pointer to the SCSI_IO reqest message frame
2908 *
2909 * Supporting protection 1 and 3.
2910 *
2911 * Returns nothing
2912 */
2913static void
2914_scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request)
2915{
2916 u16 eedp_flags;
2917 unsigned char prot_op = scsi_get_prot_op(scmd);
2918 unsigned char prot_type = scsi_get_prot_type(scmd);
2919
2920 if (prot_type == SCSI_PROT_DIF_TYPE0 ||
2921 prot_type == SCSI_PROT_DIF_TYPE2 ||
2922 prot_op == SCSI_PROT_NORMAL)
2923 return;
2924
2925 if (prot_op == SCSI_PROT_READ_STRIP)
2926 eedp_flags = MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP;
2927 else if (prot_op == SCSI_PROT_WRITE_INSERT)
2928 eedp_flags = MPI2_SCSIIO_EEDPFLAGS_INSERT_OP;
2929 else
2930 return;
2931
3c621b3e
EM
2932 switch (prot_type) {
2933 case SCSI_PROT_DIF_TYPE1:
2934
2935 /*
2936 * enable ref/guard checking
2937 * auto increment ref tag
2938 */
463217bf 2939 eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
3c621b3e
EM
2940 MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
2941 MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
2942 mpi_request->CDB.EEDP32.PrimaryReferenceTag =
2943 cpu_to_be32(scsi_get_lba(scmd));
2944
2945 break;
2946
2947 case SCSI_PROT_DIF_TYPE3:
2948
2949 /*
2950 * enable guard checking
2951 */
463217bf 2952 eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
3c621b3e
EM
2953 break;
2954 }
463217bf
KD
2955 mpi_request->EEDPBlockSize = cpu_to_le32(scmd->device->sector_size);
2956 mpi_request->EEDPFlags = cpu_to_le16(eedp_flags);
3c621b3e
EM
2957}
2958
2959/**
2960 * _scsih_eedp_error_handling - return sense code for EEDP errors
2961 * @scmd: pointer to scsi command object
2962 * @ioc_status: ioc status
2963 *
2964 * Returns nothing
2965 */
2966static void
2967_scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
2968{
2969 u8 ascq;
2970 u8 sk;
2971 u8 host_byte;
2972
2973 switch (ioc_status) {
2974 case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
2975 ascq = 0x01;
2976 break;
2977 case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
2978 ascq = 0x02;
2979 break;
2980 case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR:
2981 ascq = 0x03;
2982 break;
2983 default:
2984 ascq = 0x00;
2985 break;
2986 }
2987
2988 if (scmd->sc_data_direction == DMA_TO_DEVICE) {
2989 sk = ILLEGAL_REQUEST;
2990 host_byte = DID_ABORT;
2991 } else {
2992 sk = ABORTED_COMMAND;
2993 host_byte = DID_OK;
2994 }
2995
2996 scsi_build_sense_buffer(0, scmd->sense_buffer, sk, 0x10, ascq);
2997 scmd->result = DRIVER_SENSE << 24 | (host_byte << 16) |
2998 SAM_STAT_CHECK_CONDITION;
2999}
3000
635374e7 3001/**
d5d135b3 3002 * _scsih_qcmd - main scsi request entry point
635374e7
EM
3003 * @scmd: pointer to scsi command object
3004 * @done: function pointer to be invoked on completion
3005 *
3006 * The callback index is set inside `ioc->scsi_io_cb_idx`.
3007 *
3008 * Returns 0 on success. If there's a failure, return either:
3009 * SCSI_MLQUEUE_DEVICE_BUSY if the device queue is full, or
3010 * SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full
3011 */
3012static int
d5d135b3 3013_scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
635374e7
EM
3014{
3015 struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
3016 struct MPT2SAS_DEVICE *sas_device_priv_data;
3017 struct MPT2SAS_TARGET *sas_target_priv_data;
3018 Mpi2SCSIIORequest_t *mpi_request;
3019 u32 mpi_control;
3020 u16 smid;
635374e7
EM
3021
3022 scmd->scsi_done = done;
3023 sas_device_priv_data = scmd->device->hostdata;
3024 if (!sas_device_priv_data) {
3025 scmd->result = DID_NO_CONNECT << 16;
3026 scmd->scsi_done(scmd);
3027 return 0;
3028 }
3029
3030 sas_target_priv_data = sas_device_priv_data->sas_target;
3031 if (!sas_target_priv_data || sas_target_priv_data->handle ==
3032 MPT2SAS_INVALID_DEVICE_HANDLE || sas_target_priv_data->deleted) {
3033 scmd->result = DID_NO_CONNECT << 16;
3034 scmd->scsi_done(scmd);
3035 return 0;
3036 }
3037
3038 /* see if we are busy with task managment stuff */
e4e7c7ed 3039 if (sas_device_priv_data->block || sas_target_priv_data->tm_busy)
155dd4c7
KD
3040 return SCSI_MLQUEUE_DEVICE_BUSY;
3041 else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
635374e7 3042 return SCSI_MLQUEUE_HOST_BUSY;
635374e7
EM
3043
3044 if (scmd->sc_data_direction == DMA_FROM_DEVICE)
3045 mpi_control = MPI2_SCSIIO_CONTROL_READ;
3046 else if (scmd->sc_data_direction == DMA_TO_DEVICE)
3047 mpi_control = MPI2_SCSIIO_CONTROL_WRITE;
3048 else
3049 mpi_control = MPI2_SCSIIO_CONTROL_NODATATRANSFER;
3050
3051 /* set tags */
3052 if (!(sas_device_priv_data->flags & MPT_DEVICE_FLAGS_INIT)) {
3053 if (scmd->device->tagged_supported) {
3054 if (scmd->device->ordered_tags)
3055 mpi_control |= MPI2_SCSIIO_CONTROL_ORDEREDQ;
3056 else
3057 mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
3058 } else
3059/* MPI Revision I (UNIT = 0xA) - removed MPI2_SCSIIO_CONTROL_UNTAGGED */
3060/* mpi_control |= MPI2_SCSIIO_CONTROL_UNTAGGED;
3061 */
3062 mpi_control |= (0x500);
3063
3064 } else
3065 mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
3ed21525
KD
3066 /* Make sure Device is not raid volume */
3067 if (!_scsih_is_raid(&scmd->device->sdev_gendev) &&
3068 sas_is_tlr_enabled(scmd->device))
635374e7
EM
3069 mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
3070
595bb0bd 3071 smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd);
635374e7
EM
3072 if (!smid) {
3073 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
3074 ioc->name, __func__);
3075 goto out;
3076 }
3077 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
3078 memset(mpi_request, 0, sizeof(Mpi2SCSIIORequest_t));
3c621b3e 3079 _scsih_setup_eedp(scmd, mpi_request);
635374e7
EM
3080 mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
3081 if (sas_device_priv_data->sas_target->flags &
3082 MPT_TARGET_FLAGS_RAID_COMPONENT)
3083 mpi_request->Function = MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3084 else
3085 mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
3086 mpi_request->DevHandle =
3087 cpu_to_le16(sas_device_priv_data->sas_target->handle);
3088 mpi_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
3089 mpi_request->Control = cpu_to_le32(mpi_control);
3090 mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len);
3091 mpi_request->MsgFlags = MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR;
3092 mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
3093 mpi_request->SenseBufferLowAddress =
ec9472c7 3094 mpt2sas_base_get_sense_buffer_dma(ioc, smid);
635374e7
EM
3095 mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4;
3096 mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI +
3097 MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR);
7b936b02
KD
3098 mpi_request->VF_ID = 0; /* TODO */
3099 mpi_request->VP_ID = 0;
635374e7
EM
3100 int_to_scsilun(sas_device_priv_data->lun, (struct scsi_lun *)
3101 mpi_request->LUN);
3102 memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
3103
3104 if (!mpi_request->DataLength) {
3105 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request->SGL);
3106 } else {
3107 if (_scsih_build_scatter_gather(ioc, scmd, smid)) {
3108 mpt2sas_base_free_smid(ioc, smid);
3109 goto out;
3110 }
3111 }
3112
7b936b02 3113 mpt2sas_base_put_smid_scsi_io(ioc, smid,
635374e7
EM
3114 sas_device_priv_data->sas_target->handle);
3115 return 0;
3116
3117 out:
3118 return SCSI_MLQUEUE_HOST_BUSY;
3119}
3120
3121/**
3122 * _scsih_normalize_sense - normalize descriptor and fixed format sense data
3123 * @sense_buffer: sense data returned by target
3124 * @data: normalized skey/asc/ascq
3125 *
3126 * Return nothing.
3127 */
3128static void
3129_scsih_normalize_sense(char *sense_buffer, struct sense_info *data)
3130{
3131 if ((sense_buffer[0] & 0x7F) >= 0x72) {
3132 /* descriptor format */
3133 data->skey = sense_buffer[1] & 0x0F;
3134 data->asc = sense_buffer[2];
3135 data->ascq = sense_buffer[3];
3136 } else {
3137 /* fixed format */
3138 data->skey = sense_buffer[2] & 0x0F;
3139 data->asc = sense_buffer[12];
3140 data->ascq = sense_buffer[13];
3141 }
3142}
3143
3144#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
3145/**
af901ca1 3146 * _scsih_scsi_ioc_info - translated non-successfull SCSI_IO request
635374e7
EM
3147 * @ioc: per adapter object
3148 * @scmd: pointer to scsi command object
3149 * @mpi_reply: reply mf payload returned from firmware
3150 *
3151 * scsi_status - SCSI Status code returned from target device
3152 * scsi_state - state info associated with SCSI_IO determined by ioc
3153 * ioc_status - ioc supplied status info
3154 *
3155 * Return nothing.
3156 */
3157static void
3158_scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
3159 Mpi2SCSIIOReply_t *mpi_reply, u16 smid)
3160{
3161 u32 response_info;
3162 u8 *response_bytes;
3163 u16 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) &
3164 MPI2_IOCSTATUS_MASK;
3165 u8 scsi_state = mpi_reply->SCSIState;
3166 u8 scsi_status = mpi_reply->SCSIStatus;
3167 char *desc_ioc_state = NULL;
3168 char *desc_scsi_status = NULL;
3169 char *desc_scsi_state = ioc->tmp_string;
be9e8cd7
KD
3170 u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
3171
3172 if (log_info == 0x31170000)
3173 return;
635374e7
EM
3174
3175 switch (ioc_status) {
3176 case MPI2_IOCSTATUS_SUCCESS:
3177 desc_ioc_state = "success";
3178 break;
3179 case MPI2_IOCSTATUS_INVALID_FUNCTION:
3180 desc_ioc_state = "invalid function";
3181 break;
3182 case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
3183 desc_ioc_state = "scsi recovered error";
3184 break;
3185 case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE:
3186 desc_ioc_state = "scsi invalid dev handle";
3187 break;
3188 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
3189 desc_ioc_state = "scsi device not there";
3190 break;
3191 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
3192 desc_ioc_state = "scsi data overrun";
3193 break;
3194 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
3195 desc_ioc_state = "scsi data underrun";
3196 break;
3197 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
3198 desc_ioc_state = "scsi io data error";
3199 break;
3200 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
3201 desc_ioc_state = "scsi protocol error";
3202 break;
3203 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
3204 desc_ioc_state = "scsi task terminated";
3205 break;
3206 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
3207 desc_ioc_state = "scsi residual mismatch";
3208 break;
3209 case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
3210 desc_ioc_state = "scsi task mgmt failed";
3211 break;
3212 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
3213 desc_ioc_state = "scsi ioc terminated";
3214 break;
3215 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
3216 desc_ioc_state = "scsi ext terminated";
3217 break;
3c621b3e
EM
3218 case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
3219 desc_ioc_state = "eedp guard error";
3220 break;
3221 case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR:
3222 desc_ioc_state = "eedp ref tag error";
3223 break;
3224 case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
3225 desc_ioc_state = "eedp app tag error";
3226 break;
635374e7
EM
3227 default:
3228 desc_ioc_state = "unknown";
3229 break;
3230 }
3231
3232 switch (scsi_status) {
3233 case MPI2_SCSI_STATUS_GOOD:
3234 desc_scsi_status = "good";
3235 break;
3236 case MPI2_SCSI_STATUS_CHECK_CONDITION:
3237 desc_scsi_status = "check condition";
3238 break;
3239 case MPI2_SCSI_STATUS_CONDITION_MET:
3240 desc_scsi_status = "condition met";
3241 break;
3242 case MPI2_SCSI_STATUS_BUSY:
3243 desc_scsi_status = "busy";
3244 break;
3245 case MPI2_SCSI_STATUS_INTERMEDIATE:
3246 desc_scsi_status = "intermediate";
3247 break;
3248 case MPI2_SCSI_STATUS_INTERMEDIATE_CONDMET:
3249 desc_scsi_status = "intermediate condmet";
3250 break;
3251 case MPI2_SCSI_STATUS_RESERVATION_CONFLICT:
3252 desc_scsi_status = "reservation conflict";
3253 break;
3254 case MPI2_SCSI_STATUS_COMMAND_TERMINATED:
3255 desc_scsi_status = "command terminated";
3256 break;
3257 case MPI2_SCSI_STATUS_TASK_SET_FULL:
3258 desc_scsi_status = "task set full";
3259 break;
3260 case MPI2_SCSI_STATUS_ACA_ACTIVE:
3261 desc_scsi_status = "aca active";
3262 break;
3263 case MPI2_SCSI_STATUS_TASK_ABORTED:
3264 desc_scsi_status = "task aborted";
3265 break;
3266 default:
3267 desc_scsi_status = "unknown";
3268 break;
3269 }
3270
3271 desc_scsi_state[0] = '\0';
3272 if (!scsi_state)
3273 desc_scsi_state = " ";
3274 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
3275 strcat(desc_scsi_state, "response info ");
3276 if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
3277 strcat(desc_scsi_state, "state terminated ");
3278 if (scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS)
3279 strcat(desc_scsi_state, "no status ");
3280 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_FAILED)
3281 strcat(desc_scsi_state, "autosense failed ");
3282 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID)
3283 strcat(desc_scsi_state, "autosense valid ");
3284
3285 scsi_print_command(scmd);
3286 printk(MPT2SAS_WARN_FMT "\tdev handle(0x%04x), "
3287 "ioc_status(%s)(0x%04x), smid(%d)\n", ioc->name,
3288 le16_to_cpu(mpi_reply->DevHandle), desc_ioc_state,
3289 ioc_status, smid);
3290 printk(MPT2SAS_WARN_FMT "\trequest_len(%d), underflow(%d), "
3291 "resid(%d)\n", ioc->name, scsi_bufflen(scmd), scmd->underflow,
3292 scsi_get_resid(scmd));
3293 printk(MPT2SAS_WARN_FMT "\ttag(%d), transfer_count(%d), "
3294 "sc->result(0x%08x)\n", ioc->name, le16_to_cpu(mpi_reply->TaskTag),
3295 le32_to_cpu(mpi_reply->TransferCount), scmd->result);
3296 printk(MPT2SAS_WARN_FMT "\tscsi_status(%s)(0x%02x), "
3297 "scsi_state(%s)(0x%02x)\n", ioc->name, desc_scsi_status,
3298 scsi_status, desc_scsi_state, scsi_state);
3299
3300 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
3301 struct sense_info data;
3302 _scsih_normalize_sense(scmd->sense_buffer, &data);
3303 printk(MPT2SAS_WARN_FMT "\t[sense_key,asc,ascq]: "
3304 "[0x%02x,0x%02x,0x%02x]\n", ioc->name, data.skey,
3305 data.asc, data.ascq);
3306 }
3307
3308 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
3309 response_info = le32_to_cpu(mpi_reply->ResponseInfo);
3310 response_bytes = (u8 *)&response_info;
9982f594 3311 _scsih_response_code(ioc, response_bytes[0]);
635374e7
EM
3312 }
3313}
3314#endif
3315
3316/**
3317 * _scsih_smart_predicted_fault - illuminate Fault LED
3318 * @ioc: per adapter object
3319 * @handle: device handle
3320 *
3321 * Return nothing.
3322 */
3323static void
3324_scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3325{
3326 Mpi2SepReply_t mpi_reply;
3327 Mpi2SepRequest_t mpi_request;
3328 struct scsi_target *starget;
3329 struct MPT2SAS_TARGET *sas_target_priv_data;
3330 Mpi2EventNotificationReply_t *event_reply;
3331 Mpi2EventDataSasDeviceStatusChange_t *event_data;
3332 struct _sas_device *sas_device;
3333 ssize_t sz;
3334 unsigned long flags;
3335
3336 /* only handle non-raid devices */
3337 spin_lock_irqsave(&ioc->sas_device_lock, flags);
3338 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
3339 if (!sas_device) {
3340 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3341 return;
3342 }
3343 starget = sas_device->starget;
3344 sas_target_priv_data = starget->hostdata;
3345
3346 if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) ||
3347 ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))) {
3348 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3349 return;
3350 }
3351 starget_printk(KERN_WARNING, starget, "predicted fault\n");
3352 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3353
3354 if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) {
3355 memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t));
3356 mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
3357 mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS;
3358 mpi_request.SlotStatus =
3359 MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT;
3360 mpi_request.DevHandle = cpu_to_le16(handle);
3361 mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS;
3362 if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply,
3363 &mpi_request)) != 0) {
3364 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3365 ioc->name, __FILE__, __LINE__, __func__);
3366 return;
3367 }
3368
3369 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) {
3370 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
3371 "enclosure_processor: ioc_status (0x%04x), "
3372 "loginfo(0x%08x)\n", ioc->name,
3373 le16_to_cpu(mpi_reply.IOCStatus),
3374 le32_to_cpu(mpi_reply.IOCLogInfo)));
3375 return;
3376 }
3377 }
3378
3379 /* insert into event log */
3380 sz = offsetof(Mpi2EventNotificationReply_t, EventData) +
3381 sizeof(Mpi2EventDataSasDeviceStatusChange_t);
3382 event_reply = kzalloc(sz, GFP_KERNEL);
3383 if (!event_reply) {
3384 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3385 ioc->name, __FILE__, __LINE__, __func__);
3386 return;
3387 }
3388
3389 event_reply->Function = MPI2_FUNCTION_EVENT_NOTIFICATION;
3390 event_reply->Event =
3391 cpu_to_le16(MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE);
3392 event_reply->MsgLength = sz/4;
3393 event_reply->EventDataLength =
3394 cpu_to_le16(sizeof(Mpi2EventDataSasDeviceStatusChange_t)/4);
3395 event_data = (Mpi2EventDataSasDeviceStatusChange_t *)
3396 event_reply->EventData;
3397 event_data->ReasonCode = MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA;
3398 event_data->ASC = 0x5D;
3399 event_data->DevHandle = cpu_to_le16(handle);
3400 event_data->SASAddress = cpu_to_le64(sas_target_priv_data->sas_address);
3401 mpt2sas_ctl_add_to_event_log(ioc, event_reply);
3402 kfree(event_reply);
3403}
3404
3405/**
d5d135b3 3406 * _scsih_io_done - scsi request callback
635374e7
EM
3407 * @ioc: per adapter object
3408 * @smid: system request message index
7b936b02 3409 * @msix_index: MSIX table index supplied by the OS
635374e7
EM
3410 * @reply: reply message frame(lower 32bit addr)
3411 *
77e63ed4 3412 * Callback handler when using _scsih_qcmd.
635374e7 3413 *
77e63ed4
KD
3414 * Return 1 meaning mf should be freed from _base_interrupt
3415 * 0 means the mf is freed from this function.
635374e7 3416 */
77e63ed4 3417static u8
7b936b02 3418_scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
635374e7
EM
3419{
3420 Mpi2SCSIIORequest_t *mpi_request;
3421 Mpi2SCSIIOReply_t *mpi_reply;
3422 struct scsi_cmnd *scmd;
3423 u16 ioc_status;
3424 u32 xfer_cnt;
3425 u8 scsi_state;
3426 u8 scsi_status;
3427 u32 log_info;
3428 struct MPT2SAS_DEVICE *sas_device_priv_data;
9982f594 3429 u32 response_code = 0;
635374e7
EM
3430
3431 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
595bb0bd 3432 scmd = _scsih_scsi_lookup_get(ioc, smid);
635374e7 3433 if (scmd == NULL)
77e63ed4 3434 return 1;
635374e7
EM
3435
3436 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
3437
3438 if (mpi_reply == NULL) {
3439 scmd->result = DID_OK << 16;
3440 goto out;
3441 }
3442
3443 sas_device_priv_data = scmd->device->hostdata;
3444 if (!sas_device_priv_data || !sas_device_priv_data->sas_target ||
3445 sas_device_priv_data->sas_target->deleted) {
3446 scmd->result = DID_NO_CONNECT << 16;
3447 goto out;
3448 }
3449
3450 /* turning off TLR */
9982f594
KD
3451 scsi_state = mpi_reply->SCSIState;
3452 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
3453 response_code =
3454 le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
635374e7
EM
3455 if (!sas_device_priv_data->tlr_snoop_check) {
3456 sas_device_priv_data->tlr_snoop_check++;
3ed21525
KD
3457 if (!_scsih_is_raid(&scmd->device->sdev_gendev) &&
3458 sas_is_tlr_enabled(scmd->device) &&
84f0b04a
KD
3459 response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) {
3460 sas_disable_tlr(scmd->device);
3461 sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n");
3462 }
635374e7
EM
3463 }
3464
3465 xfer_cnt = le32_to_cpu(mpi_reply->TransferCount);
3466 scsi_set_resid(scmd, scsi_bufflen(scmd) - xfer_cnt);
3467 ioc_status = le16_to_cpu(mpi_reply->IOCStatus);
3468 if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
3469 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
3470 else
3471 log_info = 0;
3472 ioc_status &= MPI2_IOCSTATUS_MASK;
635374e7
EM
3473 scsi_status = mpi_reply->SCSIStatus;
3474
3475 if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
3476 (scsi_status == MPI2_SCSI_STATUS_BUSY ||
3477 scsi_status == MPI2_SCSI_STATUS_RESERVATION_CONFLICT ||
3478 scsi_status == MPI2_SCSI_STATUS_TASK_SET_FULL)) {
3479 ioc_status = MPI2_IOCSTATUS_SUCCESS;
3480 }
3481
3482 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
3483 struct sense_info data;
3484 const void *sense_data = mpt2sas_base_get_sense_buffer(ioc,
3485 smid);
0d04df9b 3486 u32 sz = min_t(u32, SCSI_SENSE_BUFFERSIZE,
635374e7 3487 le32_to_cpu(mpi_reply->SenseCount));
0d04df9b 3488 memcpy(scmd->sense_buffer, sense_data, sz);
635374e7
EM
3489 _scsih_normalize_sense(scmd->sense_buffer, &data);
3490 /* failure prediction threshold exceeded */
3491 if (data.asc == 0x5D)
3492 _scsih_smart_predicted_fault(ioc,
3493 le16_to_cpu(mpi_reply->DevHandle));
3494 }
3495
3496 switch (ioc_status) {
3497 case MPI2_IOCSTATUS_BUSY:
3498 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
3499 scmd->result = SAM_STAT_BUSY;
3500 break;
3501
3502 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
3503 scmd->result = DID_NO_CONNECT << 16;
3504 break;
3505
3506 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
3507 if (sas_device_priv_data->block) {
e4e7c7ed
KD
3508 scmd->result = DID_TRANSPORT_DISRUPTED << 16;
3509 goto out;
635374e7 3510 }
635374e7
EM
3511 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
3512 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
3513 scmd->result = DID_RESET << 16;
3514 break;
3515
3516 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
3517 if ((xfer_cnt == 0) || (scmd->underflow > xfer_cnt))
3518 scmd->result = DID_SOFT_ERROR << 16;
3519 else
3520 scmd->result = (DID_OK << 16) | scsi_status;
3521 break;
3522
3523 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
3524 scmd->result = (DID_OK << 16) | scsi_status;
3525
3526 if ((scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID))
3527 break;
3528
3529 if (xfer_cnt < scmd->underflow) {
3530 if (scsi_status == SAM_STAT_BUSY)
3531 scmd->result = SAM_STAT_BUSY;
3532 else
3533 scmd->result = DID_SOFT_ERROR << 16;
3534 } else if (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED |
3535 MPI2_SCSI_STATE_NO_SCSI_STATUS))
3536 scmd->result = DID_SOFT_ERROR << 16;
3537 else if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
3538 scmd->result = DID_RESET << 16;
3539 else if (!xfer_cnt && scmd->cmnd[0] == REPORT_LUNS) {
3540 mpi_reply->SCSIState = MPI2_SCSI_STATE_AUTOSENSE_VALID;
3541 mpi_reply->SCSIStatus = SAM_STAT_CHECK_CONDITION;
3542 scmd->result = (DRIVER_SENSE << 24) |
3543 SAM_STAT_CHECK_CONDITION;
3544 scmd->sense_buffer[0] = 0x70;
3545 scmd->sense_buffer[2] = ILLEGAL_REQUEST;
3546 scmd->sense_buffer[12] = 0x20;
3547 scmd->sense_buffer[13] = 0;
3548 }
3549 break;
3550
3551 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
3552 scsi_set_resid(scmd, 0);
3553 case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
3554 case MPI2_IOCSTATUS_SUCCESS:
3555 scmd->result = (DID_OK << 16) | scsi_status;
9982f594
KD
3556 if (response_code ==
3557 MPI2_SCSITASKMGMT_RSP_INVALID_FRAME ||
3558 (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED |
3559 MPI2_SCSI_STATE_NO_SCSI_STATUS)))
635374e7
EM
3560 scmd->result = DID_SOFT_ERROR << 16;
3561 else if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
3562 scmd->result = DID_RESET << 16;
3563 break;
3564
3c621b3e
EM
3565 case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
3566 case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR:
3567 case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
3568 _scsih_eedp_error_handling(scmd, ioc_status);
3569 break;
635374e7
EM
3570 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
3571 case MPI2_IOCSTATUS_INVALID_FUNCTION:
3572 case MPI2_IOCSTATUS_INVALID_SGL:
3573 case MPI2_IOCSTATUS_INTERNAL_ERROR:
3574 case MPI2_IOCSTATUS_INVALID_FIELD:
3575 case MPI2_IOCSTATUS_INVALID_STATE:
3576 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
3577 case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
3578 default:
3579 scmd->result = DID_SOFT_ERROR << 16;
3580 break;
3581
3582 }
3583
3584#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
3585 if (scmd->result && (ioc->logging_level & MPT_DEBUG_REPLY))
3586 _scsih_scsi_ioc_info(ioc , scmd, mpi_reply, smid);
3587#endif
3588
3589 out:
3590 scsi_dma_unmap(scmd);
3591 scmd->scsi_done(scmd);
77e63ed4 3592 return 1;
635374e7
EM
3593}
3594
635374e7
EM
3595/**
3596 * _scsih_sas_host_refresh - refreshing sas host object contents
3597 * @ioc: per adapter object
635374e7
EM
3598 * Context: user
3599 *
3600 * During port enable, fw will send topology events for every device. Its
3601 * possible that the handles may change from the previous setting, so this
3602 * code keeping handles updating if changed.
3603 *
3604 * Return nothing.
3605 */
3606static void
c5e039be 3607_scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc)
635374e7
EM
3608{
3609 u16 sz;
3610 u16 ioc_status;
3611 int i;
3612 Mpi2ConfigReply_t mpi_reply;
3613 Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
c5e039be 3614 u16 attached_handle;
635374e7
EM
3615
3616 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT
3617 "updating handles for sas_host(0x%016llx)\n",
3618 ioc->name, (unsigned long long)ioc->sas_hba.sas_address));
3619
3620 sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys
3621 * sizeof(Mpi2SasIOUnit0PhyData_t));
3622 sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL);
3623 if (!sas_iounit_pg0) {
3624 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3625 ioc->name, __FILE__, __LINE__, __func__);
3626 return;
3627 }
635374e7 3628
c5e039be
KD
3629 if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
3630 sas_iounit_pg0, sz)) != 0)
3631 goto out;
3632 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
3633 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
3634 goto out;
3635 for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
3636 if (i == 0)
3637 ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
3638 PhyData[0].ControllerDevHandle);
3639 ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
3640 attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i].
3641 AttachedDevHandle);
3642 mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address,
3643 attached_handle, i, sas_iounit_pg0->PhyData[i].
3644 NegotiatedLinkRate >> 4);
3645 }
635374e7
EM
3646 out:
3647 kfree(sas_iounit_pg0);
3648}
3649
3650/**
3651 * _scsih_sas_host_add - create sas host object
3652 * @ioc: per adapter object
3653 *
3654 * Creating host side data object, stored in ioc->sas_hba
3655 *
3656 * Return nothing.
3657 */
3658static void
3659_scsih_sas_host_add(struct MPT2SAS_ADAPTER *ioc)
3660{
3661 int i;
3662 Mpi2ConfigReply_t mpi_reply;
3663 Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
3664 Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
3665 Mpi2SasPhyPage0_t phy_pg0;
3666 Mpi2SasDevicePage0_t sas_device_pg0;
3667 Mpi2SasEnclosurePage0_t enclosure_pg0;
3668 u16 ioc_status;
3669 u16 sz;
3670 u16 device_missing_delay;
3671
3672 mpt2sas_config_get_number_hba_phys(ioc, &ioc->sas_hba.num_phys);
3673 if (!ioc->sas_hba.num_phys) {
3674 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3675 ioc->name, __FILE__, __LINE__, __func__);
3676 return;
3677 }
3678
3679 /* sas_iounit page 0 */
3680 sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys *
3681 sizeof(Mpi2SasIOUnit0PhyData_t));
3682 sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL);
3683 if (!sas_iounit_pg0) {
3684 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3685 ioc->name, __FILE__, __LINE__, __func__);
3686 return;
3687 }
3688 if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
3689 sas_iounit_pg0, sz))) {
3690 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3691 ioc->name, __FILE__, __LINE__, __func__);
3692 goto out;
3693 }
3694 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
3695 MPI2_IOCSTATUS_MASK;
3696 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
3697 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3698 ioc->name, __FILE__, __LINE__, __func__);
3699 goto out;
3700 }
3701
3702 /* sas_iounit page 1 */
3703 sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
3704 sizeof(Mpi2SasIOUnit1PhyData_t));
3705 sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
3706 if (!sas_iounit_pg1) {
3707 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3708 ioc->name, __FILE__, __LINE__, __func__);
3709 goto out;
3710 }
3711 if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
3712 sas_iounit_pg1, sz))) {
3713 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3714 ioc->name, __FILE__, __LINE__, __func__);
3715 goto out;
3716 }
3717 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
3718 MPI2_IOCSTATUS_MASK;
3719 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
3720 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3721 ioc->name, __FILE__, __LINE__, __func__);
3722 goto out;
3723 }
3724
3725 ioc->io_missing_delay =
3726 le16_to_cpu(sas_iounit_pg1->IODeviceMissingDelay);
3727 device_missing_delay =
3728 le16_to_cpu(sas_iounit_pg1->ReportDeviceMissingDelay);
3729 if (device_missing_delay & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16)
3730 ioc->device_missing_delay = (device_missing_delay &
3731 MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16;
3732 else
3733 ioc->device_missing_delay = device_missing_delay &
3734 MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
3735
3736 ioc->sas_hba.parent_dev = &ioc->shost->shost_gendev;
3737 ioc->sas_hba.phy = kcalloc(ioc->sas_hba.num_phys,
3738 sizeof(struct _sas_phy), GFP_KERNEL);
3739 if (!ioc->sas_hba.phy) {
3740 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3741 ioc->name, __FILE__, __LINE__, __func__);
3742 goto out;
3743 }
3744 for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
3745 if ((mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0,
3746 i))) {
3747 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3748 ioc->name, __FILE__, __LINE__, __func__);
3749 goto out;
3750 }
3751 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
3752 MPI2_IOCSTATUS_MASK;
3753 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
3754 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3755 ioc->name, __FILE__, __LINE__, __func__);
3756 goto out;
3757 }
c5e039be
KD
3758
3759 if (i == 0)
3760 ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
3761 PhyData[0].ControllerDevHandle);
3762 ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
635374e7
EM
3763 ioc->sas_hba.phy[i].phy_id = i;
3764 mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i],
3765 phy_pg0, ioc->sas_hba.parent_dev);
3766 }
3767 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
c5e039be 3768 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.handle))) {
635374e7
EM
3769 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3770 ioc->name, __FILE__, __LINE__, __func__);
3771 goto out;
3772 }
635374e7
EM
3773 ioc->sas_hba.enclosure_handle =
3774 le16_to_cpu(sas_device_pg0.EnclosureHandle);
3775 ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
3776 printk(MPT2SAS_INFO_FMT "host_add: handle(0x%04x), "
3777 "sas_addr(0x%016llx), phys(%d)\n", ioc->name, ioc->sas_hba.handle,
3778 (unsigned long long) ioc->sas_hba.sas_address,
3779 ioc->sas_hba.num_phys) ;
3780
3781 if (ioc->sas_hba.enclosure_handle) {
3782 if (!(mpt2sas_config_get_enclosure_pg0(ioc, &mpi_reply,
3783 &enclosure_pg0,
3784 MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
3785 ioc->sas_hba.enclosure_handle))) {
3786 ioc->sas_hba.enclosure_logical_id =
3787 le64_to_cpu(enclosure_pg0.EnclosureLogicalID);
3788 }
3789 }
3790
3791 out:
3792 kfree(sas_iounit_pg1);
3793 kfree(sas_iounit_pg0);
3794}
3795
3796/**
3797 * _scsih_expander_add - creating expander object
3798 * @ioc: per adapter object
3799 * @handle: expander handle
3800 *
3801 * Creating expander object, stored in ioc->sas_expander_list.
3802 *
3803 * Return 0 for success, else error.
3804 */
3805static int
3806_scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3807{
3808 struct _sas_node *sas_expander;
3809 Mpi2ConfigReply_t mpi_reply;
3810 Mpi2ExpanderPage0_t expander_pg0;
3811 Mpi2ExpanderPage1_t expander_pg1;
3812 Mpi2SasEnclosurePage0_t enclosure_pg0;
3813 u32 ioc_status;
3814 u16 parent_handle;
c5e039be 3815 __le64 sas_address, sas_address_parent = 0;
635374e7
EM
3816 int i;
3817 unsigned long flags;
20f5895d 3818 struct _sas_port *mpt2sas_port = NULL;
635374e7
EM
3819 int rc = 0;
3820
3821 if (!handle)
3822 return -1;
3823
155dd4c7
KD
3824 if (ioc->shost_recovery)
3825 return -1;
3826
635374e7
EM
3827 if ((mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
3828 MPI2_SAS_EXPAND_PGAD_FORM_HNDL, handle))) {
3829 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3830 ioc->name, __FILE__, __LINE__, __func__);
3831 return -1;
3832 }
3833
3834 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
3835 MPI2_IOCSTATUS_MASK;
3836 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
3837 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3838 ioc->name, __FILE__, __LINE__, __func__);
3839 return -1;
3840 }
3841
3842 /* handle out of order topology events */
3843 parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle);
c5e039be
KD
3844 if (_scsih_get_sas_address(ioc, parent_handle, &sas_address_parent)
3845 != 0) {
3846 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3847 ioc->name, __FILE__, __LINE__, __func__);
3848 return -1;
3849 }
3850 if (sas_address_parent != ioc->sas_hba.sas_address) {
635374e7 3851 spin_lock_irqsave(&ioc->sas_node_lock, flags);
c5e039be
KD
3852 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
3853 sas_address_parent);
635374e7
EM
3854 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
3855 if (!sas_expander) {
3856 rc = _scsih_expander_add(ioc, parent_handle);
3857 if (rc != 0)
3858 return rc;
3859 }
3860 }
3861
635374e7 3862 spin_lock_irqsave(&ioc->sas_node_lock, flags);
595bb0bd 3863 sas_address = le64_to_cpu(expander_pg0.SASAddress);
635374e7
EM
3864 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
3865 sas_address);
3866 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
3867
3868 if (sas_expander)
3869 return 0;
3870
3871 sas_expander = kzalloc(sizeof(struct _sas_node),
3872 GFP_KERNEL);
3873 if (!sas_expander) {
3874 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3875 ioc->name, __FILE__, __LINE__, __func__);
3876 return -1;
3877 }
3878
3879 sas_expander->handle = handle;
3880 sas_expander->num_phys = expander_pg0.NumPhys;
c5e039be 3881 sas_expander->sas_address_parent = sas_address_parent;
635374e7
EM
3882 sas_expander->sas_address = sas_address;
3883
3884 printk(MPT2SAS_INFO_FMT "expander_add: handle(0x%04x),"
3885 " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name,
c5e039be 3886 handle, parent_handle, (unsigned long long)
635374e7
EM
3887 sas_expander->sas_address, sas_expander->num_phys);
3888
3889 if (!sas_expander->num_phys)
3890 goto out_fail;
3891 sas_expander->phy = kcalloc(sas_expander->num_phys,
3892 sizeof(struct _sas_phy), GFP_KERNEL);
3893 if (!sas_expander->phy) {
3894 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3895 ioc->name, __FILE__, __LINE__, __func__);
3896 rc = -1;
3897 goto out_fail;
3898 }
3899
3900 INIT_LIST_HEAD(&sas_expander->sas_port_list);
3901 mpt2sas_port = mpt2sas_transport_port_add(ioc, handle,
c5e039be 3902 sas_address_parent);
635374e7
EM
3903 if (!mpt2sas_port) {
3904 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3905 ioc->name, __FILE__, __LINE__, __func__);
3906 rc = -1;
3907 goto out_fail;
3908 }
3909 sas_expander->parent_dev = &mpt2sas_port->rphy->dev;
3910
3911 for (i = 0 ; i < sas_expander->num_phys ; i++) {
3912 if ((mpt2sas_config_get_expander_pg1(ioc, &mpi_reply,
3913 &expander_pg1, i, handle))) {
3914 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3915 ioc->name, __FILE__, __LINE__, __func__);
20f5895d
KD
3916 rc = -1;
3917 goto out_fail;
635374e7
EM
3918 }
3919 sas_expander->phy[i].handle = handle;
3920 sas_expander->phy[i].phy_id = i;
20f5895d
KD
3921
3922 if ((mpt2sas_transport_add_expander_phy(ioc,
3923 &sas_expander->phy[i], expander_pg1,
3924 sas_expander->parent_dev))) {
3925 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3926 ioc->name, __FILE__, __LINE__, __func__);
3927 rc = -1;
3928 goto out_fail;
3929 }
635374e7
EM
3930 }
3931
3932 if (sas_expander->enclosure_handle) {
3933 if (!(mpt2sas_config_get_enclosure_pg0(ioc, &mpi_reply,
3934 &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
3935 sas_expander->enclosure_handle))) {
3936 sas_expander->enclosure_logical_id =
3937 le64_to_cpu(enclosure_pg0.EnclosureLogicalID);
3938 }
3939 }
3940
3941 _scsih_expander_node_add(ioc, sas_expander);
3942 return 0;
3943
3944 out_fail:
3945
20f5895d
KD
3946 if (mpt2sas_port)
3947 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
c5e039be 3948 sas_address_parent);
635374e7
EM
3949 kfree(sas_expander);
3950 return rc;
3951}
3952
744090d3
KD
3953/**
3954 * _scsih_done - scsih callback handler.
3955 * @ioc: per adapter object
3956 * @smid: system request message index
3957 * @msix_index: MSIX table index supplied by the OS
3958 * @reply: reply message frame(lower 32bit addr)
3959 *
3960 * Callback handler when sending internal generated message frames.
3961 * The callback index passed is `ioc->scsih_cb_idx`
3962 *
3963 * Return 1 meaning mf should be freed from _base_interrupt
3964 * 0 means the mf is freed from this function.
3965 */
3966static u8
3967_scsih_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3968{
3969 MPI2DefaultReply_t *mpi_reply;
3970
3971 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
3972 if (ioc->scsih_cmds.status == MPT2_CMD_NOT_USED)
3973 return 1;
3974 if (ioc->scsih_cmds.smid != smid)
3975 return 1;
3976 ioc->scsih_cmds.status |= MPT2_CMD_COMPLETE;
3977 if (mpi_reply) {
3978 memcpy(ioc->scsih_cmds.reply, mpi_reply,
3979 mpi_reply->MsgLength*4);
3980 ioc->scsih_cmds.status |= MPT2_CMD_REPLY_VALID;
3981 }
3982 ioc->scsih_cmds.status &= ~MPT2_CMD_PENDING;
3983 complete(&ioc->scsih_cmds.done);
3984 return 1;
3985}
3986
635374e7
EM
3987/**
3988 * _scsih_expander_remove - removing expander object
3989 * @ioc: per adapter object
c5e039be 3990 * @sas_address: expander sas_address
635374e7
EM
3991 *
3992 * Return nothing.
3993 */
3994static void
c5e039be 3995_scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
635374e7
EM
3996{
3997 struct _sas_node *sas_expander;
3998 unsigned long flags;
3999
155dd4c7
KD
4000 if (ioc->shost_recovery)
4001 return;
4002
635374e7 4003 spin_lock_irqsave(&ioc->sas_node_lock, flags);
c5e039be
KD
4004 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
4005 sas_address);
635374e7
EM
4006 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
4007 _scsih_expander_node_remove(ioc, sas_expander);
4008}
4009
4010/**
4011 * _scsih_add_device - creating sas device object
4012 * @ioc: per adapter object
4013 * @handle: sas device handle
4014 * @phy_num: phy number end device attached to
4015 * @is_pd: is this hidden raid component
4016 *
4017 * Creating end device object, stored in ioc->sas_device_list.
4018 *
4019 * Returns 0 for success, non-zero for failure.
4020 */
4021static int
4022_scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
4023{
4024 Mpi2ConfigReply_t mpi_reply;
4025 Mpi2SasDevicePage0_t sas_device_pg0;
4026 Mpi2SasEnclosurePage0_t enclosure_pg0;
4027 struct _sas_device *sas_device;
4028 u32 ioc_status;
4029 __le64 sas_address;
4030 u32 device_info;
4031 unsigned long flags;
4032
4033 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
4034 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
4035 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
4036 ioc->name, __FILE__, __LINE__, __func__);
4037 return -1;
4038 }
4039
4040 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
4041 MPI2_IOCSTATUS_MASK;
4042 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
4043 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
4044 ioc->name, __FILE__, __LINE__, __func__);
4045 return -1;
4046 }
4047
4048 /* check if device is present */
4049 if (!(le16_to_cpu(sas_device_pg0.Flags) &
4050 MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) {
4051 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
4052 ioc->name, __FILE__, __LINE__, __func__);
4053 printk(MPT2SAS_ERR_FMT "Flags = 0x%04x\n",
4054 ioc->name, le16_to_cpu(sas_device_pg0.Flags));
4055 return -1;
4056 }
4057
4058 /* check if there were any issus with discovery */
4059 if (sas_device_pg0.AccessStatus ==
4060 MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED) {
4061 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
4062 ioc->name, __FILE__, __LINE__, __func__);
4063 printk(MPT2SAS_ERR_FMT "AccessStatus = 0x%02x\n",
4064 ioc->name, sas_device_pg0.AccessStatus);
4065 return -1;
4066 }
4067
4068 /* check if this is end device */
4069 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
4070 if (!(_scsih_is_end_device(device_info))) {
4071 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
4072 ioc->name, __FILE__, __LINE__, __func__);
4073 return -1;
4074 }
4075
4076 sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
4077
4078 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4079 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
4080 sas_address);
4081 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4082
4083 if (sas_device) {
4084 _scsih_ublock_io_device(ioc, handle);
4085 return 0;
4086 }
4087
4088 sas_device = kzalloc(sizeof(struct _sas_device),
4089 GFP_KERNEL);
4090 if (!sas_device) {
4091 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
4092 ioc->name, __FILE__, __LINE__, __func__);
4093 return -1;
4094 }
4095
4096 sas_device->handle = handle;
c5e039be
KD
4097 if (_scsih_get_sas_address(ioc, le16_to_cpu
4098 (sas_device_pg0.ParentDevHandle),
4099 &sas_device->sas_address_parent) != 0)
4100 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
4101 ioc->name, __FILE__, __LINE__, __func__);
635374e7
EM
4102 sas_device->enclosure_handle =
4103 le16_to_cpu(sas_device_pg0.EnclosureHandle);
4104 sas_device->slot =
4105 le16_to_cpu(sas_device_pg0.Slot);
4106 sas_device->device_info = device_info;
4107 sas_device->sas_address = sas_address;
4108 sas_device->hidden_raid_component = is_pd;
4109
4110 /* get enclosure_logical_id */
15052c9e
KD
4111 if (sas_device->enclosure_handle && !(mpt2sas_config_get_enclosure_pg0(
4112 ioc, &mpi_reply, &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
4113 sas_device->enclosure_handle)))
635374e7
EM
4114 sas_device->enclosure_logical_id =
4115 le64_to_cpu(enclosure_pg0.EnclosureLogicalID);
635374e7
EM
4116
4117 /* get device name */
4118 sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName);
4119
4120 if (ioc->wait_for_port_enable_to_complete)
4121 _scsih_sas_device_init_add(ioc, sas_device);
4122 else
4123 _scsih_sas_device_add(ioc, sas_device);
4124
4125 return 0;
4126}
4127
4128/**
4129 * _scsih_remove_device - removing sas device object
4130 * @ioc: per adapter object
c5e039be 4131 * @sas_device: the sas_device object
635374e7
EM
4132 *
4133 * Return nothing.
4134 */
4135static void
c5e039be
KD
4136_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device
4137 *sas_device)
635374e7
EM
4138{
4139 struct MPT2SAS_TARGET *sas_target_priv_data;
635374e7
EM
4140 Mpi2SasIoUnitControlReply_t mpi_reply;
4141 Mpi2SasIoUnitControlRequest_t mpi_request;
c5e039be 4142 u16 device_handle, handle;
635374e7 4143
c5e039be 4144 if (!sas_device)
635374e7 4145 return;
635374e7 4146
c5e039be
KD
4147 handle = sas_device->handle;
4148 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle(0x%04x),"
4149 " sas_addr(0x%016llx)\n", ioc->name, __func__, handle,
4150 (unsigned long long) sas_device->sas_address));
635374e7
EM
4151
4152 if (sas_device->starget && sas_device->starget->hostdata) {
4153 sas_target_priv_data = sas_device->starget->hostdata;
4154 sas_target_priv_data->deleted = 1;
4155 }
635374e7 4156
c5e039be 4157 if (ioc->remove_host || ioc->shost_recovery || !handle)
635374e7
EM
4158 goto out;
4159
77e63ed4
KD
4160 if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) {
4161 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip "
c5e039be
KD
4162 "target_reset handle(0x%04x)\n", ioc->name,
4163 handle));
77e63ed4
KD
4164 goto skip_tr;
4165 }
4166
635374e7
EM
4167 /* Target Reset to flush out all the outstanding IO */
4168 device_handle = (sas_device->hidden_raid_component) ?
4169 sas_device->volume_handle : handle;
4170 if (device_handle) {
4171 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset: "
4172 "handle(0x%04x)\n", ioc->name, device_handle));
4173 mutex_lock(&ioc->tm_cmds.mutex);
4174 mpt2sas_scsih_issue_tm(ioc, device_handle, 0,
4175 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 10);
4176 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
4177 mutex_unlock(&ioc->tm_cmds.mutex);
4178 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset "
4179 "done: handle(0x%04x)\n", ioc->name, device_handle));
155dd4c7
KD
4180 if (ioc->shost_recovery)
4181 goto out;
635374e7 4182 }
77e63ed4
KD
4183 skip_tr:
4184
4185 if ((sas_device->state & MPTSAS_STATE_CNTRL_COMPLETE)) {
4186 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip "
4187 "sas_cntrl handle(0x%04x)\n", ioc->name, handle));
4188 goto out;
4189 }
635374e7
EM
4190
4191 /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */
4192 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle"
4193 "(0x%04x)\n", ioc->name, handle));
4194 memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
4195 mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
4196 mpi_request.Operation = MPI2_SAS_OP_REMOVE_DEVICE;
4197 mpi_request.DevHandle = handle;
7b936b02
KD
4198 mpi_request.VF_ID = 0; /* TODO */
4199 mpi_request.VP_ID = 0;
635374e7
EM
4200 if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply,
4201 &mpi_request)) != 0) {
4202 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
4203 ioc->name, __FILE__, __LINE__, __func__);
4204 }
4205
4206 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: ioc_status"
4207 "(0x%04x), loginfo(0x%08x)\n", ioc->name,
4208 le16_to_cpu(mpi_reply.IOCStatus),
4209 le32_to_cpu(mpi_reply.IOCLogInfo)));
4210
4211 out:
34a03bef
KD
4212
4213 _scsih_ublock_io_device(ioc, handle);
4214
635374e7 4215 mpt2sas_transport_port_remove(ioc, sas_device->sas_address,
c5e039be 4216 sas_device->sas_address_parent);
635374e7
EM
4217
4218 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr"
c5e039be 4219 "(0x%016llx)\n", ioc->name, handle,
635374e7
EM
4220 (unsigned long long) sas_device->sas_address);
4221 _scsih_sas_device_remove(ioc, sas_device);
4222
4223 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit: handle"
4224 "(0x%04x)\n", ioc->name, __func__, handle));
4225}
4226
4227#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4228/**
4229 * _scsih_sas_topology_change_event_debug - debug for topology event
4230 * @ioc: per adapter object
4231 * @event_data: event data payload
4232 * Context: user.
4233 */
4234static void
4235_scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4236 Mpi2EventDataSasTopologyChangeList_t *event_data)
4237{
4238 int i;
4239 u16 handle;
4240 u16 reason_code;
4241 u8 phy_number;
4242 char *status_str = NULL;
e7d59c17 4243 u8 link_rate, prev_link_rate;
635374e7
EM
4244
4245 switch (event_data->ExpStatus) {
4246 case MPI2_EVENT_SAS_TOPO_ES_ADDED:
4247 status_str = "add";
4248 break;
4249 case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING:
4250 status_str = "remove";
4251 break;
4252 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
e7d59c17 4253 case 0:
635374e7
EM
4254 status_str = "responding";
4255 break;
4256 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
4257 status_str = "remove delay";
4258 break;
4259 default:
4260 status_str = "unknown status";
4261 break;
4262 }
4263 printk(MPT2SAS_DEBUG_FMT "sas topology change: (%s)\n",
4264 ioc->name, status_str);
4265 printk(KERN_DEBUG "\thandle(0x%04x), enclosure_handle(0x%04x) "
4266 "start_phy(%02d), count(%d)\n",
4267 le16_to_cpu(event_data->ExpanderDevHandle),
4268 le16_to_cpu(event_data->EnclosureHandle),
4269 event_data->StartPhyNum, event_data->NumEntries);
4270 for (i = 0; i < event_data->NumEntries; i++) {
4271 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
4272 if (!handle)
4273 continue;
4274 phy_number = event_data->StartPhyNum + i;
4275 reason_code = event_data->PHY[i].PhyStatus &
4276 MPI2_EVENT_SAS_TOPO_RC_MASK;
4277 switch (reason_code) {
4278 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
e7d59c17 4279 status_str = "target add";
635374e7
EM
4280 break;
4281 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
e7d59c17 4282 status_str = "target remove";
635374e7
EM
4283 break;
4284 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
e7d59c17 4285 status_str = "delay target remove";
635374e7
EM
4286 break;
4287 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
e7d59c17 4288 status_str = "link rate change";
635374e7
EM
4289 break;
4290 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
e7d59c17 4291 status_str = "target responding";
635374e7
EM
4292 break;
4293 default:
e7d59c17 4294 status_str = "unknown";
635374e7
EM
4295 break;
4296 }
e7d59c17
KD
4297 link_rate = event_data->PHY[i].LinkRate >> 4;
4298 prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
4299 printk(KERN_DEBUG "\tphy(%02d), attached_handle(0x%04x): %s:"
4300 " link rate: new(0x%02x), old(0x%02x)\n", phy_number,
4301 handle, status_str, link_rate, prev_link_rate);
4302
635374e7
EM
4303 }
4304}
4305#endif
4306
4307/**
4308 * _scsih_sas_topology_change_event - handle topology changes
4309 * @ioc: per adapter object
7b936b02 4310 * @fw_event: The fw_event_work object
635374e7
EM
4311 * Context: user.
4312 *
4313 */
4314static void
7b936b02 4315_scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
635374e7
EM
4316 struct fw_event_work *fw_event)
4317{
4318 int i;
4319 u16 parent_handle, handle;
4320 u16 reason_code;
4321 u8 phy_number;
4322 struct _sas_node *sas_expander;
c5e039be
KD
4323 struct _sas_device *sas_device;
4324 u64 sas_address;
635374e7 4325 unsigned long flags;
e7d59c17 4326 u8 link_rate, prev_link_rate;
7b936b02 4327 Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data;
635374e7
EM
4328
4329#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4330 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
4331 _scsih_sas_topology_change_event_debug(ioc, event_data);
4332#endif
4333
c5e039be
KD
4334 if (ioc->shost_recovery)
4335 return;
4336
635374e7
EM
4337 if (!ioc->sas_hba.num_phys)
4338 _scsih_sas_host_add(ioc);
4339 else
c5e039be 4340 _scsih_sas_host_refresh(ioc);
635374e7
EM
4341
4342 if (fw_event->ignore) {
4343 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring expander "
4344 "event\n", ioc->name));
4345 return;
4346 }
4347
4348 parent_handle = le16_to_cpu(event_data->ExpanderDevHandle);
4349
4350 /* handle expander add */
4351 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_ADDED)
4352 if (_scsih_expander_add(ioc, parent_handle) != 0)
4353 return;
4354
c5e039be
KD
4355 spin_lock_irqsave(&ioc->sas_node_lock, flags);
4356 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
4357 parent_handle);
4358 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
4359 if (sas_expander)
4360 sas_address = sas_expander->sas_address;
4361 else if (parent_handle < ioc->sas_hba.num_phys)
4362 sas_address = ioc->sas_hba.sas_address;
4363 else
4364 return;
4365
635374e7
EM
4366 /* handle siblings events */
4367 for (i = 0; i < event_data->NumEntries; i++) {
4368 if (fw_event->ignore) {
4369 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring "
4370 "expander event\n", ioc->name));
4371 return;
4372 }
155dd4c7
KD
4373 if (ioc->shost_recovery)
4374 return;
308609c6
KD
4375 phy_number = event_data->StartPhyNum + i;
4376 reason_code = event_data->PHY[i].PhyStatus &
4377 MPI2_EVENT_SAS_TOPO_RC_MASK;
4378 if ((event_data->PHY[i].PhyStatus &
4379 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) && (reason_code !=
4380 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING))
635374e7
EM
4381 continue;
4382 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
4383 if (!handle)
4384 continue;
c5e039be 4385 link_rate = event_data->PHY[i].LinkRate >> 4;
e7d59c17 4386 prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
635374e7
EM
4387 switch (reason_code) {
4388 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
e7d59c17
KD
4389
4390 if (link_rate == prev_link_rate)
4391 break;
4392
4393 mpt2sas_transport_update_links(ioc, sas_address,
4394 handle, phy_number, link_rate);
4395
4396 if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)
4397 _scsih_ublock_io_device(ioc, handle);
4398 break;
635374e7 4399 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
c5e039be
KD
4400
4401 mpt2sas_transport_update_links(ioc, sas_address,
4402 handle, phy_number, link_rate);
4403
e7d59c17 4404 _scsih_add_device(ioc, handle, phy_number, 0);
635374e7
EM
4405 break;
4406 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
c5e039be
KD
4407
4408 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4409 sas_device = _scsih_sas_device_find_by_handle(ioc,
4410 handle);
4411 if (!sas_device) {
4412 spin_unlock_irqrestore(&ioc->sas_device_lock,
4413 flags);
4414 break;
4415 }
4416 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4417 _scsih_remove_device(ioc, sas_device);
635374e7
EM
4418 break;
4419 }
4420 }
4421
4422 /* handle expander removal */
c5e039be
KD
4423 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING &&
4424 sas_expander)
4425 _scsih_expander_remove(ioc, sas_address);
635374e7
EM
4426
4427}
4428
4429#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4430/**
4431 * _scsih_sas_device_status_change_event_debug - debug for device event
4432 * @event_data: event data payload
4433 * Context: user.
4434 *
4435 * Return nothing.
4436 */
4437static void
4438_scsih_sas_device_status_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4439 Mpi2EventDataSasDeviceStatusChange_t *event_data)
4440{
4441 char *reason_str = NULL;
4442
4443 switch (event_data->ReasonCode) {
4444 case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
4445 reason_str = "smart data";
4446 break;
4447 case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
4448 reason_str = "unsupported device discovered";
4449 break;
4450 case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
4451 reason_str = "internal device reset";
4452 break;
4453 case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
4454 reason_str = "internal task abort";
4455 break;
4456 case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
4457 reason_str = "internal task abort set";
4458 break;
4459 case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
4460 reason_str = "internal clear task set";
4461 break;
4462 case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
4463 reason_str = "internal query task";
4464 break;
4465 case MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE:
4466 reason_str = "sata init failure";
4467 break;
4468 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET:
4469 reason_str = "internal device reset complete";
4470 break;
4471 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL:
4472 reason_str = "internal task abort complete";
4473 break;
4474 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION:
4475 reason_str = "internal async notification";
4476 break;
ec6c2b43
KD
4477 case MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY:
4478 reason_str = "expander reduced functionality";
4479 break;
4480 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY:
4481 reason_str = "expander reduced functionality complete";
4482 break;
635374e7
EM
4483 default:
4484 reason_str = "unknown reason";
4485 break;
4486 }
4487 printk(MPT2SAS_DEBUG_FMT "device status change: (%s)\n"
4488 "\thandle(0x%04x), sas address(0x%016llx)", ioc->name,
4489 reason_str, le16_to_cpu(event_data->DevHandle),
4490 (unsigned long long)le64_to_cpu(event_data->SASAddress));
4491 if (event_data->ReasonCode == MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA)
4492 printk(MPT2SAS_DEBUG_FMT ", ASC(0x%x), ASCQ(0x%x)\n", ioc->name,
4493 event_data->ASC, event_data->ASCQ);
4494 printk(KERN_INFO "\n");
4495}
4496#endif
4497
4498/**
4499 * _scsih_sas_device_status_change_event - handle device status change
4500 * @ioc: per adapter object
7b936b02 4501 * @fw_event: The fw_event_work object
635374e7
EM
4502 * Context: user.
4503 *
4504 * Return nothing.
4505 */
4506static void
7b936b02
KD
4507_scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc,
4508 struct fw_event_work *fw_event)
635374e7 4509{
8ffc457e
KD
4510 struct MPT2SAS_TARGET *target_priv_data;
4511 struct _sas_device *sas_device;
4512 __le64 sas_address;
4513 unsigned long flags;
4514 Mpi2EventDataSasDeviceStatusChange_t *event_data =
4515 fw_event->event_data;
4516
635374e7
EM
4517#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4518 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
7b936b02 4519 _scsih_sas_device_status_change_event_debug(ioc,
8ffc457e 4520 event_data);
635374e7 4521#endif
8ffc457e
KD
4522
4523 if (!(event_data->ReasonCode ==
4524 MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
4525 event_data->ReasonCode ==
4526 MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET))
4527 return;
4528
4529 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4530 sas_address = le64_to_cpu(event_data->SASAddress);
4531 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
4532 sas_address);
4533 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4534
4535 if (!sas_device || !sas_device->starget)
4536 return;
4537
4538 target_priv_data = sas_device->starget->hostdata;
4539 if (!target_priv_data)
4540 return;
4541
4542 if (event_data->ReasonCode ==
4543 MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET)
4544 target_priv_data->tm_busy = 1;
4545 else
4546 target_priv_data->tm_busy = 0;
635374e7
EM
4547}
4548
4549#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4550/**
4551 * _scsih_sas_enclosure_dev_status_change_event_debug - debug for enclosure event
4552 * @ioc: per adapter object
4553 * @event_data: event data payload
4554 * Context: user.
4555 *
4556 * Return nothing.
4557 */
4558static void
4559_scsih_sas_enclosure_dev_status_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4560 Mpi2EventDataSasEnclDevStatusChange_t *event_data)
4561{
4562 char *reason_str = NULL;
4563
4564 switch (event_data->ReasonCode) {
4565 case MPI2_EVENT_SAS_ENCL_RC_ADDED:
4566 reason_str = "enclosure add";
4567 break;
4568 case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING:
4569 reason_str = "enclosure remove";
4570 break;
4571 default:
4572 reason_str = "unknown reason";
4573 break;
4574 }
4575
4576 printk(MPT2SAS_DEBUG_FMT "enclosure status change: (%s)\n"
4577 "\thandle(0x%04x), enclosure logical id(0x%016llx)"
4578 " number slots(%d)\n", ioc->name, reason_str,
4579 le16_to_cpu(event_data->EnclosureHandle),
4580 (unsigned long long)le64_to_cpu(event_data->EnclosureLogicalID),
4581 le16_to_cpu(event_data->StartSlot));
4582}
4583#endif
4584
4585/**
4586 * _scsih_sas_enclosure_dev_status_change_event - handle enclosure events
4587 * @ioc: per adapter object
7b936b02 4588 * @fw_event: The fw_event_work object
635374e7
EM
4589 * Context: user.
4590 *
4591 * Return nothing.
4592 */
4593static void
4594_scsih_sas_enclosure_dev_status_change_event(struct MPT2SAS_ADAPTER *ioc,
7b936b02 4595 struct fw_event_work *fw_event)
635374e7
EM
4596{
4597#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4598 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
4599 _scsih_sas_enclosure_dev_status_change_event_debug(ioc,
7b936b02 4600 fw_event->event_data);
635374e7
EM
4601#endif
4602}
4603
4604/**
4605 * _scsih_sas_broadcast_primative_event - handle broadcast events
4606 * @ioc: per adapter object
7b936b02 4607 * @fw_event: The fw_event_work object
635374e7
EM
4608 * Context: user.
4609 *
4610 * Return nothing.
4611 */
4612static void
7b936b02
KD
4613_scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
4614 struct fw_event_work *fw_event)
635374e7
EM
4615{
4616 struct scsi_cmnd *scmd;
4617 u16 smid, handle;
4618 u32 lun;
4619 struct MPT2SAS_DEVICE *sas_device_priv_data;
4620 u32 termination_count;
4621 u32 query_count;
4622 Mpi2SCSITaskManagementReply_t *mpi_reply;
7b936b02
KD
4623#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4624 Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data;
4625#endif
463217bf 4626 u16 ioc_status;
635374e7
EM
4627 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: "
4628 "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum,
4629 event_data->PortWidth));
635374e7
EM
4630 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name,
4631 __func__));
4632
4633 mutex_lock(&ioc->tm_cmds.mutex);
4634 termination_count = 0;
4635 query_count = 0;
4636 mpi_reply = ioc->tm_cmds.reply;
595bb0bd 4637 for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
635374e7
EM
4638 scmd = _scsih_scsi_lookup_get(ioc, smid);
4639 if (!scmd)
4640 continue;
4641 sas_device_priv_data = scmd->device->hostdata;
4642 if (!sas_device_priv_data || !sas_device_priv_data->sas_target)
4643 continue;
4644 /* skip hidden raid components */
4645 if (sas_device_priv_data->sas_target->flags &
4646 MPT_TARGET_FLAGS_RAID_COMPONENT)
4647 continue;
4648 /* skip volumes */
4649 if (sas_device_priv_data->sas_target->flags &
4650 MPT_TARGET_FLAGS_VOLUME)
4651 continue;
4652
4653 handle = sas_device_priv_data->sas_target->handle;
4654 lun = sas_device_priv_data->lun;
4655 query_count++;
4656
4657 mpt2sas_scsih_issue_tm(ioc, handle, lun,
4658 MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30);
8901cbb4 4659 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
463217bf
KD
4660 ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
4661 & MPI2_IOCSTATUS_MASK;
4662 if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&
635374e7
EM
4663 (mpi_reply->ResponseCode ==
4664 MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
4665 mpi_reply->ResponseCode ==
4666 MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
4667 continue;
4668
4669 mpt2sas_scsih_issue_tm(ioc, handle, lun,
8901cbb4
EM
4670 MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, 0, 30);
4671 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
635374e7
EM
4672 termination_count += le32_to_cpu(mpi_reply->TerminationCount);
4673 }
635374e7
EM
4674 ioc->broadcast_aen_busy = 0;
4675 mutex_unlock(&ioc->tm_cmds.mutex);
4676
4677 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT
4678 "%s - exit, query_count = %d termination_count = %d\n",
4679 ioc->name, __func__, query_count, termination_count));
4680}
4681
4682/**
4683 * _scsih_sas_discovery_event - handle discovery events
4684 * @ioc: per adapter object
7b936b02 4685 * @fw_event: The fw_event_work object
635374e7
EM
4686 * Context: user.
4687 *
4688 * Return nothing.
4689 */
4690static void
7b936b02
KD
4691_scsih_sas_discovery_event(struct MPT2SAS_ADAPTER *ioc,
4692 struct fw_event_work *fw_event)
635374e7 4693{
7b936b02
KD
4694 Mpi2EventDataSasDiscovery_t *event_data = fw_event->event_data;
4695
635374e7
EM
4696#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4697 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) {
4698 printk(MPT2SAS_DEBUG_FMT "discovery event: (%s)", ioc->name,
4699 (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ?
4700 "start" : "stop");
4701 if (event_data->DiscoveryStatus)
595bb0bd
KD
4702 printk("discovery_status(0x%08x)",
4703 le32_to_cpu(event_data->DiscoveryStatus));
635374e7
EM
4704 printk("\n");
4705 }
4706#endif
4707
4708 if (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED &&
4709 !ioc->sas_hba.num_phys)
4710 _scsih_sas_host_add(ioc);
4711}
4712
4713/**
4714 * _scsih_reprobe_lun - reprobing lun
4715 * @sdev: scsi device struct
4716 * @no_uld_attach: sdev->no_uld_attach flag setting
4717 *
4718 **/
4719static void
4720_scsih_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach)
4721{
4722 int rc;
4723
4724 sdev->no_uld_attach = no_uld_attach ? 1 : 0;
4725 sdev_printk(KERN_INFO, sdev, "%s raid component\n",
4726 sdev->no_uld_attach ? "hidding" : "exposing");
4727 rc = scsi_device_reprobe(sdev);
4728}
4729
4730/**
4731 * _scsih_reprobe_target - reprobing target
4732 * @starget: scsi target struct
4733 * @no_uld_attach: sdev->no_uld_attach flag setting
4734 *
4735 * Note: no_uld_attach flag determines whether the disk device is attached
4736 * to block layer. A value of `1` means to not attach.
4737 **/
4738static void
4739_scsih_reprobe_target(struct scsi_target *starget, int no_uld_attach)
4740{
4741 struct MPT2SAS_TARGET *sas_target_priv_data = starget->hostdata;
4742
4743 if (no_uld_attach)
4744 sas_target_priv_data->flags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
4745 else
4746 sas_target_priv_data->flags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
4747
4748 starget_for_each_device(starget, no_uld_attach ? (void *)1 : NULL,
4749 _scsih_reprobe_lun);
4750}
4751/**
4752 * _scsih_sas_volume_add - add new volume
4753 * @ioc: per adapter object
4754 * @element: IR config element data
4755 * Context: user.
4756 *
4757 * Return nothing.
4758 */
4759static void
4760_scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc,
4761 Mpi2EventIrConfigElement_t *element)
4762{
4763 struct _raid_device *raid_device;
4764 unsigned long flags;
4765 u64 wwid;
4766 u16 handle = le16_to_cpu(element->VolDevHandle);
4767 int rc;
4768
635374e7
EM
4769 mpt2sas_config_get_volume_wwid(ioc, handle, &wwid);
4770 if (!wwid) {
4771 printk(MPT2SAS_ERR_FMT
4772 "failure at %s:%d/%s()!\n", ioc->name,
4773 __FILE__, __LINE__, __func__);
4774 return;
4775 }
4776
4777 spin_lock_irqsave(&ioc->raid_device_lock, flags);
4778 raid_device = _scsih_raid_device_find_by_wwid(ioc, wwid);
4779 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
4780
4781 if (raid_device)
4782 return;
4783
4784 raid_device = kzalloc(sizeof(struct _raid_device), GFP_KERNEL);
4785 if (!raid_device) {
4786 printk(MPT2SAS_ERR_FMT
4787 "failure at %s:%d/%s()!\n", ioc->name,
4788 __FILE__, __LINE__, __func__);
4789 return;
4790 }
4791
4792 raid_device->id = ioc->sas_id++;
4793 raid_device->channel = RAID_CHANNEL;
4794 raid_device->handle = handle;
4795 raid_device->wwid = wwid;
4796 _scsih_raid_device_add(ioc, raid_device);
4797 if (!ioc->wait_for_port_enable_to_complete) {
4798 rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
4799 raid_device->id, 0);
4800 if (rc)
4801 _scsih_raid_device_remove(ioc, raid_device);
4802 } else
4803 _scsih_determine_boot_device(ioc, raid_device, 1);
4804}
4805
4806/**
4807 * _scsih_sas_volume_delete - delete volume
4808 * @ioc: per adapter object
4809 * @element: IR config element data
4810 * Context: user.
4811 *
4812 * Return nothing.
4813 */
4814static void
4815_scsih_sas_volume_delete(struct MPT2SAS_ADAPTER *ioc,
4816 Mpi2EventIrConfigElement_t *element)
4817{
4818 struct _raid_device *raid_device;
4819 u16 handle = le16_to_cpu(element->VolDevHandle);
4820 unsigned long flags;
4821 struct MPT2SAS_TARGET *sas_target_priv_data;
4822
635374e7
EM
4823 spin_lock_irqsave(&ioc->raid_device_lock, flags);
4824 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
4825 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
4826 if (!raid_device)
4827 return;
4828 if (raid_device->starget) {
4829 sas_target_priv_data = raid_device->starget->hostdata;
4830 sas_target_priv_data->deleted = 1;
4831 scsi_remove_target(&raid_device->starget->dev);
4832 }
4833 _scsih_raid_device_remove(ioc, raid_device);
4834}
4835
4836/**
4837 * _scsih_sas_pd_expose - expose pd component to /dev/sdX
4838 * @ioc: per adapter object
4839 * @element: IR config element data
4840 * Context: user.
4841 *
4842 * Return nothing.
4843 */
4844static void
4845_scsih_sas_pd_expose(struct MPT2SAS_ADAPTER *ioc,
4846 Mpi2EventIrConfigElement_t *element)
4847{
4848 struct _sas_device *sas_device;
4849 unsigned long flags;
4850 u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
4851
4852 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4853 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
4854 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4855 if (!sas_device)
4856 return;
4857
4858 /* exposing raid component */
4859 sas_device->volume_handle = 0;
4860 sas_device->volume_wwid = 0;
4861 sas_device->hidden_raid_component = 0;
4862 _scsih_reprobe_target(sas_device->starget, 0);
4863}
4864
4865/**
4866 * _scsih_sas_pd_hide - hide pd component from /dev/sdX
4867 * @ioc: per adapter object
4868 * @element: IR config element data
4869 * Context: user.
4870 *
4871 * Return nothing.
4872 */
4873static void
4874_scsih_sas_pd_hide(struct MPT2SAS_ADAPTER *ioc,
4875 Mpi2EventIrConfigElement_t *element)
4876{
4877 struct _sas_device *sas_device;
4878 unsigned long flags;
4879 u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
4880
4881 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4882 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
4883 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4884 if (!sas_device)
4885 return;
4886
4887 /* hiding raid component */
4888 mpt2sas_config_get_volume_handle(ioc, handle,
4889 &sas_device->volume_handle);
4890 mpt2sas_config_get_volume_wwid(ioc, sas_device->volume_handle,
4891 &sas_device->volume_wwid);
4892 sas_device->hidden_raid_component = 1;
4893 _scsih_reprobe_target(sas_device->starget, 1);
4894}
4895
4896/**
4897 * _scsih_sas_pd_delete - delete pd component
4898 * @ioc: per adapter object
4899 * @element: IR config element data
4900 * Context: user.
4901 *
4902 * Return nothing.
4903 */
4904static void
4905_scsih_sas_pd_delete(struct MPT2SAS_ADAPTER *ioc,
4906 Mpi2EventIrConfigElement_t *element)
4907{
4908 struct _sas_device *sas_device;
4909 unsigned long flags;
4910 u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
4911
4912 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4913 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
4914 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4915 if (!sas_device)
4916 return;
c5e039be 4917 _scsih_remove_device(ioc, sas_device);
635374e7
EM
4918}
4919
4920/**
4921 * _scsih_sas_pd_add - remove pd component
4922 * @ioc: per adapter object
4923 * @element: IR config element data
4924 * Context: user.
4925 *
4926 * Return nothing.
4927 */
4928static void
4929_scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc,
4930 Mpi2EventIrConfigElement_t *element)
4931{
4932 struct _sas_device *sas_device;
4933 unsigned long flags;
4934 u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
62727a7b
KD
4935 Mpi2ConfigReply_t mpi_reply;
4936 Mpi2SasDevicePage0_t sas_device_pg0;
4937 u32 ioc_status;
c5e039be
KD
4938 u64 sas_address;
4939 u16 parent_handle;
635374e7
EM
4940
4941 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4942 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
4943 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
62727a7b 4944 if (sas_device) {
635374e7 4945 sas_device->hidden_raid_component = 1;
62727a7b
KD
4946 return;
4947 }
4948
4949 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
4950 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
4951 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
4952 ioc->name, __FILE__, __LINE__, __func__);
4953 return;
4954 }
4955
4956 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
4957 MPI2_IOCSTATUS_MASK;
4958 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
4959 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
4960 ioc->name, __FILE__, __LINE__, __func__);
4961 return;
4962 }
4963
c5e039be
KD
4964 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
4965 if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address))
4966 mpt2sas_transport_update_links(ioc, sas_address, handle,
4967 sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
62727a7b
KD
4968
4969 _scsih_add_device(ioc, handle, 0, 1);
635374e7
EM
4970}
4971
4972#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4973/**
4974 * _scsih_sas_ir_config_change_event_debug - debug for IR Config Change events
4975 * @ioc: per adapter object
4976 * @event_data: event data payload
4977 * Context: user.
4978 *
4979 * Return nothing.
4980 */
4981static void
4982_scsih_sas_ir_config_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4983 Mpi2EventDataIrConfigChangeList_t *event_data)
4984{
4985 Mpi2EventIrConfigElement_t *element;
4986 u8 element_type;
4987 int i;
4988 char *reason_str = NULL, *element_str = NULL;
4989
4990 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
4991
4992 printk(MPT2SAS_DEBUG_FMT "raid config change: (%s), elements(%d)\n",
4993 ioc->name, (le32_to_cpu(event_data->Flags) &
4994 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ?
4995 "foreign" : "native", event_data->NumElements);
4996 for (i = 0; i < event_data->NumElements; i++, element++) {
4997 switch (element->ReasonCode) {
4998 case MPI2_EVENT_IR_CHANGE_RC_ADDED:
4999 reason_str = "add";
5000 break;
5001 case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
5002 reason_str = "remove";
5003 break;
5004 case MPI2_EVENT_IR_CHANGE_RC_NO_CHANGE:
5005 reason_str = "no change";
5006 break;
5007 case MPI2_EVENT_IR_CHANGE_RC_HIDE:
5008 reason_str = "hide";
5009 break;
5010 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
5011 reason_str = "unhide";
5012 break;
5013 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
5014 reason_str = "volume_created";
5015 break;
5016 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
5017 reason_str = "volume_deleted";
5018 break;
5019 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
5020 reason_str = "pd_created";
5021 break;
5022 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
5023 reason_str = "pd_deleted";
5024 break;
5025 default:
5026 reason_str = "unknown reason";
5027 break;
5028 }
5029 element_type = le16_to_cpu(element->ElementFlags) &
5030 MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK;
5031 switch (element_type) {
5032 case MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT:
5033 element_str = "volume";
5034 break;
5035 case MPI2_EVENT_IR_CHANGE_EFLAGS_VOLPHYSDISK_ELEMENT:
5036 element_str = "phys disk";
5037 break;
5038 case MPI2_EVENT_IR_CHANGE_EFLAGS_HOTSPARE_ELEMENT:
5039 element_str = "hot spare";
5040 break;
5041 default:
5042 element_str = "unknown element";
5043 break;
5044 }
5045 printk(KERN_DEBUG "\t(%s:%s), vol handle(0x%04x), "
5046 "pd handle(0x%04x), pd num(0x%02x)\n", element_str,
5047 reason_str, le16_to_cpu(element->VolDevHandle),
5048 le16_to_cpu(element->PhysDiskDevHandle),
5049 element->PhysDiskNum);
5050 }
5051}
5052#endif
5053
5054/**
5055 * _scsih_sas_ir_config_change_event - handle ir configuration change events
5056 * @ioc: per adapter object
7b936b02 5057 * @fw_event: The fw_event_work object
635374e7
EM
5058 * Context: user.
5059 *
5060 * Return nothing.
5061 */
5062static void
7b936b02
KD
5063_scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,
5064 struct fw_event_work *fw_event)
635374e7
EM
5065{
5066 Mpi2EventIrConfigElement_t *element;
5067 int i;
62727a7b 5068 u8 foreign_config;
7b936b02 5069 Mpi2EventDataIrConfigChangeList_t *event_data = fw_event->event_data;
635374e7
EM
5070
5071#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
5072 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
5073 _scsih_sas_ir_config_change_event_debug(ioc, event_data);
5074
5075#endif
62727a7b
KD
5076 foreign_config = (le32_to_cpu(event_data->Flags) &
5077 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0;
635374e7
EM
5078
5079 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
5080 for (i = 0; i < event_data->NumElements; i++, element++) {
5081
5082 switch (element->ReasonCode) {
5083 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
5084 case MPI2_EVENT_IR_CHANGE_RC_ADDED:
62727a7b
KD
5085 if (!foreign_config)
5086 _scsih_sas_volume_add(ioc, element);
635374e7
EM
5087 break;
5088 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
5089 case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
62727a7b
KD
5090 if (!foreign_config)
5091 _scsih_sas_volume_delete(ioc, element);
635374e7
EM
5092 break;
5093 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
5094 _scsih_sas_pd_hide(ioc, element);
5095 break;
5096 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
5097 _scsih_sas_pd_expose(ioc, element);
5098 break;
5099 case MPI2_EVENT_IR_CHANGE_RC_HIDE:
5100 _scsih_sas_pd_add(ioc, element);
5101 break;
5102 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
5103 _scsih_sas_pd_delete(ioc, element);
5104 break;
5105 }
5106 }
5107}
5108
5109/**
5110 * _scsih_sas_ir_volume_event - IR volume event
5111 * @ioc: per adapter object
7b936b02 5112 * @fw_event: The fw_event_work object
635374e7
EM
5113 * Context: user.
5114 *
5115 * Return nothing.
5116 */
5117static void
7b936b02
KD
5118_scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,
5119 struct fw_event_work *fw_event)
635374e7
EM
5120{
5121 u64 wwid;
5122 unsigned long flags;
5123 struct _raid_device *raid_device;
5124 u16 handle;
5125 u32 state;
5126 int rc;
5127 struct MPT2SAS_TARGET *sas_target_priv_data;
7b936b02 5128 Mpi2EventDataIrVolume_t *event_data = fw_event->event_data;
635374e7
EM
5129
5130 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
5131 return;
5132
5133 handle = le16_to_cpu(event_data->VolDevHandle);
5134 state = le32_to_cpu(event_data->NewValue);
5135 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle(0x%04x), "
5136 "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle,
5137 le32_to_cpu(event_data->PreviousValue), state));
5138
5139 spin_lock_irqsave(&ioc->raid_device_lock, flags);
5140 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
5141 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
5142
5143 switch (state) {
5144 case MPI2_RAID_VOL_STATE_MISSING:
5145 case MPI2_RAID_VOL_STATE_FAILED:
5146 if (!raid_device)
5147 break;
5148 if (raid_device->starget) {
5149 sas_target_priv_data = raid_device->starget->hostdata;
5150 sas_target_priv_data->deleted = 1;
5151 scsi_remove_target(&raid_device->starget->dev);
5152 }
5153 _scsih_raid_device_remove(ioc, raid_device);
5154 break;
5155
5156 case MPI2_RAID_VOL_STATE_ONLINE:
5157 case MPI2_RAID_VOL_STATE_DEGRADED:
5158 case MPI2_RAID_VOL_STATE_OPTIMAL:
5159 if (raid_device)
5160 break;
5161
5162 mpt2sas_config_get_volume_wwid(ioc, handle, &wwid);
5163 if (!wwid) {
5164 printk(MPT2SAS_ERR_FMT
5165 "failure at %s:%d/%s()!\n", ioc->name,
5166 __FILE__, __LINE__, __func__);
5167 break;
5168 }
5169
5170 raid_device = kzalloc(sizeof(struct _raid_device), GFP_KERNEL);
5171 if (!raid_device) {
5172 printk(MPT2SAS_ERR_FMT
5173 "failure at %s:%d/%s()!\n", ioc->name,
5174 __FILE__, __LINE__, __func__);
5175 break;
5176 }
5177
5178 raid_device->id = ioc->sas_id++;
5179 raid_device->channel = RAID_CHANNEL;
5180 raid_device->handle = handle;
5181 raid_device->wwid = wwid;
5182 _scsih_raid_device_add(ioc, raid_device);
5183 rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
5184 raid_device->id, 0);
5185 if (rc)
5186 _scsih_raid_device_remove(ioc, raid_device);
5187 break;
5188
5189 case MPI2_RAID_VOL_STATE_INITIALIZING:
5190 default:
5191 break;
5192 }
5193}
5194
5195/**
5196 * _scsih_sas_ir_physical_disk_event - PD event
5197 * @ioc: per adapter object
7b936b02 5198 * @fw_event: The fw_event_work object
635374e7
EM
5199 * Context: user.
5200 *
5201 * Return nothing.
5202 */
5203static void
7b936b02
KD
5204_scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
5205 struct fw_event_work *fw_event)
635374e7 5206{
c5e039be 5207 u16 handle, parent_handle;
635374e7
EM
5208 u32 state;
5209 struct _sas_device *sas_device;
5210 unsigned long flags;
62727a7b
KD
5211 Mpi2ConfigReply_t mpi_reply;
5212 Mpi2SasDevicePage0_t sas_device_pg0;
5213 u32 ioc_status;
7b936b02 5214 Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data;
c5e039be 5215 u64 sas_address;
635374e7
EM
5216
5217 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
5218 return;
5219
5220 handle = le16_to_cpu(event_data->PhysDiskDevHandle);
5221 state = le32_to_cpu(event_data->NewValue);
5222
5223 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle(0x%04x), "
5224 "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle,
5225 le32_to_cpu(event_data->PreviousValue), state));
5226
5227 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5228 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
5229 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5230
5231 switch (state) {
635374e7
EM
5232 case MPI2_RAID_PD_STATE_ONLINE:
5233 case MPI2_RAID_PD_STATE_DEGRADED:
5234 case MPI2_RAID_PD_STATE_REBUILDING:
5235 case MPI2_RAID_PD_STATE_OPTIMAL:
62727a7b 5236 if (sas_device) {
635374e7 5237 sas_device->hidden_raid_component = 1;
62727a7b
KD
5238 return;
5239 }
5240
5241 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
5242 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
5243 handle))) {
5244 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
5245 ioc->name, __FILE__, __LINE__, __func__);
5246 return;
5247 }
5248
5249 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
5250 MPI2_IOCSTATUS_MASK;
5251 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
5252 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
5253 ioc->name, __FILE__, __LINE__, __func__);
5254 return;
5255 }
5256
c5e039be
KD
5257 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
5258 if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address))
5259 mpt2sas_transport_update_links(ioc, sas_address, handle,
5260 sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
62727a7b
KD
5261
5262 _scsih_add_device(ioc, handle, 0, 1);
5263
635374e7
EM
5264 break;
5265
62727a7b 5266 case MPI2_RAID_PD_STATE_OFFLINE:
635374e7
EM
5267 case MPI2_RAID_PD_STATE_NOT_CONFIGURED:
5268 case MPI2_RAID_PD_STATE_NOT_COMPATIBLE:
5269 case MPI2_RAID_PD_STATE_HOT_SPARE:
5270 default:
5271 break;
5272 }
5273}
5274
5275#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
5276/**
5277 * _scsih_sas_ir_operation_status_event_debug - debug for IR op event
5278 * @ioc: per adapter object
5279 * @event_data: event data payload
5280 * Context: user.
5281 *
5282 * Return nothing.
5283 */
5284static void
5285_scsih_sas_ir_operation_status_event_debug(struct MPT2SAS_ADAPTER *ioc,
5286 Mpi2EventDataIrOperationStatus_t *event_data)
5287{
5288 char *reason_str = NULL;
5289
5290 switch (event_data->RAIDOperation) {
5291 case MPI2_EVENT_IR_RAIDOP_RESYNC:
5292 reason_str = "resync";
5293 break;
5294 case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION:
5295 reason_str = "online capacity expansion";
5296 break;
5297 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK:
5298 reason_str = "consistency check";
5299 break;
ec6c2b43
KD
5300 case MPI2_EVENT_IR_RAIDOP_BACKGROUND_INIT:
5301 reason_str = "background init";
5302 break;
5303 case MPI2_EVENT_IR_RAIDOP_MAKE_DATA_CONSISTENT:
5304 reason_str = "make data consistent";
635374e7
EM
5305 break;
5306 }
5307
ec6c2b43
KD
5308 if (!reason_str)
5309 return;
5310
635374e7
EM
5311 printk(MPT2SAS_INFO_FMT "raid operational status: (%s)"
5312 "\thandle(0x%04x), percent complete(%d)\n",
5313 ioc->name, reason_str,
5314 le16_to_cpu(event_data->VolDevHandle),
5315 event_data->PercentComplete);
5316}
5317#endif
5318
5319/**
5320 * _scsih_sas_ir_operation_status_event - handle RAID operation events
5321 * @ioc: per adapter object
7b936b02 5322 * @fw_event: The fw_event_work object
635374e7
EM
5323 * Context: user.
5324 *
5325 * Return nothing.
5326 */
5327static void
7b936b02
KD
5328_scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc,
5329 struct fw_event_work *fw_event)
635374e7 5330{
f7c95ef0
KD
5331 Mpi2EventDataIrOperationStatus_t *event_data = fw_event->event_data;
5332 static struct _raid_device *raid_device;
5333 unsigned long flags;
5334 u16 handle;
5335
635374e7
EM
5336#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
5337 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
7b936b02 5338 _scsih_sas_ir_operation_status_event_debug(ioc,
f7c95ef0 5339 event_data);
635374e7 5340#endif
f7c95ef0
KD
5341
5342 /* code added for raid transport support */
5343 if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) {
5344
5345 handle = le16_to_cpu(event_data->VolDevHandle);
5346
5347 spin_lock_irqsave(&ioc->raid_device_lock, flags);
5348 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
5349 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
5350
5351 if (!raid_device)
5352 return;
5353
5354 if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC)
5355 raid_device->percent_complete =
5356 event_data->PercentComplete;
5357 }
635374e7
EM
5358}
5359
5360/**
5361 * _scsih_task_set_full - handle task set full
5362 * @ioc: per adapter object
7b936b02 5363 * @fw_event: The fw_event_work object
635374e7
EM
5364 * Context: user.
5365 *
5366 * Throttle back qdepth.
5367 */
5368static void
7b936b02
KD
5369_scsih_task_set_full(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
5370 *fw_event)
635374e7
EM
5371{
5372 unsigned long flags;
5373 struct _sas_device *sas_device;
5374 static struct _raid_device *raid_device;
5375 struct scsi_device *sdev;
5376 int depth;
5377 u16 current_depth;
5378 u16 handle;
5379 int id, channel;
5380 u64 sas_address;
7b936b02 5381 Mpi2EventDataTaskSetFull_t *event_data = fw_event->event_data;
635374e7
EM
5382
5383 current_depth = le16_to_cpu(event_data->CurrentDepth);
5384 handle = le16_to_cpu(event_data->DevHandle);
5385 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5386 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
5387 if (!sas_device) {
5388 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5389 return;
5390 }
5391 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5392 id = sas_device->id;
5393 channel = sas_device->channel;
5394 sas_address = sas_device->sas_address;
5395
5396 /* if hidden raid component, then change to volume characteristics */
5397 if (sas_device->hidden_raid_component && sas_device->volume_handle) {
5398 spin_lock_irqsave(&ioc->raid_device_lock, flags);
5399 raid_device = _scsih_raid_device_find_by_handle(
5400 ioc, sas_device->volume_handle);
5401 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
5402 if (raid_device) {
5403 id = raid_device->id;
5404 channel = raid_device->channel;
5405 handle = raid_device->handle;
5406 sas_address = raid_device->wwid;
5407 }
5408 }
5409
5410 if (ioc->logging_level & MPT_DEBUG_TASK_SET_FULL)
5411 starget_printk(KERN_DEBUG, sas_device->starget, "task set "
5412 "full: handle(0x%04x), sas_addr(0x%016llx), depth(%d)\n",
5413 handle, (unsigned long long)sas_address, current_depth);
5414
5415 shost_for_each_device(sdev, ioc->shost) {
5416 if (sdev->id == id && sdev->channel == channel) {
5417 if (current_depth > sdev->queue_depth) {
5418 if (ioc->logging_level &
5419 MPT_DEBUG_TASK_SET_FULL)
5420 sdev_printk(KERN_INFO, sdev, "strange "
5421 "observation, the queue depth is"
5422 " (%d) meanwhile fw queue depth "
5423 "is (%d)\n", sdev->queue_depth,
5424 current_depth);
5425 continue;
5426 }
5427 depth = scsi_track_queue_full(sdev,
5428 current_depth - 1);
5429 if (depth > 0)
5430 sdev_printk(KERN_INFO, sdev, "Queue depth "
5431 "reduced to (%d)\n", depth);
5432 else if (depth < 0)
5433 sdev_printk(KERN_INFO, sdev, "Tagged Command "
5434 "Queueing is being disabled\n");
5435 else if (depth == 0)
5436 if (ioc->logging_level &
5437 MPT_DEBUG_TASK_SET_FULL)
5438 sdev_printk(KERN_INFO, sdev,
5439 "Queue depth not changed yet\n");
5440 }
5441 }
5442}
5443
5444/**
5445 * _scsih_mark_responding_sas_device - mark a sas_devices as responding
5446 * @ioc: per adapter object
5447 * @sas_address: sas address
5448 * @slot: enclosure slot id
5449 * @handle: device handle
5450 *
5451 * After host reset, find out whether devices are still responding.
5452 * Used in _scsi_remove_unresponsive_sas_devices.
5453 *
5454 * Return nothing.
5455 */
5456static void
5457_scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
5458 u16 slot, u16 handle)
5459{
5460 struct MPT2SAS_TARGET *sas_target_priv_data;
5461 struct scsi_target *starget;
5462 struct _sas_device *sas_device;
5463 unsigned long flags;
5464
5465 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5466 list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
5467 if (sas_device->sas_address == sas_address &&
5468 sas_device->slot == slot && sas_device->starget) {
5469 sas_device->responding = 1;
77e63ed4
KD
5470 sas_device->state = 0;
5471 starget = sas_device->starget;
5472 sas_target_priv_data = starget->hostdata;
5473 sas_target_priv_data->tm_busy = 0;
635374e7
EM
5474 starget_printk(KERN_INFO, sas_device->starget,
5475 "handle(0x%04x), sas_addr(0x%016llx), enclosure "
5476 "logical id(0x%016llx), slot(%d)\n", handle,
5477 (unsigned long long)sas_device->sas_address,
5478 (unsigned long long)
5479 sas_device->enclosure_logical_id,
5480 sas_device->slot);
5481 if (sas_device->handle == handle)
5482 goto out;
5483 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
5484 sas_device->handle);
5485 sas_device->handle = handle;
635374e7
EM
5486 sas_target_priv_data->handle = handle;
5487 goto out;
5488 }
5489 }
5490 out:
5491 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5492}
5493
5494/**
5495 * _scsih_search_responding_sas_devices -
5496 * @ioc: per adapter object
5497 *
5498 * After host reset, find out whether devices are still responding.
5499 * If not remove.
5500 *
5501 * Return nothing.
5502 */
5503static void
5504_scsih_search_responding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
5505{
5506 Mpi2SasDevicePage0_t sas_device_pg0;
5507 Mpi2ConfigReply_t mpi_reply;
5508 u16 ioc_status;
5509 __le64 sas_address;
5510 u16 handle;
5511 u32 device_info;
5512 u16 slot;
5513
5514 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__);
5515
5516 if (list_empty(&ioc->sas_device_list))
5517 return;
5518
5519 handle = 0xFFFF;
5520 while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
5521 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
5522 handle))) {
5523 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
5524 MPI2_IOCSTATUS_MASK;
5525 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
5526 break;
5527 handle = le16_to_cpu(sas_device_pg0.DevHandle);
5528 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
5529 if (!(_scsih_is_end_device(device_info)))
5530 continue;
5531 sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
5532 slot = le16_to_cpu(sas_device_pg0.Slot);
5533 _scsih_mark_responding_sas_device(ioc, sas_address, slot,
5534 handle);
5535 }
5536}
5537
5538/**
5539 * _scsih_mark_responding_raid_device - mark a raid_device as responding
5540 * @ioc: per adapter object
5541 * @wwid: world wide identifier for raid volume
5542 * @handle: device handle
5543 *
5544 * After host reset, find out whether devices are still responding.
5545 * Used in _scsi_remove_unresponsive_raid_devices.
5546 *
5547 * Return nothing.
5548 */
5549static void
5550_scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid,
5551 u16 handle)
5552{
5553 struct MPT2SAS_TARGET *sas_target_priv_data;
5554 struct scsi_target *starget;
5555 struct _raid_device *raid_device;
5556 unsigned long flags;
5557
5558 spin_lock_irqsave(&ioc->raid_device_lock, flags);
5559 list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
5560 if (raid_device->wwid == wwid && raid_device->starget) {
5561 raid_device->responding = 1;
5562 starget_printk(KERN_INFO, raid_device->starget,
5563 "handle(0x%04x), wwid(0x%016llx)\n", handle,
5564 (unsigned long long)raid_device->wwid);
5565 if (raid_device->handle == handle)
5566 goto out;
5567 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
5568 raid_device->handle);
5569 raid_device->handle = handle;
5570 starget = raid_device->starget;
5571 sas_target_priv_data = starget->hostdata;
5572 sas_target_priv_data->handle = handle;
5573 goto out;
5574 }
5575 }
5576 out:
5577 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
5578}
5579
5580/**
5581 * _scsih_search_responding_raid_devices -
5582 * @ioc: per adapter object
5583 *
5584 * After host reset, find out whether devices are still responding.
5585 * If not remove.
5586 *
5587 * Return nothing.
5588 */
5589static void
5590_scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
5591{
5592 Mpi2RaidVolPage1_t volume_pg1;
5593 Mpi2ConfigReply_t mpi_reply;
5594 u16 ioc_status;
5595 u16 handle;
5596
5597 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__);
5598
5599 if (list_empty(&ioc->raid_device_list))
5600 return;
5601
5602 handle = 0xFFFF;
5603 while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
5604 &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
5605 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
5606 MPI2_IOCSTATUS_MASK;
5607 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
5608 break;
5609 handle = le16_to_cpu(volume_pg1.DevHandle);
5610 _scsih_mark_responding_raid_device(ioc,
5611 le64_to_cpu(volume_pg1.WWID), handle);
5612 }
5613}
5614
5615/**
5616 * _scsih_mark_responding_expander - mark a expander as responding
5617 * @ioc: per adapter object
5618 * @sas_address: sas address
5619 * @handle:
5620 *
5621 * After host reset, find out whether devices are still responding.
5622 * Used in _scsi_remove_unresponsive_expanders.
5623 *
5624 * Return nothing.
5625 */
5626static void
5627_scsih_mark_responding_expander(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
5628 u16 handle)
5629{
5630 struct _sas_node *sas_expander;
5631 unsigned long flags;
c5e039be 5632 int i;
635374e7
EM
5633
5634 spin_lock_irqsave(&ioc->sas_node_lock, flags);
5635 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
c5e039be
KD
5636 if (sas_expander->sas_address != sas_address)
5637 continue;
5638 sas_expander->responding = 1;
5639 if (sas_expander->handle == handle)
635374e7 5640 goto out;
c5e039be
KD
5641 printk(KERN_INFO "\texpander(0x%016llx): handle changed"
5642 " from(0x%04x) to (0x%04x)!!!\n",
5643 (unsigned long long)sas_expander->sas_address,
5644 sas_expander->handle, handle);
5645 sas_expander->handle = handle;
5646 for (i = 0 ; i < sas_expander->num_phys ; i++)
5647 sas_expander->phy[i].handle = handle;
5648 goto out;
635374e7
EM
5649 }
5650 out:
5651 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
5652}
5653
5654/**
5655 * _scsih_search_responding_expanders -
5656 * @ioc: per adapter object
5657 *
5658 * After host reset, find out whether devices are still responding.
5659 * If not remove.
5660 *
5661 * Return nothing.
5662 */
5663static void
5664_scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc)
5665{
5666 Mpi2ExpanderPage0_t expander_pg0;
5667 Mpi2ConfigReply_t mpi_reply;
5668 u16 ioc_status;
5669 __le64 sas_address;
5670 u16 handle;
5671
5672 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__);
5673
5674 if (list_empty(&ioc->sas_expander_list))
5675 return;
5676
5677 handle = 0xFFFF;
5678 while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
5679 MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) {
5680
5681 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
5682 MPI2_IOCSTATUS_MASK;
5683 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
5684 break;
5685
5686 handle = le16_to_cpu(expander_pg0.DevHandle);
5687 sas_address = le64_to_cpu(expander_pg0.SASAddress);
5688 printk(KERN_INFO "\texpander present: handle(0x%04x), "
5689 "sas_addr(0x%016llx)\n", handle,
5690 (unsigned long long)sas_address);
5691 _scsih_mark_responding_expander(ioc, sas_address, handle);
5692 }
5693
5694}
5695
5696/**
5697 * _scsih_remove_unresponding_devices - removing unresponding devices
5698 * @ioc: per adapter object
5699 *
5700 * Return nothing.
5701 */
5702static void
5703_scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
5704{
5705 struct _sas_device *sas_device, *sas_device_next;
cd4e12e8 5706 struct _sas_node *sas_expander;
635374e7 5707 struct _raid_device *raid_device, *raid_device_next;
635374e7 5708
635374e7
EM
5709
5710 list_for_each_entry_safe(sas_device, sas_device_next,
5711 &ioc->sas_device_list, list) {
5712 if (sas_device->responding) {
5713 sas_device->responding = 0;
5714 continue;
5715 }
5716 if (sas_device->starget)
5717 starget_printk(KERN_INFO, sas_device->starget,
5718 "removing: handle(0x%04x), sas_addr(0x%016llx), "
5719 "enclosure logical id(0x%016llx), slot(%d)\n",
5720 sas_device->handle,
5721 (unsigned long long)sas_device->sas_address,
5722 (unsigned long long)
5723 sas_device->enclosure_logical_id,
5724 sas_device->slot);
c5e039be
KD
5725 /* invalidate the device handle */
5726 sas_device->handle = 0;
5727 _scsih_remove_device(ioc, sas_device);
635374e7
EM
5728 }
5729
5730 list_for_each_entry_safe(raid_device, raid_device_next,
5731 &ioc->raid_device_list, list) {
5732 if (raid_device->responding) {
5733 raid_device->responding = 0;
5734 continue;
5735 }
5736 if (raid_device->starget) {
5737 starget_printk(KERN_INFO, raid_device->starget,
5738 "removing: handle(0x%04x), wwid(0x%016llx)\n",
5739 raid_device->handle,
5740 (unsigned long long)raid_device->wwid);
5741 scsi_remove_target(&raid_device->starget->dev);
5742 }
5743 _scsih_raid_device_remove(ioc, raid_device);
5744 }
5745
cd4e12e8
KD
5746 retry_expander_search:
5747 sas_expander = NULL;
5748 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
635374e7
EM
5749 if (sas_expander->responding) {
5750 sas_expander->responding = 0;
5751 continue;
5752 }
c5e039be 5753 _scsih_expander_remove(ioc, sas_expander->sas_address);
cd4e12e8
KD
5754 goto retry_expander_search;
5755 }
5756}
5757
5758/**
5759 * mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
5760 * @ioc: per adapter object
5761 * @reset_phase: phase
5762 *
5763 * The handler for doing any required cleanup or initialization.
5764 *
5765 * The reset phase can be MPT2_IOC_PRE_RESET, MPT2_IOC_AFTER_RESET,
5766 * MPT2_IOC_DONE_RESET
5767 *
5768 * Return nothing.
5769 */
5770void
5771mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
5772{
5773 switch (reset_phase) {
5774 case MPT2_IOC_PRE_RESET:
5775 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
5776 "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
5777 _scsih_fw_event_off(ioc);
5778 break;
5779 case MPT2_IOC_AFTER_RESET:
5780 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
5781 "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
5782 if (ioc->tm_cmds.status & MPT2_CMD_PENDING) {
5783 ioc->tm_cmds.status |= MPT2_CMD_RESET;
5784 mpt2sas_base_free_smid(ioc, ioc->tm_cmds.smid);
5785 complete(&ioc->tm_cmds.done);
5786 }
5787 _scsih_fw_event_on(ioc);
5788 _scsih_flush_running_cmds(ioc);
5789 break;
5790 case MPT2_IOC_DONE_RESET:
5791 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
5792 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
c5e039be 5793 _scsih_sas_host_refresh(ioc);
cd4e12e8
KD
5794 _scsih_search_responding_sas_devices(ioc);
5795 _scsih_search_responding_raid_devices(ioc);
5796 _scsih_search_responding_expanders(ioc);
5797 break;
5798 case MPT2_IOC_RUNNING:
5799 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
5800 "MPT2_IOC_RUNNING\n", ioc->name, __func__));
5801 _scsih_remove_unresponding_devices(ioc);
5802 break;
635374e7
EM
5803 }
5804}
5805
5806/**
5807 * _firmware_event_work - delayed task for processing firmware events
5808 * @ioc: per adapter object
5809 * @work: equal to the fw_event_work object
5810 * Context: user.
5811 *
5812 * Return nothing.
5813 */
5814static void
5815_firmware_event_work(struct work_struct *work)
5816{
5817 struct fw_event_work *fw_event = container_of(work,
6f92a7a0 5818 struct fw_event_work, work);
635374e7
EM
5819 unsigned long flags;
5820 struct MPT2SAS_ADAPTER *ioc = fw_event->ioc;
5821
635374e7
EM
5822 /* the queue is being flushed so ignore this event */
5823 spin_lock_irqsave(&ioc->fw_event_lock, flags);
5824 if (ioc->fw_events_off || ioc->remove_host) {
5825 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5826 _scsih_fw_event_free(ioc, fw_event);
5827 return;
5828 }
5829 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5830
635374e7 5831 if (ioc->shost_recovery) {
635374e7
EM
5832 _scsih_fw_event_requeue(ioc, fw_event, 1000);
5833 return;
5834 }
635374e7
EM
5835
5836 switch (fw_event->event) {
5837 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
7b936b02 5838 _scsih_sas_topology_change_event(ioc, fw_event);
635374e7
EM
5839 break;
5840 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
7b936b02
KD
5841 _scsih_sas_device_status_change_event(ioc,
5842 fw_event);
635374e7
EM
5843 break;
5844 case MPI2_EVENT_SAS_DISCOVERY:
7b936b02
KD
5845 _scsih_sas_discovery_event(ioc,
5846 fw_event);
635374e7
EM
5847 break;
5848 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
7b936b02
KD
5849 _scsih_sas_broadcast_primative_event(ioc,
5850 fw_event);
635374e7
EM
5851 break;
5852 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
5853 _scsih_sas_enclosure_dev_status_change_event(ioc,
7b936b02 5854 fw_event);
635374e7
EM
5855 break;
5856 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
7b936b02 5857 _scsih_sas_ir_config_change_event(ioc, fw_event);
635374e7
EM
5858 break;
5859 case MPI2_EVENT_IR_VOLUME:
7b936b02 5860 _scsih_sas_ir_volume_event(ioc, fw_event);
635374e7
EM
5861 break;
5862 case MPI2_EVENT_IR_PHYSICAL_DISK:
7b936b02 5863 _scsih_sas_ir_physical_disk_event(ioc, fw_event);
635374e7
EM
5864 break;
5865 case MPI2_EVENT_IR_OPERATION_STATUS:
7b936b02 5866 _scsih_sas_ir_operation_status_event(ioc, fw_event);
635374e7
EM
5867 break;
5868 case MPI2_EVENT_TASK_SET_FULL:
7b936b02 5869 _scsih_task_set_full(ioc, fw_event);
635374e7
EM
5870 break;
5871 }
5872 _scsih_fw_event_free(ioc, fw_event);
5873}
5874
5875/**
5876 * mpt2sas_scsih_event_callback - firmware event handler (called at ISR time)
5877 * @ioc: per adapter object
7b936b02 5878 * @msix_index: MSIX table index supplied by the OS
635374e7
EM
5879 * @reply: reply message frame(lower 32bit addr)
5880 * Context: interrupt.
5881 *
5882 * This function merely adds a new work task into ioc->firmware_event_thread.
5883 * The tasks are worked from _firmware_event_work in user context.
5884 *
77e63ed4
KD
5885 * Return 1 meaning mf should be freed from _base_interrupt
5886 * 0 means the mf is freed from this function.
635374e7 5887 */
77e63ed4 5888u8
7b936b02
KD
5889mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
5890 u32 reply)
635374e7
EM
5891{
5892 struct fw_event_work *fw_event;
5893 Mpi2EventNotificationReply_t *mpi_reply;
5894 unsigned long flags;
5895 u16 event;
5896
5897 /* events turned off due to host reset or driver unloading */
5898 spin_lock_irqsave(&ioc->fw_event_lock, flags);
5899 if (ioc->fw_events_off || ioc->remove_host) {
5900 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
77e63ed4 5901 return 1;
635374e7
EM
5902 }
5903 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5904
77e63ed4 5905 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
635374e7
EM
5906 event = le16_to_cpu(mpi_reply->Event);
5907
5908 switch (event) {
5909 /* handle these */
5910 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
5911 {
5912 Mpi2EventDataSasBroadcastPrimitive_t *baen_data =
5913 (Mpi2EventDataSasBroadcastPrimitive_t *)
5914 mpi_reply->EventData;
5915
5916 if (baen_data->Primitive !=
5917 MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT ||
5918 ioc->broadcast_aen_busy)
77e63ed4 5919 return 1;
635374e7
EM
5920 ioc->broadcast_aen_busy = 1;
5921 break;
5922 }
5923
5924 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
5925 _scsih_check_topo_delete_events(ioc,
5926 (Mpi2EventDataSasTopologyChangeList_t *)
5927 mpi_reply->EventData);
5928 break;
5929
5930 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
5931 case MPI2_EVENT_IR_OPERATION_STATUS:
5932 case MPI2_EVENT_SAS_DISCOVERY:
5933 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
5934 case MPI2_EVENT_IR_VOLUME:
5935 case MPI2_EVENT_IR_PHYSICAL_DISK:
5936 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
5937 case MPI2_EVENT_TASK_SET_FULL:
5938 break;
5939
5940 default: /* ignore the rest */
77e63ed4 5941 return 1;
635374e7
EM
5942 }
5943
5944 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
5945 if (!fw_event) {
5946 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
5947 ioc->name, __FILE__, __LINE__, __func__);
77e63ed4 5948 return 1;
635374e7
EM
5949 }
5950 fw_event->event_data =
5951 kzalloc(mpi_reply->EventDataLength*4, GFP_ATOMIC);
5952 if (!fw_event->event_data) {
5953 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
5954 ioc->name, __FILE__, __LINE__, __func__);
5955 kfree(fw_event);
77e63ed4 5956 return 1;
635374e7
EM
5957 }
5958
5959 memcpy(fw_event->event_data, mpi_reply->EventData,
5960 mpi_reply->EventDataLength*4);
5961 fw_event->ioc = ioc;
7b936b02
KD
5962 fw_event->VF_ID = mpi_reply->VF_ID;
5963 fw_event->VP_ID = mpi_reply->VP_ID;
635374e7
EM
5964 fw_event->event = event;
5965 _scsih_fw_event_add(ioc, fw_event);
77e63ed4 5966 return 1;
635374e7
EM
5967}
5968
5969/* shost template */
5970static struct scsi_host_template scsih_driver_template = {
5971 .module = THIS_MODULE,
5972 .name = "Fusion MPT SAS Host",
5973 .proc_name = MPT2SAS_DRIVER_NAME,
d5d135b3
EM
5974 .queuecommand = _scsih_qcmd,
5975 .target_alloc = _scsih_target_alloc,
5976 .slave_alloc = _scsih_slave_alloc,
5977 .slave_configure = _scsih_slave_configure,
5978 .target_destroy = _scsih_target_destroy,
5979 .slave_destroy = _scsih_slave_destroy,
5980 .change_queue_depth = _scsih_change_queue_depth,
5981 .change_queue_type = _scsih_change_queue_type,
5982 .eh_abort_handler = _scsih_abort,
5983 .eh_device_reset_handler = _scsih_dev_reset,
5984 .eh_target_reset_handler = _scsih_target_reset,
5985 .eh_host_reset_handler = _scsih_host_reset,
5986 .bios_param = _scsih_bios_param,
635374e7
EM
5987 .can_queue = 1,
5988 .this_id = -1,
5989 .sg_tablesize = MPT2SAS_SG_DEPTH,
5990 .max_sectors = 8192,
5991 .cmd_per_lun = 7,
5992 .use_clustering = ENABLE_CLUSTERING,
5993 .shost_attrs = mpt2sas_host_attrs,
5994 .sdev_attrs = mpt2sas_dev_attrs,
5995};
5996
5997/**
5998 * _scsih_expander_node_remove - removing expander device from list.
5999 * @ioc: per adapter object
6000 * @sas_expander: the sas_device object
6001 * Context: Calling function should acquire ioc->sas_node_lock.
6002 *
6003 * Removing object and freeing associated memory from the
6004 * ioc->sas_expander_list.
6005 *
6006 * Return nothing.
6007 */
6008static void
6009_scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
6010 struct _sas_node *sas_expander)
6011{
6012 struct _sas_port *mpt2sas_port;
6013 struct _sas_device *sas_device;
6014 struct _sas_node *expander_sibling;
6015 unsigned long flags;
6016
6017 if (!sas_expander)
6018 return;
6019
6020 /* remove sibling ports attached to this expander */
6021 retry_device_search:
6022 list_for_each_entry(mpt2sas_port,
6023 &sas_expander->sas_port_list, port_list) {
6024 if (mpt2sas_port->remote_identify.device_type ==
6025 SAS_END_DEVICE) {
6026 spin_lock_irqsave(&ioc->sas_device_lock, flags);
6027 sas_device =
6028 mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
6029 mpt2sas_port->remote_identify.sas_address);
6030 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
6031 if (!sas_device)
6032 continue;
c5e039be 6033 _scsih_remove_device(ioc, sas_device);
155dd4c7
KD
6034 if (ioc->shost_recovery)
6035 return;
635374e7
EM
6036 goto retry_device_search;
6037 }
6038 }
6039
6040 retry_expander_search:
6041 list_for_each_entry(mpt2sas_port,
6042 &sas_expander->sas_port_list, port_list) {
6043
6044 if (mpt2sas_port->remote_identify.device_type ==
6045 MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
6046 mpt2sas_port->remote_identify.device_type ==
6047 MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
6048
6049 spin_lock_irqsave(&ioc->sas_node_lock, flags);
6050 expander_sibling =
6051 mpt2sas_scsih_expander_find_by_sas_address(
6052 ioc, mpt2sas_port->remote_identify.sas_address);
6053 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
6054 if (!expander_sibling)
6055 continue;
c5e039be
KD
6056 _scsih_expander_remove(ioc,
6057 expander_sibling->sas_address);
155dd4c7
KD
6058 if (ioc->shost_recovery)
6059 return;
635374e7
EM
6060 goto retry_expander_search;
6061 }
6062 }
6063
6064 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
c5e039be 6065 sas_expander->sas_address_parent);
635374e7
EM
6066
6067 printk(MPT2SAS_INFO_FMT "expander_remove: handle"
6068 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name,
6069 sas_expander->handle, (unsigned long long)
6070 sas_expander->sas_address);
6071
6072 list_del(&sas_expander->list);
6073 kfree(sas_expander->phy);
6074 kfree(sas_expander);
6075}
6076
744090d3
KD
6077/**
6078 * _scsih_ir_shutdown - IR shutdown notification
6079 * @ioc: per adapter object
6080 *
6081 * Sending RAID Action to alert the Integrated RAID subsystem of the IOC that
6082 * the host system is shutting down.
6083 *
6084 * Return nothing.
6085 */
6086static void
6087_scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc)
6088{
6089 Mpi2RaidActionRequest_t *mpi_request;
6090 Mpi2RaidActionReply_t *mpi_reply;
6091 u16 smid;
6092
6093 /* is IR firmware build loaded ? */
6094 if (!ioc->ir_firmware)
6095 return;
6096
6097 /* are there any volumes ? */
6098 if (list_empty(&ioc->raid_device_list))
6099 return;
6100
6101 mutex_lock(&ioc->scsih_cmds.mutex);
6102
6103 if (ioc->scsih_cmds.status != MPT2_CMD_NOT_USED) {
6104 printk(MPT2SAS_ERR_FMT "%s: scsih_cmd in use\n",
6105 ioc->name, __func__);
6106 goto out;
6107 }
6108 ioc->scsih_cmds.status = MPT2_CMD_PENDING;
6109
6110 smid = mpt2sas_base_get_smid(ioc, ioc->scsih_cb_idx);
6111 if (!smid) {
6112 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
6113 ioc->name, __func__);
6114 ioc->scsih_cmds.status = MPT2_CMD_NOT_USED;
6115 goto out;
6116 }
6117
6118 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
6119 ioc->scsih_cmds.smid = smid;
6120 memset(mpi_request, 0, sizeof(Mpi2RaidActionRequest_t));
6121
6122 mpi_request->Function = MPI2_FUNCTION_RAID_ACTION;
6123 mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
6124
6125 printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name);
6126 init_completion(&ioc->scsih_cmds.done);
6127 mpt2sas_base_put_smid_default(ioc, smid);
6128 wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ);
6129
6130 if (!(ioc->scsih_cmds.status & MPT2_CMD_COMPLETE)) {
6131 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
6132 ioc->name, __func__);
6133 goto out;
6134 }
6135
6136 if (ioc->scsih_cmds.status & MPT2_CMD_REPLY_VALID) {
6137 mpi_reply = ioc->scsih_cmds.reply;
6138
6139 printk(MPT2SAS_INFO_FMT "IR shutdown (complete): "
6140 "ioc_status(0x%04x), loginfo(0x%08x)\n",
6141 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
6142 le32_to_cpu(mpi_reply->IOCLogInfo));
6143 }
6144
6145 out:
6146 ioc->scsih_cmds.status = MPT2_CMD_NOT_USED;
6147 mutex_unlock(&ioc->scsih_cmds.mutex);
6148}
6149
6150/**
6151 * _scsih_shutdown - routine call during system shutdown
6152 * @pdev: PCI device struct
6153 *
6154 * Return nothing.
6155 */
6156static void
6157_scsih_shutdown(struct pci_dev *pdev)
6158{
6159 struct Scsi_Host *shost = pci_get_drvdata(pdev);
6160 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
6161
6162 _scsih_ir_shutdown(ioc);
6163 mpt2sas_base_detach(ioc);
6164}
6165
635374e7 6166/**
d5d135b3 6167 * _scsih_remove - detach and remove add host
635374e7
EM
6168 * @pdev: PCI device struct
6169 *
744090d3 6170 * Routine called when unloading the driver.
635374e7
EM
6171 * Return nothing.
6172 */
6173static void __devexit
d5d135b3 6174_scsih_remove(struct pci_dev *pdev)
635374e7
EM
6175{
6176 struct Scsi_Host *shost = pci_get_drvdata(pdev);
6177 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
6178 struct _sas_port *mpt2sas_port;
6179 struct _sas_device *sas_device;
6180 struct _sas_node *expander_sibling;
d7384b28
KD
6181 struct _raid_device *raid_device, *next;
6182 struct MPT2SAS_TARGET *sas_target_priv_data;
635374e7
EM
6183 struct workqueue_struct *wq;
6184 unsigned long flags;
6185
6186 ioc->remove_host = 1;
6187 _scsih_fw_event_off(ioc);
6188
6189 spin_lock_irqsave(&ioc->fw_event_lock, flags);
6190 wq = ioc->firmware_event_thread;
6191 ioc->firmware_event_thread = NULL;
6192 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
6193 if (wq)
6194 destroy_workqueue(wq);
6195
d7384b28
KD
6196 /* release all the volumes */
6197 list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list,
6198 list) {
6199 if (raid_device->starget) {
6200 sas_target_priv_data =
6201 raid_device->starget->hostdata;
6202 sas_target_priv_data->deleted = 1;
6203 scsi_remove_target(&raid_device->starget->dev);
6204 }
6205 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid"
6206 "(0x%016llx)\n", ioc->name, raid_device->handle,
6207 (unsigned long long) raid_device->wwid);
6208 _scsih_raid_device_remove(ioc, raid_device);
6209 }
6210
635374e7
EM
6211 /* free ports attached to the sas_host */
6212 retry_again:
6213 list_for_each_entry(mpt2sas_port,
6214 &ioc->sas_hba.sas_port_list, port_list) {
6215 if (mpt2sas_port->remote_identify.device_type ==
6216 SAS_END_DEVICE) {
6217 sas_device =
6218 mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
6219 mpt2sas_port->remote_identify.sas_address);
6220 if (sas_device) {
c5e039be 6221 _scsih_remove_device(ioc, sas_device);
635374e7
EM
6222 goto retry_again;
6223 }
6224 } else {
6225 expander_sibling =
6226 mpt2sas_scsih_expander_find_by_sas_address(ioc,
6227 mpt2sas_port->remote_identify.sas_address);
6228 if (expander_sibling) {
6229 _scsih_expander_remove(ioc,
c5e039be 6230 expander_sibling->sas_address);
635374e7
EM
6231 goto retry_again;
6232 }
6233 }
6234 }
6235
6236 /* free phys attached to the sas_host */
6237 if (ioc->sas_hba.num_phys) {
6238 kfree(ioc->sas_hba.phy);
6239 ioc->sas_hba.phy = NULL;
6240 ioc->sas_hba.num_phys = 0;
6241 }
6242
6243 sas_remove_host(shost);
744090d3 6244 _scsih_shutdown(pdev);
635374e7
EM
6245 list_del(&ioc->list);
6246 scsi_remove_host(shost);
6247 scsi_host_put(shost);
6248}
6249
6250/**
6251 * _scsih_probe_boot_devices - reports 1st device
6252 * @ioc: per adapter object
6253 *
6254 * If specified in bios page 2, this routine reports the 1st
6255 * device scsi-ml or sas transport for persistent boot device
6256 * purposes. Please refer to function _scsih_determine_boot_device()
6257 */
6258static void
6259_scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
6260{
6261 u8 is_raid;
6262 void *device;
6263 struct _sas_device *sas_device;
6264 struct _raid_device *raid_device;
c5e039be
KD
6265 u16 handle;
6266 u64 sas_address_parent;
635374e7
EM
6267 u64 sas_address;
6268 unsigned long flags;
6269 int rc;
6270
6271 device = NULL;
6272 if (ioc->req_boot_device.device) {
6273 device = ioc->req_boot_device.device;
6274 is_raid = ioc->req_boot_device.is_raid;
6275 } else if (ioc->req_alt_boot_device.device) {
6276 device = ioc->req_alt_boot_device.device;
6277 is_raid = ioc->req_alt_boot_device.is_raid;
6278 } else if (ioc->current_boot_device.device) {
6279 device = ioc->current_boot_device.device;
6280 is_raid = ioc->current_boot_device.is_raid;
6281 }
6282
6283 if (!device)
6284 return;
6285
6286 if (is_raid) {
6287 raid_device = device;
6288 rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
6289 raid_device->id, 0);
6290 if (rc)
6291 _scsih_raid_device_remove(ioc, raid_device);
6292 } else {
6293 sas_device = device;
6294 handle = sas_device->handle;
c5e039be 6295 sas_address_parent = sas_device->sas_address_parent;
635374e7
EM
6296 sas_address = sas_device->sas_address;
6297 spin_lock_irqsave(&ioc->sas_device_lock, flags);
6298 list_move_tail(&sas_device->list, &ioc->sas_device_list);
6299 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
6300 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
c5e039be 6301 sas_device->sas_address_parent)) {
635374e7
EM
6302 _scsih_sas_device_remove(ioc, sas_device);
6303 } else if (!sas_device->starget) {
6304 mpt2sas_transport_port_remove(ioc, sas_address,
c5e039be 6305 sas_address_parent);
635374e7
EM
6306 _scsih_sas_device_remove(ioc, sas_device);
6307 }
6308 }
6309}
6310
6311/**
6312 * _scsih_probe_raid - reporting raid volumes to scsi-ml
6313 * @ioc: per adapter object
6314 *
6315 * Called during initial loading of the driver.
6316 */
6317static void
6318_scsih_probe_raid(struct MPT2SAS_ADAPTER *ioc)
6319{
6320 struct _raid_device *raid_device, *raid_next;
6321 int rc;
6322
6323 list_for_each_entry_safe(raid_device, raid_next,
6324 &ioc->raid_device_list, list) {
6325 if (raid_device->starget)
6326 continue;
6327 rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
6328 raid_device->id, 0);
6329 if (rc)
6330 _scsih_raid_device_remove(ioc, raid_device);
6331 }
6332}
6333
6334/**
77e63ed4 6335 * _scsih_probe_sas - reporting sas devices to sas transport
635374e7
EM
6336 * @ioc: per adapter object
6337 *
6338 * Called during initial loading of the driver.
6339 */
6340static void
6341_scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
6342{
6343 struct _sas_device *sas_device, *next;
6344 unsigned long flags;
635374e7
EM
6345
6346 /* SAS Device List */
6347 list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list,
6348 list) {
6349 spin_lock_irqsave(&ioc->sas_device_lock, flags);
6350 list_move_tail(&sas_device->list, &ioc->sas_device_list);
6351 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
6352
c5e039be
KD
6353 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
6354 sas_device->sas_address_parent)) {
635374e7
EM
6355 _scsih_sas_device_remove(ioc, sas_device);
6356 } else if (!sas_device->starget) {
c5e039be
KD
6357 mpt2sas_transport_port_remove(ioc,
6358 sas_device->sas_address,
6359 sas_device->sas_address_parent);
635374e7
EM
6360 _scsih_sas_device_remove(ioc, sas_device);
6361 }
6362 }
6363}
6364
6365/**
6366 * _scsih_probe_devices - probing for devices
6367 * @ioc: per adapter object
6368 *
6369 * Called during initial loading of the driver.
6370 */
6371static void
6372_scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc)
6373{
6374 u16 volume_mapping_flags =
6375 le16_to_cpu(ioc->ioc_pg8.IRVolumeMappingFlags) &
6376 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
6377
6378 if (!(ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR))
6379 return; /* return when IOC doesn't support initiator mode */
6380
6381 _scsih_probe_boot_devices(ioc);
6382
6383 if (ioc->ir_firmware) {
6384 if ((volume_mapping_flags &
6385 MPI2_IOCPAGE8_IRFLAGS_HIGH_VOLUME_MAPPING)) {
6386 _scsih_probe_sas(ioc);
6387 _scsih_probe_raid(ioc);
6388 } else {
6389 _scsih_probe_raid(ioc);
6390 _scsih_probe_sas(ioc);
6391 }
6392 } else
6393 _scsih_probe_sas(ioc);
6394}
6395
6396/**
d5d135b3 6397 * _scsih_probe - attach and add scsi host
635374e7
EM
6398 * @pdev: PCI device struct
6399 * @id: pci device id
6400 *
6401 * Returns 0 success, anything else error.
6402 */
6403static int
d5d135b3 6404_scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
635374e7
EM
6405{
6406 struct MPT2SAS_ADAPTER *ioc;
6407 struct Scsi_Host *shost;
6408
6409 shost = scsi_host_alloc(&scsih_driver_template,
6410 sizeof(struct MPT2SAS_ADAPTER));
6411 if (!shost)
6412 return -ENODEV;
6413
6414 /* init local params */
6415 ioc = shost_priv(shost);
6416 memset(ioc, 0, sizeof(struct MPT2SAS_ADAPTER));
6417 INIT_LIST_HEAD(&ioc->list);
ba33fadf 6418 list_add_tail(&ioc->list, &mpt2sas_ioc_list);
635374e7
EM
6419 ioc->shost = shost;
6420 ioc->id = mpt_ids++;
6421 sprintf(ioc->name, "%s%d", MPT2SAS_DRIVER_NAME, ioc->id);
6422 ioc->pdev = pdev;
6423 ioc->scsi_io_cb_idx = scsi_io_cb_idx;
6424 ioc->tm_cb_idx = tm_cb_idx;
6425 ioc->ctl_cb_idx = ctl_cb_idx;
6426 ioc->base_cb_idx = base_cb_idx;
6427 ioc->transport_cb_idx = transport_cb_idx;
744090d3 6428 ioc->scsih_cb_idx = scsih_cb_idx;
635374e7 6429 ioc->config_cb_idx = config_cb_idx;
77e63ed4
KD
6430 ioc->tm_tr_cb_idx = tm_tr_cb_idx;
6431 ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx;
635374e7
EM
6432 ioc->logging_level = logging_level;
6433 /* misc semaphores and spin locks */
6434 spin_lock_init(&ioc->ioc_reset_in_progress_lock);
6435 spin_lock_init(&ioc->scsi_lookup_lock);
6436 spin_lock_init(&ioc->sas_device_lock);
6437 spin_lock_init(&ioc->sas_node_lock);
6438 spin_lock_init(&ioc->fw_event_lock);
6439 spin_lock_init(&ioc->raid_device_lock);
6440
6441 INIT_LIST_HEAD(&ioc->sas_device_list);
6442 INIT_LIST_HEAD(&ioc->sas_device_init_list);
6443 INIT_LIST_HEAD(&ioc->sas_expander_list);
6444 INIT_LIST_HEAD(&ioc->fw_event_list);
6445 INIT_LIST_HEAD(&ioc->raid_device_list);
6446 INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list);
77e63ed4 6447 INIT_LIST_HEAD(&ioc->delayed_tr_list);
635374e7
EM
6448
6449 /* init shost parameters */
6450 shost->max_cmd_len = 16;
6451 shost->max_lun = max_lun;
6452 shost->transportt = mpt2sas_transport_template;
6453 shost->unique_id = ioc->id;
6454
6455 if ((scsi_add_host(shost, &pdev->dev))) {
6456 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
6457 ioc->name, __FILE__, __LINE__, __func__);
6458 list_del(&ioc->list);
6459 goto out_add_shost_fail;
6460 }
6461
3c621b3e
EM
6462 scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION
6463 | SHOST_DIF_TYPE3_PROTECTION);
77e63ed4 6464 scsi_host_set_guard(shost, SHOST_DIX_GUARD_CRC);
3c621b3e 6465
635374e7
EM
6466 /* event thread */
6467 snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name),
6468 "fw_event%d", ioc->id);
6469 ioc->firmware_event_thread = create_singlethread_workqueue(
6470 ioc->firmware_event_name);
6471 if (!ioc->firmware_event_thread) {
6472 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
6473 ioc->name, __FILE__, __LINE__, __func__);
6474 goto out_thread_fail;
6475 }
6476
6477 ioc->wait_for_port_enable_to_complete = 1;
6478 if ((mpt2sas_base_attach(ioc))) {
6479 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
6480 ioc->name, __FILE__, __LINE__, __func__);
6481 goto out_attach_fail;
6482 }
6483
6484 ioc->wait_for_port_enable_to_complete = 0;
6485 _scsih_probe_devices(ioc);
6486 return 0;
6487
6488 out_attach_fail:
6489 destroy_workqueue(ioc->firmware_event_thread);
6490 out_thread_fail:
6491 list_del(&ioc->list);
6492 scsi_remove_host(shost);
6493 out_add_shost_fail:
6494 return -ENODEV;
6495}
6496
6497#ifdef CONFIG_PM
6498/**
d5d135b3 6499 * _scsih_suspend - power management suspend main entry point
635374e7
EM
6500 * @pdev: PCI device struct
6501 * @state: PM state change to (usually PCI_D3)
6502 *
6503 * Returns 0 success, anything else error.
6504 */
6505static int
d5d135b3 6506_scsih_suspend(struct pci_dev *pdev, pm_message_t state)
635374e7
EM
6507{
6508 struct Scsi_Host *shost = pci_get_drvdata(pdev);
6509 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
6510 u32 device_state;
6511
e4750c98 6512 mpt2sas_base_stop_watchdog(ioc);
635374e7
EM
6513 flush_scheduled_work();
6514 scsi_block_requests(shost);
6515 device_state = pci_choose_state(pdev, state);
6516 printk(MPT2SAS_INFO_FMT "pdev=0x%p, slot=%s, entering "
6517 "operating state [D%d]\n", ioc->name, pdev,
6518 pci_name(pdev), device_state);
6519
6520 mpt2sas_base_free_resources(ioc);
6521 pci_save_state(pdev);
6522 pci_disable_device(pdev);
6523 pci_set_power_state(pdev, device_state);
6524 return 0;
6525}
6526
6527/**
d5d135b3 6528 * _scsih_resume - power management resume main entry point
635374e7
EM
6529 * @pdev: PCI device struct
6530 *
6531 * Returns 0 success, anything else error.
6532 */
6533static int
d5d135b3 6534_scsih_resume(struct pci_dev *pdev)
635374e7
EM
6535{
6536 struct Scsi_Host *shost = pci_get_drvdata(pdev);
6537 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
6538 u32 device_state = pdev->current_state;
6539 int r;
6540
6541 printk(MPT2SAS_INFO_FMT "pdev=0x%p, slot=%s, previous "
6542 "operating state [D%d]\n", ioc->name, pdev,
6543 pci_name(pdev), device_state);
6544
6545 pci_set_power_state(pdev, PCI_D0);
6546 pci_enable_wake(pdev, PCI_D0, 0);
6547 pci_restore_state(pdev);
6548 ioc->pdev = pdev;
6549 r = mpt2sas_base_map_resources(ioc);
6550 if (r)
6551 return r;
6552
6553 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, SOFT_RESET);
6554 scsi_unblock_requests(shost);
e4750c98 6555 mpt2sas_base_start_watchdog(ioc);
635374e7
EM
6556 return 0;
6557}
6558#endif /* CONFIG_PM */
6559
6560
6561static struct pci_driver scsih_driver = {
6562 .name = MPT2SAS_DRIVER_NAME,
6563 .id_table = scsih_pci_table,
d5d135b3
EM
6564 .probe = _scsih_probe,
6565 .remove = __devexit_p(_scsih_remove),
744090d3 6566 .shutdown = _scsih_shutdown,
635374e7 6567#ifdef CONFIG_PM
d5d135b3
EM
6568 .suspend = _scsih_suspend,
6569 .resume = _scsih_resume,
635374e7
EM
6570#endif
6571};
6572
f7c95ef0
KD
6573/* raid transport support */
6574static struct raid_function_template mpt2sas_raid_functions = {
6575 .cookie = &scsih_driver_template,
6576 .is_raid = _scsih_is_raid,
6577 .get_resync = _scsih_get_resync,
6578 .get_state = _scsih_get_state,
6579};
635374e7
EM
6580
6581/**
d5d135b3 6582 * _scsih_init - main entry point for this driver.
635374e7
EM
6583 *
6584 * Returns 0 success, anything else error.
6585 */
6586static int __init
d5d135b3 6587_scsih_init(void)
635374e7
EM
6588{
6589 int error;
6590
6591 mpt_ids = 0;
6592 printk(KERN_INFO "%s version %s loaded\n", MPT2SAS_DRIVER_NAME,
6593 MPT2SAS_DRIVER_VERSION);
6594
6595 mpt2sas_transport_template =
6596 sas_attach_transport(&mpt2sas_transport_functions);
6597 if (!mpt2sas_transport_template)
6598 return -ENODEV;
f7c95ef0
KD
6599 /* raid transport support */
6600 mpt2sas_raid_template = raid_class_attach(&mpt2sas_raid_functions);
6601 if (!mpt2sas_raid_template) {
6602 sas_release_transport(mpt2sas_transport_template);
6603 return -ENODEV;
6604 }
635374e7
EM
6605
6606 mpt2sas_base_initialize_callback_handler();
6607
6608 /* queuecommand callback hander */
d5d135b3 6609 scsi_io_cb_idx = mpt2sas_base_register_callback_handler(_scsih_io_done);
635374e7
EM
6610
6611 /* task managment callback handler */
d5d135b3 6612 tm_cb_idx = mpt2sas_base_register_callback_handler(_scsih_tm_done);
635374e7
EM
6613
6614 /* base internal commands callback handler */
6615 base_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_base_done);
6616
6617 /* transport internal commands callback handler */
6618 transport_cb_idx = mpt2sas_base_register_callback_handler(
6619 mpt2sas_transport_done);
6620
744090d3
KD
6621 /* scsih internal commands callback handler */
6622 scsih_cb_idx = mpt2sas_base_register_callback_handler(_scsih_done);
6623
635374e7
EM
6624 /* configuration page API internal commands callback handler */
6625 config_cb_idx = mpt2sas_base_register_callback_handler(
6626 mpt2sas_config_done);
6627
6628 /* ctl module callback handler */
6629 ctl_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_ctl_done);
6630
77e63ed4
KD
6631 tm_tr_cb_idx = mpt2sas_base_register_callback_handler(
6632 _scsih_tm_tr_complete);
6633 tm_sas_control_cb_idx = mpt2sas_base_register_callback_handler(
6634 _scsih_sas_control_complete);
6635
635374e7
EM
6636 mpt2sas_ctl_init();
6637
6638 error = pci_register_driver(&scsih_driver);
f7c95ef0
KD
6639 if (error) {
6640 /* raid transport support */
6641 raid_class_release(mpt2sas_raid_template);
635374e7 6642 sas_release_transport(mpt2sas_transport_template);
f7c95ef0 6643 }
635374e7
EM
6644
6645 return error;
6646}
6647
6648/**
d5d135b3 6649 * _scsih_exit - exit point for this driver (when it is a module).
635374e7
EM
6650 *
6651 * Returns 0 success, anything else error.
6652 */
6653static void __exit
d5d135b3 6654_scsih_exit(void)
635374e7
EM
6655{
6656 printk(KERN_INFO "mpt2sas version %s unloading\n",
6657 MPT2SAS_DRIVER_VERSION);
6658
6659 pci_unregister_driver(&scsih_driver);
6660
f7c95ef0
KD
6661 mpt2sas_ctl_exit();
6662
635374e7
EM
6663 mpt2sas_base_release_callback_handler(scsi_io_cb_idx);
6664 mpt2sas_base_release_callback_handler(tm_cb_idx);
6665 mpt2sas_base_release_callback_handler(base_cb_idx);
6666 mpt2sas_base_release_callback_handler(transport_cb_idx);
744090d3 6667 mpt2sas_base_release_callback_handler(scsih_cb_idx);
635374e7
EM
6668 mpt2sas_base_release_callback_handler(config_cb_idx);
6669 mpt2sas_base_release_callback_handler(ctl_cb_idx);
6670
77e63ed4
KD
6671 mpt2sas_base_release_callback_handler(tm_tr_cb_idx);
6672 mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx);
6673
f7c95ef0
KD
6674 /* raid transport support */
6675 raid_class_release(mpt2sas_raid_template);
6676 sas_release_transport(mpt2sas_transport_template);
6677
635374e7
EM
6678}
6679
d5d135b3
EM
6680module_init(_scsih_init);
6681module_exit(_scsih_exit);